Even though I feel pretty tired this evening, I had to satisfy my curiosity and took a quick look at Zend_Dojo.
My first result: (Click on the picture to see the demo)

Looks quite nice. If you (like me) don’t know the Dojo Toolkit yet, you probably need some time to understand the documentation. It would have been easier to play around with Dojo independently from the Zend_Dojo stuff for some time, but as long as there is no time pressure on you, trial and error can be fun too. I simply tried to follow the Zend_Dojo documentation. First of all you need to tell the view object where it can find the Zend_Dojo ViewHelpers. I’m doing this in my bootstrap file (I’m using the default directory structure like it is described in the docs):
<?php
error_reporting(E_ALL|E_STRICT
);
set_include_path('../library' . PATH_SEPARATOR .
get_include_path());
require_once 'Zend/Loader.php';
Zend_Loader::
registerAutoload();
$layout = Zend_Layout::
startMvc();
// Tell the view where it finds Zend_Dojo ViewHelper
$layout->
getView()->
addHelperPath('Zend/Dojo/View/Helper/',
'Zend_Dojo_View_Helper');
$front = Zend_Controller_Front::
getInstance();
$front->
addControllerDirectory('../application/controllers');
$front->
throwExceptions(true);
$front->
dispatch();
Next step is to include the Dojo library. Because this belongs into the <head> part of your HTML document, I’m changing my layout file (layout.phtml):
<?php echo $this->
doctype() ?>
<html>
<head>
<title>roetgers.org Dojo Demo</title>
<meta http-equiv=
"Content-Type" content=
"text/html; charset=utf-8">
<?php
// My own stylesheet
echo $this->
headLink()->
setStylesheet('/css/my.css');
// Check if dojo library is needed
if ($this->
dojo()->
isEnabled()):
// Include dojo library
$this->
dojo()->
setLocalPath('/js/dojo/dojo.js')
// Use dojo theme tundra
->
addStyleSheetModule('dijit.themes.tundra');
// Echo out the dojo <script> tags
echo $this->
dojo();
endif;
?>
</head>
<!-- Set body
class to
"tundra" -->
<body
class=
"tundra">
<?php echo $this->
layout()->
content ?>
</body>
</html>
After those changes my application is prepared to use Dojo. In the beginning of a view script you need to tell the ZF, that Dojo is needed by calling
If you don’t do this, the Dojo library will not be included in your layout.phtml file and Dojo won’t work. My first target was to create a TabContainer. Of course there is a ViewHelper which you can use to create such a container:
echo $this->
tabContainer($id,
$content,
$params,
$attribs);
Looks like a normal ViewHelper. But there is a difference because all layout containers know the capture methods captureStart() and captureEnd():
<?php
$this->
dojo()->
enable();
// Container with tabs
$this->
tabContainer()->
captureStart('tab1',
array(),
array('style' =>
'width:800px;height:500px;'));
// My content goes here
echo $this->
tabContainer()->
captureEnd('tab1');
I really like this way of adding content into a container, because your view script stays readable even if you start nesting containers into containers. Let’s have a look at my complete view script which I used for my sample:
<?php
$this->
dojo()->
enable();
// Container with tabs
$this->
tabContainer()->
captureStart('tab1',
array(),
array('style' =>
'width:800px;height:500px;'));
// First tab "Dates"
$this->
contentPane()->
captureStart('pane1',
array(),
array('title' =>
'Dates'));
echo $this->
form1;
echo $this->
contentPane()->
captureEnd('pane1');
// Second tab "FAQ"
$this->
contentPane()->
captureStart('pane2',
array(),
array('title' =>
'FAQ'));
echo '<h1>FAQ</h1>
<dl><dt>Question 1?</dt><dd>This is my answer 1!</dd></dl>
<dl><dt>Question 2?</dt><dd>Good question, next one.</dd></dl>
<dl><dt>Question 3?</dt><dd>Ok, that\'s enough!</dd></dl>
';
echo $this->
contentPane()->
captureEnd('pane2');
// Third tab "Closable"
$this->
contentPane()->
captureStart('pane3',
array(),
array('title' =>
'Closable',
'closable' =>
true));
echo 'You can close me!';
echo $this->
contentPane()->
captureEnd('pane3');
// Fourth tab "Splitted"
$this->
contentPane()->
captureStart('pane4',
array(),
array('title' =>
'Splitted'));
$this->
splitContainer()->
captureStart('split1',
array(),
array('style' =>
'width:250px;height:250px;'));
$this->
contentPane()->
captureStart('splitpane1',
array(),
array());
echo 'Hey, I am on the left side!';
echo $this->
contentPane()->
captureEnd('splitpane1');
$this->
contentPane()->
captureStart('splitpane2',
array(),
array());
echo 'Cool!';
echo $this->
contentPane()->
captureEnd('splitpane2');
echo $this->
splitContainer()->
captureEnd('split1');
echo $this->
contentPane()->
captureEnd('pane4');
echo $this->
tabContainer()->
captureEnd('tab1');
As you can see every tab is a new ContentPane. ContentPanes can be used inside every layout container except the AccordionContainer. Have a look at the docs for more information on that.
I’m displaying a form in the first tab. This form is an object of the class Zend_Dojo_Form. There are some really cool Dojo widgets (Dijits) which you can use to spice your forms up. The form is created in my IndexController:
public function indexAction
()
{
$form1 =
new Zend_Dojo_Form
();
$form1->
setMethod('post')->
setAction("/");
$form1->
addElement('DateTextBox',
'date1',
array(
'label' =>
'Choose a date:',
'datePattern' =>
'yyyy-MM-dd',
'validators' =>
array('Date'),
'required' =>
true
))
->
addElement('TimeTextBox',
'time1',
array(
'label' =>
'Choose a time:',
'timePattern' =>
'HH:mm:ss',
))
->
addElement('NumberSpinner',
'number1',
array(
'label' =>
'Choose a number:',
'value' =>
0,
'smallDelta' =>
1,
'min' =>
0,
'max' =>
30,
'defaultTimeout' =>
100,
'timeoutChangeRate' =>
100,
))
->
addElement('HorizontalSlider',
'slide1',
array(
'label' =>
'Let\'s slide:',
'minimum' =>
0,
'maximum' =>
25,
'discreteValues' =>
10,
'style' =>
'width: 450px;',
'topDecorationDijit' =>
'HorizontalRuleLabels',
'topDecorationLabels' =>
array('0%',
'50%',
'100%'),
'topDecorationParams' =>
array('style' =>
'padding-bottom: 20px;'),
))
->
addElement('SubmitButton',
'submit',
array(
'label' =>
'Submit!'
));
$this->
view->
form1 =
$form1;
}
As you can see it is ridiculous easy to put together such a form. Basically it is the same as with the normal Zend_Form. Of course the Dojo form elements have different names (e.g. “SubmitButton” instead of “submit”) and you need some additional array keys in the form element configuration but then the magic happens.
This is only the very first step on my way of understanding Dojo but so far it looks promising! I’ll write more about it as soon as I digged deeper into that topic.
Link to My Demo