2.2. ZendX_JQuery View Helpers
Prev | Chapter 2. ZendX_JQuery | Next

## 2.2. ZendX_JQuery View Helpers

Zend Framework provides jQuery related View Helpers through its Extras Library. These can be enabled in two ways, adding jQuery to the view helper path:

    $view->addHelperPath("ZendX/JQuery/View/Helper", "ZendX_JQuery_View_Helper");

Or using the `ZendX_JQuery::enableView(Zend_View_Interface $view)` method that does the same for you.

### 2.2.1. jQuery() View Helper

The `jQuery()` view helper simplifies setup of your jQuery environment in your application. It takes care of loading the core and ui library dependencies if necessary and acts as a stack for all the registered onLoad javascript statements. All jQuery view helpers put their javascript code onto this stack. It acts as a collector for everything jQuery in your application with the following responsibilities:

- Handling deployment of CDN or a local path jQuery Core and UI libraries.

- Handling $(document).onLoad() events.

- Specifying additional stylesheet themes to use.

The `jQuery()` view helper implementation, like its `dojo()` pendant, follows the placeholder architecture implementation; the data set in it persists between view objects, and may be directly echo'd from your layout script. Since views specified in a Zend_Layout script file are rendered before the layout itself, the `jQuery()` helper can act as a stack for jQuery statements and render them into the head segment of the html page.

Contrary to Dojo, themes cannot be loaded from a CDN for the jQuery UI widgets and have to be implemented in your pages stylesheet file or loaded from an extra stylesheet file. A default theme called Flora can be obtained from the jQuery UI downloadable file.

Example 2.1. jQuery() View Helper Example

In this example a jQuery environment using the core and UI libraries will be needed. UI Widgets should be rendered with the Flora thema that is installed in 'public/styles/flora.all.css'. The jQuery libraries are both loaded from local paths.

To register the jQuery functionality inside the view object, you have to add the appropriate helpers to the view helper path. There are many ways of accomplishing this, based on the requirements that the jQuery helpers have. If you need them in one specific view only, you can use the addHelperPath method on initialization of this view, or right before rendering:

    $view->addHelperPath('ZendX/JQuery/View/Helper/', 'ZendX_JQuery_View_Helper');

If you need them throughout your application, you can register them in your bootstrap file using access to the Controller Plugin ViewRenderer:

    $view = new Zend_View();
    $view->addHelperPath('ZendX/JQuery/View/Helper/', 'ZendX_JQuery_View_Helper');

    $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
    $viewRenderer->setView($view)
    Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);

Now in the view script we want to display a Date Picker and an Ajax based Link.

    <?= $this->ajaxLink("Show me something",
                        "/hello/world",
                        array('update' => '#content')); ?>

    <div id="content"></div>

    <form method="post" action="/hello/world">
    Pick your Date: <?= $this->datePicker("dp1",
                                          '',
                                          array('defaultDate' =>
                                                    date('Y/m/d', time()))); ?>
    <input type="submit" value="Submit" />
    </form>

Both helpers now stacked some javascript statements on the jQuery helper and printed a link and a form element respectively. To access the javascript we have to utilize the jQuery() functionality. Both helpers already activated their dependencies that is they have called `jQuery()->enable()` and `jQuery()->enableUi()`. We only have to print the jQuery() environment, and we choose to do so in the layout script's head segment:

    <html>
        <head>
            <title>A jQuery View Helper Example</title>
            <?= $this->jQuery(); ?>
        </head>

        <body>
            <?= $this->layout()->content; ?>
        </body>
    </html>

Although `$this->layout()->content;` is printed behind the `$this->jQuery()` statement, the content of the view script is rendered before. This way all the javascript onLoad code has already been put on the onLoad stack and can be printed within the head segment of the html document.

#### 2.2.1.1. jQuery NoConflict Mode

jQuery offers a noConflict mode that allows the library to be run side by side with other javascript libraries that operate in the global namespace, Prototype for example. The Zend Framework jQuery View Helper makes usage of the noConflict mode very easy. If you want to run Prototype and jQuery side by side you can call `ZendX_JQuery_View_Helper_JQuery::enableNoConflictMode();` and all jQuery helpers will operate in the No Conflict Mode.

Example 2.2. Building your own Helper with No Conflict Mode

To make use of the NoConflict Mode in your own jQuery helper, you only have to use the static method `ZendX_JQuery_View_Helper_JQuery::getJQueryHandler()` method. It returns the variable jQuery is operating in at the moment, either `$` or `$j`

    class MyHelper_SomeHelper extends Zend_View_Helper_Abstract
    {
        public function someHelper()
        {
            $jquery = $this->view->jQuery();
            $jquery->enable(); // enable jQuery Core Library

            // get current jQuery handler based on noConflict settings
            $jqHandler = ZendX_JQuery_View_Helper_JQuery::getJQueryHandler();

            $function = '("#element").click(function() '
                      . '{ alert("noConflict Mode Save Helper!"); }'
                      . ')';
            $jquery->addOnload($jqHandler . $function);
            return '';
        }
    }

#### 2.2.1.2. jQuery UI Themes

Since there are no online available themes to use out of the box, the implementation of the UI library themes is a bit more complex than with the Dojo helper. The jQuery UI documentation describes for each component what stylesheet information is needed and the Default and Flora Themes from the downloadable archive give hints on the usage of stylesheets. The jQuery helper offers the function `jQuery()->addStylesheet($path);` function to include the dependant stylesheets whenever the helper is enabled and rendered. You can optionally merge the required stylesheet information in your main stylesheet file.

#### 2.2.1.3. Methods Available

The `jQuery()` view helper always returns an instance of the jQuery placeholder container. That container object has the following methods available:

##### 2.2.1.3.1. jQuery Core Library methods

- `enable()`: explicitly enable jQuery integration.

- `disable()`: disable jQuery integration.

- `isEnabled()`: determine whether or not jQuery integration is enabled.

- `setCdnVersion()`: set the jQuery version that should be loaded from the Google Ajax Library CDN

- `getCdnVersion()`: get the current jQuery version that is set for CDN inclusion.

- `useCdn()`: Return true, if CDN usage is currently enabled

- `useLocalPath()`: Return true, if local usage is currently enabled

- `setLocalPath()`: Set the local path to the jQuery Core library

- `getLocalPath()`: If set, return the local path to the jQuery Core library

##### 2.2.1.3.2. jQuery UI Library methods

- `uiEnable()`: explicitly enable jQuery UI integration.

- `uiDisable()`: disable jQuery UI integration.

- `uiIsEnabled()`: determine whether or not jQuery UI integration is enabled.

- `setUiCdnVersion()`: set the jQuery UI version that should be loaded from the Google Ajax Library CDN

- `getUiCdnVersion()`: get the current jQuery UI version that is set for CDN inclusion.

- `useUiCdn()`: Return true, if CDN usage is currently enabled for jQuery UI

- `useUiLocal()`: Return true, if local usage is currently enabled for jQuery UI

- `setUiLocalPath()`: Set the local path to the jQuery UI library

- `getUiLocalPath()`: If set, get the local path to the jQuery UI library

##### 2.2.1.3.3. jQuery Helper Utility methods

- `setView(Zend_View_Interface $view)`: set a view instance in the container.

- `onLoadCaptureStart()`: Start capturing javascript code for jQuery onLoad execution.

- `onLoadCaptureEnd()`: Stop capturing

- `javascriptCaptureStart()`: Start capturing javascript code that has to be rendered after the inclusion of either jQuery Core or UI libraries.

- `javascriptCaptureEnd()`: Stop capturing.

- `addJavascriptFile($path)`: Add javascript file to be included after jQuery Core or UI library.

- `getJavascriptFiles()`: Return all currently registered additional javascript files.

- `clearJavascriptFiles()`: Clear the javascript files

- `addJavascript($statement)`: Add javascript statement to be included after jQuery Core or UI library.

- `getJavascript()`: Return all currently registered additional javascript statements.

- `clearJavascript()`: Clear the javascript statements.

- `addStylesheet($path)`: Add a stylesheet file that is needed for a jQuery view helper to display correctly.

- `getStylesheets()`: Get all currently registered additional stylesheets.

- `addOnLoad($statement)`: Add javascript statement that should be executed on document loading.

- `getOnLoadActions()`: Return all currently registered onLoad statements.

- `setRenderMode($mask)`: Render only a specific subset of the jQuery environment via ZendX_JQuery::RENDER_ constants. Rendering all elements is the default behaviour.

- `getRenderMode()`: Return the current jQuery environment rendering mode.

These are quite a number of methods, but many of them are used for internally by all the additional view helpers and during the printing of the jQuery environment. Unless you want to build your own jQuery helper or have a complex use-case, you will probably only get in contact with a view methods of these.

#### 2.2.1.4. Refactoring jQuery environment with setRenderMode()

Using the current setup that was described, each page of your website would show a different subset of jQuery code that would be needed to keep the current jQuery related items running. Also different files or stylesheets may be included depending on which helpers you implemented in your application. In production stage you might want to centralize all the javascript your application generated into a single file, or disable stylesheet rendering because you have merged all the stylesheets into a single file and include it statically in your layout. To allow a smooth refactoring you can enable or disable the rendering of certain jQuery environment blocks with help of the following constants and the `jQuery()->setRenderMode($bitmask)` function.

- `ZendX_JQuery::RENDER_LIBRARY`: Renders jQuery Core and UI library

- `ZendX_JQuery::RENDER_SOURCES`: Renders additional javascript files

- `ZendX_JQuery::RENDER_STYLESHEETS`: Renders jQuery related stylesheets

- `ZendX_JQuery::RENDER_JAVASCRIPT`: Render additional javascript statements

- `ZendX_JQuery::RENDER_JQUERY_ON_LOAD`: Render jQuery onLoad statements

- `ZendX_JQuery::RENDER_ALL`: Render all previously mentioned blocks, this is default behaviour.

For an example, if you would have merged jQuery Core and UI libraries as well as other files into a single large file as well as merged stylesheets to keep HTTP requests low on your production application. You could disallow the jQuery helper to render those parts, but render all the other stuff with the following statement in your view:

    $view->jQuery
         ->setRenderMode(ZendX_JQuery::RENDER_JAVASCRIPT |
                         ZendX_JQuery::RENDER_JQUERY_ON_LOAD);

This statement makes sure only the required javascript statements and onLoad blocks of the current page are rendered by the jQuery helper.

### 2.2.2. JQuery Helpers

#### 2.2.2.1. AjaxLink Helper

The AjaxLink helper uses jQuery's ajax capabilities to offer the creation of links that do ajax requests and inject the response into a chosen DOM element. It also offers the possibility to append simple jQuery effects to both the link and the response DOM element. A simple example introduces its functionality:

    <!-- Inside your View Object -->
    <div id="container"></div>
    <?= $this->view->ajaxLink("Link Name",
                              "url.php",
                              array('update' => '#container')); ?>

This example creates a link with the label "Link Name" that fires an ajax request to url.php upon click and renders the response into the div container "#container". The function header for the ajaxLink is as follows: `function ajaxLink($label, $url, $options, $params);` The options array is very powerful and offers you lots of functionality to customize your ajax requests.

Available options are:

Table 2.1. AjaxLink options

Option | Data Type | Default Value | Description
--- | --- | --- | ---
`update` | `string` | `false` | Container to inject response content into, use jQuery CSS Selector syntax, ie. "#container" or ".box"
`method` | `string` | `Implicit GET or POST` | Request method, is implicitly chosen as GET when no parameters given and POST when parameters given.
`complete` | `string` | `false` | Javascript callback executed, when ajax request is complete. This option allows for shortcut effects, see next section.
`beforeSend` | `string` | `false` | Javascript callback executed right before ajax request is started. This option allows for shortcut effects, see next section.
`noscript` | `boolean` | `true` | If true the link generated will contain a href attribute to the given link for non-javascript enabled browsers. If false href will resolve to "#".
`dataType` | `string` | `html` | What type of data is the Ajax Response of? Possible are Html, Text, Json. Processing Json responses has to be done with custom "complete" callback functions.
`attribs` | `array` | `null` | Additional HTML attributes the ajaxable link should have.
`title, id, class` | `string` | `false` | Convenience shortcuts for HTML Attributes.
`inline` | `boolean` | `false` | Although far from best practice, you can set javascript for this link inline in "onclick" attribute.

To enlighten the usage of this helper it is best to show another bunch of more complex examples. This example assumes that you have only one view object that you want to display and don't care a lot about html best practices, since we have to output the jQuery environment just before the closing body tag.

    <html>
        <head>
            <title>Zend Framework jQuery AjaxLink Example</title>
            <script language="javascript"
                    type="text/javascript"
                    src="myCallbackFuncs.js"></script>
        </head>

        <body>
            <!-- without echoing jQuery this following -->
            <!-- list only prints a list of for links -->
            <ul>
                <li>
                    <?= $this->ajaxLink("Example 1",
                                        "/ctrl/action1",
                                        array('update' => '#content',
                                              'noscript' => false,
                                              'method' => 'POST')); ?>
                </li>
                <li>
                    <?= $this->ajaxLink("Example 2",
                                        "/ctrl/action2",
                                        array('update' => '#content',
                                              'class' => 'someLink'),
                                        array('param1' => 'value1',
                                              'param2' => 'value2')); ?>
                </li>
                <li><?= $this->ajaxLink("Example 3",
                                        "/ctrl/action3",
                                        array('dataType' => 'json',
                                              'complete' => 'alert(data)')); ?>
                </li>
                <li><?= $this->ajaxLink("Example 4",
                                        "/ctrl/action4",
                                        array('beforeSend' => 'hide',
                                              'complete' => 'show')); ?>
                </li>
                <li>
                    <?= $this->ajaxLink("Example 5",
                                        "/ctrl/action5",
                                        array('beforeSend' =>
                                                'myBeforeSendCallbackJsFunc();',
                                              'complete' =>
                                                'myCompleteCallbackJsFunc(data);')); ?>
                </li>
            </ul>

            <!-- only at this point the javascript is printed to sreen -->
            <?= $this->jQuery(); ?>
        </body>
    </html>

You might have already seen that the 'update', 'complete', and 'beforeSend' options have to be executed in specific order and syntax so that you cannot use those callbacks and override their behaviour completely when you are using `ajaxLink()`. For larger use cases you will probably want to write the request via jQuery on your own. The primary use case for the callbacks is effect usage, other uses may very well become hard to maintain. As shown in Example Link 5, you can also forward the beforeSend/complete Callbacks to your own javascript functions.

##### 2.2.2.1.1. Shortcut Effects

You can use shortcut effect names to make your links actions more fancy. For example the Container that will contain the ajax response may very well be invisible in the first place. Additionally you can use shortcut effects on the link to hide it after clicking. The following effects can be used for callbacks:

- `complete` callback: 'show', 'showslow', 'shownormal', 'showfast', 'fadein', 'fadeinslow', 'fadeinfast', 'slidedown', 'slidedownslow', 'slidedownfast'. These all correspond to the jQuery effects fadeIn(), show() and slideDown() and will be executed on the container specified in `update`.

- `beforeSend` callback: 'fadeout', 'fadeoutslow', 'fadeoutfast', 'hide', 'hideslow', 'hidefast', 'slideup'. These correspond to the jQuery effects fadeOut(), hide(), slideUp() and are executed on the clicked link.

    <?= $this->ajaxLink("Example 6",
                        "/ctrl/action6",
                        array('beforeSend' => 'hide',
                              'complete' => 'show')); ?>

#### 2.2.2.2. jQuery UI Library Helpers

The jQuery UI Library offers a range of layout and form specific widgets that are integrated into the Zend Framework via View Helpers. The form-elements are easy to handle and will be described first, whereas the layout specific widgets are a bit more complex to use.

##### 2.2.2.2.1. jQuery UI Form Helpers

The method signature for all form view helpers closely resembles the Dojo View helpers signature, `helper($id, $value, $params, $attribs)`. A description of the parameters follows:

- `$id`: Will act as the identifier name for the helper element inside a form. If in the attributes no id element is given, this will also become the form element id, that has to be unique across the DOM.

- `$value`: Default value of the element.

- `$params`: Widget specific parameters that customize the look and feel of the widget. These options are unique to each widget and described in the jQuery UI documentation. The data is casted to JSON, so make sure to use the `Zend_Json_Expr` class to mark executable javascript as safe.

- `$attribs`: HTML Attributes of the Form Helper

The following UI widgets are available as form view helpers. Make sure you use the correct version of jQuery UI library to be able to use them. The Google CDN only offers jQuery UI up to version 1.5.2 since 1.6 is still in late-development.

- `autoComplete($id, $value, $params, $attribs)`: The AutoComplete View helper works since jQuery UI 1.6 and creates a text field and registeres it to have auto complete functionality. The completion data source has to be given as jQuery related parameters 'url' or 'data' as described in the jQuery UI manual.

- `colorPicker($id, $value, $params, $attribs)`: ColorPicker is available in jQuery UI since 1.6 and creates a text field that opens up a color picking tool when activated.

- `datePicker($id, $value, $params, $attribs)`: Create a DatePicker inside a text field. This widget is available since jQuery UI 1.5 and can therefore currently be used with the Google CDN. Using the 'handles' option to create multiple handles overwrites the default set value and the jQuery parameter 'startValue' internally inside the view helper.

- `slider($id, $value, $params, $attribs)`: Create a Sliding element that updates its value into a hidden form field. Available since jQuery UI 1.5.

- `spinner($id, $value, $params, $attribs)`: Create a Spinner element that can spin through numeric values in a specified range. This is set on top of a form text field and is available only since jQuery UI 1.6.

Example 2.3. Showing jQuery Form View Helper Usage

In this example we want to simulate a fictional web application that offers auctions on travel locations. A user may specify a city to travel, a start and end date, and a maximum amount of money he is willing to pay. Therefore we need an autoComplete field for all the currently known travel locations, a date picker for start and end dates and a spinner to specify the amount.

    <form method="post" action="bid.php">
        <label for="locaction">Where do you want to travel?</label>
        <?= $this->autoComplete("location",
                                "",
                                array('data' => array('New York',
                                                      'Mexico City',
                                                      'Sydney',
                                                      'Ruegen',
                                                      'Baden Baden'),
                                      'multiple' => true)); ?>
        <br />

        <label for="startDate">Travel Start Date:</label>
        <?= $this->datePicker("startDate",
                              '',
                              array('defaultDate' => '+7',
                                    'minDate' => '+7',
                                    'onClose' => 'myJsonFuncCechkingValidity')); ?>
        <br />

        <label for="startDate">Travel End Date:</label>
        <?= $this->datePicker("endDate",
                              '',
                              array('defaultDate' => '+14',
                                    'minDate' => '+7',
                                    'onClose' => 'myJsonFuncCechkingValidity')); ?>
        <br />

        <label for="bid">Your Bid:</label>
        <?= $this->spinner("bid",
                           "",
                           array('min' => 1205.50,
                                 'max' => 10000,
                                 'start' => 1205.50,
                                 'currency' => '€')); ?>
        <br />

        <input type="submit" value="Bid!" />
    </form>

You can see the use of jQuery UI Widget specific parameters. These all correspond to those given in the jQuery UI docs and are converted to JSON and handed through to the view script.

##### 2.2.2.2.2. Using an Action Helper to Send Data to AutoComplete

The jQuery UI Autocomplete Widget can load data from a remote location rather than from an javascript array, making its usage really useful. Zend Framework currently providers a bunch of server-side AutoComplete Helpers and there is one for jQuery too. You register the helper to the controller helper broker and it takes care of disabling layouts and renders an array of data correctly to be read by the AutoComplete field. To use the Action Helper you have to put this rather long statement into your bootstrap or Controller initialization function:

    Zend_Controller_Action_HelperBroker::addHelper(
        new ZendX_JQuery_Controller_Action_Helper_AutoComplete()
    );

You can then directly call the helper to render AutoComplete Output in your Controller

    class MyIndexController extends Zend_Controller_Action
    {
        public function autocompleteAction()
        {
            // The data sent via the ajax call is inside $_GET['q']
            $filter = $_GET['q'];

            // Disable Layout and stuff, just displaying AutoComplete Information.
            $this->_helper->autoComplete(array("New York", "Bonn", "Tokio"));
        }
    }

##### 2.2.2.2.3. jQuery UI Layout Helpers

There is a wide range of Layout helpers that the UI library offers. The ones covered by Zend Framework view helpers are Accordion, Dialog, Tabs. Dialog is the most simple one, whereas Accordion and Tab extend a common abstract class and offer a secondary view helper for pane generation. The following view helpers exist in the jQuery view helpers collection, an example accompanies them to show their usage.

- `dialog($id, $content, $params, $attribs)`: Create a Dialog Box that is rendered with the given content.on startup. If the option 'autoOpen' set to false is specified the box will not be displayed on load but can be shown with the additional `dialog("open")` javascript function. See UI docs for details.

- `tabPane($id, $content, $options)`: Add a new pane to a tab container with the given `$id`. The given `$content` is shown in this tab pane. To set the title use `$options['title']`. If `$options['contentUrl']` is set, the content of the tab is requested via ajax on tab activation.

- `tabContainer($id, $params, $attribs)`: Render a tab container with all the currently registered panes. This view helper also offers to add panes with the following syntax: `$this->tabContainer()->addPane($id, $label, $content, $options)`.

- `accordionPane($id, $content, $options)`: Add a new pane to the accordion container with the given `$id`. The given `$content` is shown in this tab pane. To set the title use `$options['title']`.

- `accordionContainer($id, $params, $attribs)`: Render an accordion container with all the currently registered panes. This view helper also offers to add panes with the following syntax: `$this->accordionContainer()->addPane($id, $label, $content, $options)`.

Example 2.4. Showing the latest news in a Tab Container

For this example we assume the developer already wrote the controller and model side of the script and assigned an array of news items to the view script. This array contains at most 5 news elements, so we don't have to care about the tab container getting to many tabs.

    <?= foreach($this->news AS $article): ?>
    <? $this->tabPane("newstab",
                      $article->body,
                      array('title' => $article->title)); ?>
    <?= endforeach; ?>

    <h2>Latest News</h2>
    <?= $this->tabContainer("newstab",
                            array(),
                            array('class' => 'flora')); ?>

Prev | Up | Next
Chapter 2. ZendX_JQuery | Home | 2.3. ZendX_JQuery Form Elements and Decorators