I'm trying to fill an jQuery Autocomplete with JSON data from inside an Ajax function. This is what my script looks like:
<script>
$(function() {
$("#autocomplete").autocomplete({
source: function(request, response)
{
$.ajax({
url: "<?php echo $this->webroot;?>portfolios/ajax_clients_dropdown/"+request.term+".json",
dataType: "jsonp"
success: function(data)
{
response(data);
}
});
}
});
});
</script>
<label>Clients</label>
<div class = "ui-widget">
<input id = "autocomplete">
</div>
This code use to run without any errors, but do not do anything when I type something in the search box. It's like the JSON isn't working. I tried fiddling with it, but now it gives me a "Expected token '}' " error.
This script is in my view file, and the url should point to a function in my controller. If I run the controller function in my browser, it returns JSON data correctly. I have a log function that runs as soon as the function is called. It records in the log when I run it directly in a browser, but doesn't record anything when I run the webpage normally(call the function from the view side).
Can someone please check it out?
in action ajax_clients_dropdown inside portfoliosController put this
public function ajax_clients_dropdown($model="portfolio") {
$this->loadModel($model); // loadmodel let me use this action for multiple model
$this->$model->recursive = -1;
$this->autoRender = false;
$this->layout = 'ajax';
if ($this->request->is('ajax')) {
$results = $this->$model->find('all', array('fields' => array('id','name'),
'conditions' => array('name LIKE ' => '%'. $this->request->query['q'] . '%'),
));
$return_arr= array();
// you can change this loop with this
// $res = Hash::extract($results, '{n}.source'); // and change in your find condition 'name' with "name as label' cause in our script we will use the term "label"
foreach ($results as $row) {
$row_array['id'] = $row['source']['id'];
$row_array['label'] = $row['source']['name'];
array_push($return_arr,$row_array);
}
// echo json_encode($return_arr); WRONG!!!
// THE TRICK IS HERE => add before your json the callback send by jquery and it will work!!!!
$response = $this->request->query["callback"] . "(" . json_encode($return_arr) . ")";
echo $response;
}
}
in /Layout/ajax.ctp put this code
<?php echo $this->fetch('content'); ?>
in your default layout between and remember to load jquery and jqueryui
...
<?php
echo $this->Html->script('jquery-1.11.1');
echo $this->Html->script('jquery-migrate-1.2.1');
echo $this->Html->script('jquery-ui/jquery-ui-1.10.4.min');
?>
...
and in your view View/Portofolio/yourview.ctp try to do something like this
<input id="tags" placeholder="your placeholder . bla bla bla">
</div>
<hr>
<input id="source_dest_id" type="hidden" name="source_dest_id" value=""/>
<script>
$(function(){
$( "#tags" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "<?php echo $this->webroot;?>portfolios/ajax_clients_dropdown",
dataType: "jsonp",
data: {
q: request.term
},
success: function( data ) {
response( data );
}
});
},
minLength: 2,
open: function() {
$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
},
close: function() {
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
},
focus: function(event, ui) {
// prevent autocomplete from updating the textbox
event.preventDefault();
// manually update the textbox
$(this).val(ui.item.label);
},
select: function(event, ui) {
// prevent autocomplete from updating the textbox
event.preventDefault();
// manually update the textbox and hidden field
$(this).val(ui.item.label);
$("#source_dest_id").val(ui.item.id);
}
});
});
</script>
I hope this help :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.