Quick links: Content - sections - sub sections
EN FR

Theres is no specific XML element for a text input with autocompletion. You have to use a menulist with a plugin autocomplete_html or autocompleteajax_html.

These widgets display a simple input. When the user starts to type a word, a search is made and a list of results appears. The user can select one of the result, so he doesn't have to type the whole word or sentence.

Autocompletion with data embeded into the web page

The search is made into the datasource indicated into menulist.

The datasource should notcontain too many items, else the web page should be heavy. If the weight might be a problem, it is better to use remote data.

In the present case, you can use the widget autocomplete_html. It searches into the content of an hidden <select> generated by the widget.

For example, into the jForms file, use a menulist with a datasource or a static list of items.


  <menulist ref="mylist">
    <label>test</label>
    <datasource dao="mymodule~mydao"/>
  </menulist>

In a template, indicate the widget autocomplete_html:


{form $form, $submitAction, $submitParam, 'html', array(
  'plugins'=>array(
    'mylist'=>'autocomplete_html'
 ))}

{formcontrols}
   {ctrl_label} ... {ctrl_control}
{/formcontrols}
{/form}

The widget accepts a specific attribute, attr-autocomplete, that is an array which may contain HTML attributes (class, style...) for the input element used to type the search term.


{formcontrols}
   {ifctrl 'mylist'}
      {ctrl_control '', array(
           'attr-autocomplete'=>array('style'=>'width:40em;')}
   {else}
      {ctrl_control}
   {/ifctrl}
{/formcontrols}

Autocompletion with remote data

If the datasource contains many items (more than few dozen items), it is preferable to use autocompleteajax_html, which launch an http request to the application, to do the search and returning the results.

You have to indicate the url that will return results, in the attribute sources into attr-autocomplete.

In the controller which displays the form:


$tpl->assign('searchUrl', jUrl::get('mymodule~myctrl:searchTerm'));

And in the template :


{form $form, $submitAction, $submitParam, 'html', array(
    'plugins'=>array(
        'mylist'=>'autocompleteajax_html'
))}
{formcontrols}
   {ifctrl 'mylist'}
      {ctrl_control '', array(
           'attr-autocomplete'=>array(
                'source'=> $searchUrl)}
   {else}
      {ctrl_control}
   {/ifctrl}
{/formcontrols}

Note that the URL may be an other web site. Carefull with the CORS.

In all case, the server should accept a query parameter term which contains what the user types, and it should return a JSON array containing all results. Each results is an object with a label atribute and an id attribute.

For example, in one of your controller :


function searchTerm()
{
    $rep = $this->getResponse('json');
    $term = $this->param('term');
    if (strlen($term) < 2) {
        $rep->data = array();
        return $rep;
    }

    $dao = jDao::get('mymodule~mydao');
    $conditions = new jDaoConditions();
    $conditions->addCondition('name', 'like', '%'.$term.'%');
    $conditions->addItemOrder('name', 'asc');
    $list = $dao->findBy($conditions);
    $towns = array();
    foreach ($list as $prop) {
        $towns[] = ['label' => $prop->name, 'id' => $prop->id];
    }
    $rep->data = $towns;
    return $rep;
}