Добро пожаловать на форум PHP программистов!
За последние 24 часа нас посетили 17199 программистов и 1833 робота. Сейчас ищут 1717 программистов ...

Javascript support

Вернуться к: HTML_QuickForm2

Javascript support

Javascript support – Client-side validation and Javascript-backed elements

While HTML_QuickForm implemented client-side validation and provided several Javascript-backed elements, support for Javascript there was quite limited. Basically, all scripts were inlined and there were some rudimentary checks to prevent outputting the same (library) code twice.

This was addressed in HTML_QuickForm2, Javascript handled by the package is logically split into several parts:

  1. Libraries;

  2. Form setup code;

  3. Inline script.

A page containing two Javascript-backed forms will look like this:

 
...
[JS libraries used by form1 and form2]
...
[form1 html, including inline javascript]
[form1 setup code]
...
[form2 html, including inline javascript]
[form2 setup code]
...

An instance of HTML_QuickForm2_JavascriptBuilder takes care of libraries and setup code, inline code can be added using HTML_QuickForm2_Element_Script element.

The new approach allows keeping the code that does not change (libraries) in external files, instead of bloating the resultant HTML. If form's structure does not change either, generated form setup code may also be moved to an external file. Only code that changes from one request to the other (e.g. setting the element's value) has to be inlined.

There are currently two library files installed with the package:

quickform.js

Helper methods and validation library.

quickform-hierselect.js

Support functions for hierselect elements.

Human-readable versions of these files are installed into HTML_QuickForm2/js directory under PEAR's data_dir and minified versions are installed into HTML_QuickForm2/js/min. If you have trouble finding where data_dir is, you can use config-show command of PEAR installer.

There is also a dualselect.php example showing among other things how to create a custom element with an additional JS library.

Javascript builder class

HTML_QuickForm2_JavascriptBuilder is used together with renderers. Form Javascript is generated in the course of HTML_QuickForm2::render() call, so that call is mandatory if you are using Javascript in your form.

Javascript library files are registered via HTML_QuickForm2_JavascriptBuilder::addLibrary(). You will only need to call this directly if you create custom Elements or Rules or maybe want to override validation behaviour (see below). Correct $webPath and $absPath need to be provided so the builder class can generate both links to external files and inline code.

Form setup code usually contains client-side validation rules added with HTML_QuickForm2_JavascriptBuilder::addRule() and element setup code added with HTML_QuickForm2_JavascriptBuilder::addElementJavascript(), the latter dealing with event handlers necessary for element behaviour. For example, built-in Hierselect element adds onchange handlers for contained selects, onreset handler for a containing form and onload handler for window. Once again, you will only directly call addElementJavascript() if you are creating a custom element or want to add some custom setup code. You don't need to call addRule() at all, as it is done automatically if you added a Rule to an Element with HTML_QuickForm2_Rule::CLIENT flag set.

HTML_QuickForm2_JavascriptBuilder also contains a static helper method encode() which encodes a PHP value as a Javascript literal. This is similar to json_encode(), but does not enforce UTF-8 charset.

Outputting libraries

While form setup code and inline Javascript is automatically output when rendering a form, libraries are not output automatically. The main reasons for this are

  1. Links to the library files are usually placed in <head></head> section of HTML document, while renderer outputs only the form itself.

  2. If your page contains several forms, you'll only need to have one set of libraries for them. You may use the same instance of HTML_QuickForm2_JavascriptBuilder when rendering all forms.

There are two ways to include the library code in your page, both relying on HTML_QuickForm2_JavascriptBuilder::getLibraries():

  • Inline the libraries, including their contents into the page

    <?php
    require_once 'HTML/QuickForm2/Renderer.php';

    $renderer HTML_QuickForm2_Renderer::factory('default');
    $form->render($renderer);

    echo 
    $renderer->getJavascriptBuilder()->getLibraries(truetrue);
    echo 
    $renderer;
    ?>

  • Copy/symlink *.js files installed with the package to some directory under your website's document root and provide this information to JavascriptBuilder:

    <?php
    require_once 'HTML/QuickForm2/Renderer.php';
    require_once 
    'HTML/QuickForm2/JavascriptBuilder.php';

    $renderer HTML_QuickForm2_Renderer::factory('default');
    // Here '/path/to/libraries' is whatever directory available via HTTP you copied libraries to
    $renderer->setJavascriptBuilder(new HTML_QuickForm2_JavascriptBuilder('/path/to/libraries'));
    $form->render($renderer);

    // This will output necessary <script src="/path/to/libraries/..."></script> tags
    foreach ($renderer->getJavascriptBuilder()->getLibraries() as $link) {
        echo 
    $link "\n";
    }
    echo 
    $renderer;
    ?>

The latter approach is obviously recommended for production use.

Libraries should be output before forms and definitely before form setup code. Both inline scripts and form setup code can contain calls to library functions and changes to library properties.

Outputting form setup code

Form setup code is returned by HTML_QuickForm2_JavascriptBuilder::getFormJavascript(). This method is automatically called by built-in Renderers and thus the code is included in their output.

Note that HTML_QuickForm2's Javascript library does not use DOMContentLoaded event like jQuery and similar libraries do:

 $(document).ready(function() {     // some code that will be run when complete DOM tree is built });

Instead, form setup code is run immediately and should be output after the form, when form's DOM tree is already available.

Validation library description

Javascript code has API documentation comments that can be extracted with JsDoc toolkit. SVN checkout of HTML_QuickForm2 contains Phing build file for this.

All Javascript code defined in HTML_QuickForm2 lives in qf "namespace". Deeper namespaces are used to group related functionality.

qf.Map is a class for Hash Map data structure. It is used internally to store validation errors and Container values.

 var map = new qf.Map(); map.set('a key', 'a value'); alert(map.get('a key')); // a value alert(map.hasKey('another key') ? 'true' : 'false'); // false alert(map.length()); // 1  var map2 = new qf.Map({foo: 'foo value', bar: 'bar value'}); map.merge(map2); map.remove('foo'); alert(map.getKeys().join(', ')); // a key, bar alert(map.getValues().join(', ')); // a value, bar value map.clear(); alert(map.isEmpty() ? 'true' : 'false'); // true

qf.form namespace contains methods for getting and setting elements' values: qf.form.getValue(), qf.form.getSubmitValue() (shorthand qf.$v()), qf.form.getContainerSubmitValue() (shorthand qf.$cv()), qf.form.setValue().

Methods for handling CSS classes on elements live in qf.classes namespace: qf.classes.add(), qf.classes.remove(), qf.classes.has().

qf.events namespace contains helper methods for crossbrowser events support: qf.events.addListener(), qf.events.removeListener(), qf.events.fixEvent(). The latter is expected to be used in event handlers in the following way

 qf.Validator.submitHandler = function(event) {     event = qf.events.fixEvent(event);     // ... };

HTML_QuickForm2 does not contain a full-blown crossbrowser event library because it does not need one, the above are simple convenience methods. There are numerous well-known JS frameworks with good crossbrowser events support, use one if needed.

qf.rules and qf.elements namespaces are intended for rule implementations and element support methods, respectively. For example, Hierselect element puts its code into qf.elements.hierselect.

Client-side validation is performed by an instance of qf.Validator. Its constructor accepts DOM object of a form it needs to validate, sets up necessary event handlers on that object and adds itself as a validator property of it.

It is easiest to disable client-side validation for a form by clearing validator property from form's DOM object:

 document.getElementById(formId).validator = null;

qf.Validator exposes several methods which can be overriden to change the way validation results are presented to user:

onStart()

Called before starting the validation. May be used e.g. to clear the errors from form elements.

onFieldError()

Called on setting the element error.

onFieldValid()

Called on successfully validating the element.

onFormValid()

Called on successfully validating the whole form.

onFormError()

Called on failed form validation. List of errors is available in this.errors property, which is an instance of qf.Map.

These can be overriden either for a particular instance of qf.Validator or for all its instances if qf.Validator.prototype is changed.

For example, if you want to display a list of validation errors in an alert() (as was done in HTML_QuickForm and pre-0.6.0 HTML_QuickForm2) you can do the following:

 var form = document.getElementById(formId); form.validator.onFormError = function() {     alert('Invalid information entered:\n - ' +           this.errors.getValues().join('\n - ') +           '\nPlease correct these fields.'); }; // don't set errors on elements form.validator.onFieldError = function() {}; form.validator.onFieldValid = function() {};

If you want to disable submit button to prevent duplicate form submits:

 document.getElementById(formId).validator.onFormValid = function() {     document.getElementById(submitId).disabled = true; };



Вернуться к: HTML_QuickForm2

© 2024 «PHP.RU — Сообщество PHP-Программистов»
Главная | Форум | Реклама на сайте | Контакты VIP Сувениры
Разработка компании ODware