How to create dependent selects (EXAMPLE)
How to create dependent selects (EXAMPLE)
INTRIO:
I recently needed to make an editor that:
- used dependent select boxes using ajax
- passed back select values rather than labels/text
I didn't find anything so I did it myself and now I'm posting so that people can use it if they like.
NOTES:
- makes use of closures; have not looked if there are memory leaks
- directly modified the datatables-editor.js file which is why u see all the obfuscated code (see: http://editor.datatables.net/tutorials/field_types for external extensions)
- can only handle selects but can easily be extended to add support for other field types with a lil work
- updated to now preselect current values
CODE:
[code]
j.dependentselect = e.extend(!0, {}, f.Editor.models.fieldType, {create:function (a) {
a._input = h.createElement("select");
a._input.id = a.id;
// find dependField and store it (for now only select is valid)
a.dependRef = this._findField(a.dependField)._input;
// attach update handler to dependRef (for now only select events are valid)
e(a.dependRef).bind(a.dependEvent, function() {
j.dependentselect.update(a);
});
return a._input;
}, get:function (a) {
// get selected option label
// do not use jquery .val() anymore
return e(a._input).find('option:selected').text();
}, set:function (a, b) {
this.update(a, b);
}, update:function (a, b) {
var ajaxData = {};
ajaxData[a.dependParam] = e(a.dependRef).attr('value');
var select = $(a._input);
var options;
if(select.prop) {
options = select.prop('options');
}
else {
options = select.attr('options');
}
e.ajax({
url:a.dependAjaxUrl,
data:ajaxData,
dataType:"json",
type:"GET",
success:function (data) {
var optionsData = data.result;
// remove all options
e("option", select).remove();
// create new options
e.each(optionsData, function(value, label) {
var selected = false;
if(label == b) {
selected = true;
}
options[options.length] = new Option(label, value, false, selected);
});
e(a._input).val(b)
},error:a.dependErrorHandler // attach errorhandler
});
}, enable:function (a) {
a._input.disabled = !1
}, disable:function (a) {
a._input.disabled = !0
}});
[/code]
USE:
[code]
editor = new $.fn.dataTable.Editor( {
"ajaxUrl": "datatables.ajax",
"domTable": "#hobbies",
"onPreSubmit": function (e) { // change data to pass back select values instead of labels
var category = this.dom.form[0]; // todo: use better select
var interest = this.dom.form[1]; // todo: use better select
e.data.category = category.options[category.selectedIndex].value;
e.data.interest = interest.options[interest.selectedIndex].value;
}
},
"fields": [ {
"label": "Category:",
"name": "category",
"type": "select",
"ipOpts": hobbyCategoryOptions
},
{
"label": "Interest:",
"name": "interest",
"type": "dependentselect",
"dependField" : "category", // the name of the source field
"dependEvent" : "change",
"dependAjaxUrl": "getInterestValues.ajax",
"dependParam": "hobbyCategory",
"dependErrorHandler": function(jqXHR, textStatus, errorThrown) {alert ("Error updating Interest.");}
},
{
"label": "Comment:",
"name": "comment"
}
]
} );
[/code]
Cheers & Enjoy
I recently needed to make an editor that:
- used dependent select boxes using ajax
- passed back select values rather than labels/text
I didn't find anything so I did it myself and now I'm posting so that people can use it if they like.
NOTES:
- makes use of closures; have not looked if there are memory leaks
- directly modified the datatables-editor.js file which is why u see all the obfuscated code (see: http://editor.datatables.net/tutorials/field_types for external extensions)
- can only handle selects but can easily be extended to add support for other field types with a lil work
- updated to now preselect current values
CODE:
[code]
j.dependentselect = e.extend(!0, {}, f.Editor.models.fieldType, {create:function (a) {
a._input = h.createElement("select");
a._input.id = a.id;
// find dependField and store it (for now only select is valid)
a.dependRef = this._findField(a.dependField)._input;
// attach update handler to dependRef (for now only select events are valid)
e(a.dependRef).bind(a.dependEvent, function() {
j.dependentselect.update(a);
});
return a._input;
}, get:function (a) {
// get selected option label
// do not use jquery .val() anymore
return e(a._input).find('option:selected').text();
}, set:function (a, b) {
this.update(a, b);
}, update:function (a, b) {
var ajaxData = {};
ajaxData[a.dependParam] = e(a.dependRef).attr('value');
var select = $(a._input);
var options;
if(select.prop) {
options = select.prop('options');
}
else {
options = select.attr('options');
}
e.ajax({
url:a.dependAjaxUrl,
data:ajaxData,
dataType:"json",
type:"GET",
success:function (data) {
var optionsData = data.result;
// remove all options
e("option", select).remove();
// create new options
e.each(optionsData, function(value, label) {
var selected = false;
if(label == b) {
selected = true;
}
options[options.length] = new Option(label, value, false, selected);
});
e(a._input).val(b)
},error:a.dependErrorHandler // attach errorhandler
});
}, enable:function (a) {
a._input.disabled = !1
}, disable:function (a) {
a._input.disabled = !0
}});
[/code]
USE:
[code]
editor = new $.fn.dataTable.Editor( {
"ajaxUrl": "datatables.ajax",
"domTable": "#hobbies",
"onPreSubmit": function (e) { // change data to pass back select values instead of labels
var category = this.dom.form[0]; // todo: use better select
var interest = this.dom.form[1]; // todo: use better select
e.data.category = category.options[category.selectedIndex].value;
e.data.interest = interest.options[interest.selectedIndex].value;
}
},
"fields": [ {
"label": "Category:",
"name": "category",
"type": "select",
"ipOpts": hobbyCategoryOptions
},
{
"label": "Interest:",
"name": "interest",
"type": "dependentselect",
"dependField" : "category", // the name of the source field
"dependEvent" : "change",
"dependAjaxUrl": "getInterestValues.ajax",
"dependParam": "hobbyCategory",
"dependErrorHandler": function(jqXHR, textStatus, errorThrown) {alert ("Error updating Interest.");}
},
{
"label": "Comment:",
"name": "comment"
}
]
} );
[/code]
Cheers & Enjoy
This discussion has been closed.
Replies
That's superb - thanks for sharing this with us! Really nice plug-in :-)
Regards,
Allan