$.fn.yiiListView.update not returning the jqXHR object

The [font=“Courier New”]$.fn.yiiListView.update[/font] (and for that matter: [font=“Courier New”]$.fn.yiiGridView.update[/font]) function does not return the jqXHR object that is returned by the [font=“Courier New”]$.ajax[/font] function. I came across this because I want to use the [font=“Courier New”]$.fn.yiiListView.update[/font] function while still being able to abort the AJAX request. I don’t know if this could be called a bug, or rather a feature request?


Returning the jqXHR object makes it possible to create a less jumpy (while updating) listview. Esspecialy if it is updated while typing (in an onkeypressed event handler).

I waggishly posted a related topic elsewhere (because I got no response): See http://www.yiiframework.com/forum/index.php/topic/31687-where-to-post-a-patch/ for more info ;D

I proposed a patch in that topic. But Mdomba rightfully added that my patch breaks the pattern for the returnvalue of the update function. This is because [font="Courier New"]$.fn.yiiGridView.update[/font] function allready returns the jquery object for the gridview.

Since I don’t know if the returnvalue for that function is used elsewhere, I guess there is no choice but to devise an other way to reach the jqXHR object. All I can think off at this moment is to make the jqXHR object available from within the [font=“Courier New”]yiiListView[/font] object like so [font=“Courier New”]$.fn.yiiGridView.getRequest()[/font] or something like that, but that seems a little dirty. Also, it would break when more than one listview is used on the same page.

Is there anyone that can shine a light on this problem? Or come with a more elegant solution? Or even a semi-elegant workaround?

I would really like to be able to update future versions of Yii without my site breaking!

Can you explain how would you use the returned jqXHR object?

a bit of brainstorming:

the gridview update method is more complex… as it does more things than just calling an ajax method, and it can work even without making the ajax method at all… that’s a problem as I see to make it return always a consistent value (jqXHR object)…

I guess that if we would like to return the jqXHR object then a bit of refactor would be needed there… maybe to create two methods from that one… or as you suggested above to find another way of returning that object.

I’m using the jqXHR object to be able to abort the XHR request if there has been a change in form since the request was issued. This is needed if you’d want to be able to automatically update on a textchanged (keypressed) event somewhere. It serves the responsiveness of the website in this case. This is because you can request the dynamic content according to the text in the textfield, while still bein’ able to change the contents of the textfield.

I use a bit of delay after a user has typed something new (in for example a search field). But after that delay the XHR request is done and if the user types in the search field before the server responded to the request it would just do a new request. The problem is that the first request still finishes updating the page content (and possibly executing some javascript). This is not always desirable behavior. Especially because there is no way to guarantee that the first request will finish before the second does.

If I’m able to abort the first request (if it’s still running off course) right before I start the second request, this would solve the problem.

I’ve been thinking and I lean towards the two methods solution. I’m not totally familiar with the workings of the yiiGridview javascript, but the object [font=“Courier New”]$.fn.yiiGridView[/font] seems to have a static nature (as in only one instance exists). Correct me if I’m wrong here. I’m just not confident about a good name for the function to return the jqXHR object.

I guess it could be something like: [font="Courier New"]$.fn.yiiGridView.getLastXmlHttpRequest()[/font]

Or it could be a property like: [font="Courier New"]$.fn.yiiGridView.lastXmlHttpRequest[/font]

You’d have to call this method or property right after the call to the [font=“Courier New”]$.fn.yiiGridView.update[/font] function to be (not entirely) sure that you get the right jqXHR object. (It still feels a little dirty, though ;))

If you don’t get what I’m goin’ on about than I could post some sample code that I envision using this method. Let me know what you think!

I understand you completely… there is actually a request for a similar functionality - https://github.com/y.../yii/issues/387

In CActiveForm we have something similar with the "validateOnType"… there the ajax() call is put in an setTimeout()… and if a new call is made before the old one is issued… the old one is cleared and only the new one is made…

Problem of this approach is that you cannot cancel the ajax request if it is started… it just prevents the queue up of ajax calls…

To really make this shine I guess you would have to have an object instance of yiigridview/listview per visible listview/gridview. But I think that will be a potential re-factoring nightmare and I’m not even sure if it is possible without breaking BC.

There is one other way I can think of returning an extra variable (similar to “out” variables in C#). But that also seems a little icky. I think it would have to involve passing a function as a parameter to the update function. And I guess the framework wouldn’t be served with the bad example that it will set. Since there is no hint of consistency with any other code (at least that I know of).

Another option (and I don’t know why I haven’t thought of that before) is to create a new setting for initializing the yiigridview/yiilistview. It could be named something like [font=“Courier New”]autoAbortAjaxOnNewRequest[/font]. This way we could build in the functionality to abort the previous jqXHR (if still busy) while a new one is bein’ created. Off course this setting would be set to false by default as not to break BC.

I think this is a very viable option because I can’t think of any other reason to have a reference to the jqXHR object than to abort it (but maybe any of you can ;). Also you could think about making this behavior standard in Yii 2.0 for example (but maybe even in the current branch) 'cause I think it will only break BC in very specific cases.

If a second update is called without the first one being finished we can abort it of course. I think that this would not break BC at all… who would need the first call to be completed in this case ?

Can you create a pull request for this… or propose the code change?

Exactly my point ;D

I’ll see what I can do ;)