Cool, thanks. I hope i find some time to test it.
Cool, thanks. I hope i find some time to test it.
Thank you… just check that you get the latest version… as I’m fixing things as I find them…
I had a look and it seems to work fine. And it’s much cleaner code IMHO .
Some things i noticed:
selectCeckedRows somehow doesn’t really fit well into the clean names of other methods. I think there should be a ‘setSelection’ method instead. Then the in selectCheckedRows (wich should be private) this method could be used instead
Instead of using a custom pseudo-event mechanism, why don’t we use jQuery’s built in event system? Then if e.g. ‘beforeAjaxUpate’ is set, it should just attach it as a handler for e.g. ‘yiiGridViewBeforeAjaxUpdate’ in the init method. And trigger this event where beforeAjaxUpdate was called before. This would allow to bind events purely form clientside code.
Thank you for testing…
You are right selectCheckedRows is used only internally no need for it to be public… but I did not understand your comment as getSelection() is already there… like the getChecked()
for now the idea is to maintain the code totally BC compatible… so that we do not break current users code… but at the same time to get users used to the new format that will be used from now on (yii 2.0)…
I agree for the events… will try to find a way to implement them by keeping the "pseudo-events" too…
getSelectoin() is there - but not setSelection().
Sorry… I still don’t get it…
Here is the getSelection() - http://code.google.com/p/yii/source/browse/trunk/framework/zii/widgets/assets/gridview/jquery.yiigridview.js#279
getSelection is a getter, i talk about a setter . We should not only have a method to read out current selection, we should also allow to set the current selected rows from outside. Then instead of having public ‘selectCheckedRows’ you could implement the private method like this:
function _selectCheckedRows() {
// ... obtain ids of current checked rows here ... then:
methods.setSelection(ids);
}
Inside setSelection you can also deal with the update of the select-all checkbox. Maybe also allow to supress update of Checkboxes at all with another parameter: setSelection(ids, updateCheckboxes). If updateCheckboxes is true (default), then the checkbox status is also updated.
Got it this time… .did not notice the “get” just the misspell “selectoin” and was wondering where that was
selectCheckedBoxes is used to preCheck those checkboxes that has a value in the table… for example if you use an attribute from the database… if the value of that attribute is not 0… the checkbox will be checked… this is used only when the grid is refreshed…
I dont see the point in having the setSelection() / setChecked() (note that we have two separate functionality - selecting the row and selecting the checkbox) as this is done by clicking the row / checkbox…
I think setSelection() could be very useful. Consider not only having a “select all” option on top, but also a select by status, like “select all open”, “select all closed”, … It’s exactly methods like these that i’m missing from most of the yii components: I want to be able to interact much more with them from javascript. So why hide these options and not provide a very flexible interface to the user? We should make the clientside components as open and flexible as the server side ones.
It’s not only making the clientside open… it’s about connecting it to the backend (PHP / database)…
Can you elaborate a bit more on this…
how would you call setSelection() in the case of "select all open"… what would you send as a parameter… (array with: rowID/status or rowNumber/staus pairs)… how woudl you get those information to be sent as parameter?
one problem to consider is that if pagination is used… the checkbox status is not "remembered" and refreshed from scrach on every page change (selectCheckedRows)
setSelection should accept an array of keys - that’s all. Just as counterpart to getSelection, which returns these keys. Then i can write my own javascript to filter the right ids. This of course would require another method “getKeys” which returns all ids of current rows in the grid.
The keys are currently kept in the hidden DIV… and there is the getKeys method there… I still don’t get the picture you have in mind for this setter… what would be the difference of the user checking the boxes directly… instead of collecting the keys and sending it to the setter to check the boxes…
Say I want to be able to have a link on top of a list with 100 cars, wich says "select all Audi" (with a dropdown for the manufacturer). So instead of letting the user go through the list, he can just select all "Audi" with a single click. Then the user can click "buy", or "delete" or whatever to process the current selection. There may be lot more of these type of links, but you should (hopefully) get the idea now.
So in my javascript when the user clicks "select all Audi" i would fetch the current ids from the grid (call getKeys()), and do whatever is necessary to filter these ids to get all ids that match "audi" (my own logic does this). Then i can call setSelection(ids).
This is only one example how this could be used. Think of the grid as an embedded component in a more complex Js application. If it should be really useful, we need full control over the grid through javascript. And thus need to provide a full interface to do all kind of interaction with the grid.
What I’m interested to see is just that “your logic of selecting which one is the audi”… as IMO this is not very simple… and if you implement this… why not at the same time just check the related checkbox instead of storing the ID in the array that would be sent to a method that would check the checkbox… (sometime I just miss the chat option on this forum )
Maybe there is no checkbox - only the standard "click a row" type of selection…
again its the same… checking or selecting… to select the row… you just need to add the "selected" class…
But this is like touching the internals of the grid (like messing around with private stuff…). All this should be encapsuled inside the components. We should follow clean OOP even on Js and only access the interface of a component.
Managing the current selection is definitely something which the grid should be responsible for. You should not have to know much, how the grid works inside.
Yes, I see now your point… but IMO that will be possible only in the next gridview version (Yii 2.0) if we design it for this purpose from the scracth
Right, that’s why i posted this to the 2.0 section …
I want to stress again, that this really affects all client side components. Another very important one is the active form. It should be much easier to integrate it into your custom Js applications. I think by doing so, we really lift Yii to the next level as the future of the web lies on the client side.
Some notes regarding current state of Yii client side and possible usage of 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.
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.