Results does not show up after search, why? - javascript

I am using the newest Select2 4.0.6-rc.1 and I am making an AJAX search, I am getting results back but for some reason they don't show up as an option on the SELECT element. Maybe I am missing some basic setup but I have been reading the docs and I can't find anything helpful. Here is what I have:
<select class="form-control" id="query"></select>
$(function() {
var $query = $("#query");
$query.select2({
width: 550,
placeholder: 'Search for a form ...',
minimumInputLength: 3,
ajax: {
url: '/ajax/forms/ajax_search_by_name',
data: function (params) {
return {
q: params.term
};
},
dataType: 'json',
delay: 250,
processResults: function (data) {
return {
results: data.items
};
}
}
});
});
The result from the backend looks like:
{
"results": [
{
"id": 1247,
"name": "amerita_infusion_services_colorado_synagis_referral_form"
},
{
"id": 3471,
"name": "medicaid_colorado_viekira"
}
]
}
Which I think is the right way to return them. I have setup a Fiddle - which BTW I couldn't make it to work with the /echo/json request - so you can play with it a little bit.
What I am missing here?

Related

Select2 won't load remote json response

I have an API that is called by Select2 (v4.0.5) however the debug message in the console says:
Select2: The AJAX results did not return an array in the results key of the response.
When I review the documentation at Select2's documentation site I seem to be following it correctly. This is the javascript I use on the webpage:
$('#account_id').select2({
debug: true,
minimumInputLength: 3,
dataType: 'json',
ajax: {
url: '/api/account-query',
data: function (params) {
var query = {
search: params.term,
v: "new"
}
return query;
},
}
});
This is the response from the API (sensitive bits redacted):
{
"results": [{
"id": "redacted-1",
"text": "text redacted 1"
},{
"id": "redacted-2",
"text": "text redacted 2"
},{
"id": "redacted-3",
"text": "text redacted 3"
},{
"id": "redacted-4",
"text": "text redacted 4"
},{
"id": "redacted-5",
"text": "text redacted 5"
}]
}
If I take the select2 code and supply it with the static json response (without results prepended, just the array) it works just fine.
What am I missing?
Thanks!
You have to provide the processResults callback function so Select2 able to render result in proper way.
I have created a jsfiddle (https://jsfiddle.net/shcavbng/) demo that doing the same.
$('#account_id').select2({
debug: true,
minimumInputLength: 3,
dataType: 'json',
ajax: {
url: 'https://reqres.in/api/users',
data: function (params) {
console.log('params =>' , params);
var query = {
search: params.term,
v: "new"
}
return query;
},
processResults: function (data) {
console.log('results =>' , data);
data = data.data.reduce(function(o,i){o.push({id:i.id,text:i.first_name});return o;},[]);
console.log('results =>' , data);
return {
results: data
};
}
}
});
I figured it out, and as expected I was overlooking a simple aspect:
Content-Type header needed to be application/json vs text/html

Select2 with JSON data serialized from Django

I have data in JSON created by Django serialization.
I use the example:
Select2 Loading remote data but still I getting information in a field that nothing found.
What should change to select2 work with data generated by Django?
JSON Data:
[{
"fields": {
"sku": "8"
},
"model": "catalog.product",
"pk": 8
},{
"fields": {
"sku": "9"
},
"model": "catalog.product",
"pk": 9
}]
Html:
<select class="js-data-example-ajax"><option value="3620194" selected="selected">select2/select2</option></select>
JavaScript:
$('.js-data-example-ajax').select2({
ajax: {
url: "{% url 'catalog.views.product_sku_json' %}",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term, // search term
page: params.page
};
},
processResults: function (data, params) {
// parse the results into the format expected by Select2
// since we are using custom formatting functions we do not need to
// alter the remote JSON data, except to indicate that infinite
// scrolling can be used
params.page = params.page || 1;
return {
results: data.items,
pagination: {
more: (params.page * 30) < data.total_count
}
};
},
cache: true
},
escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
minimumInputLength: 1,
});
Answer by kevin-brown on github:
You are going to need to re-map your results to have id and text keys.
https://select2.github.io/announcements-4.0.html#changed-id
And it works thanks Kevin!

Typeahead shows results as undefined

I am trying to use typeahead to display google suggestions.
The Ajax call works fine and data is returned properly:
Before executing return process(data);
data contains an array of strings that start with "w".
data = ["walmart", "weather", "wells fargo", "worldstarhiphop",
"walgreens", "wikipedia", "white pages", "world cup", "webmd",
"weather radar"]
However the suggestions displayed show "undefined" instead of real words.
Any idea what I am missing here? Thanks.
<input type="text" class="typeahead" placeholder="Search">
$('.typeahead').typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
source: function (query, process) {
$.getJSON("Home/Suggest", { query: query }, function (data) {
return process(data);
});
}
});
Update:
After some research, I found an answer to my question and will post it here, if someone needs it.
The trick is - the "process" callback function expects the results in a format:
[{value: "string1"}, {value: "string2"}, {value: "string3"}]
and not just an array of strings.
$('.typeahead').typeahead(
{ hint: true, highlight: true, minLength: 1 }, // options
{
source: function (query, process) { // source dataset, data = array of strings
$.getJSON('Home/Suggest', { query: query }, function (data) {
//data=["string1", "string2", "string3"]
//process callback function needs it
//in a format [{value: "string1"}, {value: "string2"}, {value: "string3"}]
var output = $.map(data, function (string) { return { value: string }; });
process(output);
});
}
});

Post row datas from DataTable to an Ajax Form

I have a set of JSON data that are displayed using datatables. In one of the columns, I add a button and a text box only if the value in that column and another column meets a certain condition. this is the bit of code I used to do this:
$(document).ready(function (){
var alertTable = $('#alert-table').DataTable({
"jQueryUI": true,
"order": [ 3, 'desc' ],
"columns": [
{ "data": "source", "visible": false },
{ "data": "host" },
{ "data": "priority" },
{ "data": "ack", "render": function( data, type, row ) {
if (row.ack == "0" && row.priority > "2") {
return '<form><input class="ackname" type="text" value="Enter your name"><input class="ackbutton" type="button" value="Ack Alert" onclick="<get all items for that row and POST to a URL>"></form>';
}
return data;
}
},
],
"language": {
"emptyTable": "No Alerts Available in Table"
}
});
});
This works fine by adding a button and text in the cell. What I am looking to achieve is, when any of the button is been clicked, it should POST all the values for that row including what is typed in the text box to a URL which has another function that would extract those details and update the database and send back the refreshed data. I am new to datatables and jquery, any guide would be highly appreciated.
Have made some changes to the code, instead of form you can use div.
$(document).ready(function (){
var alertTable = $('#alert-table').DataTable({
"jQueryUI": true,
"order": [ 3, 'desc' ],
"columns": [
{ "data": "source", "visible": false },
{ "data": "host" },
{ "data": "priority" },
{ "data": "ack", "render": function( data, type, row ) {
if (row.ack == "0" && row.priority > "2") {
return '<div><input class="ackname" type="text" value="Enter your name"><input class="ackbutton" type="button" value="Ack Alert"></div>';
}
return data;
}
},
],
"language": {
"emptyTable": "No Alerts Available in Table"
}
});
$(document).on("click",".ackbutton",function() {
var currentIndex = $(this).parent().parent().index();
var rowData = alertTable.row( index ).data();
//extract the textbox value
var TextboxValue = $(this).siblings(".ackname").val();
var objToSave = {}; //Create the object as per the requirement
//Add the textbox value also to same object and send to server
objToSave["TextValue"] = TextboxValue;
$.ajax({
url: "url to another page"
data: JSON.stringify({dataForSave : objToSave}),
type: "POST",dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(datas) {
//Your success Code
},
error: function(error) {
alert(error.responseText);
}
});
});
});
Since both the pages are in same project, you can also do it using single ajax, passing all the values to server at once and then calling the other page internally from server and passing in the values using query string.
This is not a running code, rather to give you a basic idea on how to proceed.
Hope this helps :)

How to get jstree to work properly with ajax loaded content

For a project I am trying to create an ajax-powered treeview control. My ajax scripts are working fine on the back end, but the tree is not being displayed properly. When I hard code the ajax response into my tree container, it is displayed properly:
However, when I try to load the tree via ajax I get this:
Here is my JS code:
$(document).ready(function() {
function customMenu(node) {
var items = {
createItem : {
label : "Generate random number(s)",
action: function() {
console.log("Creating children...");
var selectedId = $("#treeview").jstree("get_selected").attr("id");
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: "libs/add.php",
data: "fact_id=" + selectedId,
dataType: "json",
success: function(data) {
console.log(data);
}
});
}
}
}
return items;
}
$("#treeview").jstree({
"plugins" : ["themes", "html_data", "ui", "crrm", "contextmenu"], contextmenu: {items: customMenu, select_node: true}
});
$.ajax({
url: "libs/display.php",
dataType: "json"
}).success(function(data) {
$("#treeview ul").append(data);
});
});
Does anyone have any idea what my problem is? Any help would be appreciated.
EDIT
After looking closer, I realize that the exact problem is that the necessary classes are not being added to the child nodes when calling via ajax. Still, I'm not sure why.
ANOTHER EDIT
display.php now contains this response text:
[
{
"attr": {
"id": 1
},
"data": 649,
"state": "closed"
},
{
"attr": {
"id": 1
},
"data": 108,
"state": "closed"
},
{
"attr": {
"id": 1
},
"data": 86,
"state": "closed"
},
{
"attr": {
"id": 1
},
"data": 46,
"state": "closed"
}
]
Am I headed in the right direction?
Is your stylesheet being included, and have you set up correct URLs to the icons? It looks to me like that's why your data isn't being styled. However, looking at your code, a more likely reason that you aren't getting your styling is because you are just calling an arbitrary AJAX call outside the jsTree scope.
Take a look at the docs for the json_data plugin for jsTree. It's easy to use, provided you set up display.php correctly to only fetch the node that jsTree is requesting. It will make concurrent calls and get the nodes it needs, your script simply needs to serve them to it:
$("#treeview").jstree({
"plugins" : ["themes", "html_data", "ui", "crrm", "contextmenu"],
"contextmenu": {
items: customMenu,
select_node: true
},
"json_data": {
"ajax": {
"url": "libs/display.php",
"data": function(n) {
return { id : n.attr ? n.attr("id") : 0
}
}
}
});
The json_data plugin basically acts as a wrapper for a jQuery AJAX call, but the events are bound directly the jsTree core and the returned results are handled by jsTree. You'll probably need to tweak your return values a bit depending on what display.php is responding with, and what you have set your tree up to look like structurally.
Edit
This is a similar post that might help you:
jsTree and AJAX > Load all data via ajax

Categories