Strict Autocomplete with Scriptaculous (Part II)

These days when I showed my example to some friends I realized that in fact even the second example had potential bugs. In fact not a bug, but missing functionality which could mislead the user while using the component.

What I found: When the user prefer to type instead of selecting the value from the list, then it’s possible to have “nothing selected” in ID field, but in fact the user have feeling that he select the correct value. This is extremely valid when the options are short and typing 3-4 chars which in fact is more convenient to type instead of selecting.

In the “perfect” world – especially in that example which I am interested with, the user need to enter valid ID once he/she try to enter something in the field. Well, then the solution provided is not the perfect solution.

Realizing that, I start searching in Scriptaculous lib how to handle it. In fact, in Autocompleter there is no callback function for onComplete action /then the list is ready after Ajax request/. I search over the Internet about it, but I didn’t find anything which could help me especially with Scriptaculous lib. Then I decided to make the small add-on in the core lib and to modify that part which will do this “select first option from available”.
I did with the following code in controlls.js file:

The original function was:

onComplete: function(request, element) {
    this.updateChoices(request.responseText);
}

After my modification I have also extra call back as well as the required functionality.

onComplete: function(request, element) {
this.updateChoices(request.responseText);

if(this.options.selectFirst == true){
      currentValue = this.element.value.toLowerCase();
      this.selectEntry();
      currentText = this.getCurrentEntry().innerHTML.toLowerCase();
     
      if(currentText.indexOf(currentValue) == 0){
          if(this.element.createTextRange){//IE
              this.element.value = currentText;
              sRange = this.element.createTextRange();
              sRange.findText( currentText.substr(currentValue.length) );
              sRange.select();
          } else { //Mozilla or other
              this.element.value = currentText;
              this.element.setSelectionRange(currentValue.length, currentText.length);
          }
      }
    }
    this.options.customCallback();
  }

so now, if you add in options of the Autocompleter

selectFirst:true

The function will select every time the first entry in the list.

I already proposed this change to Scriptaculous community, so I hope they will add it in the official lib for next release.

6 thoughts on “Strict Autocomplete with Scriptaculous (Part II)

  1. ThomasNo Gravatar

    Very good Article! I’m very new to cake and it helped me to solve the problem of how to set an autocomplete field – if the content belongs to the actual controller (e.g. name of all dvds if the controller dvds_controller).

    But I still have a problem with fields that belong to other db-tables, for example I have the table dvds and another table genres.
    Both are connected through the table dvd_genres where dvds_id and genres_id are stored.

    If I want to list all genres by name in an autocomplete field, cake sets a selectbox with the genres instead of an inputfield. I used the following code to set the field:
    autoComplete(‘genre’, ‘ajax_autocomplete’, array(‘label’=>’Genre’, ‘type’=>’text’, ‘strict’=>true));
    but nothing changed. Cake still sets the selectbox.

    How can I handle this kind of autocomplete?

  2. Nik ChankovNo Gravatar Post author

    Hi Thomas, as you can see the article is a little bit outdated (2007). I would suggest to use jQuery and to set a separate action which will handle the server output.

  3. ThomasNo Gravatar

    Hi Nik,thank you for the fast response!!!

    Finallay I’ve got it to work with prototype and scriptaculous. But like you explained above I have the problem that – if a user types his own text – the field would be empty after the focús is off. Though I changed the controlls.js to your new code the problem is still there. You wrote in your response that it would be better to use jQurey.

    Unfortunately I have no experience with jQuery. Is it enough to replace the $javascript->link for prototype etc. with one to jQuery or must I change some Code if I want to use it? If yes, would you give me a hint how I have to do it?

Leave a Reply

Your email address will not be published. Required fields are marked *