Loading values into Selectize.js - javascript

Problem
I have a text input that I have selectized as tags which works fine for querying remote data, I can search and even create new items using it and that all works OK.
Using selectize:
var $select = $('.authorsearch').selectize({
valueField: 'AuthorId',
labelField: 'AuthorName',
searchField: ['AuthorName'],
maxOptions: 10,
create: function (input, callback) {
$.ajax({
url: '/Author/AjaxCreate',
data: { 'AuthorName': input },
type: 'POST',
dataType: 'json',
success: function (response) {
return callback(response);
}
});
},
render: {
option: function (item, escape) {
return '<div>' + escape(item.AuthorName) + '</div>';
}
},
load: function (query, callback) {
if (!query.length) return callback();
$.ajax({
url: '/Author/SearchAuthorsByName/' + query,
type: 'POST',
dataType: 'json',
data: {
maxresults: 10
},
error: function () {
callback();
},
success: function (res) {
callback(res);
}
});
}
});
The text box:
<input class="authorsearch" id="Authors" name="Authors" type="text" value="" />
Examples:
Then when I select one (in this case 'apple') it comes up in a badge as you'd expect, and the underlying value of the textbox is a comma separated list of the values of these items.
Current Output
The problem is when I load a page and want values retrieved from the database to be displayed in the selectized text input as tags, it only loads the values and I can see no way of displaying the displayname instead.
<input class="authorsearch" id="Authors" name="Authors" type="text" value="1,3,4" />
Desired Ouput
I have tried all sorts of values for the inputs value field to have it load the items as showing their displayname and not their values. Below is an example of a single object being returned as JSON, being able to load a JSON array of these as selectized tags would be ideal.
[{"AuthorId":1,"AuthorName":"Test Author"},
{"AuthorId":3,"AuthorName":"Apple"},
{"AuthorId":4,"AuthorName":"Test Author 2"}]
How can I go about this? Do I need to form the value of the text box a particular way, or do I need to load my existing values using some javascript?

Thanks to your answer and based on your onInitialize() approach I ended up with a similar solution. In my case I just needed to translate one value, thus I was able to store the id and label as data attributes in the input field.
<input type="text" data-actual-value="1213" data-init-label="Label for 1213 item">
Then on initialization:
onInitialize: function() {
var actualValue = this.$input.data('actual-value');
if (actualValue){
this.addOption({id: actualValue, value: this.$input.data('init-label')});
this.setValue(actualValue);
this.blur();
}
}
According to these options:
$('input').selectize({
valueField: 'id',
labelField: 'value',
searchField: 'value',
create: false,
maxItems: 1,
preload: true,
// I had to initialize options in order to addOption to work properly
// although I'm loading the data remotely
options: [],
load: ... ,
render: ...,
onInitialize: ....
});
I know this does not answer your question but wanted to share just in case this could help someone.

I ended up using the onInitialize callback to load the JSON values stored in a data-* field. You can see it in action here in this jsfiddle.
<input class="authorsearch" id="Authors" name="Authors" type="text" value=""
data-selectize-value='[{"AuthorId":1,"AuthorName":"Test"},{"AuthorId":2,"AuthorName":"Test2"}]'/>
Basically it parses the data-selectize-value value and then adds the option(s) to the selectize then adds the items themselves.
onInitialize: function() {
var existingOptions = JSON.parse(this.$input.attr('data-selectize-value'));
var self = this;
if(Object.prototype.toString.call( existingOptions ) === "[object Array]") {
existingOptions.forEach( function (existingOption) {
self.addOption(existingOption);
self.addItem(existingOption[self.settings.valueField]);
});
}
else if (typeof existingOptions === 'object') {
self.addOption(existingOptions);
self.addItem(existingOptions[self.settings.valueField]);
}
}
My solution does presume my JSON object is formed correctly, and that it's either a single object or an object Array, so it may or may not be appropriate for someone elses needs.
So it parses:
[{"AuthorId":1,"AuthorName":"Test"},
{"AuthorId":2,"AuthorName":"Test2"}]
To:
Based of course on my selectize settings in my original post above.

Even simpler on new version of selectize using items attribute. Basically to set a selected item you need to have it first in the options. But if you use remote data like me, the options are empty so you need to add it to both places.
$('select').selectize({
valueField: 'id',
labelField: 'name',
options:[{id:'123',name:'hello'}],
items: ['123'],
...
This is working for me and took me a while to figure it out... so just sharing

Related

Select2 - Multi Select Autocompletion - Programmatically population of field

I am using the bundled AUI Select2 Lib in a JIRA 8.13 instance.
What I would like to try is to code an autocompletion field with multiple values. My main components are running so far, but I have some problems while populating the field programmatically via JavaScript.
This my basic setup:
field.auiSelect2(
{
multiple: true,
closeOnSelect: true,
tokenSeparators: [","],
placeholder: PLACEHOLDER,
minimumInputLength: 2,
formatResult: format,
initSelection: function (element, callback) {
callback({id: $(element).val(), text: $(element).val()});
},
ajax: {
url: <...>,
dataType: 'json',
data: function (term) {
return {term: term,};
},
results: function (results) {
return results;
},
quietMillis: 250,
cache: false
},
});
The field population code is the following:
field.val(["A","B","C"]).trigger('change');
But this results in a single entry in the input field value "A,B,C" which is wrapped within a single gray box instead of multiple boxes - one for each passed value.
Any ideas on how to solve this issue? I guess it might be related to the initSelection parameter.
https://codepen.io/aschuma/pen/rNLRLWL
$(field).auiSelect2("data", [{id: "A", text: "A"},{id:"B", text: "B"},{id:"C", text: "C"}]);
https://codepen.io/aschuma/pen/ExyMNJP
This error is because you are using an <input> element instead of a <select> element. When you call this:
field.val(["A","B","C"]).trigger('change');
what you are really doing is setting the value of the <input> field which operates completely separately from select2. An <input> field can only have a single value, so it is likely that jQuery simply calls a standard .join() on the array and then sets the value to that. You can verify this is correct by simply opening a console and running:
console.log(["A","B","C"].join())
which will result in the string "A,B,C". What you might need is a <select> element which can support multiple values. Also note that the latest version of AUI Select2 (9.1.4) uses select2 version 3.4.5 instead of the latest version (4.0.13 as of the time of this post).
You could also set the data on the select2 instance itself like so:
$(field).auiSelect2('data', [
{id: 'A', text: 'A'},
{id: 'B', text: 'B'},
{id: 'C', text: 'C'},
]);
Found this thread because we had the same problem. I can confirm that it's also posible using elements if you use the following code.
AJS.$('#customfield_14882').auiSelect2(
{
multiple: true,
closeOnSelect: true,
tokenSeparators: [","],
placeholder: PlaceHolder,
minimumInputLength: 1,
allowClear:true,
initSelection: function (element, callback) {
var arr = $(element).val().split(',');
var res=[];
for(var i=0;i<arr.length;i++){
res[i]={id:arr[i],text:arr[i]};
}
callback(res);
},
ajax: {
url: "<url>",
dataType: 'json',
data: function (term) {
return {term: term};
},
results: function (results) {
return {results:results};
},
quietMillis: 250,
cache: false
},
});

Selectize Not Loading Options With Ajax

I am using ExpressJS to build a mangament dashboard for a community I am part of. I currently have a modal that shows up to add new games to a database. The data is fetched remotely but I am having trouble getting the data to show up to select it.
I am able to use to console.log to show the data being retrieved but I am not sure where I am falling short.
Code
$(document).ready(function () {
$('#ttitle').selectize({
create: false,
valueField: 'appid',
labelField: 'name',
searchField: 'name',
closeAfterSelect: true,
options: [],
load: function (query, callback) {
if (!query.length) return callback();
$.ajax({
url: `/games/all?search=${encodeURIComponent(query)}`,
type: 'GET',
error: function () {
callback();
},
success: function (res) {
console.log(res.value)
callback(res.value);
}
});
}
});
});
While typing in the search box, console shows the following
HTML - if it matters
<div class="form-group">
<label for="ttitle">Game Title</label>
<select name="ttitle" id="ttitle">
<option></option>
</select>
</div>
The searchField setting takes an array value (not a string), so you need to change it to:
searchField: ['name']
Otherwise, your setup looks fine.

Adding to x-editable select source with button click

I have using BootstrapTable with X-editable. I have a select box, that I would like to update the source data with a button click. Ideally, I like to get the source from the column, push a value to it and reload it without changing any edits to that column by the user.
Full code:
http://jsfiddle.net/rp4nkb46/1/
relevant code:
$('#addoption').click(function () {
names.push({value: 5, text: 'Bob'})
$('#table').bootstrapTable('OnRefresh', {});
});
Use a function to return the names array rather than specifying the array directly in your table setup:
$(function () {
$('#table').bootstrapTable({
columns: [{field: 'Contact',
title: 'Contact',
editable: {
type: 'select',
source: function() { return names; }
}
}],
data: data
});
});
It seems that the X-Editable will bind a supplied array once upon creation of the control but will call the function each time.

Selectize: Setting Default Value in onInitialize with setValue

I have a web application with multiple Selectize objects initialized on the page. I'm trying to have each instance load a default value based on the query string when the page loads, where ?<obj.name>=<KeywordID>. All URL parameters have already been serialized are are a dictionary call that.urlParams.
I know there are other ways to initializing Selectize with a default value I could try; but, I'm curious why calling setValue inside onInitialize isn't working for me because I'm getting any error messages when I run this code.
I'm bundling all this JavaScript with Browserify, but I don't think that's contributing to this problem.
In terms of debugging, I've tried logging this to the console inside onInititalize and found that setValue is up one level in the Function.prototype property, the options property is full of data from load, the key for those objects inside options corresponds to the KeywordID. But when I log getValue(val) to the console, I get an empty string. Is there a way to make this work or am I ignoring something about Selectize or JavaScript?
module.exports = function() {
var that = this;
...
this.selectize = $(this).container.selectize({
valueField: 'KeywordID', // an integer value
create: false,
labelField: 'Name',
searchField: 'Name',
preload: true,
allowEmptyOptions: true,
closeAfterSelect: true,
maxItems: 1,
render: {
option: function(item) {
return that.template(item);
},
},
onInitialize: function() {
var val = parseInt(that.urlParams[that.name], 10); // e.g. 5
this.setValue(val);
},
load: function(query, callback) {
$.ajax({
url: that.url,
type: 'GET',
error: callback,
success: callback
})
}
});
};
...
After sprinkling in some console.logs into Selectize.js, I found that the ajax data hadn't been imported, when the initialize event was triggered. I ended up finding a solution using jQuery.when() to make setValue fire after the data had been loaded, but I still wish I could find a one-function-does-one-thing solution.
module.exports = function() {
var that = this;
...
this.selectize = $(this).container.selectize({
valueField: 'KeywordID', // an integer value
create: false,
labelField: 'Name',
searchField: 'Name',
preload: true,
allowEmptyOptions: true,
closeAfterSelect: true,
maxItems: 1,
render: {
option: function(item) {
return that.template(item);
},
},
load: function(query, callback) {
var self = this;
$.when( $.ajax({
url: that.url,
type: 'GET',
error: callback,
success: callback
}) ).then(function() {
var val = parseInt(that.urlParams[that.name], 10); // e.g. 5
self.setValue(val);
});
}
});
};
...
You just need to add the option before setting it as the value, as this line in addItem will be checking for it:
if (!self.options.hasOwnProperty(value)) return;
inside onInitialize you would do:
var val = that.urlParams[that.name]; //It might work with parseInt, I haven't used integers in selectize options though, only strings.
var opt = {id:val, text:val};
self.addOption(opt);
self.setValue(opt.id);
Instead of using onInitialize you could add a load trigger to the selectize. This will fire after the load has finished and will execute setValue() as expected.
var $select = $(this).container.selectize({
// ...
load: function(query, callback) {
// ...
}
});
var selectize = $select[0].selectize;
selectize.on('load', function(options) {
// ...
selectize.setValue(val);
});
Note that for this you first have to get the selectize instanze ($select[0].selectize).
in my case it need refresh i just added another command beside it
$select[0].selectize.setValue(opt);
i added this
$select[0].selectize.options[opt].selected = true;
and changes applied
but i dont know why?
You can initialize each selectize' selected value by setting the items property. Fetch the value from your querystring then add it as an item of the items property value:
const selectedValue = getQueryStringValue('name') //set your query string value here
$('#sel').selectize({
valueField: 'id',
labelField: 'title',
preload: true,
options: [
{ id: 0, title: 'Item 1' },
{ id: 1, title: 'Item 2' },
],
items: [ selectedValue ],
});
Since it accepts array, you can set multiple selected items

Select2 - Can't select a value?

Release version (Select 4.0.1)
HTML
<select id="search_customers" style="width: 300px;"></select>
Javascript:
$("#search_customers").select2({
multiple: false,
allowClear: true,
ajax: {
url: "#Url.Action("
SearchCustomers ", "
Home ")",
dataType: 'json',
delay: 250,
data: function(params) {
return {
id: params.term, // search term
};
},
processResults: function(data, params) {
return {
results: data
} // Data is a List<T> of id an text
},
}
});
The dropdown works, and I can see my records, however, when I click on one of the options the box closes, and the selected record isn't shown. My box looks like this
I've tried everything I can think of. The issue appears in all browsers. The data being return is a list of id/text pairs.
Controller code
var customers = this.service.SearchCustomers(id).Select(x => new { id = x.CustomerID, text = x.CustomerName }).ToList();
return Json(customers, JsonRequestBehavior.AllowGet);
My customer ID's had leading spaces for some reason. (Old ERP system), so adding a .Trim() call to the select statement on the customer ID fixed it. Apparently select2 doesn't like " 56", but "56" is fine!

Categories