I have this callback function, which creates list of categories on my page.
this.getCategoryAdCount(function (categories) {
//added selectize plugin to display multiply choice
var values = categories.map(function (cat) {return { item : cat.id, text : cat.name + ' (' +cat.count + ')'}; }); //this is my data from the server
this.$filtercat.selectize({
plugins: ['remove_button'],
delimiter: ',',
persist: false,
maxItems: 5,
options: values,
labelField: "text",
valueField: "item",
sortField: 'text',
searchField: 'text',
create: function(input) {
return {
value: input,
text: input
}
}
});
}.bind(this));
It works good, but I have already existing function, which calls .selectize on every $('select') element on my page
$('select').each(function(k, v) {
var el = $(v);
var options = SJA.Config.selectizeOptions;
el.selectize(options);
});
In this config I have list of options
selectizeOptions: {
persist: true,
maxOptions: 99999,
dropdownParent: 'body',
sortField: false,
render: {
option: function(data) {
return '<div data-value="' + data.value + '" title="' + data.text + '" data-selectable class="option">' + data.text + '</div>';
}
}
},
So I don't want to call .selectize once again inside my callback function. Is it possible to extend somehow options only for the this.$filtercat variable without calling .selectize ?
Related
I'm using selectize js to populate country data (from db) as a dropdown. this dropdown is working fine on onChange, onload.
I'm trying to append a dropdown option on the following condition: user queries for "us", "usa" or "united states". In this case it should return 'united states' as country from db.
I'm returning a json object with 'united states' when user types 'us' or 'usa', 'united' but it doesn't populate in autocomplete:
country_selector = $('#data_country').selectize({
valueField: 'id',
labelField: 'name',
searchField: ['name'],
options: [],
create: false,
maxItems: 1,
openOnFocus: true,
closeAfterSelect: false,
preload: true,
highlight: false,
render: {
option: function (item, escape) {
return '<div class="game-section--country-list--selected-country" data-country = "' + item.id + '" id = "game-selected-country"><span class = "game-section--country-list--name" > ' + item.name + '</span>' + '</div>';
},
item: function (item, escape) {
return '<div class="game-section--country-list--selected-country" data-country = "' + item.id + '" id = "game-selected-country"><span class = "game-section--country-list--name" > ' + item.name + '</span>' + '</div>';
}
},
load: function (query, callback) {
var selectize = this;
var form_data = {
'q': query,
'action': 'countries'
};
$.ajax({
url: game_section_ajax_object.ajaxurl, // AJAX handler,
type: 'POST',
dataType: 'json',
data: form_data,
error: function () {
callback();
},
success: function (res) {
/*here i m adding new element to json on condtion when q = 'us or usa or united*/
res.countries.push(
{ id: "US", name: "United States" }
);
callback(res.countries);
/*but it doesnt append united states in dropdown on autocompelte*/
}
}
});
},
)}
I expect the dropdown options to show "united states" when user type any of below keyword "us", "usa", "united states".
I load data via an ajax call in dataInit which works and everything works fine BUT none of my columns (only dropdown columns) don't set the id value.
e.g. I have itemId and itemCode properties. I load the data and displays correctly but if I change the value in the drop down then it doesn't bind/update my itemId value.
Essentially I want the dropdown to bind to my id column thus when saving it I get an Id to save.
,{
key: false,
hidden: true,
name: 'itemId',
index: 'itemId',
editable: false
}, {
key: false,
name: 'itemCode',
index: 'itemId',
editable: true,
edittype: 'select',
editoptions: {
dataInit: function(element) {
$.ajax({
url: '#Url.Action("GetItems", "Maintenance")',
dataType: 'json',
type: 'POST',
success: function(response) {
var array = response;
if (array != null) {
var i;
for (i in array) {
if (array.hasOwnProperty(i)) {
if (itemId == array[i].id) {
$(element).append("<option value=" +
array[i].id +
" selected>" +
array[i].code +
"</option>");
} else {
$(element).append("<option value=" +
array[i].id +
">" +
array[i].code +
"</option>");
}
}
}
}
}
});
}
},
editrules: { required: true}
Here is my answer.....Look at the data events. I find the selected row and then I set the cell. The console log was just to test.
{
key: false,
hidden: true,
name: 'userId',
index: 'userId',
editable: false
}, {
key: false,
name: 'userName',
index: 'userName',
editable: true,
edittype: 'select',
editoptions: {
dataInit: function(element) {
$.ajax({
url: '#Url.Action("GetUsers", "Maintenance")',
dataType: 'json',
type: 'POST',
success: function(response) {
var array = response;
if (array != null) {
var i;
for (i in array) {
if (array.hasOwnProperty(i)) {
if (userId == array[i].id) {
$(element).append("<option value=" +
array[i].id +
" selected>" +
array[i].userName +
"</option>");
} else {
$(element).append("<option value=" +
array[i].id +
">" +
array[i].userName +
"</option>");
}
}
}
}
}
});
},
dataEvents: [
{ type: 'change',
fn: function (e) {
var rowId = $("#jqgrid").jqGrid('getGridParam', 'selrow');
$('#jqgrid').jqGrid('setCell', rowId, 'userId', $(e.target).val());
console.log($("#jqgrid").jqGrid('getCell', rowId, 'userId'));
}
}
]
}
Using selectize.js the standard multi select returns an array of strings: ["1","2","3"] this works perfectly with the following code:
$('.selectize').selectize();
I want to use remote data loading due to having a large amount of data but when setting selectize up that way I get back ["1,2,3"] rather than the desired ["1","2","3"].
Here is the code:
var formatName = function(item) {
return $.trim((item.first_name || '') + ' ' + (item.last_name || ''));
};
$('.selectize-contacts').selectize({
delimiter: ',',
valueField: 'id',
labelField: 'name',
searchField: ['first_name', 'last_name', 'email'],
sortField: [
{field: 'first_name', direction: 'asc'},
{field: 'last_name', direction: 'asc'}
],
options: [],
create: false,
render: {
item: function(item, escape) {
var name = formatName(item);
debugger;
return '<div>' + (name ? '<span class="name">' + escape(name) + '</span>' : '') + '</div>';
},
option: function(item, escape) {
var name = formatName(item);
return '<div>' + escape(name) + '</div>';
}
},
load: function(query, callback) {
if (!query.length) return callback();
$.ajax({
url: $(".selectize-contacts").data("search") + '?q=' + query,
type: 'GET',
error: function() {
callback();
},
success: function(data) {
callback(data);
}
});
},
});
Any advice on why these values are different would be much appreciated.
By looking at the code. Selectize checks if it has be initialized from a multiselect only then it returns the items, otherwise it joins the items to a string. You can still get the items by using selectize.items instead of selectize.getValue()
I have an ExtJs Combobox with multiple true and I want to show "X values selected" on the input field instead of "Value 1, Value 2, Value 3". I tried with select listener but when I set the value to the input field and then you call multicombo.getValue() it takes the value from the input field. I would need something like take the value from the valueField (a hidden input).
My code:
var multiCombo = Ext.create('Ext.form.field.ComboBox', {
renderTo: item.id,
multiSelect: true,
displayField: 'name',
editable: false,
valueField: 'id',
emptyText: 'Select',
hiddenName: 'data[Model][' + item.getAttribute('question-id') + '][value]',
submitValue: true,
inputType: 'hidden',
value: selectedOptions,
width: 300,
store: store,
queryMode: 'local',
listeners: {
expand: function (combo) {
var values = Ext.get(combo.hiddenDataEl.dom.lastChild).dom.value;
values = values.split(",");
Ext.each(values, function (value, i) {
values[i] = parseInt(value);
});
combo.setValue(values);
Ext.get(combo.getInputId()).dom.value = values.length + ' selected';
},
select: function (combo, values) {
if (values[values.length - 1].data.id === parseInt(item.getAttribute('not-applicable'))) {
combo.setValue(parseInt(item.getAttribute('not-applicable')));
} else {
var notApplicable = -1;
var newValues = combo.getValue();
if ((notApplicable = combo.getValue().indexOf(parseInt(item.getAttribute('not-applicable')))) != -1) {
newValues.splice(notApplicable, 1);
}
combo.setValue(newValues);
}
Ext.get(combo.hiddenDataEl.dom.lastChild).dom.value = combo.getValue().join(',');
optionsSelected = combo.getValue();
Ext.get(combo.getInputId()).dom.value = optionsSelected.length + ' selected';
},
change: function (combo) {
if (item.getAttribute('required') == 'true') {
if (combo.getValue().length == 0) {
question.findParentNode('li', 1, true).addCls("is_required");
} else {
question.findParentNode('li', 1, true).removeCls("is_required");
}
//There is no ExtJs equivalent for this
$('#' + combo.getInputId()).keyup();
}
}
}
});
I'm not sure that I follow what is going on with all of the event handlers (so I may be missing something), but the simplest way to achieve what you described in your first sentence above is to provide your own implementation for the combo's getDisplayValue method. Here it is in the docs.
Just set it up to return a count of how many values are selected. Here's an example:
var multiCombo = Ext.create('Ext.form.field.ComboBox', {
renderTo: item.id,
multiSelect: true,
displayField: 'name',
// your own getDisplayValue implementation
getDisplayValue: function() {
return multiCombo.value.length + ' values selected';
},
editable: false,
valueField: 'id',
emptyText: 'Select',
hiddenName: 'data[Model][' + item.getAttribute('question-id') + '][value]',
submitValue: true,
inputType: 'hidden',
value: selectedOptions,
width: 300,
store: store,
queryMode: 'local',
});
Also this may help:
getDisplayValue: function() {
return (this.displayTplData.length > 1) ? this.displayTplData.length + ' selected' : this.displayTplData[0].name;
},
I wrote the following implementation of combo box with dynamic data upload.
Code
Loyalty.tools.DictionaryComboBox = Ext.extend(Ext.form.ComboBox,
{
defaultConfig:{
defaults:{
labelWidth:150
},
displayField:'value',
valueField:'key',
forceSelection:true,
mode:'local',
typeAhead: true,
triggerAction: 'all',
selectOnFocus:true
},
constructor:function (config) {
Ext.apply(config, this.defaultConfig);
config['store'] = new Ext.data.Store({
fields:['key', 'value', 'description'],
proxy:{
type:'ajax',
url:config.dictionaryPath + '/' + config.dictionaryName
}
});
Loyalty.tools.DictionaryComboBox.superclass.constructor.call(this, config);
}
}
);
and I use it the following way
new Loyalty.tools.DictionaryComboBox({
fieldLabel: Loyalty.messages['company.grid.filter.forma'],
dictionaryPath: config.dictionaryPath,
dictionaryName: 'forma',
name: 'forma',
id:'forma',
allowBlank:true,
labelWidth:config.labelWidth
}),
I have the two problems
1) How can I get the list data when combo box is loading( rather than on the first click)
2) and if I'm putting a key in the combo box so that it immediately display the desired value?
1) how are you loading the store. I think you need to add autoLoad: true like so
fields:['key', 'value', 'description'],
autoLoad: true,
2) are you asking how do i select the combo box
var mycombo = Ext.getCmp('mycombo');
mycombo.setValue(id);
i decided my problem. Unfortunately I had to use not "right" metod
Loyalty.tools.DictionaryComboBox = Ext.extend(Ext.form.ComboBox,
{
defaultConfig:{
defaults:{
labelWidth:150
},
displayField:'value',
valueField:'key',
forceSelection:true,
queryMode: 'local',
typeAhead: true,
triggerAction: 'all',
selectOnFocus:true
},
constructor:function (config) {
Ext.apply(config, this.defaultConfig);
var isStoreProvided = (config['store'] == undefined);
if (isStoreProvided) {
var el = this;
config['store'] = new Ext.data.Store({
fields:['key', 'value', 'description'],
autoLoad:true,
proxy:{
type:'ajax',
url:config.dictionaryPath + '/' + config.dictionaryName
},
listeners: {
'load': function() {
if (config['initialValue'] != undefined) {
el.setValue(config['initialValue']);
config['initialValue'] = undefined;
}
}
}
});
}
Loyalty.tools.DictionaryComboBox.superclass.constructor.call(this, config);
}
}
);