Unable to select the newly added selectize components post an ajax call - javascript

Unable to select the newly added selectize components post an ajax call
I have pre populated the options with the currently selected options, and trying to retrieve more option with an ajax call from the server.
My server returns data like this but I am not sure what to do with this data
[{"id":303,"name":"Short Sleeve Opening"}]
I've tried using the addOption and refreshOptions methods, but they doesn't seem to work.
Below is the piece of code which is invoking the selectize component.
$(function () {
$select_options = $('select').selectize({
plugins: ['restore_on_backspace', 'remove_button', 'drag_drop'],
delimiter: ',',
persist: false,
create: function (input) { // I am not sure if this is of any use, as I never found the control to enter in this part of code during debugging.
return {
value: input,
text: input
}
},
load: function (query, callback) {
if (!query.length) return callback();
$.ajax({
dataType: 'json',
url: '/measurement_tags/autocomplete_key?q=' + encodeURIComponent(query),
error: function () {
callback(); //Not sure what the callback should be, documenation is not self explanatory
},
success: function (res) {
//Added this callback to add the new options to the list, it is adding the new options to the list but I can't select them at all
//Moreover, second time I try to use autocomplete it doesn't work. The control doesn't reach the load method, and no error observed in console
for (index in res) {
$('.selectize-dropdown-content').append('<div class="option" data-selectable="" data-value="' + res[index].id + ' ">' + res[index].name + '</div>');
}
}
});
}
});
});
What is the exact way to add the new options to the list permanently?

Finally achieved this after wasting whole day:
$(function () {
$select_options = $('select').selectize({
plugins: ['restore_on_backspace', 'remove_button', 'drag_drop'],
delimiter: ',',
persist: false,
options: [],
load: function (query) {
$.ajax({
dataType: 'json',
url: '/measurement_tags/autocomplete_key?q=' + encodeURIComponent(query),
success: function (res) {
updateOptions(res);
}
});
}
});
var updateOptions = function (newOptions) {
var selectize = $select_options[0].selectize;
for (index in newOptions) {
selectize.addOption({
value: newOptions[index].id,
text: newOptions[index].name,
});
}
selectize.refreshOptions();
}
});

Related

How can I fill all data in select2 (4.0) when page loaded?

I am using select2 plugin (v.4.0).
What I am trying to do:
$("#search-input-chains").select2({
placeholder: "Unit",
theme: "bootstrap4",
allowClear: true,
initSelection: function (element, callback) {
callback({id: 1, text: 'Text'});
},
ajax: {
url: function () {
return getURLForFilial();
},
dataType: 'json',
delay: 250,
processResults: function (response) {
console.log(response);
return {
results: response
};
},
cache: false
}
});
function getURLForFilial() {
return '/user/rest/data/entry/units/branches?type=1';
}
I need to understand, whether my control has data retrieved from DB or not, and if there is no data - this select list shall not be activated.
I found how I can understand the data amount:
$("#search-input-chains").data().select2.results.$results[0].childNodes.length
(maybe there is another way that is much better?)
But this piece of code returns 0 until I will activate (click) on the select2 box and trigger AJAX request to find data.
I read a lot about how can I perform the pre-call off AJAX, but it doesn't work.
I tried to trigger event on select2 in such a way:
$("#search-input-chains").val().trigger('change');
Please, advice, how can I load data to my select2 control with the page load to understand whether I need to disable this select or not?
I've made it via AJAX:
ajax({
type: 'GET',
url: '/user/rest/data/entry/units/branches?type=1'
}).then(function (data) {
if (data.length !== 0) {
chainsSelectElement.prop("disabled", false);
chainSelectorHasData = true;
} else {
// create the option and append to Select2
let option = new Option('Nothing', 'null', true, true);
chainsSelectElement.append(option);
chainSelectorHasData = false;
chainsSelectElement.prop("disabled", true);
}
getDataForSubdivisions();
});

jQuery promises with summernote hints

I am working on getting a live user list from a database for the Summernote Hints however when using async it just falls over, however with async off it causes the UI to freeze... clearly not optimal for the UX.
$(document).ready(function()
{
$('.editor').summernote({
height: 300,
hint: {
match: /\B#(\w*)$/,
users: function(keyword) {
var result = data;
$.ajax({
url: '/users/' + keyword,
type: 'get',
async: false //This works but freezes the UI
}).done(function(data)
{
result = data; //Set the result to the returned json array
});
return result;
},
search: function (keyword, callback) {
callback(this.users(keyword)); //callback must be an array
},
content: function (item) {
return '#' + item;
}
}
});
});
How can I get async to work without falling over? I believe it has something to do with promises however not sure.
Don't call callback. users needs to call that from the done function.
$(document).ready(function()
{
$('.editor').summernote({
height: 300,
hint: {
match: /\B#(\w*)$/,
users: function(keyword, callback) {
$.ajax({
url: '/users/' + keyword,
type: 'get',
async: true //This works but freezes the UI
}).done(callback);
},
search: function (keyword, callback) {
this.users(keyword, callback); //callback must be an array
},
content: function (item) {
return '#' + item;
}
}
});
});

C# Webservice json data jquery ui with custom formatting

I'm using asp.net webservice to use it in jQuery UI autocomplete plugin and here is the data I'm getting.
{"d":[
{
"__type":"WebS.Model.SearchModel",
"MainCommodityId":1,
"MainCommodityName":"Pulses",
"SubcommodityId":3,
"SubCommodityName":"Urid Dal",
"BrandId":3,
"BrandName":"President"
},
{
"__type":"WebS.Model.SearchModel",
"MainCommodityId":1,
"MainCommodityName":"Pulses",
"SubcommodityId":1,
"SubCommodityName":"Red Gram",
"BrandId":4,
"BrandName":"President"
}
]
}
This is the script I'm using:
$(document).ready(function () {
$(".input-search").autocomplete({
source: function (request, response) {
$.ajax({
url: '/WebServices/GetAllBrandNames.asmx/getAllBrands',
data: "{ 'data': '" + request.term + "'}",
dataType: "json",
contentType: "application/json; charset=utf-8",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data.d, function (item) {
return {
value: item.BrandName,
label: item.SubCommodityName
}
}))
},
error: function (response) {
alert('error');
},
failure: function (response) {
alert('faii');
}
});
},
select: function (e, i) {
console.log(i.MainCommodityId);
console.log(i.SubcommodityId);
console.log(i.BrandId);
},
minLength: 1
}).autocomplete("instance")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + "" + item.BrandName + " in " + item.MainCommodityName + " - " + item.SubCommodityName + "</a>")
.appendTo(ul);
};
});
The issues are:
When I tried to enter keyword say: pre the aforesaid output is coming in json. However, the list is returning only one "President" item where it should display 2 items.
The list is displaying "undefined in undefined - undefined" instead of values after adding .autocomplete("instance")._renderItem function.
console.logs are also undefined after selecting an item.
How can these issues fixed?
The default behavior of the select event is to update the input with ui.item.value. This code runs after your event handler.
Simply prevent the default action on select and focus using event.preventDefault() or by return false and use _renderItem for custom dropdown.
focus: function(event, ui) {
// prevent autocomplete from updating the textbox
event.preventDefault(); // or return false;
}
select: function(event, ui) {
// prevent autocomplete from updating the textbox
event.preventDefault();
//do something
}
References:
jQuery UI Autocomplete Examples
Example 2
Finally, I was able to achieve what I wanted. Answering my question as it may helpful to someone.
javascript:
$(document).ready(function () {
$(".input-search").autocomplete({
source: function (request, response) {
$.ajax({
url: '/WebServices/GetAllBrandNames.asmx/getAllBrands',
data: "{ 'data': '" + request.term + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data.d, function (item) {
// don't forget to $.map to (data.d where d is the top node
return {
// assign values from json response for further use
brandid: item.BrandId,
brand: item.BrandName,
maincommodityid: item.MainCommodityId,
maincommodity: item.MainCommodityName,
subcommodityid: item.SubcommodityId,
subcommodity: item.SubCommodityName
}
}));
},
error: function (response) {
alert('Server Error. Please try again.');
},
failure: function (response) {
alert('Failed to get result');
}
});
},
focus: function (event, ui) {
// prevent autocomplete from updating the textbox
event.preventDefault();
},
select: function (event, ui) {
// prevent autocomplete from updating the textbox
event.preventDefault();
// do further action here such as assigning id to hidden field etc.
$(".input-search").val(ui.item.brand);
// navigate to the selected item's url ex: /catalogue/1/1/pulses/red-gram/4/president
var str = "/catalogue/" + ui.item.maincommodityid + "/" +
ui.item.subcommodityid + "/" + $.trim(ui.item.maincommodity.replace(/\s+/g, '-').toLowerCase()) + "/" +
$.trim(ui.item.subcommodity.replace(/\s+/g, '-').toLowerCase()) + "/" + ui.item.brandid + "/" +
$.trim(ui.item.brand.replace(/\s+/g, '-').toLowerCase());
window.location = str;
},
minLength: 3
}).autocomplete("instance")._renderItem = function (ul, item) {
// get values and create custom display
var $a = $("<a></a>");
$("<strong></strong>").text(item.brand).appendTo($a);
$("<span></span>").text(" in ").appendTo($a);
$("<span></span>").text(item.subcommodity).appendTo($a);
return $("<li></li>").append($a).appendTo(ul);
};
});
CSS:
ul.ui-front {
z-index: 1200; // change z-index according to your UI.
}
Usually I do this way and Its work.
$(document).ready(function () {
var jsondata=array();
$.post("/WebServices/GetAllBrandNames.asmx/getAllBrands",{data: request.term},function(data){
var data=JSON.parse(data);
$.each(data.d, function( index, value ) {
jsondata[index].value=value;
});
$(".input-search").autocomplete({
source:jsondata,
//other property and events
})
});
I mean apply source JSON after completing request because sometimes if AJAX takes some time to load execution pointer still execute rest of code without waiting for response.
I did not test this code but I always do this way and never get your kind of error. Good Luck

How to log "select2" selected value

I use "Select2" as dropdown list.
Now i´d like my page content to change upon my choice in Select2.
I´m stepping forward and have come to this:
JS
$(document).ready(function(){
// display logs
function log(text) {
$('#logs').append(text + '<br>');
}
//SELECT2
$( ".select2_choose_objnr" ).select2({
placeholder: "Välj Objekt..",
ajax: {
url: "php.php",
type: "POST",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term // search term
};
},
processResults: function (data) {
return {
results: data
};
},
cache: true
},
}).on("change", function(e) {
log("change val=" + e.val);
});
});
From this Js, i got: val=undefined
How can i change my code to get the selected value/text ?
For v4.0.3
In the change callback, call $(this).val() to retrieve an array of selected values
.on("change", function(e) {
log("change val=" + $(this).val());
});
val() is a function, not a property and you want to call it on $(this)
You can accesss the full data
.on('change', function(e) {
// Access to full data
console.log($(this).select2('data'));
});

Alter the filter on autocomplete to allow sorting on complete string

I have a functioning autocomplete jQuery input control but there are two things it is doing that I would like to alter.
First, it fires again and again. I would like for the data to be returned once, cached and not called again.
Second, I would like for the user to type in the control and based on what they type be able to search the entire string and not just the beginning.
This is my functioning script that returns data to the autocomplete and WORKS.
<script type="text/javascript">
$(function () {
$('#datePicker').datepicker();
});
$(document).ready(function() {
$("#autocomplete").autocomplete({
source: function (request, response) {
$.ajax({
url: "FacilitiesAsync",
type: 'GET',
cache: true,
data: 'sourceDb=myDb',
dataType: 'json',
success: function (json) {
// call autocomplete callback method with results
response($.map(json, function (name) {
return {
label: name.label,
value: name.value
};
}));
},
error: function (xmlHttpRequest, textStatus, errorThrown) {
$("#autocomplete").text(textStatus + ', ' + errorThrown);
}
});
},
select: function (event, ui) {
$('#autocomplete').val(ui.item.label);
return false;
},
messages: {
noResults: '',
results: function () {
}
}
});
});
</script>
I found this bit of code that overrides the filter feature of the autocomplete but I have NO IDEA where to add this. I have tried several places to no avail....
// Overrides the default autocomplete filter function to search only from the beginning of the string
$("#autocomplete").autocomplete.filter = function (array, term) {
var matcher = new RegExp("\\b" + $.ui.autocomplete.escapeRegex(term), "i");
return $.grep(array, function (value) {
return matcher.test(value.label || value.value || value);
});
};
My input control looks like this.
<input id="autocomplete" />
I appreciate the direction...
To cache the data from your server, setup a separate function which handles (and caches, if necessary) the response from your ajax call:
var cachedResult = null;
function fetchResponse(callback) {
if (cachedResult) callback(cachedResult)
$.ajax({
url: "FacilitiesAsync",
type: 'GET',
cache: true,
data: 'sourceDb=myDb',
dataType: 'json',
success: function (json) {
// call autocomplete callback method with results
var cachedResult = $.map(json, function (name) {
return {
label: name.label,
value: name.value
};
});
callback(cachedResult);
},
error: function (xmlHttpRequest, textStatus, errorThrown) {
$("#autocomplete").text(textStatus + ', ' + errorThrown);
}
});
}
$(document).ready(function() {
$("#autocomplete").autocomplete({
source: function (request, response) {
fetchResponse(function(result) {
response(result)
})
}
});
});
As for the custom matcher, look no further than the docs, in the Using a custom source callback to match only the beginning of terms example. Your custom matcher only differs in the regex pattern. Note also that this is all done within the "source" callback.

Categories

Resources