LOGIC Library

This site is the Logic involvement in sharing expertise and skills acquired in daily work. The goal is to create a solid knowledge base and share best practices in software development and systems management.

More info about us can be found on logicsistemi.it.

Joomla! 2.5 form validation - part 3

It's time to complete our validation example by managing the required attributes server side and by adding custom validation rules server and client side.

Server side custom rule

In the previous part we talk about the rule class and how specific classes are derived from it by setting the regex attribute or by overriding the test method.

We try now to write our class to validate the amount field. Let's write some code that check that it's a positive number lower than 1000. This could be done using only a regular expression, but for completeness, we override alse the test method.

We start by creating a new file, called amount.php and by putting it in the root folder of our module. This is the code to write inside it:

<?
class JFormRuleAmount extends JFormRule
{
    protected $regex = '^[0-9]*$';
    public function test(&$element, $value, $group = null, &$input = null, &$form = null)
    {
        // If the field is empty and not required, the field is valid.
        $required = ((string) $element['required'] == 'true' || (string) $element['required'] == 'required');
        if (!$required && empty($value)) {
            return true;
        }
        // Test the value against the regular expression.
        if (!parent::test($element, $value, $group, $input, $form)) {
            return false;
        }
	  // Lower than 1000
        if ($value >= 1000) {
	    return false;
        }
        
        return true;
    }
}

The code is simple. We define the regular expression needed to validate the fieldy setting the regex attribute and we write some custom test method that performs these actions:

  • if the field is empty and not required it's valid
  • the field must match the regular expression
  • the value must be lower thant 1000

If you can use only the regular expression to validate the field, you don't need to override the test method.

Activating the custom rule

To put our custom rule to work, we have to instruct our module where to search it.

This is the first part of the base module code rewritten to load the custom class, and to take care of the required attributes.

<?php
	defined ( '_JEXEC' ) or die ( 'Restricted access' );
	
	JHtml::_('behavior.formvalidation');
	$msg = "";
	$msg_class = "";
	if ($_REQUEST["validatedform"] == "submit") {
		$msg_class = "message";
		
		$arrValidation["name"]["required"] = "true";
		$arrValidation["email"]["validate"] = "email";
		$arrValidation["amount"]["validate"] = "amount";
				
		$valid = true;
		JFormHelper::addRulePath(dirname(__FILE__));
		foreach ($_REQUEST["jform"] as $name => $value) {
			if (isset($arrValidation[$name])) {
				if (isset($arrValidation[$name]["validate"])) {
					$rule = JFormHelper::loadRuleType($arrValidation[$name]["validate"], true);
				
					// Run the field validation rule test.
					$test = $rule->test($arrValidation[$name], $value);
					
					if ($test == false) {
						$valid = false;
						$msg .= "<br />" . $name . " is invalid";
					}
				} else {
					if (isset($arrValidation[$name]["required"])) {
						if (($arrValidation[$name]["required"] == "true") && !$value) {
							$valid = false;
							$msg .= "<br />" . $name . " is required";
						}
					}
				}
			}
		}
		
		if ($valid) {
			$msg = "Data saved!";
		} else {
			$jform_name = str_replace("\"", "&quot;", $_REQUEST["jform"]["name"]);
			$jform_email = str_replace("\"", "&quot;", $_REQUEST["jform"]["email"]);
			$jform_amount = str_replace("\"", "&quot;", $_REQUEST["jform"]["amount"]);
			$msg = "Error validating fields: " . $msg;
		}
	}

The most important thing to note is the following instruction:

JformHelper::addRulePath(dirname(__FILE__));

It tells to the Joomla! Engine where to look for additional classes. By default rules classes are searched in the SITE_ROOT/library/joomla/form/rules folder. This instruction tells the engine to search them also in our module folder.

Dealing with required attributes

Required attributes are already checked in the different rule classes and also in our custom rule. The problem with these attributes is when no validation rule is specified for a field (such as for our name field).

In these cases no check is performed agaist them, so we have to write some code to deal with this problem. If you look at the previous PHP code, you notice that, in the case no validation rule is specified we perform a custom check agaist required values. This should do the trick.

Client side validation

The last thing to add is the client side validation corresponding to the amount custom rule.

This is very easy to perform: just write a custom Javascript file with the validation code and add it to the module with a script tag.

This is the code to put in amount.js file:

window.addEvent('domready', function() {
    document.formvalidator.setHandler('amount',
        function (value) {
            if (value != "") {
                if (!value.match(/^[0-9]*$/g)) {
                    return false;
                } else {
                    if (eval(value) >= 1000) {
                        return false;
                    }
                }
            }
            return true;
    });
});

The code use the mootools library to extend the validation for the amount class.

The required check is already performed by the formvalidator, so we also have to test the regular expression and the maximum limit.

To add it to the page we use the addScript method of the document object. In this way the script is added to the top of the page. The same approach can be take for the myValidate function.

Here is the second part of the base module code, with the required HTML:

	$js_path = JURI::root(true) . "/modules/mod_validatedform"; 

$document =& JFactory::getDocument();
     $document->addScript($js_path . "/amount.js"); if ($msg_class != "") { ?> <script language="javascript"> function myValidate(f) { if (document.formvalidator.isValid(f)) { return true; } else { var msg = 'Some values are not acceptable. Please retry.'; alert(msg); } return false; } </script> <div id="system-message-container"> <dl id="system-message"> <dd class="<?=$msg_class?> message"> <ul> <li><?=$msg?></li> </ul> </dd> </dl> </div> <? } ?> <form name="formvalidator" method="post" action="<?=$_SERVER["REQUEST_URI"]?>" class="form-validate" onSubmit="return myValidate(this);"> <input type="hidden" value="submit" name="validatedform" /> <fieldset> <legend>Validated form</legend> <dl> <dt> <label for="jform_name">Name:</label> </dt> <dd> <input type="text" size="30" value="<?=$jform_name?>" id="jform_name" name="jform[name]" class="required" /> </dd> <dt> <label for="jform_email" id="jform_email-lbl">E-mail:</label> </dt> <dd> <input type="text" size="30" value="<?=$jform_email?>" id="jform_email" name="jform[email]" class="validate-email" /> </dd> <dt> <label for="jform_amount" id="jform_amount-lbl">Amount:</label> </dt> <dd> <input type="text" size="30" value="<?=$jform_amount?>" id="jform_amount" name="jform[amount]" class="validate-amount" /> </dd> </dl> </fieldset> <div> <button type="submit">Save data</button> </div> </form>

Conclusion

That's all. For sure you have noticed that a custom validation code is far more easy to write than this based on Joomla! classes, and you're right. This example was written this way to explain how some Joomla! classes works and, I hope, you have now a better understand of this.

Please, don't use this example in a production environment. Before doing this you have to add a lot of code to perform security controls!

Add comment


Security code
Refresh

Contents

Part 1: Client side validation
Part 2: Server side validation
Part 3: Custom rules
Download the complete package