Wednesday, July 1, 2009

Zend Framework and dojo- Auto Complete Example

Creation of auto complete in Zend Framework using dojo is like a piece of cake. In one of my previous post I discuss how to create filtering select and populate that using dojo and ajax.
Here I am going to discuss how to create auto complete with combo box. The auto complete textbox will automatically/dynamically fetch data from the database.
So lets get started.
First of all create following functions in you controller.
public function getForm()
{
if (null === $this->_form) {
$this->_form = new Zend_Form();
$this->_form->setMethod('get')
->setAction($this->getRequest()->getBaseUrl() . '/test/process')
->addElements(array(
'test' => array(
'type' => 'text',
'options' => array(
'filters' => array('StringTrim'),
'dojoType' => array('dijit.form.ComboBox'),
'store' => 'testStore',
'autoComplete' => 'false',
'hasDownArrow' => 'true',
'label' => 'Your input:',
)),
'go' => array('type' => 'submit',
'options' => array('label' => 'Go!'))
));
}
return $this->_form;
}

In the above code define a function and create a form adding it a combo box.
The important attributes of the combo box are
dojoType, store and autocomplet.
Next create the following actions in your controller where you defined getForm() method.
class DojoController extends Zend_Controller_Action
{
public function autocompleteAction()
{
$this->view->form = $this->getForm();
}
public function recordsAction()
{
}
}

In the above code we get the form by calling the method defined and assign it to the view template.
Next in the view template file write.
Zend_Dojo_View_Helper_Dojo::setUseDeclarative();
$this->dojo()->setLocalPath('http://localhost/z/js/dojo/dojo/dojo.js')
->addStyleSheetModule('dijit.themes.tundra')
->addStylesheet('http://localhost/z/js/dojo/dojox/grid/_grid/tundraGrid.css');
echo $this->dojo();
?>
<script type="text/javascript">
dojo.require("dojox.data.QueryReadStore");
dojo.require("dijit.form.ComboBox");
dojo.require("dojo.parser");
</script>
<div dojoType="dojox.data.QueryReadStore" jsId="testStore" url="records"></div>
<?
echo $this->form;
?>

In the code above we first tell zend that we want to use declarative mode than programmatic which is default.
Next we set local path to dojo.js and necessary css and theme.
Next we specify which dojo js files we require.
The most important thing in the above code is
<div dojoType=”dojox.data.QueryReadStore” jsId=”testStore” url=”records”></div>

Here we specify dojoType and jsId. Keep in mind that the jsId is same to the combobox store attribute.
Another important thing is url of the div. this url is used by dojo QueryReadStore to pull data from the action.
To populate our combo box in the records action of the Dojo Controller write the following.
public function recordsAction()
{
$db=Zend_Registry::get('db');
$sql = 'SELECT name FROM company';
$result = $db->fetchAll($sql);
$dojoData= new Zend_Dojo_Data('name',$result,'id');
echo $dojoData->toJson();
exit;
}

The above code is simple to understand. We first get reference to the db object store in the bootsrap.
Next we write sql. Keep in mind that I have company table with name field in my database.
Next I fetch all data(name). give it to Zend_Dojo_Data. And convert resultant data to Json.
That’s it.
Cheers.

6 comments:

  1. Hi Faheem Abbas,
    I really like your tutorial on the autocomplete example. I just ran into a problem which I can not sort out.
    Everything works fine, combobox is created, JSON request is passed, so far everything is fine.
    However I only have "undefined" values in the comobox after the request was received, thus it is a correct JSON envelope...
    Any hints would be gratefully appreciated,
    cheers
    Andy

    ReplyDelete
  2. Hi,

    The database query I have will return over a 1000 records and is taking a very long time. When the user types another letter in the select box it searches the db again. Surely only one db lookup is required? Is it worth having this for a large number of records

    ReplyDelete
  3. I needed additionally the following line:
    dojo.require("dijit.form.Form");

    ReplyDelete
  4. The database query I have will return over a 1000 records and is taking a very long time. When the user types another letter in the select box it searches the db again. Surely only one db lookup is required? Is it worth having this for a large number of records

    ReplyDelete
  5. Ecorptrainings.com provides DOJO in hyderabad with best faculties on real time projects. We give the best online trainingamong the DOJO in Hyderabad. Classroom Training in Hyderabad India

    ReplyDelete
  6. Any clues on what this error means:
    dijit.form.ComboBox: TypeError: _3b.getValue(...) is undefined

    ReplyDelete