Some notes regarding current state of Yii client side and possible usage of jQuery UI widget factory:
- jQuery UI widget factory:
I now use client side code which is based on jQuery UI widgets and can say it allows to structure code well and allows easier and much more obvious way to extend existing JS code.
For example, now if I want to change some part of update process for CGridView I should do something like this after registering standard script:
$.fn.yiiGridView.update = function(id, options) {
//my update code
}
While with jQuery UI widgets I use inheritance to override methods I need.
Another good feature of jQuery UI widgets is an easy and clean way to define set of options supported by the widget and default values.
The problem with widgets can be that they bind JS object instance to the HTML element. So if you update a page and replace HTML element then you will loose the JS object.
So now I do not use the original jQuery widgets code, but have my own modified copy of base widget class which store JS object instances in the array and do not bind them to the HTML elements.
-
It would be good if all Yii widgets will have separate registerClientScript() method to allow the user use own scripts (or extended versions of standard scripts) (for example, CActiveForm now registers scripts in the run() method).
-
Current approach to ajax updates:
I do not like that now yii documentation and examples forces users to pay no attention to ajax requests which do updates.
Usual practice is to render full HTML page and then in the JS code take out a piece of it (for example, updated grid) and insert it to the document.
Yes, it is easy for the user and easy in implementation, but this is just not right to do so.
Ideally JS code should use json to do updates or at least we should render only grid when we want update it and not the full page.
I have a solution for this, in short I do following:
-
have extended version of CWidgetFactory which supports rendering widgets by id, like ‘#post.grid’
-
I have separate config files for such widgets, for example, for ‘#posts.grid’ there is ‘protected/controls/post/grid.php’ which returns an array with grid configuration (resolution of the config file for widget is very similar to resolution of view file for controller)
-
In the view I have $this->widget(’#post.grid’)
-
In the controller I have:
//This is similar to performAjaxValidation() method for active form
//render requested widget and finish
if (Yii::app()->request->isAjaxRequest
&& isset($_GET['controlId'])
&& $_GET['controlId'] == 'post-grid'
) {
echo $this->processOutput($this->widget('#grid'));
Yii::app()->end();
}
This is simplified version and it also requires support on the client side, but I think the idea should be clear.
It would be good to heave some solution for ajax interactions in Yii. It maybe something completely different from waht I describing, but we need some standard way to build AJAX-enabled applications.
- I think it would be good if documentation will mention alternative approaches to setup ajax requests (maybe guide section?).
Such helpers as CHtml::ajaxLink() are very convenient for simple cases, but when you trying to setup complex ajax interaction then in is much easier just output HTML in the view and include separate js file which will use ids / classes to hook on HTML elements.
Now I know this, but I remember that when I started leaning yii and jQuery the only way I used is complex configurations for ajaxLinks and I had half of my view files filled with php config arrays while the same can be easily done with few lines of js code.
And I suspect that now many people have the same problem, at least search for ‘ajaxlink’ in the forum returns large number of topics.
- Maybe we can take a look also at the backbone.js? I did not used it by myself, but it seems like it can help to structure client-side code even better then jQuery widget factory and can help to implement "correct" way of interaction between JS and PHP based on json data and not on the HTML.