dojo 1.10 adding sort behaviour of CheckedMultiSelect - sorting

Hello everyone i am desperately trying to sort a CheckedMultiSelect with little luck, it seems that despite changing the order of the data in the store it is always displayed alphabetically.
Being relatively new to dojo i have tried to look around for a tutorial but alas i am having no joy.
Can someone explain to me how best to sort the data in a CheckedMultiSelect that is being populated by a Memory store?
Code:
var store = new Memory({'data', : data});
//where this is my CheckedMultiSelect box
this._set("store", store);
in my postCreate function i now do this:
this.options = this.store.query({}, {sort: [{attribute: "name", descending: "true"}]});
this._set("labelAttr", "name");
console.log(this.options);
I can see both in firebug and in console that the data is in the right order however now i cannot see anything but checkboxes, there is a space where the value of that selection should be).
I dont know if this is going to help at all but this is the code that sets the data that populates the multi select, everything beforehand is just parsing of a string into the store object.
No matter what I do i cannot get the order to change, even changing the order of the elements in the stores data does not make a blind bit of difference, i am guessing there is some sort of behaviour that CheckedMultiSelect has in regards to sorting but it is just that; a guess.

You set sortByLabel: false, then provide a queryOptions object (see example below).
As to why we'd need sortByLabel, see _FormSelectWidget:
// sortByLabel: Boolean
// Flag to sort the options returned from a store by the label of
// the store.
sortByLabel: true,
... Though there appear to be plans to deprecate it.
Here's the example:
var checkedMultiSelect = new CheckedMultiSelect ({
dropDown: true,
multiple: true,
labelAttr: "label", // Need this to be able to use Memory directly
sortByLabel: false, // Need this to override sort
queryOptions: { // Now, finally, specify sort order.
sort: [
{attribute:'sortByMeFirst'},
{attribute:'sortByMeSecond', descending: true}
]
},
store: memoryStore
}, "dropdown");
See: jsfiddle sorting a CheckedMultiSelect

Related

How to clear all data is jsGrid?

There are many answers on how to clear the data from the similarly-named jqGrid, but I can't find any way to clear data from jsGrid. I just want to delete all rows and reset the grid to its default, with no rows.
I do see a Batch Delete method here, but it works with checkboxes and conditionals and I'm not seeing how to simply delete all rows unconditionally.
You can set data option to empty array:
$("jsGrid").jsGrid("option", "data", []);
The only thing that seems to work for me is
$("#jsGrid").jsGrid({
controller: {
loadData: function(filter) {
return [];
}
}
});
We need to return an empty array or object.
I hope this helps.
What worked without implications for me was
$(".jsgrid-grid-body").children().remove();
if I wanted to keep the headers to indicate that there simply aren't any rows, and
$("#jsGrid").children().remove();
if I wanted to remove the whole grid.

Loading dynamic "chosen" select elements

I am using the jQuery plugin chosen (by Harvest). It is working fine on (document).ready, but I have a button that, when clicked, uses ajax to dynamically create more select objects that I want to use the "chosen" feature. However, only the original select elements have the "chosen" features, and the new (dynamically created) do not work. I am using jQuery.get to append the new elements. Here is a sample of the code:
jQuery(".select").chosen();//this one loads correctly
jQuery("#add-stage").click(function() {
jQuery.get('/myurl',{},function(response) {
//response contains html with 2 more select elements with 'select' class
jQuery('#stages').append(response);
jQuery(".select").chosen();//this one doesn't seem to do anything :-(
});
});
I was thinking that I need a .live() function somewhere, but I haven't been able to figure that out yet. Any help is much appreciated!
Note - I am not trying to dynamically load new options, as specified in the documentation using trigger("liszt:updated");
Ensure that the response elements have the select class.
console.log( response ); // to verify
May also be a good idea to only apply the plugin to the new element(s).
jQuery(".select").chosen();
jQuery("#add-stage").click(function() {
jQuery.get('/myurl',{},function(response) {
console.log( response ); // verify the response
var $response = $(response); // create the elements
$response.filter('.select').chosen(); // apply to top level elems
$response.find('.select').chosen(); // apply to nested elems
$response.appendTo('#stages');
});
});
Also, if /myurl is returning an entire HTML document, you may get unpredictable results.
after you code (fill the select) .write this
$(".select").trigger("chosen:updated");
I had a similar problem with Chosen. I was trying to dynamically add a new select after the user clicks on a link. I cloned the previous select and then added the clone, but Chosen options would not work. The solution was to strip the Chosen class and added elements, put the clone in the DOM and then run chosen again:
clonedSelect.find('select').removeClass('chzndone').css({'display':'block'}).removeAttr('id').next('div').remove();
mySelect.after(clonedSelect);
clonedSelect.find('select').chosen();
one way you can use chosen with ajax:
$.ajax({
url: url,
type: 'GET',
dataType: 'json',
cache: false,
data: search
}).done(function(data){
$.each(data, function(){
$('<option />', {value: this.value, text: this.text}).appendTo(selectObj);
});
chosenObj.trigger('liszt:updated');
});
where selectObj is particular select object
But ...
Chosen is implemented very bad.
It has several visual bugs, like: select some option, then start searching new one, then remove selected and the keep typing - you will get 'Select some options' extended like 'Select some options search value'.
It doesn't support JQuery chaining.
If you will try to implement AJAX you will notice, that when you loose focus of chosen, entered text disappears, now when you will click again it will show some values.
You could try to remove those values, but it will be a hard time, because you cannot use 'blur' event, because it fires as well when selecting some values.
I suggest not using chosen at all, especially with AJAX.
1.- Download Livequery plugin and call it from your page.
2.- Release the Kraken: $(".select").livequery(function() { $(this).chosen({}); });
This is an example of Chosen dynamically loading new options form database using ajax every time Chosen is clicked.
$('.my_chonsen_active').chosen({
search_contains:true
});
$('.my_chonsen_active').on('chosen:showing_dropdown', function(evt, params){
id_tosend=$(this).attr("id").toString();
$.get("ajax/correspondance/file.php",function(data){
$('#'+id_tosend).empty();
$('#'+id_tosend).append(data);
$('#'+id_tosend).trigger("chosen:updated");
});
});

How do i automatically append column names to post data sent to php when grid loads or refreshes?

I'm new to jqGrid and jquery and i'm learning as fast as i can but i still am a little lost about how to some things like how to append addition information to the post data in jqgrid that gets sent to php.
It would be nice for the php script to know what columns the grid wants when it initially loads or you press the jqgrid refresh/reload button.
I know i can use the postData option: postData:{name:val,,,}, but i was hoping to just automatically pull the column names from the colModel definitions using this function...
postData: function(){
colmodel = $('#tab4-grid').jqGrid('getGridParam','colModel');
colarray = '{';
for (var i in colmodel) {colarray += '"'+colmodel[i].name+'":"'+colmodel[i].name+'",';}
colarray += '}';
return colarray;
},
so i would not have to spell them out manually again. However, while the function produces the correct code, it's not getting posted. I can't seem to figure out the problem. Can someone help please?
thanks.
The first thing which you have to do is to rewrite
postData: function() { ... }
to
postData: {
myColumnsName: function() { ... }
}
jqGrid already send some standard parameters to the server (page, rows ,...). With the code above you will add and additional parameter with the name myColumnsName which you can fill in any way inside of the function body.
You current implementation is very dirty. You don't define local variables colmodel and colarray. Moreover you try to serialize array of strings as object ('{}') and not as array ('[]'). You should not use for (var i in colmodel) construction if you enumerate array items for (var i=0; i<colmodel.length; i++) is better. Additionally 'colModel' contain some column names ('rn', 'cb', 'subgrid') which you should skip in the enumeration. You can define as var colNames = []; and use colNames.push to fill it. Then you can use standard JSON.stringify method from json2.js to convert array to the JSON string.

Mootools: inject vs adopt

I want to dynamically add some preconfigured HTML-Elements in use of a 'click'-event with mootools.
So I can make it work with my basic knowledge, although it isn´t very nifty. I coded this so far...
This is my preconfigured element, with some text, a classname and some event, cause i wanna have events already added, when it´s inserted into my container:
var label = new Element('label', {
'text': 'Label',
'class': 'label',
'events': {
'click': function(el){
alert('click');
}
}
});
Here is my function, which adds the label-Element:
function addText(){
$('fb-buildit').addEvent('click', function(){
row.adopt(label, textinput, deletebtn);
$('the-form').adopt(row.clone());
row.empty();
/*
label.clone().inject($('the-form'));
textinput.inject($('the-form'));
deletebtn.inject($('the-form'));
*/
});
}
The second part which uses inject also works, but there, my click-Event, which fires the "alert('click')" works too. The method with adopt doesn´t add any event to my label Object, when its inserted in the dom.
Can anyone help me with this. I just wanna know why adobt ignores my "events" settings and inject doesn´t.
Thanks in advance.
(sorry for my english ^^)
you go label.clone().inject but row.adopt(label) and not row.adopt(label.clone()) -
either way. .clone() does not cloneEvents for you - you need to do that manually.
var myclone = label.clone();
myclone.cloneEvents(label);
row.adopt(label);
this is how it will work
as for why that is, events are stored in the Element storage - which is unique per element. mootools assigns a uid to each element, eg, label = 1, label.clone() -> 2, label.clone() -> 3 etc.
this goes to Storage[1] = { events: ... } and so forth. cloning an element makes for a new element.uid so events don't work unless you implicitly use .cloneEvents()
you are sometimes not doing .clone() which works because it takes the ORIGINAL element along with its storage and events.
suggestion consider looking into event delegation. you could do
formElement.addEvent("click:relay(label.myLabel)", function(e, el) {
alert("hi from "+ el.uid);
});
this means no matter how many new elements you add, as long as they are of type label and class myLabel and children of formElement, the click will always work as the event bubbles to the parent.

How to capture jqGrid column changing events?

In our application we are using a jqGrid which supports hiding and reordering of columns. When the columns are hidden or reordered we want to store the new settings into our database. But to do this we somehow need to capture the hiding or reordering event. Or possibly to capture when the colModel changes.
Is there any way to capture and handle these events?
Thanks.
You can use 'done' event of the columnChooser. Here is an example:
var grid = $("list");
grid.navButtonAdd(
'#pager',
{caption:"", buttonicon:"ui-icon-calculator", title:"Column choose",
onClickButton: function() {
grid.jqGrid('columnChooser',
{
"done": function(perm) {
if (perm) {
this.jqGrid("remapColumns", perm, true);
}
// here you can do some additional actions
}
});
}
});
UPDATED: If you define sortable option as
sortable: {
update: function (permutation) {
alert("sortable.update");
}
}
and not as sortable:true you will receive the notification about the new order of columns. See the source code of jqGrid for details. The array permutation with integers has the same meaning as in remapColumns functions (see my old answer for details).
You can capture column changes via the sortable parameter as mentinoed in Oleg's "update" above, or as discussed on jqGrid's message board.
However, please note that the array passed to your callback will be relative to the current column order. In other words, saving the array as is after moving multiple columns will not produce the desired results. See my answer on this other stackoverflow question.

Resources