select2 initial values are being replaced when a new value is selected - javascript

Below is my code for a Select2 box. I need values (tags) already assigned to a record to show initially, this is represented by the AAA and BBB values. Then I need to ajax in a list of values to pick from if they want to add new values (tags) to the already existing ones. Everything works except when they select a new value (tag) to add it replaces the existing ones, they disappear. I need them to stay.
<select class="myTags" style="width:100%" multiple="multiple"></select>
<script>
function formatResults(item) {
if (item.loading) return 'Loading...';
return '<div style="font-size:100%;">'+
'<div style="padding:5px;">'+
'<span style="background-color:##e4e4e4; color:##000000; border:1px solid ##aaa; padding:5px;">'+
item.tag+
'</span>'+
'<span style="padding:5px;">'+
' x '+item.popularity+
'</span>'+
'<p style="margin-bottom:0px;">'+
item.description+
'</p>'+
'</div>'+
'</div>';
}
function formatSelection(item) {
return item.tag;
}
jQuery(".myTags").select2({
placeholder: "add a tag, max 20 tags",
maximumSelectionLength: 20,
minimumInputLength: 2,
templateResult: formatResults,
templateSelection: formatSelection,
initSelection: function (element, callback) {
var data = [{ "tag": "AAA", "id": "111" },{ "tag": "BBB", "id": "222" }];
callback(data);
},
escapeMarkup: function (markup) { return markup; }, // let select2's custom formatter work
ajax: {
url: "tags.cfc?method=json_get_valtags",
dataType: 'json',
data: function (params) {
return {
q: params.term
};
},
processResults: function (data) {
return {
results: jQuery.map(data, function (item) {
return {
id: item.UNID,
tag: item.TAG,
description: item.DESCRIPTION,
popularity: item.POPULARITY
}
})
};
}
}
});
</script>

I figured it out. This SO post was very similar to what I needed but I had to tweak it some for my specific scenario.
(1) I had to add the select2 data option...
data: [{ "tag": "AAA", "id": "112233" },{ "tag": "BBB", "id": "11223344" }],
(2) Then I removed the entire initSelection function from the options.
(3) Then I added this at the bottom after the select2 initialization...
jQuery(".myTags").val([112233,11223344]).trigger('change');
So this is the end result...
jQuery(".myTags").select2({
data: [{ "tag": "aaa", "id": "112233" },{ "tag": "bbb", "id": "11223344" }],
placeholder: "add a tag, max 20 tags",
maximumSelectionLength: 20,
minimumInputLength: 2,
templateResult: formatResults,
templateSelection: formatSelection,
escapeMarkup: function (markup) { return markup; }, // let select2's custom formatter work
ajax: {
url: "tags.cfc?method=json_get_valtags",
dataType: 'json',
data: function (params) {
return {
q: params.term
};
},
processResults: function (data) {
return {
results: jQuery.map(data, function (item) {
return {
id: item.UNID,
tag: item.TAG,
description: item.DESCRIPTION,
popularity: item.POPULARITY
}
})
};
}
}
});
jQuery(".cmprotags").val([112233,11223344]).trigger('change');

Related

Select2 and load JSON data

I have read a lot of questions here, but i'm not able to solve this
$('.titular').select2({
placeholder: 'Select',
width: '100%',
ajax: {
url: "/ajax/ajax.php",
data: function(params) {
var query = {
query: params.term
}
return query;
},
processResults: function(data) {
console.log(data);
return {
results: $.map(data, function (item) {
return {
id: item.id,
nome: item.nome
}
})
};
},
},
escapeMarkup: function (markup) { return markup; }
});
And my JSON:
[{"id":12,"nome":"Joe Bill"},{"id":13,"nome":"PJ"},{"id":14,"nome":"John"},{"id":16,"nome":"Acme"},{"id":17,"nome":"Acme2"},{"id":18,"nome":"Acme3"}]
The results are not showing and developer console shows:
jQuery.Deferred exception: Cannot use 'in' operator to search for 'length' in [{"id":16,"nome":"Acme"},{"id":17,"nome":"Acme2"},{"id":18,"nome":"Acme3"}] TypeError: Cannot use 'in' operator to search for 'length' in [{"id":16,"nome":"Acme"},{"id":17,"nome":"Acme2"},{"id":18,"nome":"Acme3"}]
I've tried to use the JSON viewed in oficial documentation, unsuccesfully...
I appreciate any help
The console error means that you are passing to the map an string so you need to parse your data as json before. I've done a little test and it is working like this:
processResults: function (data, params) {
data = JSON.parse('[{ "id": 12, "nome": "Joe Bill" }, { "id": 13, "nome": "PJ" }, { "id": 14, "nome": "John" }, { "id": 16, "nome": "Acme" }, { "id": 17, "nome": "Acme2" }, { "id": 18, "nome": "Acme3" }]');
var r = $.map(data, function (item) { return { id: item.id, text: item.nome }});
return { results: r };
}
Hope this helps.

send json from php to autocomplete and add data attribute in input

[{
"sysid": "39",
"name": "John",
"code": "060400000"
}]
$(document).on("input", ".autocomplete", function(event) {
var name = $(this).prop('id').split('_').pop();
$(".autocomplete").autocomplete({
source: function(request, response) {
$.ajax({
type: 'POST',
url: 'autocomplete.php',
dataType: "json",
data: {
keypressed: request.term,
name: name
},
success: function(data) {
//response(data);
response($.map(data, function(item) {
return {
name: item.name,
code: item.code,
sysid: item.sysid
};
}));
}
});
},
minLength: 2
});
})
This is my sample data
[{
"sysid": "39",
"name": "John",
"code": "060400000"
}]
In my autocomplete if I use response(data); in success and $name[] = ucwords(strtolower($selected_row[$columnename])); in php page all is good but I want to add additional information for my input text like code and sysid.. So I did
$name[] = array('sysid' => $selected_row['sys_id'],'name' => ucwords(strtolower($selected_row[$columnename])),'code' => $selected_row[$columnecode]); in php and in success
response($.map(data, function(item) {
return {
name: item.name,
code: item.code,
sysid: item.sysid
};
}));
What I want to achieve is add data-code and data-idin input after completing autocmplete.
Is this possible?Any Ideas
UPDATE
Used this below but the one changing is the dropdown values what I want is the input to change like
<input data-id="39" data-code="060400000">
response($.map(data, function(item) {
return {
title: item.name,
value: item.name
};
}));
Use the render item function
$(".autocomplete").data("ui-autocomplete")._renderItem = function(ul, item) {
return '<li data-code="'+item.code+'" data-id="'+item.sysid+'">'+item.name+'</li>'
}
for more info visit

Select2 AJAX with JSON

I have been trying to populate my input with select2 using the JSON provided.
Here's the JSON:
{
"airports":
[
{
"id": "1",
"code": "AMQ",
"city": "Ambon",
"country": "Indonesia"
},
{
"id": "2",
"code": "BJW",
"city": "Bajawa",
"country": "Indonesia"
}
]
}
And the html code:
<input class="" type='hidden' value="192" data-init-text='Departing City' name='input' id='depart-airport' style="width: 300px"/>
And the js code:
$(document).ready(function() {
$('#depart-airport').select2({
minimumInputLength: 1,
ajax: {
url: "http://localhost:4000/api/airports.json",
dataType: 'json',
results: function (data) {
return { results: data};
}
}
});
});
There's no error in console, but whether I try to input them it's always saying that "searching failed" or there's not even anything. The data from json never showed.
Do you have anything to fix this around? Thanks's before :)
You have a minor error in your jQuery:
$(document).ready(function() {
$('#depart-airport').select2({
minimumInputLength: 1,
ajax: {
url: "http://localhost:4000/api/airports.json",
dataType: 'json',
results: function (data) {
// You had { results: data }, but your actual information is in data.airports
return { results: data.airports };
}
}
});
});

autocomplete jquery-ui with json data is not working small glitch

I have this code in javascript:
$("#lcountry").autocomplete({
source: function (request, response) {
$.ajax({
url: "https://graph.facebook.com/search?type=adcountry&limit=3",
type: "GET",
data: request,
success: function (data) {
response($.map(data, function (el) {
return {
label: el.name,
value: el.country_code
};
}));
}
});
},
select: function (event, ui) {
// Prevent value from being put in the input:
this.value = ui.item.label;
// Set the next input's value to the "value" of the item.
$(this).next("input").value(ui.item.value);
event.preventDefault();
}
});
unfortunately this doesnt work.When I look at the console here is the result,obviously we can see the countries, I would like to be able to return the name values in jquery autocomplete :
{
"data": [
{
"country_code": "US",
"name": "United States",
"supports_region": "true",
"supports_city": "true"
},
{
"country_code": "AR",
"name": "Argentina",
"supports_region": "false",
"supports_city": "true"
},
{
"country_code": "AU",
"name": "Australia",
"supports_region": "true",
"supports_city": "true"
}
],
"paging": {
"next": "https://graph.facebook.com/search?type=adcountry&limit=5&term=c&offset=5"
}
}
You need to use data.data - data is an object which contains a key data having the list of countries
$("#lcountry").autocomplete({
source: function (request, response) {
$.ajax({
url: "https://graph.facebook.com/search?type=adcountry&limit=3",
type: "GET",
data: request,
success: function (data) {
response($.map(data.data, function (el) {
return {
label: el.name,
value: el.country_code
};
}));
}
});
},
select: function (event, ui) {
// Prevent value from being put in the input:
this.value = ui.item.label;
// Set the next input's value to the "value" of the item.
$(this).next("input").value(ui.item.value);
event.preventDefault();
}
});
Demo: Fiddle

Filter select options based on data-* attribute

I have 2 select menus on my page.
First have 3 values: All, Active, Unactive and second is filled with data that comes from server.
I need to connect them, so that when I select an option from the first select menu, the second select will have only certain options (filter second select menu)
My idea was to get data from server with 3 elements:
[ { "Id": 1, "Name": "Active One", "Active":true },
{ "Id": 2, "Name": "Active Two", "Active":true },
{ "Id": 3, "Name": "Unactive One", "Active":false },
{ "Id": 4, "Name": "Unactive Two", "Active":false } ]
Second thing that I do is adding all options with custom attribute to that select:
<option value=' + n[index].Id + ' data-active='+n[index].Active+'>' + n[index].Name + '</option>
I have problem with filtering second select.
I've wrapped filling second select inside a plugin so it will be easier to reuse it.
Here is jsFiddle demo: http://jsfiddle.net/Misiu/pr8e9/4/
What I would like this to work is after filling select from server user will be able to select every option from second select, but when he will change first select the second one will update-show only appropriate options.
So if he'll select Active he will be able to select only Active One or Active Two.
EDIT: This is working solution thanks to #oe.elvik
Alternative solution:
(function ($) {
var meinData;
$.fn.createOptions = function(filter) {
var $this = this;
var n = meinData
var list = "";
for (var index = 0; index < n.length; index++) {
if(filter == -1 || (filter == 1 && n[index].Active) || (filter == 0 && !n[index].Active)){
list += '<option value=' + n[index].Id + ' data-active='+n[index].Active+'>' + n[index].Name + '</option>';
}
}
$this.filter("select").each(function () {
$(this).empty();
$(this).append(list);
if ($.ui.selectmenu && defaults.selectmenu) {
$this.selectmenu();
}
});
}
$.fn.ajaxSelect = function (options) {
var $this = this;
//options
var settings = $.extend({}, defaults, options);
//disable select
if ($.ui.selectmenu && settings.selectmenu && settings.disableOnLoad) {
$this.selectmenu('disable');
}
//ajax call
$.ajax({
type: settings.type,
contentType: settings.contentType,
url: settings.url,
dataType: settings.dataType,
data: settings.data
}).done(function (data) {
meinData = data.d || data;
$($this).createOptions(-1)
settings.success.call(this);
}).fail(function () {
settings.error.call(this);
});
return this;
};
var defaults = {
type: "POST",
contentType: "application/json; charset=utf-8",
url: '/echo/json/',
dataType: 'json',
data: null,
async: true,
selectmenu: true,
disableOnLoad: true,
success: function () {},
error: function () {}
};
})(jQuery);
$(function () {
var data = {
json: $.toJSON({
d: [{ "Id": 1, "Name": "Active One", "Active":true }, { "Id": 2, "Name": "Active Two", "Active":true },{ "Id": 3, "Name": "Unactive One", "Active":false }, { "Id": 4, "Name": "Unactive Two", "Active":false }]
}),
delay: 2//simulate loading
};
function ok() {
$('select#me').selectmenu({ select: function(event, options) {
$('select#mein').createOptions(options.value)
}
});
}
function error() {
alert('there was a problem :(');
}
$('select#me').selectmenu().selectmenu('disable');
$('select#mein').selectmenu().ajaxSelect({
data: data,
success: ok,
error: error
});
});

Categories

Resources