jQuery Select2 Plugin - javascript

I have a form that allows a user to enter information. It uses the select2 plugin.
On load, it is initiated to the visible form and works fine.
However, once I add a new div and run it again on all of the classes (original and added) it loses the values that were in the ones prior to adding a new one.
Is there a way to preserve this information when the plugin is run?
When you click on Add Vehicle, it inserts a new div and then runs the plugin again on the .carpool selector which is in each one of the divs.
$(".carpool").select2({
multiple: true,
allowClear: true,
placeHolder: 'Agent Last name',
minimumInputLength: 3,
ajax: {
url: "jsonUser.php",
dataType: 'json',
allowClear: true,
data: function (term) {
return {
term: term, // search term
};
},
results: function (data) { // parse the results into the format expected by Select2.
return {results: data};
}
},
});

Just run the plugin on the div you're adding. You have access to that specific div, because it's the one you're appending to the DOM. So if you have something like:
newDiv = $("<div>new stuff</div");
divContainer.append(newDiv);
newDiv.select2({...});
Clearly, you need to alter the above to fit the code you've got. If you need to run the plugin on some child elements of the new div, then you'd use something like:
newDiv.find("relevant child selector").select2({...});

Related

Select 2 with ajax remote data source doesn't select the correct options

I have setup a select 2 field vers 4.0.3, with a remote data source.
When I select the ith element in the list for the first time it selects the correct element. Afterwards if the list has changed and shows a different ith element and you click or press return to select the ith element, it still selects the element which was chosen the first time. So it seems that some attribute of the select2 field is not updated correctly.
I read that documentation and think that it might be connected to this warning:
For remote data sources only, Select2 does not create a new element until the item has been selected for the first time. This is done for performance reasons. Once an has been created, it will remain in the DOM even if the selection is later changed.
var remoteDataConfig = {
placeholder: gene_glb,
minimumInputLength: 1,
allowClear: true,
ajax: {
url: '/genes_select',
type: "POST",
dataType: 'json',
data: function(term) {
return {
"org_db": "value",
"searchterm": term
};
}
}
};
$("#gene_select").select2(remoteDataConfig);
Edit: One possible "not quite solution" is to remove the selected element after each select.
$('#gene_select :selected').remove();
I'm still interested in how one could fix the configuration since this should happen automatically.

select2 : cannot read property query of null

I have create javascript like this
$(document).on("select2:open", ".provider_suggestion", function() {
$(this).select2({
minimumInputLength: 2,
ajax: {
url: "../include/suggestion/provider_name.php",
dataType: 'json',
delay: 250,
data: function(params){ return { q: params.term }; },
processResults: function (data, page) { return { results: data }; },
cache: true
}
});
});
and create select html input like this
<select id="c_providers" name="c_providers" class="provider_suggestion" style="width:100%"></select>
and when page loaded, I click the select input.
I open the browser console, its mentioned that
Uncaught TypeError: Cannot read property 'query' of null
I still dont understand about this issue.
You must have already initialized the select2 somewhere previous to your provided code snippet, or I expect the select2:open listener would never fire and cause your problem. When I replicated the situation in a fiddle and peeked at the select2 source, it seemed that select2 was complaining about a dataAdapter being null, which must be a side effect of this double select2() call, or that the .select2() call is inside the listener with an unexpected context... Or something, don't have the time or interest to explore down to the root cause.
Regardless, moving the .select2() call out of the listener (and removing the then empty listener) removed the problem. Based on the limited information available in your question, it does not seem like there is any need at all to use this listener, at least the way you are using it. A simplistic working example is in this JSfiddle, where the only real difference to your original code is the removal of the listener wrapping (and the mocking of AJAX calls). So, try something like
$('#c_providers').select2({
minimumInputLength: 2,
ajax: {
url: "../include/suggestion/provider_name.php",
dataType: 'json',
delay: 250,
data: function(params){ return { q: params.term }; },
processResults: function (data, page) { return { results: data }; },
cache: true
}
});
as the only select2 initialization for this #c_providers element.

How to prevent automatic sorting in select2 tags (v4)

I'm creating a project which uses a multiple select2. It's all fine, the problem is I have to prevent the tags (and its result data array) from automatically sorting. I've searched through them but most answers are for older versions of select. Is there a flag or something for this in select2 that I don't know about?
$.getJSON("countries.json").done( function(data) {
$(".country-select").select2({
placeholder: "Select Country",
allowClear: true,
data: data,
maximumSelectionLength: 5
})
$(".country-select").change(function() {
var selected = $(".country-select").select2('data');
}
That is my code, and I want to get all unsorted data to be stored in selected. I found a solution in Select2: How to prevent tags sorting but it appends the selected element at the end of the options.

Set bootstrap tooltip to AJAX call results

I have a bootstrap tooltip that I want to load data from an AJAX requestion, with the text from the request being the titleproperty of the tooltip. My AJAX request works fine, but I have two problems:
Why isn't the data from the AJAX call making its way into the tooltip?
How can I use my ttManager object to encapsulate the tooltip's state?
Currently, when the page first loads and I click on #btnSubmit in the console I see
success and the correct data from the console.log(ttManager) line
$(document).ready(function () {
//this object's title attribute will be the value of ttManager.title seen below
var ttManager = {
title: '',
setTitle: function (data) {
this.title = data;
}
}
var ajaxCall = function () {
//this returns the top five results of text from a query
$.ajax({
type: "POST",
contentType: "application/json",
url: "Service.asmx/GetDrugs",
dataType: "json",
success: function (data) {
console.log('success');
ttManager.title = data.d;
//inside this function I want to set ttManager.title equal to the data.d
console.log(ttManager);
},
error: function (xhr) {
console.log('failed: ' + xhr.status);
}
});
}
$('#btnSubmit').tooltip({
//reference to ajax call
//title is the attribute responsible for displaying text in the tooltip
//I need to use a reusable object to set the text property instead of referencing ajaxCall
//would it be better if there below were title: ttManager.title?
title: ajaxCall,
trigger: 'click',
placement: 'right'
});
});
I'm pretty sure that I need a callback function somewhere, but I'm not sure where. Any future pointers would be appreciated, too. Thanks.
First, a little explanation of bootstrap's tooltip plugin. The tooltip displayed will pull from the elements title attribute if there's one present, otherwise it will use the title argument passed.
The next thing you need to understand is that ajax calls are asynchronous. This means code will continue to run while it's waiting for a response. So, for example, if I do something like this
$.ajax({
URL: 'google.com',
success: function(){
console.log('yay');
}
});
console.log('woohoo');
you'd see "woohoo" in the console before "yay". So, currently, you're calling $('#btnSubmit').tooltip before your ajax query has altered the state of ttManager.
The other issue is that you're currently not doing anything with ttManager in relation to bootstrap. I feel like I should also mention that the ttManager object seems meaningless here.
Personally, I would change my ajax success function to this (sets the title attribute, calls tooltip, then produces another click to make the tooltip appear)
success: function(data) {
$('#btnSubmit').attr('title', data.d)
.tooltip({
trigger: 'click',
placement: 'right'
}).click();
}
remove the current $('#btnSubmit').tooltip... code currently there, and add in a one time click handler to call your ajax.
$('#btnSubmit').one('click', function() {
ajaxCall();
});

JQGRID: Trigger Reload not working on iFrame

I have a web page with an iFrame. It loads a web page (same domain) with a jqGrid table. What I'm trying to do now is:
You press a link called search it opens a dialog with a filter form to filter your search.
When you press search button inside the dialog, it changes jqGrid url param and it should .trigger('reloadGrid').
It does all except the reloadGrid, I don't know why.
Any suggestion?
Code:
// DIALOG-ACTION-SEARCH IS THE BUTTON CLASS
$('#dialog').find('.dialog-action-search').button({icons: {
primary: 'ui-icon-search'
}, text: true}).click(function(e) {
e.preventDefault();
$('.content-center').contents().find('#list').setGridParam({
url: 'filteredsearch.html?option=1'
}).trigger('reloadGrid');
$('#dialog').dialog('destroy');
$('#dialog').remove();
});
setGridParam returns a jqGrid object, not a jQuery object, so I'm pretty sure you can't chain the trigger method. Try this instead:
var list = $('.content-center').contents().find('#list')
list.setGridParam({
url: 'filteredsearch.html?option=1'
})
list.trigger('reloadGrid');
I've found that before calling trigger('reloadGrid') with JSON data, you should reset the datatype parameter.
$("#grid").jqGrid('setGridParam', { datatype: 'json' });
In response to your comments, I would split up the chained method calls and then put a breakpoint on e.preventDefault() in Chrome debugger so you can assure that everything is actually getting hit.
$('#dialog').find('.dialog-action-search').button(
{
icons: { primary: 'ui-icon-search' } ,
text: true
});
$('#dialog').find('.dialog-action-search').click(function(e) {
e.preventDefault();
var grid = $('.content-center').contents().find('#list');
$(grid).jqGrid('setGridParam', { url: 'filteredsearch.html?option=1' });
$(grid).jqGrid('setGridParam', { datatype: 'json' });
$(grid).trigger('reloadGrid');
$("#dialog").dialog('destroy');
$("#dialog").remove();
});
While I'm a fan of chaining when you can, in this case I don't think you're going to find the root of the issues without doing things a little more explicitly, especially when using .find. How do you know that the .find is actually returning the element that you want?
I experienced same problem. I did not have time to investigate why it was happening but found a workaround for it.
In a javascript file that loads inside iframe with your grid I declared
window.top.reloadEventList = function () {
$("#grid").trigger("reloadGrid");};
Then just call
window.top.reloadEventList()
instead of
list.trigger('reloadGrid')

Categories