Select2: how to add a link instead of "No results found" text? - jquery-select2

Following is my code:
$('#cow_id_2').select2({
allowClear: true,
placeholder: "Search a cow/dam ID",
formatNoMatches: function (term) {
return "<a href=/'http://google.com/'>Add</a>";
}
});
When I try to add a link the plugin just stop working.
I am using Select2 4.0.3 version

If you're using version 4 or newer of select2, try this:
$('#cow_id_2').select2({
allowClear: true,
escapeMarkup: function (markup) { return markup; },
placeholder: "Search a cow/dam ID",
language: {
noResults: function () {
return "<a href=/'http://google.com/'>Add</a>";
}
}
});

The selected answer is correct. Here is a little precision. Instead of overriding escapeMarkup, you can return a jQuery object in the noResults method. Like thisĀ :
$('#cow_id_2').select2({
allowClear: true,
placeholder: "Search a cow/dam ID",
language: {
noResults: function () {
return $("<a href='http://google.com/'>Add</a>");
}
}
});

Related

select2 - remove inputTooShort text

How can I remove "Please enter 1 or more characters" text so when I start to type it will not show this message.
$("#js-example-basic-multiple").select2({
ajax: {
url: url,
dataType: 'json',
cache: false
},
minimumInputLength: 1
});
});
Just override inputTooShort property in language option:
$("#js-example-basic-multiple").select2({
language: {
inputTooShort: function(args) {
return "";
}
}
})
Note that there is a bug in select2 library oldiest versions: https://github.com/select2/select2/issues/3343

(Version 4.0.0-beta.3) 'more' feature for remote date loading stopped working

I just upgraded my select2 to the latest version in the subject and noticed that more loading stopped working.
select.select2({
placeholder: select.data("placeholder"),
allowClear: true,
multiple: select.attr('multiple') ? true : false,
ajax: {
url: '/Common/GetEntityItems',
dataType: 'json',
delay: 250,
data: function(term, page) {
return {
searchTerm: term,
page: page
};
},
processResults: function (data) {
var more = true;
return { results: data.items, more: more };
},
error: function (e) {
alert('error!');
},
formatResult: function (item) {
return '<div>' + item.text + '</div>';
},
formatSelection: function (item) {
return item.text;
}
}
});
Despite the unconditional true to more variable, more thing doesn't work any more. Do you see anything I am missing?
Brad,
in case you still looking for answer (it took me a couple of hours btw), you need to change
return { results: data.items, more: more };
to
return { results: data.items, pagination: { more: more } };
/Fred

Click event in select2 tag with a link

I am using select2 in tag mode. My item text is a link, e.g.:
<a href='url'>tag1</a>.
select2 seems to be swallowing the click event on the tag (selected choice) so I cannot navigate to the link.
Any ideas on how to get the link to work?
Select2 disables click events by default and for the moment, you must use a workaround to achieve the desired results. Here's an example of how I accomplished this, thanks to the resources below. This won't work if you don't re-instantiate the variable with the return value of .data('select2')
First, add a class to your links:
hello
Then you have to listen to the onSelect event of Select2
var search = $("#searchBox");
search.select2({
placeholder: "Search...",
allowClear: true,
minimumInputLength: 3,
maximumSelectionSize: 1,
escapeMarkup: function(m) { return m; },
ajax: { blah blah blah },
formatResult: window.App.formatFunction
});
search= search.data('select2');
search.onSelect = (function(fn) {
return function(data, options) {
var target;
if (options != null) {
target = $(options.target);
}
if (target && target.hasClass('detail-link')) {
window.location = target.attr('href');
} else {
return fn.apply(this, arguments);
}
}
})(search.onSelect);
This question/answer/JFiddle helped me out but its important to note the .data('select2') line
EDIT: forgot the resource -- https://stackoverflow.com/a/15637696
I use select2-selecting event:
var $q = $('#select2input');
$q.select2({
// your settings
});
$q.on('select2-selecting', function(e){
window.location = e.choice.url;
});
My AJAX payload looks like this:
{
"items":[
{
"id": "1",
"text": "Foo",
"url": "/foo"
},
{
"id": "8",
"text": "Bar",
"url": "/bar"
}
]
}

Select2 dropdown but allow new values by user?

I want to have a dropdown with a set of values but also allow the user to "select" a new value not listed there.
I see that select2 supports this if you are using it in tags mode, but is there a way to do it without using tags?
The excellent answer provided by #fmpwizard works for Select2 3.5.2 and below, but it will not work in 4.0.0.
Since very early on (but perhaps not as early as this question), Select2 has supported "tagging": where users can add in their own value if you allow them to. This can be enabled through the tags option, and you can play around with an example in the documentation.
$("select").select2({
tags: true
});
By default, this will create an option that has the same text as the search term that they have entered. You can modify the object that is used if you are looking to mark it in a special way, or create the object remotely once it is selected.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
}
});
In addition to serving as an easy to spot flag on the object passed in through the select2:select event, the extra property also allows you to render the option slightly differently in the result. So if you wanted to visually signal the fact that it is a new option by putting "(new)" next to it, you could do something like this.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
},
templateResult: function (data) {
var $result = $("<span></span>");
$result.text(data.text);
if (data.newOption) {
$result.append(" <em>(new)</em>");
}
return $result;
}
});
For version 4+ check this answer below by Kevin Brown
In Select2 3.5.2 and below, you can use something like:
$(selector).select2({
minimumInputLength:1,
"ajax": {
data:function (term, page) {
return { term:term, page:page };
},
dataType:"json",
quietMillis:100,
results: function (data, page) {
return {results: data.results};
},
"url": url
},
id: function(object) {
return object.text;
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return this.text.localeCompare(term)===0;
}).length===0) {
return {id:term, text:term};
}
},
});
(taken from an answer on the select2 mailing list, but cannot find the link now)
Just for the sake of keep the code alive, I'm posting #rrauenza Fiddle's code from his comment.
HTML
<input type='hidden' id='tags' style='width:300px'/>
jQuery
$("#tags").select2({
createSearchChoice:function(term, data) {
if ($(data).filter(function() {
return this.text.localeCompare(term)===0;
}).length===0)
{return {id:term, text:term};}
},
multiple: false,
data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});
Since many of these answers don't work in 4.0+, if you are using ajax, you could have the server add the new value as an option. So it would work like this:
User searches for value (which makes ajax request to server)
If value found great, return the option. If not just have the server append that option like this: [{"text":" my NEW option)","id":"0"}]
When the form is submitted just check to see if that option is in the db and if not create it before saving.
There is a better solution I think now
simply set tagging to true on the select options ?
tags: true
from https://select2.org/tagging
Improvent on #fmpwizard answer:
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return term.localeCompare(this.text)===0; //even if the this.text is undefined it works
}).length===0) {
return {id:term, text:term};
}
},
//solution to this error: Uncaught TypeError: Cannot read property 'localeCompare' of undefined
Thanks for the help guys, I used the code below within Codeigniter I I am using version: 3.5.2 of select2.
var results = [];
var location_url = <?php echo json_encode(site_url('job/location')); ?>;
$('.location_select').select2({
ajax: {
url: location_url,
dataType: 'json',
quietMillis: 100,
data: function (term) {
return {
term: term
};
},
results: function (data) {
results = [];
$.each(data, function(index, item){
results.push({
id: item.location_id,
text: item.location_name
});
});
return {
results: results
};
}
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, results) {
if ($(results).filter( function() {
return term.localeCompare(this.text)===0;
}).length===0) {
return {id:term, text:term + ' [New]'};
}
},
});
I just stumbled upon this from Kevin Brown.
https://stackoverflow.com/a/30019966/112680
All you have to do for v4.0.6 is use tags: true parameter.
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;
In most cases we need to compare values with insensitive register. And this code will return false, which will lead to the creation of duplicate records in the database. Moreover String.prototype.localeCompare () is not supported by browser Safary and this code will not work in this browser;
return this.text.localeCompare(term)===0;
will better replace to
return this.text.toLowerCase() === term.toLowerCase();

Need help with jqGrid and navGrid

With the main part of the jqGrid there is the postData parameter that can be set to add stuff to the POST variable. Is there a way I could do the same thing with the navGrid?
Here is what I have:
main jqGrid script
$("#"+id).jqGrid({
url:baseURL+'modules/'+module+'/config.php',
postData: {event: 'load-content',content : id,module: module},
datatype: 'json',
mtype: 'POST',
colNames:colNames,
colModel:colModel,
pager: '#pager',
rowNum:limit,
rowList:[10,20,30],
autowidth: true,
sortname: sortby,
sortorder: 'desc',
gridview: true,
viewrecords: true,
caption: title,
editurl: baseURL+'modules/'+module+'/config.php'
});
navGrid script
jQuery("#"+id).jqGrid('navGrid','#pager',
{del:true,add:true,edit:true}, //options
{height:280,reloadAfterSubmit:false}, // edit options
{height:280,reloadAfterSubmit:false}, // add options
{reloadAfterSubmit:false}, // del options
{});
What I want is to add {module: module, event: 'del-test'} to the POST of the delete button.
You can use additional editData (for add or edit operations) or delData parameter (for delete operation) and change the del options used as a parameter of 'navGrid' from
{reloadAfterSubmit:false}
to
{reloadAfterSubmit:false, editData:{module: module, event: 'del-test'}}
(the variable module should be defined before).
By the way, like with postData parameter (see this old answer) you can use function for any property of editData parameter:
{
reloadAfterSubmit:false,
delData: {
module: function() {
return "bla bla";
},
event: 'del-test'
}
}
I know it's a long time since you posted this question, I wanted to improve it anyways the wiki pages shows you the basic use of the navgrid and this is the answer that worked for me.
Best regards,
Modify your code this way
$("#" + id).jqGrid('navGrid', '#pager',
{ add: true, edit: true, del: true },
{ height:280, reloadAfterSubmit:false },
{ height:280, reloadAfterSubmit:false },
{
// settings for Delete
mtype: "post",
reloadAfterSubmit: false,
onclickSubmit: function (rp_ge, postdata) {
rp_ge.url = '<%: Url.Content("~/URL/TO/DELETE/METHOD/HERE") %>' + postdata;
},
serializeDelData: function (postdata) {
postdata.module = module;
postdata.event = 'del-test';
return postdata;
}
},
{},
{}
);

Resources