Autocompletion – the easy way

Published on and tagged with ajax  cakephp  component

Nate has published a nice component which makes the creation of an input field with Ajax autocompletion very easy. In fact, it is (almost) as easy as creating a simple input field. You can get the component from http://github.com/cakebaker/autocomplete-component (the original component from Nate is available on CakeForge, though it no longer works with current CakePHP versions).

What do you have to do? Put the component to your app/controllers/components directory. In your controller you have to include the component with:

var $components = array('Autocomplete');

Also make sure that you have defined the Ajax helper in your controller. I usually add it to the helpers array in my AppController (app/app_controller.php):

var $helpers = array('Html', 'Javascript', 'Ajax');

Please notice that the Ajax helper requires the Prototype and Scriptaculous Javascript libraries (they are placed in app/webroot/js). They are typically loaded in the “head” section of your layout with:

<?php
echo $javascript->link('prototype');
echo $javascript->link('scriptaculous');
?>

After that, you can add the autocompleter to your view.

<?php echo $ajax->autocomplete('Company.name'); ?>

One condition must be fullfilled to make this code snippet work: the controller which renders the view must have access to the appropriate model, in our example to the Company model.

That’s it :)

Thanks to Nate for the hint.

Update 2010-03-08: Added a paragraph about the requirement of the Prototype and Scriptaculous libraries. Thanks to Andy Potanin for the hint.

105 comments baked

  • jf

    Moi j’obtiens l’erreur suivante :

    Erreur : Ajax.Autocompleter is not a constructor
    Fichier source : http://localhost/cake/index.php/types/
    Ligne : 60

    Ma ligne 60 :

    new Ajax.Autocompleter(‘Type_name’, ‘Type_name_autoComplete’, ‘/cake/index.php//types/’, {asynchronous:true, evalScripts:true});

    D’ou pourrait vernir le problème ?

    Merci

  • cakebaker

    @jf: Hm, I have no idea what could be the problem. My code looks almost identical…

    I am sorry, but maybe you will have more luck in the CakePHP google group: http://groups.google.com/group/cake-php

  • jf

    Solution :
    You have to include the prototype and script.aculo.us libraries in the
    header of your page.

  • new cake

    how can I give access of one model to another for this script.

  • cakebaker

    @new cake: Sorry, I don’t understand what you try to accomplish.

  • Ritesh Agrawal

    hi,

    I am trying to use the autocomplete component but not sure where I am making a mistake

    ==== Here is my controller that access author model ====

    ===== This is the view /view/authors/auto.thtml
    link(‘prototype/prototype’);
    echo $javascript->link(‘scriptaculous/scriptaculous’);
    ?>

    Last Name
    autocomplete(‘Author/last_name’); ?>
    submit(‘View Post’)?>

    ==== Here is the generated form

    Last Name

    new Ajax.Autocompleter(‘AuthorLastName’, ‘AuthorLastName_autoComplete’, ‘/cake/authors/auto’, {});

  • Ritesh Agrawal

    hi,

    I am trying to use the autocomplete component but not sure where I am making a mistake

    ==== Here is my controller that access author model ====
    class AuthorsController extends AppController
    {
    var $name = ‘Authors’;
    var $scaffold;

    var $components = array(‘Autocomplete’);
    var $helpers = array(‘Html’, ‘Javascript’, ‘Ajax’);

    function auto(){

    }

    }//endofclass

    ===== This is the view /view/authors/auto.thtml

    php echo $javascript->link(‘prototype/prototype’);
    php echo $javascript->link(‘scriptaculous/scriptaculous’);

    form action=”/authors/auto” method=”POST”
    Last Name:
    php echo $ajax->autocomplete(‘Author/last_name’);
    php echo $html->submit(‘View Post’)

    ==== Here is the generated form
    form action=”/authors/auto” method=”POST”
    label>Last Name

    div id=”AuthorLastName_autoComplete” class=”auto_complete” /> new Ajax.Autocompleter(‘AuthorLastName’, ‘AuthorLastName_autoComplete’, ‘/cake/authors/auto’, {});

  • cakebaker

    @Ritesh Agrawal: Hm, there was a bug in the latest release of CakePHP, so maybe that is the cause for the problem. See https://trac.cakephp.org/ticket/1154 . If that does not fix the problem, please post the code in the google group (it is easier than posting code here *g*).

  • nickr

    For me, what made the difference was adding in a link to the controls.js file, so that my app\views\layout\default.html included these four lines:

    charset(‘UTF-8′) ?>
    link(‘prototype’) ?>
    link(‘controls’) ?>
    link(‘scriptaculous.js?load=effects’) ?>

    Refreshed the page and it all worked perfectly. I just need a little CSS to power the dropdown, and I’ll be set! Thanks!

  • nickr

    Oops. Am hoping I can use code tags. The four lines should be:

  • Jefferson Wellington da Cunha

    How I do to access all attributtes of other model for I to use your component autocompleting a attribute that not yourself.

    Example:
    Model A, hasMany B
    Model B, belongsTo A (Table b have a_id attribute)

    I need autocomplete a attribute different of ‘a_id’ at Controller of Model B.

    How I do?

    So Thanks,
    JWCunha

  • mirceade

    var $uses = array(‘[Model name]‘);
    You MUST include this in your controller code for the ajax autocompletion to work.

  • alwhorley

    I am a total noob, and beg some help. I am trying to use this as described, I have the html, javascript, and ajax helpers in my controller. Actually I have them in my controller and in app_controller.php. I have a form in my view that contains only the setup and completion code for the form, a submit, and the snippet from here. The component is installed in the controllers/components dir. When I call the view, I get the form, but it fails silently. when I check the javascript console, I get an Ajax is not defined error. any clues that will help with my ignorance would be very helpful.
    Al

  • cakebaker

    @alwhorley: Did you include the prototype and scriptaculous libraries in the header of your page?

  • alwhorley

    yes I have them in in the head section of my layouts/default.thtml. like this:

    charsetTag(‘UTF-8′); ?>
    link(‘lib/prototype’); ?>
    link(‘src/scriptaculous.js?load=effects’); ?>
    link(‘src/controls’); ?>

    CakePHP :
    webroot . ‘favicon.ico’;?>” type=”image/x-icon” />
    webroot . ‘favicon.ico’;?>” type=”image/x-icon” />
    css(‘cake.generic’);?>

  • alwhorley

    Oh, and thanks for your response!

  • cakebaker

    @alwhorley: Hm, to me it sounds like the ajax libraries are not loaded. If you look at the source of the generated page, does it look correct?

  • alwhorley

    D’OH, the echo command was missing in my link statements! thanks for the heads up.

  • cakebaker

    @alwhorley: Cool to hear you could solve the problem :)

  • AbhinavZone - Your Source for fun and knowledge

    Hey thanx..

    I found your script very useful.
    I am new to cake php.. can u please tell me where to find good tutorial to learn developing components for cake php…

    I think you are perfect baker ;)

  • cakebaker

    @Abhinav: Have a look at the manual, there is a chapter about writing components: http://manual.cakephp.org/chapter/components

    Btw: I am by no means a perfect baker, I make errors as everyone else ;-)

  • mazoo

    I can’t register myself on bakery.cakephp.org (white screen after “/user/add”) so i make my comment to the autocomplete component here.

    I changed line 109 of version 0.4 from

    e(“\t”.$element.”\n”);

    to

    e(“\t”.preg_replace (“/” . preg_quote($data[$model][$field]) . “/i”, “<strong>” . $data[$model][$field] . “</strong>”, $element).”\n”);

    i think it’s even a bit cooler like that :)
    Cheers,
    mazoo

  • cakebaker

    @mazoo: Did you open a ticket for that issue on https://trac.cakephp.org ?

  • mazoo

    After i saw in the cake php google group that someone else has the same problem with similar setup, i checked it again and it was fixed…

    btw: in my earlier comment about autocompletion i forgot to encode the strong tags around the second $data[][].

  • cakebaker

    @mazoo: Ok, I fixed your comment.

  • dswingle

    I’m trying to make a Live Search work for a phone list and the AutoComplete component looks like it does sort of what I want so I figure this is the place to get some help.

    I’ve got the following view code in one of my view classes:

    ‘view’,
    ‘url’ => ‘/usefulnumbers/search’,
    ‘frequency’ => 1,
    ‘loading’ => “Element.hide(‘view’)”,
    ‘complete’ => “Effect.Appear(‘view’)”
    );
    echo $ajax->observeField(‘UsefulnumberSearch’,
    $options);
    ?>

    Above that I have my form with the text input element ‘UsefulnumberSearch’.

    What I want to happen whenever I type something into that input element is for my controller to call it’s search function and render my search view form inside the ‘view’ div element.

    Now whenever I type anything into the input field, the div appears like it should but I get a SQL_Error because for some reason my code is creating a query that’s something like this:

    SELECT * FROM usefulnumbers AS Usefulnumber WHERE ‘Usefulnumber’.'search’ LIKE %%

    The problem is that search is not a column in the usefulnumbers table and I have no idea why it’s being added to the query.

    The input element that ajax observes has the name data['Usefulnumber']['search'] because I made it with the html helper

    input(‘Usefulnumber/search’,
    array(‘size’ => ’40′));
    ?>

    Could that possibly be causing my problem?

    Sorry about the length of this comment but I’ve been beating my head against the wall for a while now and any help you could give me would be GREATLY appreciated.

    Thanks,

    dswingle

  • dswingle

    crap, that first block of code should start with:

    $options = array(
    ‘update’ => ‘view’,

  • cakebaker

    @dswingle: I think the AutoComplete component expects that your input field is named like the column in which the data are for the autocomplete functionality, i.e. your input field should look like:

    input('Usefulnumber/column_name');
    

    HTH

  • dswingle

    Cakebaker, you rock almost as much as Cake itself. Thank you SO much for the help, it definitely put me in the right direction, and, with a little bit of tinkering, I’ve got livesearch working perfectly!

    Again, THANKS!

  • cakebaker

    @dswingle: Thanks, I am glad I could help :)

  • vasileios

    Hi,

    thanks for the really nice component! However, I noticed a small problem when it is used in conjunction with the $ajax->observeField. The component seems to handle all ajax requests so $ajax->observeField doesnt return any valid results. Is it possible to make the component handle only the autocomplete requests ?

    Thanks!

    Vasilis

  • cakebaker

    @Vasilis: I am not sure if it helps in your situation, but you can disable the component by setting $enabled to false.

    HTH

  • Georgi Momchilov

    Hey there,
    very cool component :)
    just have a few remarks :
    I tried to use it on a big database – good some pretty bad performance hits because of findAll() and LIKE%% .
    My solution:
    autocomplete_component.php:
    line 88: $base = array($model.’.’.$field => ‘LIKE ‘.$data[$model][$field].’%'); ( remove % in front of LIKE as people are expected to enter the first chars of the desired entry. this also makes the queries faster )
    line 95: $controller->{$model}->recursion = false;
    $results = $controller->{$model}->findAll($conditions, $field, $field.’ ASC’, 15);
    remove recursion as we actually need very little data from that model and get only the desired field. also, limit the returned records ( to 15 in my case ) – otherwise, we can get veeeery long lists.
    hope that helped someone’s frustration
    thanks,
    Georgi

  • cakebaker

    @Georgi: Thanks for this tip!

  • Josh

    If anyone is interested, here is the CSS Code I found and modified a little so it works with this:
    div.auto_complete {
    position:absolute;
    width:250px;
    background-color:white;
    border:1px solid #888;
    margin:0px;
    padding:0px;
    }
    div.auto_complete ul {
    list-style-type:none;
    margin:0px;
    padding:0px;
    }
    div.auto_complete ul li.selected { background-color: #ffb;}
    div.auto_complete ul li {
    list-style-type:none;
    display:block;
    margin:0;
    padding:2px;
    height:32px;
    cursor:pointer;
    }

  • cakebaker

    @Josh: Thanks for sharing this CSS code!

  • angrys0ul

    i cant get it to work!
    the code the view generates is

    new Ajax.Autocompleter('ApplicationCity', 'ApplicationCity_autoComplete', '/applications/search', {});

    i have checked common things like including JS files, access to model, nothing wrong there

    and why does the generated html code have autocomplete=”off” ??

    btw should i name the component autocomplete or autoComplete ??

  • cakebaker

    @angrys0ul: Hm, difficult to say what’s wrong. Do you get any errors?

  • angrys0ul

    the full code is not visible in the comment, may be its a security feature
    i dont get any kind of errors. the form renders normally but just doesnt autocomplete when something is typed

  • cakebaker

    @angrys0ul: You can paste the code to the bin (http://bin.cakephp.org). Do you get a javascript error? (if you are using Firefox then Firebug is a good tool to see such errors)

  • JoeyK

    I’ve got the same problem as angrys0ul, I’m using cake 1.2… There’s a “Ajax is not defined” error, and autocomplete=off. However if you firebug the autocomplete field to “on” everything works perfectly…

  • cakebaker

    @JoeyK: Hm, did you include the prototype and scriptaculous libraries? At least here it works fine with the latest version of Cake 1.2, and autocomplete=off is set, too.

  • Reza Muhammad

    @angrys0ul & JoeyK:

    I had the same problem with you guys, and I found out that I loaded a echo $javascript->link(‘scriptaculous.js?load=effects’);

    I don’t think you should use “load=effects”. I took that part out of my code, and the autocompletion worked fine.

  • cakebaker

    @Reza: Thanks for the hint!

  • Frederick Ricaforte

    Thanks for the post!

    Model A, hasMany B
    Model B, belongsTo A (Table b have a_id attribute)
    where A is autocomplete form to extract from B.

    In relation to post above. If you’re going to extract data from your member model and you cannot use $uses to link to your current model, you can use this patch below:

    replace:
    if (!is_array($data[$model]) || count($data[$model]) != 1 || !is_object($controller->{$controller->modelClass}->{$model}) || !is_object($controller->{$model})) {
    return false;
    }
    with:
    if (!is_array($data[$model]) || count($data[$model]) != 1 || !is_object($controller->{$controller->modelClass}->{$model}) ) {
    if(!is_object($controller->{$model})) {
    return false;
    }
    }
    if(is_object($controller->{$controller->modelClass}->{$model})) {
    $modelObject = $controller->{$controller->modelClass}->{$model};
    }
    else {
    $modelObject = $controller->{$model};
    }

    replace:
    $results = $controller->{$model}->findAll($conditions);
    with:
    $results = $modelObject->findAll($conditions);

  • cakebaker

    @Frederick: Thanks for your addition, it may be helpful for others!

  • Sam

    To make autosuggest faster when using with database, we might,

    1. Limit the resultset with the “limit” clause in the query.
    2. Index the column that is searched.

    Is there any other technique apart from these two?

  • cakebaker

    @Sam: Apart from your points, the patterns Predictive Fetch and Submission Throttling might help.

  • Mariano Guezuraga

    I made it work with 1.2 rc3:

    in the component, change:
    $base = array($model.’.’.$field => ‘LIKE %’.$data[$model][$field].’%');
    to:
    $base = array($model.’.’.$field.’ LIKE’ => ‘%’.$data[$model][$field].’%');

    and:
    $results = $controller->{$model}->findAll($conditions);
    to:
    $results = $controller->{$model}->find(‘all’, array(‘conditions’ => $conditions));
    (this last one not necessary, but I guess findAll methods will be deprecated)

  • sbeer

    Hi! It seems to be a very nice component, but I can’t make it work. I’m using 1.2 and changed the lines as Mariano suggested. I also changed autocomplete(‘Event/title’); ?> to autocomplete(‘Event.title’); ?>. I’m quite new to cake, so are there some other things I need to change to make it work? I see the input-form, but when I type something in it, nothing happens. Thanks for the help!

  • cakebaker

    @sbeer: Hm, did you add the prototype/script.aculo.us libraries to “app/webroot/js”?

  • KK Kow

    After reading through all the comments, I still can’t seem to get the autocomplete to work. No error messages is given. It just doesn’t work. Anyway, I’ll put the generated code below, please let me know is it suppose to be like this… Thanks.

    <input name="data[Member][Member/full_name]" type="text" id="Member/fullName" autocomplete="off" value="" /> 
    <div id="Member/fullName_autoComplete" class="auto_complete"></div> 
    <script type="text/javascript"> 
    //<![CDATA[ 
    new Ajax.Autocompleter('Member/fullName', 'Member/fullName_autoComplete', '/members/add', {}); 
    //]]>
  • cakebaker

    @KK Kow: Yes, the output looks correct, though I would use autocomplete(‘Member.fullName’); instead of autocomplete(‘Member/fullName’);

    Did you apply the changes to the component mentioned by Mariano? And did you load the prototype/scriptaculous libraries?

    Hope that helps!

  • KK Kow

    Hi, I somehow manage to make it work. I read on some other article saying that we need to set debug to 0 in order for the xhtml to work, so what I do is just added the following line on the first line of the startup method.

    Configure::write('debug', '0');
    

    Of course I also change the line to ‘Member.fullName’.
    Another question though, how do I add label for the my input box, I notice there is not label for the input box.

  • cakebaker

    @KK Kow: To add a label you have to use the label() method of the FormHelper:

    echo $form->label('Member.fullName', 'Name');
    
  • johneischen

    How does the ajax helper pick up this as one of its methods?

  • cakebaker

    @john: Hm, I don’t understand what you try to ask… autoComplete() is a method of the ajax helper.

  • Angeline

    Hi, I got the auto complete box working.But I need to pass the selected values to another function. How do I get the value in the auto complete box in a variable?

    And also how to select multiple entries from the auto suggested entries? like selecting a name that is suggested, put a comma,and type in another letter for which a list of auto suggested values appear. Is that possible?

  • cakebaker

    @Angeline: If you submit the form to which the auto complete box belongs, then the value will be in the usual $this->data array.

    And regarding your second question, I think it is possible to develop such a solution. However, you would have to write the Javascript code yourself, as the Ajax helper doesn’t provide this functionality as far as I know.

    Hope this helps!

  • Angeline

    Thank you, I got the value through the $this->data array. Have to work on the second part of it. Please provide me some guidelines on it if possible.

  • cakebaker

    @Angeline: At least if you want to realize it with the Prototype Javascript framework, then their mailing list/irc channel might be useful, see http://www.prototypejs.org/discuss

    Hope that helps, and good luck!

  • Simon Brüchner

    When Autocomplete AND Security is activated like:
    $components = array('Autocomplete', 'Security');
    then the autocompleter does not work.

    I can’t figure out why. :(

  • Simon Brüchner

    I figured out why: the Ajax Request does not send the Security Token for the Security component. So I added this into the controller:

    var $components = array('Autocomplete', 'Security', 'RequestHandler'); 
    
        function beforeFilter() {
            parent::beforeFilter();
            if ($this->RequestHandler->isAjax()) {
                $this->Security->validatePost = false;
            }
        }

    It works.

  • cakebaker

    @Simon: I’m glad you could solve this issue in the meantime and thanks for sharing the solution for it!

  • Ximerian

    I got the auto complete working. I’m using it to auto complete addresses that are pulled from another model(using Frederick Ricaforte’s patch to make this happen). It exists on a form that is used to log EMS calls.

    The problem this has created for me now though is when I submit the form the address field does not get entered into the database. Before I was just naming my field ‘addresses_id’ and letting it automagically work. Whats the best way for me to get that functionality back?

    Thanks for a great component.

  • cakebaker

    @Ximerian: Hm, I’m not sure I understand your issue. If the issue is that the name of the form field and the name of the table column are different, then you could

    debug($this->data);
    

    and use something like

    $this->data['YourModel']['field'] = $this->data['YourModel']['fieldname_used_in_form']
    

    in your controller to prepare the data for the save operation.

    I’m not sure whether this is helpful for you…

  • Ximerian

    @cakebaker: Thanks for the reply! I’m very new to CakePHP and have limited php background so I’m sure that was a bit of a n00b question to ask.

    I discovered the debug($this->data) from reading things on the google group last night and got it to work by adding the following to my controller:

    $addresses = $this->Call->Addresses->find('first', array('conditions' => 
    array('Addresses.address' => $this->data['Addresses']['address'])));

    and then:
    $this->data['Call']['addresses_id'] = $addresses['Addresses']['id'];

    Your way does look more elegant, but since the field name contains the actually address and not the ‘id’ of the address it doesn’t work for me. Is there a way to store both the ID and the address being return from the autocomplete? Right now the address is being stored in auto complete field and the first code snippet is searching for the ‘id’ value of that address…feels very sloppy and like there should be a simpler way, unfortunately I have no idea what that would look like…

    Thanks for the reply and again for the component!

  • cakebaker

    @Ximerian: Well, to make the component return the id and the address, you would have to slightly modify the component and, for example, set the id as an attribute of the li tag. On the client-side you then have to extract the id and put it into a hidden field. When the user submits the form, you will get both data.

    However, this approach has two drawbacks: it only works when Javascript is enabled, and if the user uses the autocomplete feature but changes the returned string, you still have to perform the find() from your snippet to figure out whether it is a new string…

  • Anurag

    i got a proplem with make more than one autocomplete for the same
    field
    i cann’t do this, it doesn’t work:

    echo $ajax->autoComplete(‘Product.name.1′, array(‘controller’ =>
    ‘product’, ‘action’ => ‘autoComplete’));

    the above code is not work!!!
    how i can make autocomplete for m more than one product in the same
    page ???

  • Anurag

    Please Ximerian,
    Help me out from my above problem…

    thanks in advance

  • cakebaker

    @Anurag: Well, you have to apply some tricks and “hack” the component a bit to make it work. The first step is to use “Product.name][" instead of "Product.name.1", to generate an input field with the name "data[Product][name][]“. The second step is to provide an array with an id as the third parameter for the autocomplete method, something like:

    autoComplete(..., ..., array('id' => 'product_1'));
    

    And the final step is to add the following snippet to the autocomplete component, right before the like statement is constructed:

    // start snippet
    if (is_array($data[$model][$field])) {
        $data[$model][$field] = $data[$model][$field][0];
    }
    // end snippet
    
    $base = array($model.'.'.$field.' LIKE' => '%'.$data[$model][$field].'%');

    Hope that helps!

  • Bainco

    Thanks very much for this component ! That’s the only ‘autocomplete’ solution I could make work (I still new to cake !).

  • cakebaker

    @Bainco: You are welcome, and have a good start with CakePHP :)

  • Laceja

    I can’t seem to make this work. I have in the controller:

    var $components = array('Autocomplete');
    

    Then in my view I have added:

    <?php echo $ajax->autocomplete('Operation.op_code'); ?>
    

    And, the rendered field looks like this:

    echo $form->input('opcode', array('value' => $furnarray[opcode],'class' => 'short100r3', 'label' => false, 'div' => false, 'action' => 'autocomplete'));
    

    Of course, I’ve included $components(‘Autocomplete’) in the contoller along with adding Ajax to the $helpers, and scriptaculus.js?load=effects and prototype.js are included in the head section.

    I’m not getting any errors. It just doesn’t work.

    Thanks.

  • cakebaker

    @Laceja: Hm, I don’t understand what you mean with “the rendered field looks like this”. If it is rendered, it should be HTML code, and not PHP. Also, did you check with Firebug, whether there are any Javascript errors? And which CakePHP version do you use?

  • Laceja

    Sorry, I meant to say this is the command I coded to render the field. But, the autocomplete doesn’t work. That is, I don’t get a list as I begin to type and I’m certain there is data in my table to match what I am typing.

  • cakebaker

    @Laceja: Hm, I still don’t get it. To use autocompletion, you have to use the second snippet from your original comment. The third snippet creates a “normal” input field without autocompletion.

    And if you use Firebug, do you see any Ajax requests when you type something into the field with autocompletion?

  • Laceja

    As I recall, the ajax->autocomplete does not support the ‘class’ => ‘short100r3′, ‘label’ => false, and ‘div’ => false properties. I am correct?

    I don’t want the control to be in it’s own div, because I’ve got an array of 40 of them. div forces each to its own line.

  • cakebaker

    @Laceja: Well, the autoComplete() method allows you to pass an options array as third parameter. However, “label” and “div” are useless, as an autocomplete field is generated without label and the generated div is necessary for the results.

  • sai

    I have a employee dropdown list in the VIEW->add.ctp — when an employee is selected and clicked next
    In the next page(same page(add.ctp) or next page(edit.ctp)) it shud display the selected empolyee and his department and salary which are present in the users table. Also there are many other fields to be filled after the department and salary are displayed in this page automatically from the datebase’s users table.
    I already have a model and controller. Its actually for a form. everything is working, but now i have to introduce this logic where instead of hand filling the department of an employee. As soon as we select employee the department field in tht page shud be displayed which is present in the user table.

  • sai

    Could you please guide me

  • Andy Potanin

    For any new users having issues with, reference this: http://book.cakephp.org/view/208/AJAX

    If you have a brand new setup, you need to download JS libraries and put them into the app/webroot/js folder.

    Put the following into your controller:

    var $components = array('Autocomplete');
    	var $helpers = array('Html', 'Javascript', 'Ajax');

    and the following into your view file (I put it into my default.ctp file) into the header”:

    <?php
    echo $javascript->link('prototype');
    echo $javascript->link('scriptaculous');
    ?>
  • cakebaker

    @Andy: Thanks for your comment, I modified the article accordingly.

  • danny

    Here’s the deal. I’d like to retrive data (that which is shown in rendered view) from one one model and then save it in another. Autocomplete works perfectly where my input’s name is: data[model][field], but to make it work for my purposes the input field has to have name in following shape: name[]. Any idea?

  • cakebaker

    @danny: I’m not sure whether the Ajax helper is useful in this case…

    One way to accomplish what you try to do is to look at the code the helper generates, copy this code, and adapt it to your needs. Another way is to use an existing auto complete solution like Ajax AutoComplete for Prototype.

    Hope this helps!

  • danny

    I’ve finally figured this out and solution was quite simple. In my example input field has name: field[] (updating database), and to show list of options (from another model) after
    new Ajax.Autocompleter("...>
    I’ve add

    {
      paramName: "data[model][field]", 
    }
  • cakebaker

    @danny: Good to hear you found a simple solution :)

  • Pawel

    I’m trying to get it working, but the only problem I have left is that when I type I get no suggestions. I’m using Cake 1.2 I have:

    class CommentsController extends AppController {
    var $name = ‘Comments’;
    var $components = array(‘Autocomplete’);
    var $helpers = array(‘Html’, ‘Javascript’, ‘Ajax’);
    var $uses = array(‘Comment’);

    Ajax requests work : I can see that using Firebug. No suggestion though. Any help?

  • cakebaker

    @Pawel: Hm, difficult to say what the problem could be…

    One idea to pinpoint the problem is to set debug to 2 to see whether the correct SQL commands are executed.

    Not sure whether this will help…

  • Albert

    Hi all,

    I’m using CakePHP 1.3.2, and trying to use this autocomplete component.

    I get the autocomplete=”off” problem, like the one angrys0ul and JoeyK mentioned here (http://cakebaker.42dh.com/2006/06/06/autocompletion-the-easy-way/#comment-17522) and here (http://cakebaker.42dh.com/2006/06/06/autocompletion-the-easy-way/#comment-59781).

    I have tried Reza Muhammad tips to unload “scriptaculous.js?load=effects” (http://cakebaker.42dh.com/2006/06/06/autocompletion-the-easy-way/#comment-74051) but the problem is still there.

    I also have tried KK Kow tips to set debug to 0 (http://cakebaker.42dh.com/2006/06/06/autocompletion-the-easy-way/#comment-128840), no effect.

    Is there any code editing needed to make this component run in CakePHP 1.3.x?

    Thanks in advance.

  • cakebaker

    @Albert: No, the component should work as is. Do you get any errors? And what versions of Protoype and Scriptaculous do you use?

  • Albert

    No errors shown. But the autocomplete isn’t working.

    Like I explained above, I have the similar problem as the one angrys0ul and JoeyK mentioned: I got attribute autocomplete=”off”, but when I firebugged it and turned it on, the autocomplete is working. So maybe the question is: what do I need to do to get autocomplete set to on when the page is shown, without needing to firebug it first?

    Prototype = 1.6.1
    Scriptaculous = 1.8.3

    Any hints or suggestions?

    Thanks!

  • cakebaker

    @Albert: Hm, that’s odd. I’m using the same versions of the JS libraries. And the “autocomplete” attribute is “off”, too. And it works fine…

    I doubt you have to change the value of the “autocomplete” attribute as its value is hard-coded in the Ajax helper. However, if it fixes your issue when setting the attribute to “on” you could copy the Ajax helper to app/views/helpers and make the change there.

    PS: Is the source of your project somewhere online?

  • Albert

    I edited the helper, and as predicted, it solved my problem. But still it’s weird..

    The source isn’t available online, unfortunately..

    Thanks!

  • Ximerian

    I had to change line 97 from
    $results = $controller->{$model}->findAll($conditions);
    to
    $results = $controller->{$model}->find('all',$conditions);
    Does the current version of the autocomplete.php work for anyone with a new 3.7 cakephp install?

  • Ximerian

    Ok I spoke to soon. I now get a drop down list like it is working, but the list is comprised of all records for that field. It’s behaving like it is ignoring the ‘LIKE’ clause…any ideas?

  • cakebaker

    @Ximerian: Thanks for your comments. It sounds like you use an old version of the component. Please try the current version from Github: http://github.com/cakebaker/autocomplete-component, at least here it works fine.

    Hope this helps!

  • Ximerian

    Might want to update the link at the top of the page. It points to a completely different component.

    Thanks!!

  • cakebaker

    @Ximerian: Ok, it is fixed now. Thanks for the hint!

  • taqman

    I got error view is undefind
    http://uppic.net/full/c0261ea525918e474404cb1b632fad17

    thank

  • cakebaker

    @taqman: Hm, what versions of CakePHP, Prototype and Scriptaculous do you use?

  • Rameena Asheer

    Thank you very much for a wonderful autocomplete.
    It works successfully in my application.

    If I want to enter a minimum number of characters before the autocomplete starts,
    like minChars in http://book.cakephp.org/es/compare/632/autoComplete.

    What is the solution??

  • cakebaker

    @Rameena: Thanks for your comment!

    You should be able to use it as it is described in the article you linked:

    echo $ajax->autocomplete('Company.name', '', array('minChars' => 3));
    

    Hope this helps!

  • Rameena Asheer

    Really thanks for your very sooooon reply.

    I want to know about how to validate these fields.

  • cakebaker

    @Rameena: If you want to validate data on the server-side check out the chapter Data Validation in the cook book.

    For client-side validation you either have to write your own validation code or use something like validation-js or LiveValidation.

    Hope this helps!

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License