vojtech-dobes / history.nette.ajax.js

Adds History API support to nette.ajax.js addon!
30 stars 27 forks source link

Add way how to force real redirect #1

Open voslartomas opened 10 years ago

voslartomas commented 10 years ago

Hi, what is the purpose of assigning redirect value to this.href? I've used old redirect function from nette.ajax and after session is expired, it was redirecting to login page. Now after implementation of history.nette.ajax, there is a problem, because it is not redirecting because of this condition.

if (redirect) {
        var regexp = new RegExp('//' + window.location.host + '($|/)');
        if ((redirect.substring(0,4) === 'http') ? regexp.test(redirect) : true) {
            this.href = redirect;
        } else {
            window.location.href = redirect;
        }
    }
vojtech-dobes commented 10 years ago

This code's purpose is to ensure, that if you make redirectUrl on serverside, you will be actually redirected there (in ajax, Nette will return the external URL in payload as usual). If it's not external URL, it's passed to this.href, so it can be processed by History API.

You don't want hard redirect after ajax request - otherwise rather screw the ajax and use normal request, as that's far more understandable behavior to users.

voslartomas commented 10 years ago

Okay, got it, but if you are redirecting, it just pass this URL, without any content in payload, so it just nicely change URL, but nothing else happen. Is that really good behaviour? Guess I am missing something.

vojtech-dobes commented 10 years ago

Well, if you don't want to change URL, why would you redirect in the first place :) ?

voslartomas commented 10 years ago

I want change the URL, but I want to change the content as well :) But there is no information about content if I call $this->redirect(''); from controller. So it just change the URL, but I need the content to be changed as well.

vojtech-dobes commented 10 years ago

History extension for nette.ajax.js should work like this: assume example scenario of form being submitted, and after that you are redirected to overview page. So, normally you would make redirect to overview page. With ajax, you can update snippets, but only on the page with forms. But with HistoryExtension, you can make redirect as usual, but in ajax request, the redirect will be immediately executed, and ideally you should invalidate (redraw) some main content snippet - so submitting form returns you URL of overview, and snippet with the whole overview page content. Which is handled automatically by snippets extension.

voslartomas commented 10 years ago

No doubt about that, I think you misunderstand what I am trying to say. I don't want to remove this behaviour, but I have this trouble with loging out, when I am using redirect function. So maybe there should be one more condition for this or I missing something and there is another way to change content. Or do you have something in payload (except url address to redirect), if you are redirecting on the very beginning of the controller process? I am sorry, I don't want to contest your work at all. I like it, but I don't know what to do in this concrete situation:)

vojtech-dobes commented 10 years ago

Yes, each redirect should end with something in snippets field of payload :). Each redirect is processed on serverside immediately (like using forward() method). So the page where you get after logging out shculd (in ajax mode) send proper content, that can be processed on client side.

voslartomas commented 10 years ago

Ok, one more scenario, what if you want redirect to different layout page? That means, you need refresh whole page? This should be done via window.location.href right? So maybe, there should be some payload parameter, like refresh, which will do this, shouldn't be?

vojtech-dobes commented 10 years ago

Well, I rather think such action should not be ajaxified.

voslartomas commented 10 years ago

That is hard to do :) If you have to check (again my example, sorry for that), whether is user logged in or not in every request (even in that ajax requests).

vojtech-dobes commented 10 years ago

Sorry, I didn't pay appropriate attention to your initial example, I apologize. You're right, that's difficult scenario. In such case it makes sense to make hard redirect even as result of ajax request.

I like clean API, maybe that's just my obsession, but what about following approach:

Your problem is only with some let's say LoginPresenter. That one requires hard redirect to. So you could mark it with annotation @noAjaxForward, and then the internal forward would be omitted, application would put redirectForce to payload instead of redirect, and that would be always processed as hard redirect. This is possible to implement for Nette 2.1.1 I think. How do you like such idea?

voslartomas commented 10 years ago

Believe or not I like clean API as well, your approach is very nice, but I am still using Nette version 2.0.* so I guess it is not possible, but it doesn't matter I can do another workaround for this situation, I was just curious, if we can implement this additional staff into this library (it would be more clear from my point of view), but I can see your point of view as well :) So thank you very much for your time!

vojtech-dobes commented 10 years ago

Hm, there is http://api.nette.org/2.1.2/source-Application.UI.Presenter.php.html#701-708, so maybe it could be implemented for 2.0.0 as well, in ResponseHandler instead of onPresenter (which was added in 2.1.1).

And of course, it still requires change in JS, support for that redirectForce or something. So I guess you can base your workaround by simple utilizing such field in payload. I will try to implement it as soon as possible, because this is good usecase - probably during the week. Thanks for dragging me to thinking about this :).

voslartomas commented 10 years ago

Thanks for suggestions :) I will try do some workaround for now and I will wait for your implementation...

IvoMIS commented 10 years ago

Hi guys, I am trying to do the same thing as "ufik". I removed whole if structure from redirect if section posted in first post and replaced it with only

window.location.href = redirect;

My application is still working correctly. Is this a right approach? And how about the implementation? Thanks.

vojtech-dobes commented 10 years ago

@im-s Please read my first comment in this thread.

For everybody who wants force redirect now:

  1. register your own extension checking for eg. forceRedirect key in payload
  2. set this value in payload instead of calling redirect()