Select2 cannot choose elements inside input - jquery-select2

I'am struggling with select2.
I have an ajax call that returns me a json. The json is formated like that (from server):
public function get_groups()
{
$result = array();
$sql = "SELECT * FROM auth_groups ";
foreach ($this->db->query($sql)->result() as $row){
$tmp = array("id" => $row->id ,"label" => $row->name );
array_push($result, $tmp);
}
header('Content-type: application/json');
echo json_encode($result);
}
Then from my javascript i have :
$('#group_choice').select2({
minimumInputLength: 2,
ajax: {
url: "/bonsejour/extranet/ajax/resources/get_groups",
dataType: 'json',
data: function (term, page) {
return {
term:term
};
},
results: function (data, page) {
var results = [];
$.each(data, function(index, item)
{
results.push({id:item.ID, text:item.label});
});
return {
results: results
};
}
}
});
Where #group_choice is an input text.
When i type some text inside the input box it does shows all the elements coming from the json. But when i try to select an element nothing happens. How can i select the elements inside the input ?
Thanks

Refer http://ivaynberg.github.io/select2/#documentation
formatSelection: formatSelectionMethod,
function formatSelectionMethod(row) { return row.text;}
I hope you will find it helpful.

Please refer to Select2 Ajax Method Not Selecting,
and take the correct value:
id: function(data){return {id: data.id};},
or
id: function(data){return data.id}

Related

select2 4.0 ajax problems since update from 3.5

Can't seem to figure out what the problem is here. This worked perfectly fine when using 3.5, but does not work with 4.0.
I am using select2.full.js as well which supports using input in this manner.
html:
<input id="vcreate-filter" type="text" name="settings[filter]" class="form-control" style="width:100%;"/>
js:
$("#vcreate-filter").select2({
placeholder: "Select or enter application...",
allowClear: true,
multiple: false,
ajax: {
dataType: 'json',
delay: 1000,
type: 'post',
url: '/process/get_application_list.php',
data: function (term, page) {
return {
term: term, // search term
page_limit: 25, // page size
page: page // page number
};
},
results: function (data, page) {
var more = (page * 25) < data.total; // whether or not there are more results available
return {
results: data.results,
more: more
};
}
},
createSearchChoice:function(term, data) {
if ($(data).filter(function() {
return this.text.localeCompare(term)===0; }).length===0) {
return {id:term, text:term};
}
}
}).on('change', function() {
$(this).valid();
});
get_application_list.php:
.......
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
// make sure there are some results else a null query will be returned
if( count($results) > 0 )
{
foreach( $results as $row )
{
$ajax_result['results'][] = array(
'id' => htmlspecialchars($row['event_target'], ENT_QUOTES, 'UTF-8'),
'text' => htmlspecialchars($row['event_target'], ENT_QUOTES, 'UTF-8')
);
}
}
else
{
// 0 results send a message back to say so.
$ajax_result['results'][] = array(
'id' => 0,
'text' => 'No results found...'
);
}
// return result array to ajax
echo json_encode($ajax_result);
html: use select element instead of input.
<select id="vcreate-filter" type="text" name="settings[filter]" class="form-control" style="width:100%;"> </select>`
js: use processResults instead of 'results' as callback property.
processResults: function (data, page) {
var more = (page * 25) < data.total; // whether or not there are more results available
return {
results: data.results,
more: more
};
}
assuming the json is in the correct format [{"id": "1", "text": "One"}, {"id": "2", "text": "Two"}]
Breaking changes seems to be documented here.

select2 remote displaying label instead of id when selecting a value from results

I have the following code in an attempt when selecting a suggestion to display the selected value instead of the id. BUT I still need to pass the id as a value. This works fine when using select2 without remote on a regular select box, but it doesn't seem to work like this on a remote data source using an input.
Here is my results:
Search suggestions (working):
Selection Result (Not working as expected..I expect the search suggestion to be selected):
Here is the code:
$("#specific_input_data").select2(
{
minimumInputLength: 2,
placeholder: <?php echo json_encode(lang('common_search')); ?>,
id: function(suggestion){ return suggestion.value; },
ajax: {
url: <?php echo json_encode($search_suggestion_url); ?>,
dataType: 'json',
data: function(term, page)
{
return {
'term': term
};
},
results: function(data, page) {
return {results: data};
}
},
formatSelection: function(suggestion) {
return suggestion.value;
},
formatResult: function(suggestion) {
return suggestion.label;
}
});
I figured i out. formatSelection needs to be selection.label

Ajax refresh in mvc div data

I am developing a MVC application, where I have a scenario to refresh a part of the page basically ajax...
<div id="ajax" style="width:10%;float:left">
#foreach (var item in #Model.SModel.Where(x=>x.StudentId==13))
{
<li>#Html.DisplayFor(score => item.StudentName)</li>
}
This is the div (part of the page) which I need to refresh on a button click. I have 2 js files, data.js and render.js...
data.js contains a template as follows:
makeAJAXCall =
function (url, params, callback) {
$.ajax({
type: "get",
timeout: 180000,
cache: false,
url: url,
dataType: "json",
data: params,
contentType: "application/json; charset=utf-8",
success: function (result) {
if (callback) {
callback(result);
}
},
error: function (req, status, error) {
}
return null;
}
});
};
getGrid = function () {
makeAJAXCall(urlCollection["getGridInfo"], "", function (result) {
renderer.renderGridInfo('ajax', result);
});
};
and render.js file is as follows:
renderGridInfo = function (area, data) {
$("#" + area).text(data);
};
return {
renderGridInfo: renderGridInfo
};
In the loading page on button click function as :
Service.addURL('getGridInfo', '#Html.Raw(#Url.Action("getGridInfo", "AjaxController"))');
Service.getGrid();
In the ajax controller, the code is :
public JsonResult getGridInfo()
{
return Json(model, JsonRequestBehavior.AllowGet);
}
But the problem I am facing is, the controller is returning the JsonResult , but the 'div' accepts the model and so the output is [object] [object] button click
Question: Is there any way to refresh this 'div' from the Jsondata returned by the controller?
I have to follow this type of design without using AjaxForm.
Look what happens:
1) you returns Json: return Json(model, JsonRequestBehavior.AllowGet);
2) you put returned Json object to the div's value: $("#" + area).text(data);
that's why you end up with json's representation inside div
You need to change it as follows:
1) assume you put html for that div to model's field called NewHtml
2) eptract html from the property of returned json: var returnedHtml = data.NewHtml;
3) use html() method instead of text(): $("#" + area).html(returnedHtml);

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();

JQuery Autocomplete source is a function

I'm using JQuery UI autocomplete, for different fields. To get the data i'm using a function as the source. It work great!
I was wondering if there were a way of not using the anonym function in the source, but to declare a generic one which will have a parameter to redirect to the right URL.
I'm quite new in JS and JQuery and so I have no idea of what the parameters request and response are comming from in the anonym function.
Here is what I'm trying to do:
$ac.autocomplete({
//Call the function here, but what are the parameter request and response???
source: autocomplete(),
minLength: 1
});
Here is the function I'd like to call
function autoComplete(request, response, url) {
$.ajax({
url: '/Comp/'+url,
dataType: "json",
type: "POST",
success: function (data) {
response($.map(data, function(item) {
return { label: item, value: item, id: item };
}));
}
});
}
Thanks a lot for your help.
You should use
source: autoComplete
instead of
source: autocomplete()
One more remark. The default implementation of jQuery UI Autocomplete use only value and label and not use id.
Reformatting ur question will pose as solution to the problem .:)
$ac.autocomplete({
minLength: 1 ,
source: function(request, response, url){
var searchParam = request.term;
$.ajax({
url: '/Comp/'+url,
data : searchParam,
dataType: "json",
type: "POST",
success: function (data) {
response($.map(data, function(item) {
return {
label: item.Firstname,
value: item.FirstName
};
});
}
});//ajax ends
}
}); //autocomplete ends
The request and response objects are expected by jQuery UI . The request.term will give u the text that the user types and the response method will return the label and value items to the widget factory for displaying the suggestion dropdown
P.S : assuming ur JSON string contains a FirstName key !
I will give an example of a situation that happened to me, might serve as an example:
Situation: After the user selects a keyword with Jquery Autocomplete not allow it to be listed. Taking into account that the query is executed the same, ie the unamended cat. server-side.
The code looked like this:
$( "#keyword-search" ).autocomplete({
minLength: 3 ,
source: function( request , response ) {
var param = { keyword_type: type , keyword_search: request.term } ;
$.ajax({
url: URI + 'search-to-json',
data : param,
dataType: "json",
type: "GET",
success: function (data) {
response($.map(data, function( item ) {
/* At this point I call a function, I use to decide whether to add on the list to be selected by the user. */
if ( ! is_record_selected( item ) ) {
return item;
}
}));
}
});
} ,
select: function( event , ui ) {
/* Before you add, looking if there is any cell */
/* If it exists, compare the id of each cell not to add an existing */
if ( validate_new_keyword( ui ) ) {
add_cell( ui ) ;
}
} ,
});
/* Any validation... */
function validate_new_keyword( ui ) {
var keyword_id = $.trim(ui.item.id) ;
Any condition...
if (keyword_id > 0) {
return true ;
}
return false ;
}
/* This function checks if a keyword has not been selected by the user, it checks for the keyword_array. */
function is_record_selected( item ) {
var index = jQuery.inArray( item.id , keyword_array ) ;
return index == -1 ? false : true;
}
Obs: Thus it is possible to use a function inside "source" and "select". =p

Resources