Thursday, April 7, 2011

Autocomplete Example With Zend_Dojo_Form_Element_FilteringSelect And Zend_Dojo_Data

Autocomplete Example With Zend_Dojo_Form_Element_FilteringSelect And Zend_Dojo_Data

Zend Framework brings lot of user interface goodies with Zend_Dojo family of classes. In this article let us explore how to build a form element with autocomplete feature.
As a prerequisite you must be familiar with
  • Zend_Controller_Action
  • Zend_Layout
  • Zend_Form
Would it be nice if I tell you that you don't need any JavaScript knowledge? Zend_Dojo empowers PHP programmers to build dynamic and appealing forms without writing a single line of JavaScript.
This example has been tested with Zend Framework 1.7.0.
In this example, we will build a text element where the visitor can either select the user from the drop down list or type the username. While typing the username, the form element generates a drop down list filtering the data from user input. Take a look at the filteringSelect Dijit example to understand the type of form element we will be building.
FilteringSelect differs from Combobox Dojo widget in that, the value of the form element must be provided in the list. Also, you could display the username on the screen and set the 'user id' as the element value.
We will use the autoCompleteDojo action helper to send JSON data.
Let's start coding.
Step 1: Set up the Dojo environment in our bootstrap file.

// Create new view object if not already instantiated
//$view = new Zend_View();
Zend_Dojo::enableView($view);
$view->dojo()
->
addStyleSheetModule('dijit.themes.tundra')
->
setDjConfigOption('usePlainJson', true)
->
disable();

$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
'ViewRenderer'
);
$viewRenderer->setView($view);

?>

We enable Zend_Dojo in the $view object and set it to the view renderer.
In this example, we use the default CDN set in Zend_Dojo. You don't have to add Dojo JavaScript files to your web server. We add the 'tundra' stylesheet.
Step 2: Create the controller. Create the file DemoController.php in your controller directory and add the code below to it.


class DemoController extends Zend_Controller_Action
{
public function
indexAction()
{
}

public function
userlistAction()
{
}

public function
getForm()
{
}

}

?>

As you can see, it is just a skeleton of our controller. We add the code to it in a moment.
We build our form in the function getForm(). In a real world application you might want to create the form in a different class and file. In indexAction we display the form and process the data submitted by the user. In userlistAction we generate the data in JSON format which is required by the filteringSelect element.
Step 3: Create the form and elements. Put the below code in the getForm() function.
= new Zend_Form;

$userId = new Zend_Dojo_Form_Element_FilteringSelect('userId');
$userId->setLabel('Select a user')
->
setAutoComplete(true)
->
setStoreId('userStore')
->
setStoreType('dojo.data.ItemFileReadStore')
->
setStoreParams(array('url'=>'/demo/userlist'))
->
setAttrib("searchAttr", "username")
->
setRequired(true);

$submit = $form->createElement('submit', 'submit');

$form->addElements(array($userId, $submit));

return
$form;

?>
$userId is the form element containing the Dojo filteringSelect widget. We give the name userStore to our data store. We are specifying that we will serve the data from the URL /demo/userlist. Finally, we are setting the searchAttr to 'username'.
Step 4: Prepare the database.
CREATE TABLE `user` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `username` VARCHAR( 100 ) NOT NULL , ) ENGINE = InnoDB   INSERT INTO `zf`.`user` ( `id` , `username` ) VALUES ( NULL , 'jamey' ), ( NULL , 'hryan' ), ( NULL , 'jennyross' ), ( NULL , 'natebrg' ), ( NULL , 'deric' );

Create a sample table and add dummy data to it.
Step 5: Fetch the data from the database, convert to JSON format and send. I use the MySQL database 'zf' in this example. Insert below code to userlistAction(). I am connecting to the database from within the action in this example. Practically, you would want to connect to the database in a centrally accessible place like the bootstrap or a front controller plugin.
= new Zend_Db_Adapter_Pdo_Mysql(array(
'host' => '127.0.0.1',
'username' => 'zf',
'password' => 'password',
'dbname' => 'zf'
));

$result = $db->fetchAll("SELECT * FROM user");
$data = new Zend_Dojo_Data('id', $result);
$this->_helper->autoCompleteDojo($data);
?>
It takes only three lines to fetch the data and send it in the format Dojo requires. We pass two parameters - id and $result the Zend_Dojo_Data constructor. 'id' is the unique identifier in our database table. The autoCompleteDojo action helper is convenient to use. It disables the layout and viewrenderer. It sets the appropriate headers and sends the data using the Zend_Dojo_Data object.
Point your browser to demo/userlist, you should receive the data in a file. Dojo uses this file via dojo.data.ItemFileReadStore.
Step 6:Set up indexAction(). Add the below code to the indexAction() function.

= $this->getForm();

if (
$this->_request->isPost()) {

if (
$form->isValid($_POST)) {
/*
* Process data
*/
$userId = $this->_getParam('userId');
//$userId contains the userId input by the user
} else {
$form->populate($_POST);

$this->view->form = $form;
}

} else {

$this->view->form = $form;
}

?>
Step 7:Set up the view and layout
In the view script index.phtml write:

<h1>Demoh1>
php
echo $this->form;
?>
In your layout file output the Dojo files and set the body tag to tundra class. When you echo $this->dojo(), links to Dojo JavaScript source files are printed. It also prints the JavaScript code that Zend Framework generates for you.
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<
head>
<
meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

php
echo $this->dojo()->addStylesheetModule('dijit.themes.tundra');
?>






echo $this->layout()->content ?>




?>
Initially it may appear that you have to write a lot of code to get this work. Once you understand the whole process it becomes trivial to build form elements with autocomplete feature.
I have attached the files to this post for your reference.
You might also want to take a look at:
Add A Cool Zend Dojo Date Picker Form Element Without Writing A Single Line Of JavaScript
AttachmentSize
zf-filteringSelect-example.tar_.gz11.6 KB

0 评论:

Post a Comment