how to call query call back data to data attribute select2 - javascript

$('#placeSelect').select2({
width: '100%',
allowClear: true,
multiple: true,
maximumSelectionSize: 1,
placeholder: "Click here and start typing to search.",
data: function(query) {
queryData{!randomJsIden}(query);
},
matcher: function (term, text) {if (text.toUpperCase().indexOf(term.toUpperCase()) == 0){return true;}return false;}
});
function queryData{!randomJsIden}(query){
Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.AutoCompleteV2_Con.getData}','{!sObjVal}','{!labelFieldVar}','{!valueFieldVar}',query.term,
function(result, event){
//if success
if(event.status){
var data = {results:[{ id: 1, text: "Ford" },
{ id: 2, text: "Dodge" },
{ id: 3, text: "Mercedes" },
{ id: 4, text: "Jaguar" }]}
query.callback( data);
}
},
{escape: true}
);
}
</script>
How to initialize query call back data to data attribute in select2 .
I cannot use data directly .In above example i am using sample data .
query : function(query){
queryData{!randomJsIden}(query);
}
I want to replace this by data attribute like this : the below one is not working
data : function(query){
queryData{!randomJsIden}(query);
}
here is the fiddle :
http://jsfiddle.net/Lnf8j/303/
Let me know any ideas from you

There are couple of issues in your code
you cannot name a function using flower braces as it is reserved notation symbol in javascript function queryData{!randomJsIden}(query), instead name it as function queryData(query){ ... }
if your adding a callback for data of your select2 then you need to return that data constructed from queryData() function.
data: function(query) {
return queryData(query);
},
function queryData(query){
...
return data;
}
If i'am not wrong,data is sourced to select2 via asynchronous call inside queryData(), which means the data is returned at unpredictable time,so you need to restrict the user from accessing the select2 component until data is feeded to it.
which means you either need to prefetch the data or disable the select2 field until data is returned from remote call.
Working Demo # JSFiddle

Related

Select2js separate results obtained by ajax call from user input

I have a select2js select field which retrieves a list of diseases based on user query to a database. The type of select is tags so that if the entry is not in the database, the user can add their own. An example of what it looks like is seen below:
The options below are populated by an ajax call made to a local api to retrieve the diseases from a database.
How can we write: "Suggestions" below the user input or hide the user input from the dropdown (seen above as "IgA ne") so that the user is more likely directed to choose one of the options from the database?
Some sample code:
HTML
<select id="diseases" class="form-control selectmultiple" name="diseases[]" multiple="multiple" aria-describedby="diseasesHelp">
</select>
<small id="diseasesHelp" class="form-text text-muted">If known to appear in certain diseases e.g. Tn syndrome</small>
JS
$('#diseases').select2({
tags: true,
placeholder: 'Select an item',
minimumInputLength: 3,
ajax: {
url: '/diseaseSelector',
dataType: 'json',
delay: 250,
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.name,
id: item.id
}
})
};
},
}
});
About the "Suggestions" below the user input, you could use Option Group. Using Ajax, the options should be in a Option Group object, in this format:
{
"text": "Group Name",
"children": [] // your options
}
So, in your case :
processResults: function (data) {
return {
results: [{
text: "Suggestions",
children: $.map(data, function (item) {
return {
text: item.name,
id: item.id
}
})
}]
};
},

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

Javascript Kendo Datasource calling MVC Controller

Sometimes I like to use the HTML5/Javascript implementations of the Kendo framework because you can do some things a little easier. In this case I need to know the number of results so I can either display a kendo grid or not, however other times I need to modify the datasource based on user input on the client side. Unfortunately you can't get the number of results or modify the datasource (as far as I know) using the MVC wrappers. How can I call the controller using the Javascript implementation of the Kendo datasource?
I was able to get this working using the following code:
Controller:
public ActionResult GetStuff(string parameter)
{
// Get your data here ...
var data = GetData(parameter);
return Json(data, JsonRequestBehavior.AllowGet);
} // end
Markup/cshtml:
<div id='myGrid'></div>
<script>
$(document).ready(function () {
// Define the dataSource, note that the schema elements are specified
var dataSource = new kendo.data.DataSource({
dataType: "json",
type: "GET",
transport: {
read: '#Url.Action("MethodName", "ControllerName", new {parameter = myParameter} )'
},
schema: {
data: "Stuff",
total: "TotalNumberofStuff",
errors: "ErrorMessage"
}
});
}
// Call fetch on the dataSource - this gets the data - the fetch method will make only one call.
// Please note that the datasource fetch call is async, so we must use it's results within the fetch function.
dataSource.fetch(function () {
var numberOfItems = dataSource.total();
if (numberOfItems == 0) {
// If 0 items are returned show the label that says there are no items
$("#myGrid").append("<p><label style='font-size: small; color: red;'>-- No Items --</label></p>");
}
else {
$("#myGrid").kendoGrid({
dataSource: dataSource,
height: function () {
return (numberOfItems >= 1 && numberOfItems <= 5) ? null : "225";
},
columns: [
{ field: "StuffId", title: "Id", width: 150 },
{ field: "Stuff", title: "Stuff", width: 150 }
]
});
}
});
</script>

Passing ajax returned data to a function issue

I have question regarding the coeditor ajax call.
I am building my own custom plugin and I want to use the ajax returned data.
function customPlugin(editor, data){
return {
title:'Audio Link',
minWidth : 200,
minHeight : 200,
buttons : [CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton],
contents: [
{
id:'tab',
label: 'custom plugin',
elements: [
{
type:'select',
id:'select box',
items: [['data[0]',0],[data[1],0] ]
}
]
}
]
}
}
//my own ajax wrapper that I can get the returned data
ajax.onFinished = function(data){
};
CKEDITOR.dialog.add('customPlugin', function(editor){
return customPlugin(editor,data);
});
I tried the following
ajax.onFinished = function(data){
CKEDITOR.dialog.add('customPlugin', function(editor){
return customPlugin(editor,data);
});
}
ckeditor would give me error saying no definition of customPlugin.
I am not sure what to do next. Can someone give me a hint? Thanks!

Creating new tags in a Select2 tag textarea

I have an input (textarea) that has Select2's tags applied to it. So when a user types in the name of an item that exists in my data base, it shows a list of matching items and the user can select one and a tag is created.
Here is my code so far for basic tag functionality:
$('#usualSuppliers').select2({
placeholder: "Usual suppliers...",
minimumInputLength: 1,
multiple: true,
id: function(e) {
return e.id + ":" + e.name;
},
ajax: {
url: ROOT + 'Ajax',
dataType: 'json',
type: 'POST',
data: function(term, page) {
return {
call: 'Record->supplierHelper',
q: term,
page_limit: 10
};
},
results: function(data, page) {
return {
results: data.suppliers
};
}
},
formatResult: formatResult,
formatSelection: formatSelection,
initSelection: function(element, callback) {
var data = [];
$(element.val().split(",")).each(function(i) {
var item = this.split(':');
data.push({
id: item[0],
title: item[1]
});
});
//$(element).val('');
callback(data);
}
});
Is there a way for a new tag to be created if the text typed does not exist? Initially I thought this could some how be done by delimiting with spaces, but some items (supplier names) will have spaces in them, so that won't work.
I think when no matches are found the user needs to somehow "create" the tag by pressing a button that could appear in the drop down box, but I have no idea how to do this.
How can I allow users to create new tags that may have spaces in them and still be able to carry on adding more tags, existing or otherwise?
Yes you can do it. There is a example in the documentation. Look at http://ivaynberg.github.io/select2/#events
$("#e11_2").select2({
createSearchChoice: function(term, data) {
if ($(data).filter( function() { return this.text.localeCompare(term)===0;
}).length===0) {
return {id:term, text:term};
}
},
multiple: true,
data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});
You have to create a function like createSearchChoice, that returns a object with 'id' and 'text'. In other case, if you return undefined the option not will be created.

Categories