简体   繁体   中英

jQuery UI Autocomplete with Ajax and JSON

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM