Zebra_Form, a jQuery augmented PHP library for creating and validating HTML forms

Get the latest updates on this PHP library via RSS

Zebra_Form, a jQuery augmented PHP library for creating and validating HTML forms

Zebra_Form is a PHP library that simplifies the process of creating and validating HTML forms. Its object-oriented structure promotes rapid HTML forms development and encourages developers to write clean and easily maintainable code. It frees the developers from the repetitive task of writing the code for validating forms by offering powerful built-in client-side and server-side validation.

Zebra_Form has integrated cross-site scripting (XSS) prevention mechanism that automatically strips out potentially malicious code from the submitted data, and also features protection against cross-site request forgery (CSRF) attacks. It also prevents automated SPAM posts, out of the box and without relying on CAPTCHA by using honeypots.

Forms layout can be generated either automatically or manually – using templates. When generated automatically, the generated output validates as HTML 4.01 Strict, XHTML 1.0 Strict or HTML5, and has the same look & feel across all major browsers like Firefox, Chrome, Opera, Safari and Internet Explorer 6+.

It provides all the controls you’d expect in an HTML form and, additionally, date/time pickers, CAPTCHA and advanced AJAX-like file upload controls – see the documentation for validation rules that can be used out of the box.

The client-side validation is done using jQuery 1.5.2+

Zebra_Form‘s code is heavily commented and generates no warnings/errors/notices when PHP’s error reporting level is set to E_ALL.


Features review

  • provides protection against cross-site scripting (XSS) and cross-site request forgery (CSRF) attacks out of the box
  • it automatically prevents automated SPAM posts using the “honeypot” technique (CAPTCHAs can also be used for even stronger protection)
  • provides both server-side and client-side validation (client-side validation is done using jQuery 1.5.2+) and has a lot of predefined rules that can be used out of the box; custom validation rules (including AJAX-based) can easily be added
  • forms’ layout can be generated either automatically or manually using templates
  • generated output validates as HTML 4.01 Strict, XHTML 1.0 Strict or HTML5
  • works in all major browsers like Firefox, Chrome, Opera, Safari and Internet Explorer 6+
  • code is heavily commented and generates no warnings/errors/notices when PHP’s error reporting level is set to E_ALL
  • has comprehensive documentation


PHP 5.2.0+ (preferably PHP 5.3.0 compiled with the “fileinfo” extension for more secure file uploads – read more at the change log for version 2.7.3)

jQuery 1.5.2+



Download the latest version, unpack it, and put it in a place accessible to your scripts.


How to use

Live demos



<!-- must be in strict mode! -->
<!DOCTYPE html>



        <title>Zebra_Form Example</title>

        <meta charset="utf-8">

        <!-- load Zebra_Form's stylesheet file -->
        <link rel="stylesheet" href="path/to/zebra_form.css">

        <!-- load jQuery -->
        <script src="path/to/jquery.js"></script>

        <!-- load Zebra_Form's JavaScript file -->
        <script src="path/to/zebra_form.js"></script>



    <!-- the PHP code below goes here -->





// include the Zebra_Form class
require 'path/to/Zebra_Form.php';

// instantiate a Zebra_Form object
$form = new Zebra_Form('form');

// the label for the "email" field
$form->add('label', 'label_email', 'email', 'Email');

// add the "email" field
$obj = $form->add('text', 'email', '', array('autocomplete' => 'off'));

// set rules

    // error messages will be sent to a variable called "error", usable in custom templates
    'required'  =>  array('error', 'Email is required!'),
    'email'     =>  array('error', 'Email address seems to be invalid!'),


// "password"
$form->add('label', 'label_password', 'password', 'Password');

$obj = $form->add('password', 'password', '', array('autocomplete' => 'off'));


    'required'  => array('error', 'Password is required!'),
    'length'    => array(6, 10, 'error', 'The password must have between 6 and 10 characters'),


// "remember me"
$form->add('checkbox', 'remember_me', 'yes');

$form->add('label', 'label_remember_me_yes', 'remember_me_yes', 'Remember me');

// "submit"
$form->add('submit', 'btnsubmit', 'Submit');

// validate the form
if ($form->validate()) {

    // do stuff here


// auto generate output, labels above form elements


Live demos



version 2.9.4

If you find this library to be useful to you, you can support the author by donating a small amount via PayPal:

Zebra_Form is distributed under the LGPL.

In plain English, this means that you have the right to view and to modify the source code of this software, but if you modify and distribute it, you are required to license your copy under a LGPL-compatible license, and to make the entire source code of your derivation available to anybody you distribute the software to.

You also have the right to use this software together with software that has different licensing terms (including, but not limited to, commercial and closed-source software), and distribute the combined software, as long as state that your software contains portions licensed under the LGPL license, and provide information about where the LGPL licensed software can be downloaded.

If you distribute copies of this software you may not change the copyright or license of this software.

You may also like:



Documentation Become a ninja.
Read the comprehensive documentation.



Click on a version to expand/collapse information.

version 2.9.4 (August 23, 2013)
  • fixed a bug where submitted values were passed through PHP’s “htmlentities” function only if the element’s “disable_xss_filters” property was not set to TRUE, potentialy leading to some strange things when used together with some WYSIWYG editors;
  • fixed a bug where setting the “datecompare” rule to a date element would clear the default value (if any); thanks Edward;
  • fixed a bug dating back to June 02, 2011 (!) from when I ported the client-side validation from MooTools to jQuery and which broke the “emails” (with an “s”) rule; thanks to Edward;
  • fixed a bug with the caching of the captcha image; thanks Sebastian Popa;
  • the clientside_validation method now has a new property called “disable_upload_validation” which can be used for disabling any client-side processing of file upload controls; useful for using custom plugins to handle file uploads; thanks Ssekirime for suggesting;
  • changed how placeholders, prefixes and character counters are positioned and these are now relative to the parent element;
  • added lots of new mime types to the mimes.json file
  • corrections in the documentation, related to the “date” element; thanks Edward;
  • added Catalan language file; thanks WaKeMaTTa;
  • updated Zebra_DatePicker to version 1.8.4; this brings 1 new method called “show_select_today” and changes the name of the “always_show_clear” method to “show_clear_date”; see the documentation for the date element; also, this also changes the caption of the “Clear” button to “Clear date” and brings a new entry in the language file for the “Today” button;
  • the project is now available on GitHub and also as a package for Composer
version 2.9.3b (June 04, 2013)
  • fixed an issue introduced in the latest release that made radio buttons and checkboxes to never pass validation; thanks to Alex Alexandrescu;
version 2.9.3 (June 02, 2013)
  • because I couldn’t find a stable fix, I reverted the change done in 2.8.1 (!) regarding how file upload works, as that affected too many users; the downside (if you can call it that way) is that the upload path is now only checked upon submit and not when selecting a file; also, upload path must be once again be specified as relative to the currently running script;
  • fixed a bug where the client-side’s “on_ready” callback was executed too soon; thanks Cesar Perales;
  • fixed a bug where the library would trigger an error message if the “additional_characters” argument of the “alphabet”, “alphanumeric”, “digits”, “float” or “number” rule would contain a “/” (slash) character; thanks Oliver Jones;
  • fixed an issue where, if client-side validation was disabled, the associated JavaScript code was still placed inside the generated output; thanks Arne Tarara;
  • fixed a bug where dates not having days or months in format (like “m, Y”) would not pass server-side validation; thanks to martin;
  • fixed a bug where the Zebra_Form_Button class was creating an <input type=”submit”> instead of <input type=”button”>; thanks to KennyG;
  • fixed a bug where if a textbox had the label inside and also had a prefix, the label was overlapping the prefix;
  • fixed a bug where when using the “convert” rule, the generated file names would be wrong;
  • fixed a bug where the “convert” rule was not deleting the original file if the type of the new file was different than the original file, even if the “preserve_original_file” was explicitly set to false;
  • fixed a bug where when the “convert” and “resize” rules were not working if the upload path set for the “upload” rule was not having a trailing slash;
  • fixed a bug where the “date” attribute of a “date” element was invalid if the format had only years or years+months;
  • fixed a bug where setting the “pair” attribute of a date element was not working as expected; thanks to Edward;
  • fixed some inconsistencies in the documentation; thanks KennyG;
  • fixed a bug where the “attach_tip” method, in JavaScript, was not working as expected; thanks Cesar Perales
  • improved some areas of the documentation;
  • updated Zebra_DatePicker to version 1.7.7; this also brings 3 new methods for the “date” element: enabled_dates, show_other_months and select_other_months;
version 2.9.2 (April 18, 2013)
  • fixed a bug introduced in the previous release that broke functionality in IE8 and below…yes, I forgot a console.log() in the code!
  • fixed a bug where the “image” control would not have the “alt” attribute set, and so the resulting HTML could not be validated by the W3C validator;
  • fixed a bug where the iFrame used for checking uploaded files client-side was sometimes be visible on IE8 and below;
  • changed how the upload path needs to be specified for the “upload” rule, which now needs to be a full web path (so not server path nor a relative path) and “process.php” and the “_upload” method in Zebra_Form.php will automatically determine the correct server path to where to upload the files to; hopefully this will solve the problems people were having; still, being behind a reverse-proxy will require manual adjustment of the logic used both in “process.php” and in the “_upload” method in “Zebra_Form.php”;
  • the “dependencies” rule now also supports “submit” buttons/images; see the example for a scenario where it makes sense;
  • removed the * (all) selector from CSS and now custom elements placed in both custom and auto-generated templates don’t suffer from it;
  • the “attach_tip” JavaScript method can now be used on any element, not just on those that already have rules attached;
  • clientside_validation method has a new “on_ready” property used for specifying a JavaScript function to be executed when the form is ready; useful for getting a reference to Zebra_Form object *after* it’s ready – see the documentation for an example;
  • updated Spanish language file; thanks WaKeMaTTa;
version 2.9.1 (March 10, 2013)
  • dropped support for PHP4; minimum required version is now PHP 5.0.2;
  • fixed some compatibility issues affecting the “dependencies” rule when used with radio buttons and jQuery 1.9.0+;
  • added support for date picker’s “always_show_clear” and “always_visible” properties; thanks to Sebastian Popa;
  • fixed a bug where the script would sometimes fail to determine the correct path for file uploads; thanks to John Prentice;
  • fixed a bug where dates having random extra white-space in them would pass validation; thanks to Arne Tarara;
  • fixed a bug where setting the “require_protocol” argument of the “url” rule to TRUE, had no effect client-side; thanks Stefan;
  • fixed an error in the documentation; thanks Stefan;
  • fixed a small bug where when specifying custom attributes for an element as a string rather than an array, would trigger a PHP warning; thanks Søren;
  • fixed a small issue with the file uploads where the content of the iFrame used for the client-side validation was destroyed before being fully loaded, resulting in a “Canceled” status rather than a 200 (OK); this was not affecting functionality;
version 2.9.0a (February 13, 2013)
  • fixed a bug where disabling weekdays resulted in date to never pass validation;
version 2.9.0 (February 10, 2013)
  • fixed a few depencies related bugs; thanks to Arne Tarara
  • fixed an issue that broke the library’s functionality when using jQuery 1.9.0 (which removed $.browser);
  • fixed a bug where date format not including days or month (like only ‘Y’ or ‘M, Y’, etc) would never pass validation; thanks to Hicham;
  • fixed a bug where the “Clear” button on the date picker was not using the string from the language file; thanks Nicola Tuveri;
  • fixed an issue where the library would break with plugins that hide the original elements and put in their places divs having the exact same classes as the original element; thanks to Daniele Picca
  • fixed a bug where the “length” rule was not taken into consideration when using “auto_fill” for elements having also the “digits” and/or “number” rule set;
  • fixed a bug where if the “length” rule had a fourth argument (the show_counter argumet), the error message would be empty;
  • fixed a bug where a text longer than set by the “length” rule could be set as default for an element;
  • fixed a bug in “process.php” which broke CAPTCHA images in PHP 5.4.0+ because the second argument to the “imagejpeg” function was an empty string instead of “null”; thanks to Thomas;
  • fixed an issue where elements having an empty string as name could be created;
  • fixed an issue where the library would sometimes generate “strict warnings” for PHP 5.3.0+;
  • custom attributes (like class names or other attributes) can now be specified when creating bulk radio buttons and checkboxes by adding a 4th argument; see the last example in each of the two links;
  • added Italian language file; thanks Nicola Tuveri;
  • updated German and French language files; thanks Andreas Schwarz;
  • some updates and corrections in the documentation; thanks to Hicham, Søren and Oliver Jones;
  • updated Zebra_DatePicker to version 1.6.7;
version 2.8.9e (January 17, 2013)
  • fixed a bug where dependencies were working only if the proxy element was a radio button or a checkbox; set thanks to Hicham;
version 2.8.9d (January 15, 2013)
  • fixed a bug where setting some of the date control’s properties would break the date picker; thanks to Bastian Flinspach;
  • fixed a bug where seting the “length” rule to having “0” (no limit) as the upper limit, would set the element’s “maxlength” attribute to “0”; thanks to Bastian Flinspach;
  • fixed a bug where keypress events on an file upload control were ignored;
  • fixed a bug where the “clientside_validation” method was always using the default values if the form contained at least one file upload control; thanks to Antonio Marmolejo;
  • fixed a bug where the character count on textareas was not done correctly if the text contained characters that would get transformed into HTML entitite; thanks to Antonio Marmolejo
  • fixed some inconsistencies in the documentation;
  • updated Zebra_DatePicker to version 1.6.6;
version 2.8.9c (January 12, 2013)
  • fixed a bug where custom arguments for the “custom” rule were not passed correctly;
  • fixed a bug where dependencies on an element with no other rules would be ignored;
  • updated Zebra_DatePicker to version 1.6.5;
version 2.8.9b (January 10, 2013)
  • fixed a bug where since the last release the files upload control was not working anymore;
  • fixed a bug where the library would trigger a JavaScript error if none of the form’s element would have any validation rule;
  • some updates in the documentation
version 2.8.9 (January 08, 2013)
  • added a new rule called “dependencies”; using it you can now have conditional validation (elements that are validated only if one or more other controls have certain values); see the example and peek into the documentation;
  • for browsers that obey the “accept” attribute for file upload controls (at the time of writing Chrome 16+ and IE 10), the file browser will now only show the files defined by the “filetype” rule or images only if the “image” rule is set;
  • added a new method: auto_fill – call this method to instruct the library to automatically fill out all or only selected form’s fields with random content while obeying any rules that might be set for each control – huge time saver for when debugging forms; check out the example;
  • added a new method: captcha_storage by which the storage method for CAPTCHA values can be changed from “cookie” to “session”; useful for users who have very restrictive cookie policies;
  • uneditable prefixes can now be added to text and password inputs – like “http://” or an area code like “+(40)”, or images and html; check out the examples and the documentation;
  • users can now regenerate CAPTCHAS if needed; see the examples;
  • previously, server-side, dates where only checked for format but not also for direction and disabled dates so malicious users could manipulate the DOM and enter out-of-range values; now the validity of date values is also enforced server-side;
  • fixed a bug where the placeholder, if the element had margins, would not be correctly positioned; thanks to Faton Sopa;
  • fixed a bug where having elements with names representing array properties in JavaScript (length, constructor, prototype) would result in error messages not showing for that particular element in client-side validation;
  • fixed a bug which I thought it was fixed in 2.8.3 regarding the order in which rules are checked;
  • fixed a bug where when having “validate_on_the_fly” for client-side validation and moving away from a date control without selecting a date, would correctly show the error tip with the message, but the error would not automatically go away when selecting date, and the user would manually need to hide the error message;
  • fixed a bug in the CSS affecting notes placed after a date control on Internet Explorer 7;
  • fixed a bug where when using placeholders for textareas the “resize” icon (on browsers that automatically place it on textareas) would appear twice; thanks to Andrei Bodeanschi
  • fixed a bug where having an error message on select control with the “other” option selected, the error message would not automatically disappear once the “other” field was filled out;
  • fixed a WebKit-specific issue where Chrome & Safari seem to get it wrong for password fields when using various font families, and display really small dots instead of the discs that appear for every other browser – now WebKit browsers will behave as expected;
  • updated Zebra_DatePicker to version 1.6.4;
version 2.8.8 (November 08, 2012)
  • fixed a bug where the library would think that an & directly before a character is an HTML entity, and would incorrectly insert a semicolon after the “entity”; thanks to Arne Tarara
  • fixed a bug where for PHP versions prior to 5.2.0 the library would trigger an error when trying to set the CSRF cookie; thanks to hector;
  • fixed a bug where custom arguments were never actually passed to custom rules; thanks to Andreas;
  • fixed a bug where in PHP versions before 5.3 using a hyphen (dash) as among the extra allowed characters in the “alphabet”, “alphanumeric”, “float”, “digits”, “number”, rule would crash the script; thanks to Andreas
  • fixed an issue where a hack was needed in order for displaying SPAM or CSRF errors in custom templates; now a new $zf_error variable will be available in custom templates which will display these errors (in the same way as it errors are displayed after server-side validation); see an example in the documentation (the second code block); thanks to Thomas;
  • fixed an issue where assigning custom classes to elements upon adding them to the form (through the add() method) would break those elements as the custom class would replace the classes added by the library; the solution was to add custom classes through the set_attributes() method; now adding custom classes directly via the add() method will work as expected; thanks to Wim;
  • fixed a bug when reporting some internal errors;
  • added a new validation rule: “url” which validates URLs; see the documentation for more information;
  • inverted the order of the first two arguments of the csrf() method – if you are using the method, make sure you update the arguments order after updating Zebra_Form!
  • minor performance tweaks in the PHP code
  • updated Spanish language file; thanks to Delegado 3iti
  • updated Zebra_DatePicker to version 1.6.1
version 2.8.7 (September 15, 2012)
  • fixed a bug with the file upload control where client-side validation would correctly report an invalid upload path *only* if the “required” rule was also set; now, when uploading a file, the library will check if the upload path exists even if the “required” rule is not set; thanks to Jan;
  • fixed a bug where if the form was validated and submitted manually through JavaScript, the library would validate the form twice; also, updated the recommended way of doing manual form validation and submission – see documentaion;
  • fixed an issue where no custom HTML attributes (like “style”, for example) could be set for the select boxes generated by the Time control; thanks to Faton Sopa;
  • custom date pickers can now also be used; to disable the default date picker you’ll have to call the newly added disable_zebra_datepicker() method available for “date” elements; date format, direction and disabled dates will still apply and will be taken into account when validating the date, but the other properties will be ignored as are specific to Zebra_DatePicker; thanks to Faton Sopa for suggesting;
  • better error handling and documentation for when the library is trying to use cookies for storing the CSRF token, but output was already sent to the browser prior to instantiating the library, and output buffering is turned off in php.ini;
  • in previous versions, when using “horizontal” templates and, thus, tables, I was using the deprecated “valign” attribute on table cells and so the generated output was not valid HTML5; now it is handled from CSS by using “vertical-align”; thanks to Andreas;
  • additions and corrections to the documentation; thanks to Jan for spotting some errors!
version 2.8.6 (August 13, 2012)
  • fixed a bug where having the ‘other’ option set for select controls having non-numerical values, would result in the form never passing validation; thanks to Edward;
  • fixed a bug where for select boxes having non-numerical indices, a malicious user could submit other values than those defined when creating the form; thanks to Edward;
  • fixed a bug with the XSS cleaner, which apeared since the update in 2.8.4; thanks to Dimitri;
  • updated Zebra_DatePicker to version 1.4.1
version 2.8.5 (July 23, 2012)
  • fixed a bug where file controls were *always* requried even if the “required” rule was not set; thanks Andre
  • fixed a few bugs related to the generation of the CSRF token where the token was always generated with the default values and was re-generated each time the csrf() method was called;
  • the library will now automatically decide what method to use for storing the CSRF token (session or cookie) in so that if a session is already started it will store the token in session or in a cookie otherwise; thanks to PunKeel for the heads up;
  • the “render” method now accepts an optional third argument for bulk variable assignment (representing a quicker method than using the old “assign” method for each variable); thanks to serge.munoz
version 2.8.4 (July 19, 2012)
  • added protection against cross-site request forgery (CSRF) attacks; the protection is enabled by default, but offers a lower level of security as it is based on session cookies (cookies that expire when the browser is closed) rather than on PHP sessions – this is intentional so that it doesn’t interfere with your environment in case you don’t use sessions. Therefore, you are encouraged to use PHP sessions and to call the newly added csrf() method and properly configure your protection against CSRF attacks, in order to maximize the level of security of your forms.
  • fixed a few bugs related to the date control; thanks Jack Everson
  • fixed a bug where setting “validate_all” to true would have no effect; thanks Thomas
  • hopefully the bug where sometimes error messages remained stuck and could not be closed anymore, is now fixed;
  • placeholders now clone the parent element’s styles (padding, border, font style, font weight, font size)
  • previously when “scroll_to_error” was set to TRUE the page would scroll to the element.top – 10px which meant that the element in question was always too close to the top edge of the screen; now the library tries to scroll so that the element is vertically centered in the view port
  • updated the part of the library taking care of cross site scripting (XSS) prevention as per the latest developments in CodeIgniter (as that particular piece of code is taken from the CodeIgniter PHP framework)
  • all error messages now correctly report the file name and the line that caused the error; PHP’s trigger_error() shows the file and the line number where the function is called and we would always trigger the errors from one of the Zebra_Form’s file when the errors actually generate from user files;
  • hidden fields used by the library internally were previously available in the $_POST superglobal after submission and now are automatically stripped out so that we don’t pollute the $_POST;
  • the minimum required PHP version is now 4.3 instead of 4.2
  • there are some additions to the language files and if you speak one of the languages there i’d be thankful if you could provide some translations. thank you!
version 2.8.3 (July 08, 2012)
  • fixed a bug where using the “digits” rule in a form having – (dashes) in its name would crash the script;
  • fixed a bug where previously *all* the rules were checked in the order defined when creating the form, potentially leading to nonsense situations like having the “filetype” or “filesize” rules before the “upload” rule, or any other rule before the “required” rule; now, the “required” rule is *always* checked first, and the “upload” rule is *always* checked first if there is no “required” rule, or second if the “required” rule is set; thanks Ovidiu Mihalcea
  • fixed a bug where the developer could forget to set the “upload” rule for a file upload control; now, failing to do so will result in an error
  • fixed a bug where the file upload control was not working in IE7; thanks to Ovidiu Mihalcea
  • fixed a bug where the “required” rule could not be set for “time” controls; thanks to Adrian North
  • fixed a bug where not selecting an option for a select box having the “multiple” attribute set, but no “required” rule, would trigger the spam filter; thanks to Faton Sopa
  • fixed a bug where labels inside text boxes were vertically centered only for the default size of the controls; this behavior could be observed when setting different heights or padings for the text boxes;
  • fixed a bug where if the process.php and mimes.json files could not be found by the script, the developer would not be able to set the correct paths through the assets_path() method, as the script was looking for those files in the constructor, and hence would break execution before executing anything else; thanks to Ovidiu Mihalcea;
  • fixed a bug where the script would not be able to determine the paths to process.php and mimes.json files if PHP’s “allow_url_fopen” was not set to true; thanks to Andrei Bodeanschi;
  • fixed a bug where file upload controls were submitted in the background on the “onchange” event even when the “upload” rule was not attached; also, the library will now trigger an error if a file upload control doesn’t have the “upload” rule attached;
  • by default, for check boxes, radio buttons and select boxes, the library will prevent the submission of other values than those declared when creating the form, by triggering the error: “SPAM attempt detected!”; therefore, if you plan on adding/removing values dynamically, from JavaScript, you will have to call the newly added disable_spam_filter() method – available for check box, radio button and select box elements – to prevent that from happening;
  • a new property of Zebra_Form is now available: “file_upload_permissions” which can be used to set the filesystem permissions for uploaded files;
  • 12 hour format can now also be used for the “time” control; thanks to Marty
  • changed the name of the “first_day_of_the_week” method (available for the “Date” control) to “first_day_of_week”; thanks to Edward for the feedback
  • default padding for text boxes, text areas, passwords and selects was changed from “padding: 4px 3px 3px” to “padding: 5px” (in zebra_form.css) thus slightly increasing their size; note that this might break your layout, so be careful and change it back if it does so;
  • updated Zebra_DatePicker to version 1.4
  • most examples were updated
  • some corrections and additions to the documentation;
version 2.8.2 (May 11, 2012)
  • the upload rule now has also a client-side validation side, where it checks if the indicated path exists and is writable
  • fixed a bug for file uploads where, if the name of the uploaded file was too long, the “x” for canceling was not visible anymore
  • fixed a bug where, after selecting a file, by clicking very close to the file’s name, users could open the file picker again, resulting in bogus visuals
  • fixed a bug which made the file name not to appear for an upload control having “upload” as the sole attached rule
  • updated Zebra_DatePicker to version 1.3.2
  • fixed a bug where setting the first day of week as anything other than Monday was not working; all credit goes to Edward!
version 2.8.1 (April 07, 2012)
  • elements can now be validated “on-the-fly” where an element is validated as soon as it looses focus; use the newly added “validate_on_the_fly” flag for the “client_side_validation”; thanks to François Rigaudie and Konstantin Stoyanov
  • all error messages can now be shown on form submit rather than only the first one; use the newly added “validate_all” flag for the “client_side_validation”; thanks to François Rigaudie and Konstantin Stoyanov;
  • file names can now be prefixed with a given string when uploading files (using the “upload” rule); thanks to Robert Warelis;
  • the library now triggers an error message if a “date” control doesn’t have the “date” rule set. note that this rule cannot be set automatically since it requires an error message to be set by the developer. thanks to bastian;
  • the “length” rule, set with the 4th argument to TRUE, will now always show the character counter; previously, the character counter was shown only if the lower limit was 0. thanks to Andy Vogar;
  • fixed a bug in the JavaScript code regarding the file upload control which was not working with jQuery UI. thanks to edward for fixing it;
  • fixed a bug where validation would fail if there were two or more file upload controls on a form. thanks to edward for fixing it;
  • fixed a bug where the class for disabled control was not correctly applied;
  • updates in documentation
  • updated Zebra_DatePicker to version 1.3.1
version 2.8 (March 10, 2012)
  • fixed a bug where the attach_tip() JavaScript method was not working properly; thanks to Andrei Bodeanschi
  • previously, the placeholders were injected to the bottom of the main document rather than right after the parent element and thus generating issues like placeholder remaining visible when hiding the parent element’s container; now the placeholders are injected in the DOM right next to the parent element;
  • fixed a bug where because of the fact that JavaScript and PHP treat new lines, accented characters and special characters differently (1 byte in JavaScript and 2 or 3 bytes in PHP), server-side validation of a maximum allowed length would sometimes fail if a textarea’s value would contain new lines, although client-side validation was ok; thanks to Andrei Bodeanski for spotting it;
  • fixed a bug where setting the “readonly_element” property to FALSE on a date element had no effect; thanks to bastian
  • fixed a bug where a date element’s “get_date” method was triggering a warning if the the element was not required and no date was selected; thanks to bastian
  • the “length” rule now accepts a 5th argument instructing the script to show a counter of remaining characters;
  • added a new method available for text, textarea and password controls, called change_case which can be used to instruct the script to force all letters typed by the user, to either uppercase or lowercase, in real-time;
  • added documentation on how to access the Zebra_Form object in JavaScript, with examples;
  • added documentation on how to use AJAX in custom validations (scroll down to the “custom” rule and keep reading);
  • tweaked the default CSS style of the date control which was a bit too short;
  • updated Zebra_DatePicker to version 1.2
version 2.7.7 (January 18, 2012)
  • fixed a bug that made disabling dates impossible; thanks to Andrei Bodeanschi
  • fixed a bug with the “convert” rule that made it always delete the converted image immediately after conversion, if the “overwrite” argument was set to TRUE
  • added albanian translation; thanks to Faton Sopa
version 2.7.6b (December 06, 2011)
  • fixed a bug where placeholders (labels used as “hints” inside text/password/textarea controls) would not follow their parent control upon resizing the browser window;
  • sometimes error messages get stuck and cannot be closed; although I couldn’t find the root of the problem I’ve done some tweaks and it seems to be working a bit better now (especially error messages related to file upload controls). the whole logic around error messages needs to be rewritten tough, as I realized that there are some faulted approaces there.
version 2.7.6 (December 06, 2011)
  • fixed a bug that appeared since the last version that made file uploads to never pass validation
version 2.7.5 (November 20, 2011)
  • fixed a bug where using multiple forms on a single page would disable client-side validation for all forms but the first one; thanks to Pedro Abreu for reporting;
  • fixed a bug where if there were selection groups in a select, it would never pass validation;
  • fixed a bug where placeholders (labels as hints inside textboxes and textareas) were not working on textareas; thanks to Chris for reporting it a long time ago and to Andrei Bodeanschi for recently reminding me about it;
  • elements that have display:none or visibility:hidden are no longer checked in the client-side validation process;
  • the Zebra_Transform plugin is not included anymore in the library; it can be downloaded and used separately from here if needed; as a result, the form’s fancy_form() method is also gone;
  • some additions to documentation;
version 2.7.4 (September 27, 2011)
  • fixed another bug that would make date validation impossible in certain scenarios;
  • minor updates to the JavaScript code;
version 2.7.3 (September 16, 2011)
  • fixed a bug where dates having the day < 10 would not pass validation; thanks to Dev for reporting;
  • fixed a bug where Zebra_TransForm was incorrectly initialized and was transforming controls on the entire page rather than just the current form’s controls
  • fixed a bug that made impossible to set custom classes for the actual <form> tag, through the form’s constructor method; thanks to Sebi Popa for reporting;
  • fixed a bug that would cause the script to trigger a warning when a select control would have [] (square brackets) in its name but the multiple attribute was not also set;
  • fixed an issue that allowed malicious users to submit arbitrary values instead of the ones defined at the form’s creation, for select controls, checkboxes and radio buttons; the severity of the issue was low as the submitted values were still filtered for cross-site scripting (XSS) attempts, so no real harm could be done; thanks for PunKeel for reporting;
  • previously, the library would rely on information available in the $_FILES super-global for determining an uploaded file’s mime type, which, as it turns out, is determined by the file’s extension, representing a potential security risk; now, for PHP versions 5.3.0+ compiled with the “php_fileinfo” extension, the uploaded file’s mime type is determined using PHP’s finfo_file function; thanks to DaveK for reporting;
  • now the script throws a JavaScript error if the JavaScript function required by a custom validation doesn’t exists; previously, it would silently ignore the fact;
  • updated the Zebra_DatePicker to version 1.1.2
  • updated documentation to reflect the recent changes in the Zebra_Image library
version 2.7.2 (August 29, 2011)
  • fixed a bug in the date picker’s JavaScript code regarding event delegation that would crash the script in certain scenarios; thanks to Sebi Popa for spotting it!;
version 2.7.1 (July 30, 2011)
  • fixed a bug where date would never validate for languages other than English; thanks to alfred;
  • the form now completely adheres to http://www.w3.org/TR/WCAG20-TECHS/H44.html which requires that all controls have an associated label; previously, the honeypot element did not have an associated label. thanks to Alexis;
  • minor optimizations in the PHP code;
  • some clarifications in the documentation regarding the “resize” rule;
version 2.7 (July 19, 2011)
  • added a new validation rule called filetype; with this rule one can restrict the types of files that are upload-able by specifying a list of allowed file extension; it’s important to note that validation is not done by file extension but by the MIME type of the uploaded files; for this, a new file is available in the root of the library called mimes.json containing the currently supported extensions and associated MIME types;
  • the library now makes use of the Zebra_TransForm jQuery plugin to replace radio buttons, check boxes and select boxes with nicer ones; see the newly added “fancy_form” method for configuration;
  • due to popular request CAPTCHA images are now easier to read;
  • if the script was run on a virtual host, it could not correctly determine the path to the “process.php” file (this file is used for validating uploads client-side and for CAPTCHAs);
  • fixed a bug that would break the file upload control when the form name had dashes in it (i.e. “my-form”); thanks to MarcosBL;
  • fixed a bug that was introduced in the previous version that made disabling the client-side validation impossible;
  • fixed a bug that caused the name of the uploaded file to appear in the wrong position;
  • fixed a bug where the “date” control’s “get_date” method was returning a string enclosed in an array rather just the plain string;
  • fixed a bug where the “date” control’s “direction” method was not working when using “false” as argument;
  • some clarification in the documentation regarding the upload rule;
  • some clarification in the documentation regarding the set_attribute method; thanks to Jack Ryan;
  • added French language file; thanks to Sébastien GASTARD;
  • added German language file; thanks to Chris Banford;
version 2.6.1 (July 01, 2011)
  • fixed a bug where the settings for client-side validation would get reset if a file upload control was added to the form. thanks to kszys for reporting.
  • fixed a bug where the client-side validation would crash when the format of the date contained day names or month names. thanks to Chris for reporting.
  • fixed a bug where determining the path where the library is located (for executing the process.php file required for AJAX-like uploads) was not working for certain configurations. thanks to kszys for helping.
  • fixed a bug that would crash the script if date format would contain “/” (slashes) – thanks to Jack Ryan for reporting
  • fixed a bug where the length rule was tested even if the element had no value nor was the required rule set. unless the required rule is set, the length rule is not to be tested as long as there is no value entered.
  • additions to the documentation of radio buttons and checkboxes. thanks to kszys the suggestion.
  • additions to the documentation of the “upload” rule where it is now stated that after the rule is run, the DOM element the rule is attached to will get an attribute called file_info which will contain information about the uploaded file, usable in the JavaScript part of a custom function.
  • Spanish language file added – thanks to José Machado for providing it
version 2.6 (June 24, 2011)
  • fixed a bug that broke the “resize” rule (thanks to jose for reporting)
  • added an extra example for the “resize” rule on how to create multiple sizes of an uploaded image by using the resize rule.
version 2.5 (June 21, 2011)
  • fixed a bug where the labels inside controls were not working in Internet Explorer prior to 9
  • corrected the documentation about how to access the JavaScript object (thanks to Jonathan Kratzke for reporting)
version 2.4 (June 20, 2011)
  • fixed a bug where the regexp rule was not working if the regular expression contained parentheses (thanks to Sebi Popa and to Dragos Oancea for reporting)
version 2.3 (June 19, 2011)
  • fixed a few bugs related the “date” control (thanks to Jack Ryan for reporting)
  • fixed a bug that affected file upload validation
version 2.2 (June 11, 2011)
  • fixed a bug where, for custom validations, the JavaScript function was not getting any additional arguments except the element’s value (thanks to Robert Grzesinski for reporting)
  • fixed a bug where the “date” control would add an invalid attribute to the element that would cause the generated output not to pass the W3C validation
  • fixed a bug where in the newest versions of PHP 5 the script would generate “PHP Strict Standards” notices because of how mktime() (with no arguments) and array_shift() is treated in these versions
  • some documentation updates and clarifications (thanks to Andrei Bodeianschi for suggesting some of those)
version 2.1 (June 02, 2011)
  • ported the client-side validation to jQuery
  • the “date” control has some new methods thanks to the integration with the Zebra_Datepicker jQuery plugin
  • regardless of the format used for a date, the submitted date can now easily be retrieved in YYYY-MM-DD format for use with a database or with PHP’s strtotime function by using the newly added get_date() method;
  • Zebra_Form was not working if the jQuery was loaded at the end of the page (thanks to Sebi P for reporting)
  • fixed a bug with custom validation rules
  • fixed a bug with “selects” having the “other” option set
version 2.0 (April 10, 2011)
  • added client-side validation. requires MooTools 1.2.5+
  • added automatic handling of file uploads. the script can now automatically upload files to a specified folder. it can also automatically check for valid image files, permitted file size and it can also automatically resize uploaded images (requires the Zebra_Image class)
  • a new method is now available: reset() which clears the values of all the form’s controls
  • added a new control type: “time”; this outputs a time picker
  • controls now have rounded corners (in browsers that support CSS3) and have a :hover state
  • infinite levels of nested option groups can now be created for “select” controls (until now, only one level could be created);
  • select controls now have a default, language dependent, “- select -” option
  • select controls can now have a new attribute: “other”. when set, a text box control will be automatically created having the name “[control_name]_other” (where [control_name] is the name of the select box). the text box will be hidden until users select the automatically added “Other…” option from the selectable options.
  • dropped XTemplate templating engine in favor of pure PHP templating
  • the generated HTML validates as HTML 4.01 Strict. If you want it to validate as XHTML 1.0 Strict use the newly added doctype() method
  • access keys can now be set for labels
  • added a bunch of new validation rules
  • improved CAPTCHA control
  • a new “control” is available – you can now add “notes” (information boxes telling the users what they are expected to enter/select in a field) in the same way as adding “labels”
  • fixed a bug regarding XSS prevention
  • fixed a bug where the “number” rule would not allow the input of negative numbers
  • fixed a bug where the “compare” rule would validate when the values was compared to that of a nonexisting control
  • fixed a bug where option groups couldn’t be created for the “select” control
  • fixed a bug that appeared since the last release that caused emails to never pass validation
  • fixed a bug that would not render the captcha image on some systems
  • many documentation refinements
version 1.2 (September 22, 2008)
  • a new feature has been added: automatic output generation. if your form does not need any special output format, you can simply call the render() method without specifying a template name to let the script handle it, thus saving you some time as you are not needed to also code the form’s layout.
  • a new type of controls has been added: “html”. with this you can insert arbitrary HTML code into your forms. This is usefull when you don’t use templates but rather let the script generate your forms and you need to have some extra HTML in your forms (notes, descriptions, etc) – because letting the script to automatically generate your forms means that you don’t have a template to insert your HTML code into
  • arrays of custom rules can now be set for controls; up until now, only one custom rule per control could be set
  • generated forms are now (more) W3C compliant
  • CAPTCHA is now case insensitive
  • default template is now nicer
  • better error reporting
  • fixed a few minor bugs
  • many documentation refinements
version 1.1.1 (May 08, 2008)
  • rewritten css for the default template
  • fixed a bug where submitting array-like controls (multiple checkboxes with sharing the same name or a “select” control with “multiple” set) would crash the script
  • fixed a bug where submitting text fields with empty spaces would pass the validation for “required” fields
  • fixed a bug where the captcha image was not updated upon submission
  • upon submission, all characters were transformed to their applicable html entities, which could cause a lot of headaches if you were submitting text in other language than english
version 1.1 (December 03, 2007)
  • added *heavy* XSS (cross site scripting) injection prevention (the class used for filtering for XSS injection is the Input class from the CodeIgniter PHP framework
  • previously some accented characters got scrambled upon submission as htmlentities() was being called without the UTF-8 argument
  • fixed an error where, when having multiple forms on a page, all forms were processed upon submission
version 1.0 (June 02, 2007)
  • trying to change the main template of the class had no effects
  • the class was not working correctly in PHP 4.x.x
  • fixed an error where using a nonnumeric index for the first element in a “select” control (indicating the “nothing selected” condition of the control) would lead to a crash
  • added validation rule for a list of comma separated email addresses
  • many people have asked for it so i’ve added an example on how to use the radio controls, the checkbox controls and on how to do quick custom validations
  • multiple instances of the form could not be created on the same page
  • error messages can now be customized from the main template (the one in the /templates folder) – thanks to Claude Quezel for suggesting
  • custom blocks can now be parsed in the form’s template by using the newly added “parseBlock” method
  • the “addOptions” method of the “select” control was overwriting any previously set options. now subsequent calls to this method will append options to the existing ones
  • custom form actions can now be specified – previously, forms were always submitted to themselves
  • a new property was added: “locked”. by default, when a form is reloaded after a submission, all the controls will have their respective submitted value, while the default value set by user will be ignored. setting this property to TRUE, will make the controls preserve their user-provided default values, ignoring the submitted value
  • previously, only variables could be passed to the addVar method. now strings and constant can also be passed
  • multiple options can now be preselected for select controls having the “multiple” attribute set (read the documentation for the constructor of select controls) – this one was actually working just wasn’t documented. thanks to sridhar for reporting
  • in order to make the generated output valid XHTML 1.0, the label controls no longer have the “name” attribute and the form has now the “action” attribute set; also the “selected” attribute is now correctly set for “select” ontrols (thanks to Claude Quezel)
  • made some changes in the main template’s CSS file, provided by Claude Quezel, that makes the fieldsets look in the same way in Firefox and Opera as in IE – thanks!
  • on some PHP installations file upload was not working (enctype and max_file_size were not being set)
version 1.0 BETA 3 (February 17, 2007)
  • for the “select” control, if options were specified having literal keys and the “required” rule was set, the control would never pass validation (thanks to sridhar for reporting)
  • a major security issue was fixed where an attacer could inject arbitrary HTML and/or JavaScript code along with the submitted data. now all the submitted data is passed through the htmlentities() function and, if magic_quotes are on, are stripslashed (thanks to Bartosz for reporting)
  • file uploads were not working because neither “enctype” nor MAX_FILE_SIZE were set upon the rendering of the form
  • if you would set a checkbox’s state as “checked” by default, any subsequent submits would set the checkbox’s value to “checked” even if user would uncheck it (thanks to sridhar for reporting)
  • “required” rule could not be set to the “file” control (thanks to sridhar for reporting)
  • a new method was added: “addVar()”. through this method, user defined variables can be made accessible from within the form’s template file
  • added a new control: “captcha” which generates CAPTCHA images
  • password controls no longer re-display the entered value
version 1.0 BETA 2 (January 05, 2007)
  • fixed various bugs in code, example and documentation;
  • in Firefox, trying to open the date picker would produce a JavaScript error;
  • the icon for opening the date picker was not visible in Firefox;
version 1.0 BETA (December 19, 2006)
  • initial release;


1291 responses to “Zebra_Form, a jQuery augmented PHP library for creating and validating HTML forms”

Follow the comments via RSS
  • John Monahan, 2014-10-10, 01:16

    This rocks!

    Is there a way to “inject” HTML into a form? For instance, I need to add “steps” and make a wizard. The library I’m using needs the tag.

    Just trying to think of how to use Zebra_Form to do it.

    Thanks for this great library!!! :-)

    • Stefan Gabos, 2014-10-13, 18:36

      There’s no “automatic” way other than using custom templates

  • Shaun, 2014-10-16, 12:17

    Good day,

    Thank for this awesome class

    I get the following error when I use multiple custom rules

    In the documentation it state you can use multiple custom rules
    ‘custom’ => array(
    array($callback_function_name1, [optional arguments to be passed to the function], $error_block, $error_message),
    array($callback_function_name1, [optional arguments to be passed to the function], $error_block, $error_message)


    in my php script

    ‘custom’ => array(
    array(‘test1′,$i,’error’,’Program moet ingelees word!’),
    array(‘test2′,$i,’error’,’Program is alreeds ingelees!’),

    then I get the following error

    Notice: Array to string conversion in C:\xampp\htdocs\check_db_data\Zebra_Form.php on line 3110

    Fatal error:

    Function Array() doesn’t exist.

    Any help please.


  • Stone, 2014-10-22, 13:37

    G’day Stefan,

    We just built your zebra_form library into an application, and it’s doing a good job for us.

    Thank you very much.

    However, you have a small logic error in your javascript which causes your addition of the highlight class on focus not to work for any fields where you subsequently add a Zebra_Form_Wrapper to an element.

    You need to move the code stub…

    — snip begins —

    // if a parent element having the "row" class exists
    if (parent.length)

    // bind these events to the element

    // when the element receives focus
    // add the "highlight" class to the parent element
    'focus': function() { parent.addClass('highlight') },

    // when the element receives focus
    // remove the "highlight" class from the parent element
    'blur': function() { parent.removeClass('highlight') }


    — snip ends —

    …to *after* the code you use to add wrappers. Otherwise the highlight class is not correctly added to the containing row on focus.

    You can see this problem on your own demo at…


    The background highlight is not correctly applied to the 2 top fields on focus which are wrapped in Zebra_Form_Wrapper, although the background highlight is applied to the third field on focus because it is not wrapped.

    We’ve patched the code at our end so it works correctly, but I thought you may want to make the small correction to your release version too.

    Thanks again.

    Best regards,


    • Stefan Gabos, 2014-10-22, 23:18

      Thanks! It is now fixed in the repository also

  • Stone, 2014-10-23, 09:38

    G’day Stefan,

    Apart from resorting to a custom template, does your code currently provide the ability to programmatically group a number of consecutive related fields within the one … structure?



    • Stone, 2014-10-23, 09:41

      Sorry, the editor removed my code. The … refers to a div class=”row” structure.

    • Stefan Gabos, 2014-10-27, 11:45

      Nope, can be done only with custom templates…which is not a bad thing :)

  • Honza Hommer, 2014-10-26, 19:59

    Hi Stefan,
    thanks for library. I have few questions:

    – Do you plan modify your library for Twitter Bootstrap 3 stylesheet?
    – It’s possible to have more than one form on one page? In my case the 2nd form submit not working.
    – It’s possible to wrap some input by div without creating custom template?


    • Stefan Gabos, 2014-10-27, 11:45

      - Yes
      – Yes, you must be doing something wrong (like both form having the same name and/or controls with the same name)
      – Nope

Leave a Reply

Your email address will not be published
You can use <strong>, <em>, <a>, <img>, <code>
Characters are not case-sensitive