Select2 and load JSON data - javascript

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.

Related

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

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

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

Knockout.js mapping plugin how to update data

The following code will fetch and bind the JSON data correctly to the view but when I GET updated data the view will not update. The data has changed but the view doesn't update. Any ideas what I'm doing wrong? I have trouble understanding how the mapping plugin works.
jQuery(document).ready(function() {
setInterval(LeaderboardViewModel, (10 * 500));
function LeaderboardViewModel() {
var self = this;
this.ArrayOfPlayers = ko.mapping.fromJS([]);
$.ajax({
type: 'GET',
url: 'http://localhost:5500/leaderboard/',
context: this,
success: function(data) {
self.SuccessfullyRetrievedModelsFromAjax(data);
},
dataType: 'json'
});
this.SuccessfullyRetrievedModelsFromAjax = function(data) {
var array = $.map(data.leaderboard, function(value, index) {
return [value];
});
console.log(array);
ko.mapping.fromJS(array, {}, self.ArrayOfPlayers);
};
}
ko.applyBindings(new LeaderboardViewModel());
});
The following HTML renders the data correctly when I load the page:
<tbody data-bind="foreach: ArrayOfPlayers">
EDIT: When I load the page it works correctly. the set interval part doesn't work.
GET data:
{
"leaderboard": {
"1": {
"deaths": 52,
"game_count": 13,
"game_defeats": 0,
"game_deserts": 0,
"game_draws": 0,
"game_wins": 13,
"id": 2,
"kills": 78,
"level": 8,
"rank": 1,
"xp": 3260
},
"10": {
"deaths": 78,
"game_count": 13,
"game_defeats": 13,
"game_deserts": 0,
"game_draws": 0,
"game_wins": 0,
"id": 1,
"kills": 52,
"level": 5,
"rank": 10,
"xp": 1570
},
}
EDIT 2: no console errors.
That's because you use keyword 'new' for applyBinding, but set timeout to function definition.
It must work in this way:
jQuery(document).ready(function() {
function LeaderboardViewModel() {
var self = this;
this.ArrayOfPlayers = ko.mapping.fromJS([]);
this.SuccessfullyRetrievedModelsFromAjax = function(data) {
var array = $.map(data.leaderboard, function(value, index) {
return [value];
});
console.log(array);
ko.mapping.fromJS(array, {}, self.ArrayOfPlayers);
};
self.UpdateMappings = function(){
$.ajax({
type: 'GET',
url: 'http://localhost:5500/leaderboard/',
context: this,
success: function(data) {
self.SuccessfullyRetrievedModelsFromAjax(data);
},
dataType: 'json'
});
};
}
var viewModel = new LeaderboardViewModel();
setInterval(viewModel.UpdateMappings, (10 * 500));
ko.applyBindings(viewModel);
});

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

Reading a JSON output in JavaScript with a lot of objects

This is my JSON output:
[
{
"Business": [
{
"id": "5739"
},
{
"userid": ""
},
{
"name": "Ben Electric"
},
{
"description": ""
},
{
"address": ""
},
{
"email": "*****#gmail.com"
},
{
"phone2": "050*****88"
},
{
"phone3": ""
},
{
"mobile": "050****88"
},
{
"opentimes": ""
},
{
"services": ""
},
{
"places": ""
},
{
"logo": null
},
{
"image": null
},
{
"video": ""
},
{
"owner_name": "Ben Brant"
},
{
"owners": "1"
},
{
"userpic": "http://graph.facebook.com/****/picture"
},
{
"circle": "3"
},
{
"fc": "0"
},
{
"rating_friends": ""
},
{
"rating_global": "3.3333"
},
{
"advice": ""
},
{
"subscription": "none"
}
]
},
{
"Business": [
{
"id": "5850"
},
{
"userid": ""
},
{
"name": "Bla Bla"
},
{
"description": ""
},
{
"address": ""
},
{
"email": "*****#gmail.com"
},
{
"phone2": ""
},
{
"phone3": ""
},
{
"mobile": "0*****995"
},
{
"opentimes": ""
},
{
"services": ""
},
{
"places": ""
},
{
"logo": null
},
{
"image": null
},
{
"video": ""
},
{
"owner_name": "Ben VBlooo"
},
{
"owners": "1"
},
{
"userpic": "http://graph.facebook.com/******/picture"
},
{
"circle": "3"
},
{
"fc": "0"
},
{
"rating_friends": ""
},
{
"rating_global": "2.0000"
},
{
"advice": ""
},
{
"subscription": "none"
}
]
},
{
"Info": {
"message": "No user for the business"
}
},
{
"OK": {
"message": "By Circle"
}
}
]
I'm trying to get the objects in javascript in this way but it doesnt work, should i loop through each Business object?? is there a way to access the real data objects directly?
Here's what I'm trying:
$.ajax({
type: 'POST',
url: 'BLABLA',
data: { BLABLA },
dataType: 'json',
success: function( resp ) {
if(resp.length == 0) {
$('.searchol').append('<li>No results found.</li>');
return;
}
$.each(resp, function(index, element) {
$('.searchol').append('Users Picture: '+element.Business.userpic);
But I cant seem to get to the object?
I just tried this code using your sample json like that
$.each(resp, function(index,element){
$.each(element, function(ind,ele){
if(ele.length){
$.each(ele,function(ind,ele){
if(ele.userpic)
console.log(ele.userpic)
})
}
})
})
"Business" is referring to an array (square bracket), so element.Business.userpic does not exist (element.Business[0].userpic exists though). Depending on what you want to achieve, you'll either have to loop through Business or access userpic of a particular array item.
Your business object is a array of object
"Business": [
{
"id": "5850"
},
Check this JSFiddle script on how to read that
Sample output
Picture: undefined (index):192
Picture: http://graph.facebook.com/****/picture
This will help you out
$.each(resp, function(index, element) {
$('.searchol').append('Users Picture: '+element.Business["userpic"]);
Your JSON is weird. Instead of :
Business : [
{ id : 'id1' }
{ name : 'name1' }
]
Business[0].id // access id
Business[1].name // access name
Where you have to remember where each attribute is in the array (or loop over the array to find it), you should have:
Business : {
id : 'id1',
name : 'name1'
}
Business.id // access id
Business.name // access name
If you can't change the JSON, you can use the following 2 methods to quickly get a property of Business:
var propMap = {
id : 0,
userid : 1,
name : 2 // etc
}
function getBusinessProp(business, prop) {
return business[propMap[prop]][prop];
}
// usage :
$('.searchol').append('Users Picture: '+ getBusinessProp(element.Business, 'userpic'));
If your array can be missing some items or the items can be in a different order for each business, then you need to iterate to find the property you're interested in:
function getBusinessProp(business, prop) {
for (var i=0; i<business.length; i++) {
if (business[i].hasOwnProperty(prop)) {
return business[i][prop];
}
}
}
// same usage, no need for the map anymore
The second method is probably better because it won't break if you change the order of the array or add new items in the array, etc and the performance boost given by using the map is probably not enough to justify the added maintenance cost.

Categories

Resources