Flexac

Flexac provides a system to enter HTML forms’ input field data with the help of an autocomplete feature. What it means is that while you’re typing inside a text input box, Flexac works “behind the scenes” fetching data that is similar (begins with or contains) what you are typing. Giving that such data exists, it then compiles a list displayed like a normal dropdown box. From the list (that you can browse with the cursor keys or the mouse) you can then choose the item that you were writing using the right arrow key or enter.

Navigate in this document

Made by Claudio Cicali and free software.

Drop me a line: claudio AT cicali.org

Bring me to the demo. NOW!

Yes, yes… the demo is just near you. Please come back.

How it is done

Flexac is:

  • A javascript program that you use where you need the autocomplete feature
  • A script (PHP, but the language is not relevant) that acts as the backend to fetch data from any source. It talks with the javascript program
  • Some plugins one for each data source. Plugins are called from the main php script when needed

Here is more:

  • The javascript <-> php-backend dialogue is based upon the glorious XMLHTTPRequest object
  • Data is transferred using the JSON data wrapper
  • Data can be locally cached (more on this later)

How to use it (by example)

Suppose that you have an HTML form with two fields that require autocomplete. Those that follows are the steps you need to use Flexac with your two fields.

  • Include the Flexac javascript program in the <head> of your HTML document:

      <script src="flexac.js"></script>
    
    
  • Add the Flexac CSS to yours:
      <style type="text/css">
      @import url(flexac.css);
      </style>
    
  • Add the flexac hook to your fields
      <input type="text" name="fooField" autocomplete="off" onfocus="flexacOn(this, 'foo', true)">
      <input type="text" name="barField" autocomplete="off" onfocus="flexacOn(this, 'bar', false, 1000)">
    

    There is no need of an ID and there are no restrictions on the field name. The hook is simply the flexacOn function that have to be bound to the onfocus event.

    • The first parameter is always this and we couldn’t care less.
    • The second is a string containing the name of the plugin to be called to fetch the autocomplete data. Perhaps all could be clearer if I had used “customers” and “countries” instead of “foo” and “bar”.
    • The third parameter tell Flexac if data retrieved must begin with the term in the input field (true) or if the term could be found anywhere (false).
    • The forth parameter is a limit. If the total number of data records (on the server) is less than this limit, then on the first request (and only then) all the data records will be requested and then cached on the client. Subsequent fetches for the autocomplete, will be made on the local stored array. If the limit is 0 or not present at all, the search data will never be cached. A word of warning: remember that if the cache is enabled (using a value for the limit greater than zero), than on the first server data request ALL data records will be transferred; and we set the flexacOn hook on the onfocus event… beware. (hint: do not use this feature on huge datasets)

    That’s all you need from the client side. (But this is not all you can do: look near the end for the configuration details)

  • By the server side, you need the provided script (by default it is flexac.php and resides in the same directory where the HTML document is) and, at least, a plugin that fetches the actual data. In this example we used “foo” and “bar”, and so we need two plugins: one that will fetch foos and one that fetches bars (or customers, countries, fruits…).

    When the autocomplete for foo is needed, flexac.php searches the subdirectory plugins/ for the existence of plugin_foo.php, that this a php script with the name that begins with “plugin_” followed by the name of the plugin.

    The plugin script is, obviously, a php one and it must contain at least the Flexac_plugin Class. The constructor of that class will receive two parameters:

    • what has been partially entered inside the HTML field
    • the eventual caching limit

    The FlexacPlugin class must define the getData($bw) method. This method will receive the “begins with” flag (true or false).

    What this function actually should do, is to prepare an associative array containing (if any) all the results that matches the pattern received.

    A skeleton-like class that instantiates the search for foos could look like this:

    
    <?php 
    class FlexacPlugin
    {
      var $query;
      var $limit;
    
      function FlexacPlugin($query, $limit)
      {
        $this->query = $query;
        $this->limit = $limit;
      }
    
      function getData($bw)
      { 
        require("all_my_foos.php");
    
        if (count($foos) <= $this->limit)
          return $foos;
    
        foreach($foos as $k => $v)
          if ($this->match($v, $bw) !== false)
            $results[$k] = $v;
    
        return $results;
      }
    
      function match($string, $beginsWith)
      {
        if (!$beginsWith)
          return (stristr($string, $this->query));
        else
          return (strpos(strtolower($string), strtolower($this->query), 0) == 0);
      }
    }
    ?>
    

    That’s all.

Configuring & tuning

The configurable options are (and are commented in) on the top of the flexac.js file. Here is the actual list:


  // Script to invoke. Parameters are "q" (query string) and "p" (plugin)
  flexac.config.script          = "flexac.php";
  // HTTP method used to invoke the script
  flexac.config.scriptMethod    = "GET";
  // Timeout (in ms) after which the list is automatically hidden
  flexac.config.hideTimeout     = 15000;
  // Timeout (in ms) after which the search is began
  flexac.config.acTimeout       = 250;
  // How many items have to stay visibile in the list
  flexac.config.listMaxItem     = 10;
  // Change the input when a choice has been made ? (adding the flexacChoose class)
  flexac.config.notifyChoose    = true;
  // Change the input when a searching... ? (adding the flexacSearching class)  
  flexac.config.notifySearching = true;

Understanding the machine

Here comes the gory details.

Whenever a key is pressed inside the input box, a timer is fired. After the timeout (default to 250ms) expires, if the user has entered at least 2 characters, the js script reads the actual value of the input field and send it to the backend script via XMLHTTPRequest. The script then reads (evaluates) the related plugin and sends back to the js the associative array of the results, encoded in JSON.

When the user choose an item from the drop down box, Flexac try to set the value of the nameofthefield_id form’s hidden input field. Speaking of foos, it will try to set the value of foo_id with the key associated to the choosen string. If that field does not exits, Flexac will create it.

Flexac is supposed to work, at least, in Internet Explorer 6+ and Mozilla based browsers.

Download & License

The whole current package, composed by:

  • The flexac.js javascript program
  • The flexac.css CSS file
  • The flexac.php backend program
  • The JSON/php required libray
  • Two plugins (from the demo)
is dowloadable from here

Credits

Partially inspired by the work of Mircho Mirev (mo /mo@momche.net/)

Comments

  1. Brian Sweeting said:

    Great work. I’ve been looking for a good implementation of this for a long time. One suggestion, you might want to add the autocomplete=”off” attribute/value to the input tag

    Posted on 04/16/05 07:29 PM    #

  2. Ken Brill said:

    It works great but, sometimes when I click on a selection I get “Choice” in the input field. I can’t figure out where the bold tags are being added or why they are being passed back sometimes.

    Posted on 11/15/05 10:03 PM    #

  3. Ken Brill said:

    It works great but, sometimes when I click on a selection I get “[strong]Ch[/strong]oice” in the input field. I can’t figure out where the bold tags are being added or why they are being passed back sometimes.

    The ‘[’ and ‘]’ are actually the html tag enclosures, cant seem to use the greater-than opr less-than signs here.

    Posted on 11/15/05 10:06 PM    #

  4. rp said:

    great help to me. keep it up. this was practically first proper example that i found and which i can modify to make a query from the database table instead of the given text file

    Posted on 12/15/05 01:02 PM    #

  5. Ian said:

    The download site at flexer.it seems to have expired.
    Has anyone got a copy of this code they could email me?
    Thanks.

    Posted on 06/25/06 08:16 PM    #

commenting closed for this article

This site

Browse by category

Contacts

Feed from feedburner Subscribe to this feed with Bloglines

Creative Commons

XFN Friendly