Section: Field with autocompletion
^ Creating a jforms file | Captcha » |
− Table of content
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;
}