What I want to do:
I want to do a input text field with a jquery autocomplete function which gets the source data from a cross-domain curl request. The result should be exactly like this example (CSS not important here): http://abload.de/img/jquerydblf5.png (So I actually want to show additional infos which I get from the curl Request). The URL to get the source data is http://www.futhead.com/15/players/search/quick/?term= and in the end I add those letters which are currently typed in at my input field (for example "Ronaldo").
At the moment I only tried to perform the searchrequest without showing all infosin the dropdown as shown in the screen above. I only want to see which playernames I actually got back by the curl request. Later I will try to add more information for the dropdown. Maybe you guys can help me as well with this as well (I think its called custom renderItem ??).
This is what I've tried:
<script>
$( "#tags" ).autocomplete({
source: function (request, response) {
$.ajax({
type: 'GET',
url: 'playerscraper.php',
dataType: "json",
data: function () {
return $("#results").val()
},
success: function (data) {
// I have no idea what this response and map is good for
response($.map(data, function (item) {
return {
label: item.label,
id: item.value,
};
}));
},
});
}
});
</script>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
My playerscraper.php is performing the curl request and actually returns a array (tested with echo):
$term = $_GET['term'];
$curlRequest = new CurlRequest();
$result = $curlRequest->get('http://www.futhead.com/15/players/search/quick/?term=' . $searchterm);
$players = array();
return json_encode($result);
My problem:
I have no idea how to do the source part for the autocomplete function this way, that I get the right results from the ajax request with my searchterm from the input field. When I type in something in the input field, nothing happens (the function which defines the source is getting called - tested with an alert).
First try to fix the problem with your help (current Code):
<script>
$( "#tags" ).autocomplete({
source: function (request, response) {
$.ajax({
type: 'GET',
url: 'playerscraper.php',
dataType: "json",
data: function () {
term: request.term
},
success: function (data) {
// I have no idea what this response and map is good for
response($.map(data, function(item) {
return {
label: item.full_name,
value: item.player_id
};
}));
},
});
},
minLength: 3,
delay: 500
});
</script>
The JSON is in a format which is incompatible with what autocomplete widget expects. This is where the $.map comes into play. You use this function to convert the JSON to desired format. Begin by returning a {label: "display name", value: "some id"} pairs like this:
response($.map(data, function(item) {
return {
label: item.full_name,
value: item.player_id
};
}));
Notes:
You should send content type header with your JSON:
header("Content-Type: application/json");
echo $result;
You should use request.term instead of input element value for the data parameter like this:
data: { term: request.term }
You should set higher delay and minLength values to reduce number of JSON requests:
delay: 500,
minLength: 3,
There are some undefined variables in your PHP script. Fix. Make sure that you echo the JSON instead of returning it. The remote server sends JSON so there is no need to json encode it again.
$term = $_GET['term'];
$result = file_get_contents('http://www.futhead.com/15/players/search/quick/?term=' . $term);
header("Content-Type: application/json");
echo $result;
Always check your PHP scripts for issues by opening directly in browser. Always look at browser JavaScript console to look for JavaScript errors and warnings.
Few things are looking wrong in in jQuery code
You have used $_GET['term'] in server side code but not passed term in ajax request query string
Need to fix as
data: {term: request.term}
extra comman(,) in code, it will create issue in IE browsers
response($.map(data, function (item) {
return {
label: item.label,
id: item.value
};
}));
Related
Twitter typeahead not working as expected, when I comment out code in the library I do get a non-styled drop down of suggestions.
jQuery('input#test').typeahead(
{
hint: true,
highlight: true,
limit:25, //still using 5 which is default in the library
minLength: 3
},
{
name: 'customLookup',
source: function(query, result) {
return jQuery.ajax({
url: url, //my dynamic url, returns custom json array that needs to be mapped
data: 'shop_name=' + query + "&limit=25", //custom limit against backend api
dataType: "json",
type: "post",
success: function(data, textStatus, xhr) {
var suggestions = [];
jQuery.map(data.data, function(item){
suggestions.push(item.name + " - " + item.address);
});
result(suggestions); //stepping in, it just skips because syncCalled already = true? Then remove that code and it gives me back a list of 5 that isn't styled...
console.log(suggestions); //has array of strings as expected
},
error: function (request, status, error) {
alert(error);
}
});
}
});
So are there options or updates I've missed capturing when configuring? Using a back end custom data source that needs JSON mapped to an array for typeahead.
Just ended up modifying the library directly and having our own copy, not sure the issue but seems to work fine with that approach and using custom CSS to style.
I'm facing issue with jquery autocomplete with ajax data as source. The data which is returning is proper and it is not issuing any errors. But still the results are not displaying as they should.
I have followed all the stackoverflow questions related this issue. And everything is pointing to what I have done. So it is not a duplicate of any of those questions.
If I use local variable data as data source, everything working as expected. It is not issue with UI as the same code is used for both the local variables and the ajax data.
My Code is:
$("#dTSearch").autocomplete({
source: function( request, response ) {
$.ajax({
type: "POST",
url: "{{path('dataSearch')}}",
dataType: "json",
data: {
type: "dashboardType",
searchTerm: $("#dTSearch").val()
},
success: function (data) {
if(data.status == 200) {
console.log(data.data);
//response( data.data );
//var dataSet = $.parseJSON(data);
response($.map(data.data, function (item, i) {
//alert(item.value);
return {
id: item.id,
label: item.label,
value: item.value
};
})
);
}
},
error: function (data) {
alert('error!');
console.log(data);
}
});
},
minLength: 3,
select: function( event, ui ) {
alert(ui.item.value);
return false;
},
open: function() {
$(this).autocomplete('widget').css('z-index', 100);
return false;
}
});
$("#dTSearch1").autocomplete({
source: dashboardTypes,
minLength: 3,
select: function( event, ui ) {
$("#onlyFunctionalDiv").show();
},
open: function() {
//$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
$(this).autocomplete('widget').css('z-index', 100);
return false;
}
});
I used the direct "response" method and "Map" in "Response" method. Nothing seems to be working.
When I consoled the results and put up alerts everything seems to be fine.
Below images shows the results and console logs I used.
Image 1:
Image 2:
In the first picture, the source is local variable and it is displaying the results when user start typing. Below is the console log of the same local variable.
The second picture is for the ajax response. When user types "func" it is calling the ajax and response is printing. But the results are not displaying as they should. The green color box indicates the response of a local variable and the red color box shows the ajax response data. Both seems to be same. But something is missing and it is not displaying the results when result set is available.
Can someone help me, what's wrong with this?
Issue is resolved. The problem is trailing semi-colon ";" at the end of return statement in the response method.
Changes in the code is:
response($.map(data.data, function (item, i) {
//alert(item.value);
return {
id: item.id,
label: item.label,
value: item.value
}
})
);
I have removed the trailing semi-colon at the end of the return statement.
myscript.js below is outputing:
[{"orcamento":"10","atual":"20","desvio":"","data":"2015-01-01","nome_conta":"BBB","nome_categoria":"abc","nome_entidade":"def"}]
myscript.js:
if (addList.length) {
$.ajax($.extend({}, ajaxObj, {
data: { "addList": JSON.stringify(addList) },
success: function (rows) {
$grid.pqGrid("commit", { type: 'add', rows: rows });
},
complete: function () {
$grid.pqGrid("hideLoading");
$grid.pqGrid("rollback", { type: 'add' });
$('#consola').text(JSON.stringify(addList));
}
}));
}
The JSON data above has to be sent to my script.php below:
if( isset($_POST["addList"]))
{
$addList = json_decode($_POST["addList"], true);
var_dump ($addList);
echo "test";
exit();
}
Although the data is correct and myscript.php is being called it isn't returning anything. I get:
NULLtest
I tried using GET, instead of POST but the result is the same, what is wrong with the code above?
EDIT:
Here's the ajaxObj used in the ajax request:
var ajaxObj = {
dataType: "json",
url:"../myscript.php",
type: "POST",
async: true,
beforeSend: function (jqXHR, settings) {
$grid.pqGrid("showLoading");
}
};
From the PHP Docs on json_decode:
NULL is returned if the json cannot be decoded or if the encoded data is deeper than the recursion limit.
So it is most likely that there is some error in your JSON data that is preventing json_decode from parsing it correctly, I've ran that snippet through jsonlint and it does say that it's valid JSON, but it's worth checking a larger sample of the data you send to the server for inconsistencies.
Other than that, is there any reason that you are calling JSON.stringify on the data object prior to sending to the server? I would try just sending the object itself as the data parameter of your AJAX call like so:
$.ajax($.extend({}, ajaxObj, {
data: { "addList": addList },
success: function (rows) {
$grid.pqGrid("commit", { type: 'add', rows: rows });
},
complete: function () {
$grid.pqGrid("hideLoading");
$grid.pqGrid("rollback", { type: 'add' });
$('#consola').text(JSON.stringify(addList));
}
}));
And see if that helps:
EDIT
I should have noticed in my original answer, you will not need to call json_decode on your posted data, jQuery encodes the data as post parameters correctly for you; It should be accessible within your PHP script as an associative array, try replacing your current var_dump statement in your PHP var_dump($_POST['addList'][0]['orcamento']); and you should be good to go.
First of all, be sure you are posting to a php file, use firebug or similar tools to track your script..
I don't see the part you defined the target PHP file on your javascript file..
A regular javascript code can look like this :
jQuery.ajax({
type : "post",
dataType : "json",
url : 'target.php',
data : {foo:bar },
success: function(response) {
// do something with response...
}
});
If you see that you are posting to the right php file the right parameters on firebug, try to use $_REQUEST if $_POST not working..
Firebug will show you the response of PHP file.. so do a print_r($_REQUEST['addList']) to see what is going on...
I am trying to work with the Select2 plugin in conjunction with the CodeIgniter framework. After a lot of effort, I managed to get it to work with AJAX data. However, now it has a weird problem. Even after typing in the entire name, the plugin does not eliminate the irrelevant options that do not match with the search term.
The below screenshot depicts this.
http://i.imgur.com/MfLcuf6.jpg?1
The Firebug console looks like this:
http://i.imgur.com/Qvko6mX.jpg
Below is my the Javascript code as well as the code for my controller
Javascript:
$("#mentor-typeahead").select2({
width: "100%",
placeholder: "Enter a mentor name",
maximumSelectionSize: 5,
minimumInputLength: 2,
multiple: true,
ajax: {
url: 'get_mentor_multi_list',
quietMillis: 500,
cache: true,
dataType: 'json',
results: function (data) {
return { results: data };
}
}
});
Controller
function get_mentor_multi_list($query = null)
{
$answer = array(array('id'=>1, 'text'=>'Inigo Montoya'),
array('id'=>2, 'text'=>'Zoey Deschanel'),
array('id'=>3, 'text'=>'Harry Potter'),
array('id'=>4, 'text'=>'Nicole Scherzinger'),
array('id'=>5, 'text'=>'Xerxes Mistry'),
array('id'=>6, 'text'=>'Tom Marvollo Riddle'),
array('id'=>7, 'text'=>'Light Yagami'),
array('id'=>8, 'text'=>'Vic Mackey'),
array('id'=>9, 'text'=>'Clark Kent'));
echo json_encode($answer);
}
I am utterly confused as to what could be causing the problem. I also tried the solution listed here link but to no avail. Any help would be appreciated.
Changed the AJAX call parameters on request but the output remains the same...
$("#mentor-typeahead").select2({
width: "100%",
placeholder: "Enter a mentor name",
maximumSelectionSize: 5,
minimumInputLength: 2,
multiple: true,
ajax: {
url: 'get_mentor_multi_list',
quietMillis: 200,
dataType: 'json',
data: function (term, page) {
return {
q: term,
page_limit: 10
};
},
results: function (data, page) {
return data;
}
}
You're missing a data function in the ajax part. See Loading Remote Data and Infinite Scroll with Remote Data in the documentation.
ajax: {
url: "http://api.rottentomatoes.com/api/public/v1.0/movies.json",
dataType: 'jsonp',
quietMillis: 100,
data: function (term, page) { // page is the one-based page number tracked by Select2
return {
q: term, //search term
page_limit: 10, // page size
page: page, // page number
apikey: "ju6z9mjyajq2djue3gbvv26t" // please do not use so this example keeps working
};
},
results: function (data, page) {
var more = (page * 10) < data.total; // whether or not there are more results available
// notice we return the value of more so Select2 knows if more results can be loaded
return {results: data.movies, more: more};
}
}
You're not using the ajax function correctly. It's doing exactly what it's supposed to do and that is to display all of the data returned from your get_mentor_multi_list() function.
In order to do this correctly, your ajax call needs to include a data attribute that includes parameters to be sent to your get_mentor_multi_list() function. get_mentor_multi_list() will then return only the results that your user is looking for.
If the data in get_mentor_multi_list() is static (i.e. not read from any database), you should consider adding it to the data attribute like in the Loading Array Data example here.
Finally, I was able to resolve the problem by myself. The problem lay in the fact that I was using CodeIgniter. Hence whatever variables that were supposed to be passed through the data attribute of the AJAX call weren't actually being passed to the controller.
I resolved this by changing the Javascript code to the following:
JavaScript
$('#mentor-typeahead').select2({
width: "100%",
placeholder: "Enter a mentor name",
maximumSelectionSize: 5,
minimumInputLength: 2,
multiple: true,
ajax: {
url: 'get_mentor_multi_list',
quietMillis: 200,
dataType: 'json',
data: function (term, page) {
return {
searchq: term // set the search term by the user as 'searchq' for convenient access
};
},
results: function (data, page) {
return {
results: data
};
}
}
});
And the controller code to look something like the following:
function get_mentor_multi_list()
{
// model code
$query = trim($_GET['searchq']); // get the search term typed by the user and trim whitespace
if(!empty($query))
{
// retrieve data from database
}
else
{
$answer = array('id' => 0, 'text' => 'No results found');
}
echo json_encode($answer);
}
PHP, returns a JSON encoded array
$this->load->model('car_model', 'cars');
$result = $this->cars->searchBrand($this->input->post('query'));
$this->output->set_status_header(200);
$this->output->set_header('Content-type: application/json');
$output = array();
foreach($result as $r)
$output['options'][$r->brandID] = $r->brandName;
print json_encode($output);
Outputs: {"options":{"9":"Audi","10":"Austin","11":"Austin Healey"}}
JS updated:
$(".searchcarBrands").typeahead({
source: function(query, typeahead) {
$.ajax({
url: site_url + '/cars/search_brand/'+query,
success: function(data) {
typeahead.process(data);
},
dataType: "json"
});
},
onselect: function(item) {
$("#someID").val(item.id);
}
});
UPDATE: Uncaught TypeError: Object function (){return a.apply(c,e.concat(k.call(arguments)))} has no method 'process'
If I type just 'A' then typeahead shows me only the first letter of each result (a bunch of A letters). If I type a second letter I see nothing anymore.
I've tried JSON.parse on the data or using data.options but no luck.
What am I doing wrong?
I've been battling this for the last day with Bootstrap 2.2.1. No matter what I did, it would not work. For me, I always got the process undefined error unless I put a breakpoint in the process function (maybe just because FireBug was open?).
Anyway, as a patch I re-downloaded Bootstrap with typeahead omitted, got the typeahead from here:
https://gist.github.com/2712048
And used this code:
$(document).ready(function() {
$('input[name=artist]').typeahead({
'source': function (typeahead) {
return $.get('/7d/search-artist.php', { 'artist': typeahead.query }, function (data) {
return typeahead.process(data);
});
},
'items': 3,
'minLength': 3
},'json')
});
My server returns this (for 'Bo'):
["Bo","Bo Burnham","Bo Diddley","Bo Bruce","Bo Carter",
"Eddie Bo","Bo Bice","Bo Kaspers Orkester","Bo Saris","Bo Ningen"]
Of course, now it ignores my minLength, but it will get me through the day. Hope this helps.
EDIT: Found the solution here:
Bootstrap 2.2 Typeahead Issue
Using the typeahead included with Bootstrap 2.2.1, the code should read:
$(document).ready(function() {
$('input[name=artist]').typeahead({
'source': function (query,typeahead) {
return $.get('/search-artist.php', { 'artist': encodeURIComponent(query) }, function (data) {
return typeahead(data);
});
},
'items': 3,
'minLength': 3
},'json')
});
Here's what I do to facilitate remote data sources with bootstrap's typeahead:
$("#search").typeahead({
source: function(typeahead, query) {
$.ajax({
url: "<?php echo base_url();?>customers/search/"+query,
success: function(data) {
typeahead.process(data);
},
dataType: "json"
});
},
onselect: function(item) {
$("#someID").val(item.id);
}
});
And then you just need to make sure your JSON-encoded arrays contain a value index for the label and an id field to set your hidden id afterwards, so like:
$this->load->model('car_model', 'cars');
$brands = $this->cars->searchBrand($this->uri->segment(4));
$output = array();
foreach($brands->result() as $r) {
$item['value'] = $r->brandName;
$item['id'] = $r->brandID;
$output[] = $item;
}
echo json_encode($output);
exit;
$.post is asynchronous, so you can't user return in it. That doesn't return anything.