Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

Zend Framework: ZendX_JQuery UI Widgets View and Form Helpers Component Proposal

Proposed Component Name ZendX_JQuery UI Widgets View and Form Helpers
Developer Notes http://framework.zend.com/wiki/display/ZFDEV/ZendX_JQuery UI Widgets View and Form Helpers
Proposers Benjamin Eberlei
Zend Liaison TBD
Revision 1.0 - 17.08.2008: Initial Draft. (wiki revision: 6)

Table of Contents

1. Overview

The jQuery UI extension adds several view helpers and form elements, aswell
as a jQuery Form Extension that combines these elements that use the functionality
of the jQuery UI Widget Library.

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

  • MUST utilize the jQuery helper
  • SHOULD allow to specify all possible options of jQuery UI widgets
  • SHOULD offer both form and view helpers for usage
  • SHOULD match Dojo naming/functionality scheme as near as possible

4. Dependencies on Other Framework Components

  • ZendX_JQuery_View_Helper_JQuery
  • Zend_Form
  • Zend_View_Helper_HtmlElement

5. Theory of Operation

The jQuery UI Widget Library is a jQuery extension that offers a (currently)
small range of widgets for UI development, Accordion, DatePicker, Dialog,
Slider and Tabs. The development pace is very fast, and the next version
that includes new widgets (for example Autocomplete) is due to be released in the next
weeks. As development of jQuery UI goes on additional helpers and form
elements will be added.

This extension offers View helpers for all those widgets and integrates them
into the form building process. It uses the jQuery Helper to stack required javascript
code onto the jQuery onLoad stack. It can optionally use the Helpers
method to include the jQuery UI library from the Google CDN to simplify
the usage of the helpers.

The DatePicker Helper will be combined with Zend Translate and Zend Locale
to offer translated date naming strings and default date display format.

Accordion and Tabs will become Decorators to group form parts together.

Slider will be an additional input field works with a hidden field to
transport the chosen slider data.

Dialog will allow to render content in a Dialog box, which includes adding
forms to a dialog box, by default dialog opens on load. But it should also
be possible to combine it with events that are triggerd by css selectors.

Autocomplete will extend an input text field to offer auto complete functionality.

6. Milestones / Tasks

  • Milestone 1: Finish First Proposal
  • Milestone 2: Community Review
  • Milestone 3: Unit Tests that cover Use-Cases
  • Milestone 4: Implementation
  • Milestone 5: Full Unit-Test Coverage
  • Milestone 6: Documentation

7. Class Index

  • ZendX_JQuery_View_Helper_Accordion
  • ZendX_JQuery_View_Helper_Autocomplete
  • ZendX_JQuery_View_Helper_DatePicker
  • ZendX_JQuery_View_Helper_Dialog
  • ZendX_JQuery_View_Helper_Slider
  • ZendX_JQuery_View_Helper_Tabs
  • ZendX_JQuery_Form
  • ZendX_JQuery_Form_Element_Autocomplete
  • ZendX_JQuery_Form_Element_DatePicker
  • ZendX_JQuery_Form_Element_Slider
  • ZendX_JQuery_Form_Decorator_Accordion
  • ZendX_JQuery_Form_Decorator_Tabs
  • ZendX_JQuery_Form_Decorator_Dialog

8. Use Cases

I have a demo up and running of all current UI widgets, showing the PHP
code to initialize them: View Helpers Demo

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Aug 18, 2008

    <p>I'm not sure how you envision the autoComplete view helper to work, but right now I don't see how you can specify a default value. Considering that the auto complete widget essentially is a combo box, which is a more flexible version of the select box (even though technically it's implemented as text input box), and given the flexibility of the autocomplete widget (per <a class="external-link" href="http://docs.jquery.com/UI/Autocomplete/autocomplete#options">http://docs.jquery.com/UI/Autocomplete/autocomplete#options</a>) I think it would make sense to stick to the formSelect view helper syntax when it comes to specifying parameters.</p>

    <p>public function autoComplete($name, $value = null, $attribs = null, $options = null);</p>

    <p>Your UC-05 would look like this:</p>

    <p><?php $data = array('New York', 'Sydney', 'Berlin', 'London', 'Peking'); ?><br />
    <?php echo $this->autoComplete('accity1', '', null, array('data' => $data )); ?></p>

    <p><?php echo $this->autoComplete('accity2', '', null, array('url' => '/from/url')); ?></p>

    <p>It might also be a good idea to automagically encode the "extraParams" option values if it's an array, but leave as-is if it's a string.</p>

    <p>That way it is possible to specify something like this:</p>

    <p><?php echo $this->autoComplete('accity', 'New York', array('style' => 'background-color: #ffffe6;'), array('url' => '/cities/search', 'extraParams' => array('country' => 'US', 'ac' => true))) ?></p>

    <p>I'd expect that to build an auto complete widget named "accity", with a default value of "New York", a yellowish background color, fed by a remote resource with the two extra parameters. So if I typed "Los" into the box, it should fire off a request to "/cities/search?q=Los&country=US&ac=true".</p>

    <p>Thanks!</p>

    1. Aug 22, 2008

      <p>Hello Marcus,</p>

      <p>thanks for the suggestions. While trying to setup some first versions of the components I realized that the autoComplete helper had to be done the way you specified. The current function header<br />
      for the autocomplete function is now: autoComplete($id, $value, $ajaxOptions, $htmlAttribs);</p>

      <p>So you would specifiy $ajaxOptions<ac:link><ri:page ri:content-title="'url'" /></ac:link> or $ajaxOptions<ac:link><ri:page ri:content-title="'data'" /></ac:link> to setup the autoComplete<br />
      datasource.</p>

      <p>You can see this in the (new) UC-05 or the online demo: <a class="external-link" href="http://www.beberlei.de/jquery/demo/">http://www.beberlei.de/jquery/demo/</a></p>

      1. Aug 25, 2008

        <p>I dig the demo and how it generates a clean snippet of Javascript! Very cool!</p>

        <p>For consistency, I recommend keeping the parameters the same as the Zend_View_Helper_FormSelect helper. That way, switching from a FormSelect to a JQuery-based autocompletion form element is simply calling a different view helper with regards to the order of passing $options and $attribs.</p>

        <p>The current convention is also that your first parameter should be $name, rather than $id. They can be the same, but that is not necessarily the case.</p>

        <p>For instance, you could have multiple autocomplete widgets that have same name, say, "recipient[]", but different id attributes ("recipient1", "recipient2", etc). I'd expect to be able to achieve that with a call such as $this->autoComplete('recipient[]', $defaultvalue, array('id' => 'recipient1'), array('url' => '/users/search'));</p>

        <p>Logically, I think, a JQuery Autocomplete widget breaks down into a text box and the JQuery-based autocompletion "add-on". That said, you could simply extend Zend_View_Helper_FormText, and add in the JQuery functionality.</p>

        <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
        class ZendX_JQuery_View_Helper_AutoComplete extends Zend_View_Helper_FormText
        {
        public function autoComplete($name, $value = null, $attribs = null,
        $options = null)

        Unknown macro: { /* * Create the text box */ $xhtml = parent}

        }
        ]]></ac:plain-text-body></ac:macro>

        1. Aug 25, 2008

          <p>If you take it a step further, you could decouple things a bit more. By encapsulating all of the JQuery UI specific functionality in a JQueryUI view helper, you're allowing developers more flexibility, and the autoComplete() view helper becomes more of a convenience helper.</p>

          <p>The actual Javascript call to hook autocompletion into a form element is</p>
          <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[$('form_element_id').autocomplete(options);]]></ac:plain-text-body></ac:macro>
          <p>(Per <a href="http://docs.jquery.com/UI/Autocomplete/autocomplete#options documentation">http://docs.jquery.com/UI/Autocomplete/autocomplete#options documentation</a>). For that you just need the element id, and the options. That goes back to the original API that you had before the revision.</p>

          <p>Not sure on the capitalization at the moment, Jqueryui, JqueryUi. JQueryUI seems most natural. I'll use that. Someone please correct me.</p>

          <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
          class ZendX_JQuery_View_Helper_JQueryUI extends Zend_View_Helper_Abstract
          {
          /**
          *

          • @return ZendX_JQuery_View_Helper_JQueryUI
            */
            public function JQueryUI()
            Unknown macro: { return $this; }

          public function autocomplete($id, $options)
          {
          /*

          • Replace these cheap includes with something more sophisticated
          • This just demonstrates the dependency on the libs
            */
            $this->view->headScript()->appendFile('/includes/jquery-latest.min.js');
            $this->view->headScript()->appendFile('/includes/jqueryui-latest.min.js');

          // Treat $options here, encode as necessary

          // Render the javascript for autocomplete. Again, just for demonstration
          $this->view->appendScript("\$('{$id}').autocomplete(" . Zend_Json::encode($options) .');');

          return '';
          }
          }
          ]]></ac:plain-text-body></ac:macro>

          <p>With that in mind, you'd get an autocomplete view helper with something like this:</p>

          <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
          class ZendX_JQuery_View_Helper_AutoComplete extends Zend_View_Helper_FormText
          {
          public function autoComplete($name, $value = null, $attribs = null,
          $options = null)

          Unknown macro: { /* * Create the text box */ $xhtml = parent}

          }
          ]]></ac:plain-text-body></ac:macro>

          <p>The advantage is that if someone wants to use autocompletion with their own view helper, or directly in their view to modify an element they've previously created through other means, they're not left out in the cold:</p>
          <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
          <input type="text" name="q" id="search" value="Enter search term" />

          <?php echo $this->JQueryUI()->autocomplete('search', array('url' => '/some/url')); ?>
          ]]></ac:plain-text-body></ac:macro>

          <p>Even though ZendX_JQuery_View_Helper_JQueryUI::autocomplete() doesn't return any output, i'd still echo the return value since there was some discussion going on regarding letting the jquery view helper return inline javascript through a configuration option.</p>

          <p>Anyway, just a thought.</p>

          <p>Thanks!</p>

          1. Aug 25, 2008

            <p>Talking about consistency, i choose to take the Dojo Helper argument layout, which is organized as $id, $value, $options, $params (for all the other helpers too). Which one is "better"? On $id i also followed the Dojo helpers closely. I am not sure what to make out of it, maybe some Zend advice?</p>

            <p>I like your suggestion to use the formText as parent and will look into it (also for the Spinner and DatePicker this might be the way to go).</p>

            <p>The idea of splitting jQuery and Form Code looks good also but maybe for this use cases shown in your last code snippet you might already write the javascript on your own again? I guess the helper is not designed to take everything from you, just the most likely use cases. Also your class "ZendX_JQuery_View_Helper_JQueryUI" does not seperate concerns, you would have to add a function for each UI Widget and its bad to extend on your own.</p>

            <p>Separating this leads to having 2 helpers for each UI Widget, the HTML and the JS one and having helpers to generate you just one simple line of javascript (jQuery isnt overly complex) is maybe a bit overkill?</p>

            1. Aug 25, 2008

              <p>I just looked at the Dojo helper layout (hadn't considered that before). A bit odd that they decided to squeeze the $params in there like that. The $id parameter documentation also says it's an int, although that's probably just an oversight. Beats me. But that really bugs me now. Would be great to get some feedback from someone more involved with those components.</p>

              <p>With regards to the separation of concerns, I figured the JQueryUI view helper is responsible for simply generating the required javascript snippets and, for instance, the autoComplete helper is responsible for generating the html portion and hooking the two together.</p>

              <p>I just looked at how Dojo works overall, and most of the magic happens in Zend_Dojo_View_Helper_Dijit, which is also the class all the Dijits extend. Zend_Dojo_View_Helper_Dojo worries about managing the javascript files (handled in Zend_Dojo_View_Helper_Dojo_Container). So that's sliced a bit differently, although the view helper example at <a class="external-link" href="http://framework.zend.com/manual/en/zend.dojo.view.html#zend.dojo.view.dojo">http://framework.zend.com/manual/en/zend.dojo.view.html#zend.dojo.view.dojo</a> looks like it's got some invalid html (dojoType attribute?).</p>

              <p>Some more brainstorming: It looks like most of the JQuery UI components are very consistent: $("#element").method(options). So you could technically provide a simple magic interface using __call().</p>

              <p>How about this (quick'n'dirty):</p>

              <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[

              class JQueryUI
              {
              public function __call($method, $args)
              {
              if (count($args == 2))

              Unknown macro: { $cssquery = $args[0]; $options = $args[1]; return "$('$cssquery').$method(" . Zend_Json}

              }
              }

              $jq = new JQueryUI(); echo $jq->autocomplete('#search', array('url' => '/some/url'));

              ]]></ac:plain-text-body></ac:macro>

              <p>As soon as Zend_Json has support for Zend_Json_Expr you're done.</p>

              <p>Okay, that's obviously not the whole answer, but maybe something can be derived from that.</p>

          2. Sep 04, 2008

            <p>Regarding the jQuery Helpers attribute layout: It will exactly match the Dojo Layout in the final implementation for consistency, even if its not consitent with the basic helpers.</p>

  2. Sep 04, 2008

    <ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Comments</ac:parameter><ac:rich-text-body>
    <p>We approve this proposal for immediate development in the extras/incubator, with the following feedback:</p>
    <ul>
    <li>Use the method name "addPane()" in both Accordion and Tabs for consistency within the offering as well as consistency with conventions set in Zend_Dojo</li>
    <li>Add a Pane view helper and form decorator to use with Accordion and Tabs for creating the panes used with them. This will allow forms to be decorated with Accordion, and sub forms with Pane.</li>
    <li>Add capturing ability to Accordion, Tabs, and Pane.</li>
    <li>As noted privately, keep the method parameter order as used with the Zend_Dojo view helpers<br />
    Excellent proposal!</li>
    </ul>
    </ac:rich-text-body></ac:macro>

  3. Sep 26, 2008

    <p>I'd like to see the ability to adjust the HTML Markup on the accordionContainer somehow. ie:<br />
    either through the settings or through methods.</p>

    <p>There's the _elementHtmlTemplate which I think could be set via a method, or have the ability to <br />
    set the accordion group tag, accordion header tag, and the accordion content tag.</p>

    <p>Just an idea there..</p>

  4. Oct 26, 2008

    <p>I have difficulties finding the new location of updated documentation of this extension.</p>

    <p>For example, this signature has apparently changed:<br />
    <?= $this->datePicker("date1", "2008/17/08", array(), array("class" => "beautify")); ?></p>

    <p>Should now be called as:<br />
    <?= $this->datePicker("date1", array('value' => "2008/17/08", "class" => "beautify", 'label' => 'myDate')); </p>

    <p>This may not be the appropriate place to note this kind of things, a link to recently updated documentation would be very much appreciated.</p>