vojtech-dobes / history.nette.ajax.js

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

Don't trigger history.ajax.js on signals and forms #23

Open zraly opened 9 years ago

zraly commented 9 years ago

history.ajax.js should trigger only on links pointing to different pages. So not signals or forms.

vojtech-dobes commented 9 years ago

I think the easiest (but manual) way to do this is to add data-ajax-off="history" attribute to those links.

vojtech-dobes commented 9 years ago

Btw please check thread #16, there are some good suggestions.

zraly commented 9 years ago

I have added data-ajax-off="history" on signals, but it still triggers this code

if ($this->isAjax()) {
    $this->invalidateControl('title');
    $this->invalidateControl('content');
}

in BasePresenter. Maybe I just should check if the request is signal or not?

fprochazka commented 9 years ago

I actually think the logic should be reverted and when you want the history plugin to apply, you should turn it on on every link, just like #22 suggest.

zraly commented 9 years ago

@fprochazka It is quite different problem, I think

zraly commented 9 years ago

Let me ask. Is there any reason or use case to have history.ajax.js turned on on signals and forms?

fprochazka commented 9 years ago

@medhi that is a tricky question. You might want to have it turned on for example on seach forms. You might also make a signal, that also does something you might wanna have in history. Generally not, but it's possible. For example, you might wanna implement step form by combining signals/forms and you might wanna "go back" in history to fix something.

I've used several of theese techniques in the past and in cases I had, it seemed appropriate.

fprochazka commented 9 years ago

@medhi IMHO the pullrequest actually solves your problem. As you'll be able to turn off history plugin and be able to turn it on only on requests you actually wanna have in history.

zraly commented 9 years ago

Thinking about it, the question is maybe little different:

Am I right, that this code should be triggered just on history request, not common ajax requests?

if ($this->isAjax()) {
    $this->invalidateControl('title');
    $this->invalidateControl('content');
}

How one can achieve this? How to detect, if request is history ajax request and only in that case redraw these snippets?

@fprochazka OK, why not to inverse it, but the pullrequest still does trigger this code on common ajax request. And that's the (different) problem.

fprochazka commented 9 years ago

I'm not sure you understand how this mechanism works, as I'm unable to understand your explanation of the problem. Let's setup some common ground.

  1. you click on a link that has .ajax (or you submit a form with .ajax, or trigger it manually using $.nette.ajax())
  2. the nette.ajax.js picks it up and prevents browser from sending the request
  3. the event propagates to all extensions
  4. nette.ajax.js calls ajax request
  5. nette aplication does some work and returns array of snippets
  6. nette.ajax.js accepts the response payload and starts triggering the extension events
  7. one of the extensions is history.ajax.js which after the snippets are replaced, it saves the state for later revert using history popstate. And it also replaces the url.

If the history ext is not enabled for the specific request, it will not be processed by it and it will not be saved to history. Also, there are no history requests. There are only normal non-ajax requests and ajax requests. And some of the ajax requests are processed by history ext which handles snippets and etc.

Therefore yes, every $presenter->isAjax() call on every ajax request should resolve to TRUE, the fact that history plugin is enabled or disabled doesn't matter.

Please try to be more specific (you might wanna try using czech), as I still probably don't understand your problem.

fprochazka commented 9 years ago

How to detect, if request is history ajax request and only in that case redraw these snippets?

You would have to create another extension, that will detect if the ajax history extension is enabled for this specific request and if so, it could add some http header (or something) to the request, so you can detect it.

fprochazka commented 9 years ago

You could probably make it a common extension, that collects all the installed extensions and then looks at settings.nette.off value and sends those that are enabled in some header

X-Nette-Ajax-Extensions: unique, snippets, history, ...

after that it's a piece of cake :)

zraly commented 9 years ago

@fprochazka I think you got my point. I need to know, if history extension will be processed. If yes, than redraw content snippet. If not, don't redraw content snippet. I think this should be general behaviour of history extension, so this mechanism should be built in. Because now, if someone uses history extension, he is forced redraw content snippet every time, even if no snippet should be redrawn.

If this is a piece of cake for you, could you create a PR? :)