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: Zend_Form_Decorator_JsValidation Component Proposal

Proposed Component Name Zend_Form_Decorator_JsValidation
Developer Notes http://framework.zend.com/wiki/display/ZFDEV/Zend_Form_Decorator_JsValidation
Proposers [Jani Hartikainen]
Revision 1. April 8 2008 Initial proposal (wiki revision: 11)

Table of Contents

1. Overview

Zend_Form_Decorator_JsValidation will generate JavaScript validation rules based on Zend_Form elements' validators
The proposal will contain generic JavaScript code that can determine whether a Zend_Form is valid or not based on the generated rules

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

  • This component will generate client-side validation rules and code based on form element validators
  • This component will not require any JavaScript libraries outside the component's own code
  • This component will provide a method for easily adding your own JS-based validators for your own validators
  • This component will support multiple forms per page
  • This component will support modern browsers with up-to-date JS support.
  • This component will degrade gracefully, so users without JS support will still be able to work with the form

4. Dependencies on Other Framework Components

  • Zend_View_Helper_InlineScript
  • Zend_View_Helper_HeadScript
  • Zend_Form
  • Zend_Form_Element
  • Zend_Form_Decorator_Abstract
  • Zend_Form_Decorator_Form

5. Theory of Operation

Zend_Form_Decorator_JsValidation will be added as a decorator to a form.

When rendered, the decorator will generate some simple JavaScript objects with parameters for the validator script. It will also output code to register the validator as the form's onsubmit event handler.

The validator script will be a simple JavaScript function that will loop through all the form's validation rules and call appropriate validators. The validators will be JavaScript functions which perform the same things as their Zend_Validate_* versions.

All the JavaScript code will be namespaced under Zend so that it will not conflict with other JS code.

6. Milestones / Tasks

  • Milestone 1: [DONE] Create initial prototype
  • Milestone 2: [DONE] Prototype checked in SVN (look here)
  • Milestone 3: Refactor prototype to be more extensible and better encapsulated etc.

7. Class Index

  • Zend_Form_Decorator_JsValidation

8. Use Cases

UC-01

The simplest way to get this decorator running, without MVC or Layouts or anything else really. This approach is only useful for testing, though.

UC-02

Creating a custom validator in JavaScript

The above would be enough JavaScript to add support for your own MyNamespace_Validate_MyValidator validator.

If your own validator does not require any parameters, you don't need to change any PHP code. However, if it takes parameters, currently you can use this method to add it:

Then, instead of adding Zend_Form_Decorator_JsValidation to your form, add your own extended decorator.

9. Class Skeletons

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

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

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

    <p>The current implementation in SVN is usable. However, if you look at the JavaScript code, it only marks the background of invalid elements red and valid elements white. This is one thing where I would like to get some feedback from you:</p>

    <p>How should the component approach handling events like this? Should the user be provided with a method in the decorator or somewhere, which they can use to define their custom JavaScript callbacks for both valid and invalid fields?</p>

    <p>Another big questionmark is the event handling. The current code adds a simple inline onsubmit="..." handler to the form tag. I initially wanted to convert that to use some external handling, but realized it is not very easy to do without an external JS library that provides better event support. </p>

    <p>If you have any ideas for the above, or pretty much anything else, do tell <ac:emoticon ac:name="smile" /></p>

  2. Apr 17, 2008

    <p>Hi,</p>

    <p>I'm trying to use your svn code but if my form (extends Zend_Form) has displaygroup as an element your javascript generation stop and this error appear:</p>

    <p>Fatal error: Call to undefined method Zend_Form_DisplayGroup::getValidators() in C:\xampp\htdocs\alquiler\library\Topcar\Decorator\JsValidation.php on line 10</p>

    <p>which is the cause?</p>

    <p>Thanks a lot</p>

    1. Apr 18, 2008

      <p>I've committed a new revision of JsValidation.php to SVN which should fix this and a bug with validating forms with no names.</p>

      1. Apr 20, 2008

        <p>Thanks!!</p>

        <p>Works like a charm... I'm adapting this to work with jquery validate plugin.</p>

        <p>Regards</p>

  3. Apr 21, 2008

    <p>I have some problem using your script:</p>

    <p>First of all when I use additional Validator I got javascript error: Error: validator is not a function<br />
    Source File: http://..../js/Zend/Form.js<br />
    Line: 29</p>

    <p>To prevent it replace file Form.js to this code:</p>
    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    var Zend = Zend || { };
    Zend.Form = Zend.Form || { };

    Zend.Form.isValid = function(form)
    {
    var c = form.elements;

    var formName = (form.getAttribute('name'))
    ? form.getAttribute('name')
    : 'form';

    var rules = Forms[formName];
    var formValidates = true;

    for(var key in rules)
    {
    var element = form[key];
    var ruleset = rules[key];

    for(var i in ruleset)
    {
    var nameParts = ruleset[i].name.split('_');
    var validator = window[nameParts[0]];
    for(var j = 1, len = nameParts.length; j < len; j++)

    Unknown macro: { validator = validator[nameParts[j]]; }

    try {
    var elementValidates = validator(element.value, ruleset[i].parameters);

    if(elementValidates)

    Unknown macro: { element.style.backgroundColor = 'white'; }

    else

    Unknown macro: { element.style.backgroundColor = 'red'; formValidates = false; break; }

    }
    catch(err)

    Unknown macro: { continue; }

    }
    }

    return formValidates;
    }
    ]]></ac:plain-text-body></ac:macro>
    <p>Also I think it very uncomfortably when you render the form and additionally u must print echo $form->getView()<span style="text-decoration: line-through;">>headScript(); echo $form</span>>getView()->inlineScript(); so I added it to render method:</p>
    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
     public function render($content)
    {
    $this->_formName = $this->getElement()->getName();

    if(!$this->_formName)

    Unknown macro: { $this->_formName = 'zend_form_' . self}

    $content = preg_replace('/<form([^>]*)>/', '<form onsubmit="return Zend.Form.isValid(this)"$1>', $content);

    $this->_generateJavaScript();

    $view = $this->getElement()->getView();

    $view->headScript()>appendFile($this>_javaScriptPath . 'Zend/Form.js');
    $view->headScript()>appendFile($this>_javaScriptPath . 'Zend/Validate.js');

    return $view->headScript().$content.$view->inlineScript();
    }
    ]]></ac:plain-text-body></ac:macro>
    <p> Also it will be good not only painting the input but alert some error! Any idea???</p>

    1. Apr 22, 2008

      <p>You can define your custom validators in JS etc. so they will work without the error, but you're right - it should handle it with a try-catch to prevent the whole form from breaking. I have updated the code in SVN with the fix.</p>

      <p>What comes to your second problem, normally you would echo the headScript and inlineScript helper contents in your layout's head section, and I think the best way to include the scripts from the validation files is to link to the files using the script tag, as this will allow the client to cache them, speeding up future page loads.</p>

      <p>The final thing is still under construction, and I've been trying to gather ideas on how to best implement that - but as you can see, not much luck there yet. For now, I would suggest adding your own code to the part which highlights the fields in red.</p>

  4. Feb 27, 2009

    <p>I have done something similar but using a JQuery plugin.</p>

    <p>I have the same design problem regarding javascript generation. Which is you need to modify the decorator to support new Validator.<br />
    If think that it would be a great addition if a validator could return its properties through an hashtable. Don't really know if this could be supported by all kind of validator.<br />
    Or, maybe a pluging mecanism to register validation rules generator.</p>

    <p>Secondly, a good addition to your proposal would be to be able to pass error message.</p>

    <p>For client on error behavior, i think that this should be modified from javascript. Exposing a callback or whatever else which should be called when the validator return false.</p>

  5. Feb 08, 2011

    <p>Archiving this proposal, feel free to recover it when you want to work on it again. For more details see <a href="http://framework.zend.com/wiki/display/ZFDEV/Archiving+of+abandoned+proposals+(Feb+5+2011)">this email</a>.</p>