Home > Zend_Form > Validation of Zend_Form(Ajax version)

Validation of Zend_Form(Ajax version)

intro
This article shows source code that validates data using Zend_Form and Ajax. It also uses Dojo library.
You can see the screens from the demonstration site.

1.Create Controller
Create the file application/constorllers/IndexController.php with the following content.

<?php
require_once 'Zend/Controller/Action.php';
require_once 'Zend/Form.php';
 
class IndexController extends Zend_Controller_Action
{
    public function getProfileForm()
    {
        $form = new Zend_Form();
        $form->setName('profileForm')
             ->setAction($this->_request->getBaseUrl() . '/index/profile')
             ->setMethod('post');
 
        $givenName = $form->createElement('text', 'givenName');
        $givenName->setLabel('Given Name')
                  ->setRequired(true)
                  ->addFilter('stringTrim')
                  ->addValidator('stringLength', false, array(1,50));
        $familyName = $form->createElement('text', 'familyName');
        $familyName->setLabel('Family Name')
                   ->setRequired(true)
                   ->addFilter('stringTrim')
                   ->addValidator('stringLength', false, array(1,50));
        $email = $form->createElement('text', 'email');
        $email->setLabel('E-Mail')
              ->setRequired(true)
              ->addFilter('stringTrim')
              ->addValidator('emailAddress', false);
        $url = $form->createElement('text', 'url');
        $url->setLabel('URL')
            ->setRequired(false)
            ->addFilter('stringTrim')
            ->addValidator('stringLength', false, array(1,100));
        $submit = $form->createElement('submit', 'submit');
        $submit->setLabel('Send');
 
        $form->addElements(array(
            $givenName, $familyName, $email, $url, $submit
        ));
 
        return $form;
    }
 
    public function init()
    {
        $ajaxContext = $this->_helper->getHelper('AjaxContext');
        $ajaxContext->addActionContext('validate', 'json')
                    ->initContext();
    }
 
    public function indexAction()
    {
        $this->_forward('profile');
    }
 
    public function profileAction()
    {
        $form = $this->getProfileForm();
        if ($this->getRequest()->isPost())
        {
            if ($form->isValid($_POST))
            {
                $values = $form->getValues();
                $this->view->values = $values;
            }
        }
        $this->view->form = $form;
    }
 
    public function validateAction()
    {
        if ($this->getRequest()->isPost())
        {
            $data = $this->getProfileForm()->processAjax($_POST);
            $this->_helper->json->sendJson($data);
        }
    }
}
2.Create View
Create the file application/views/scripts/index/profile.phtml with the following content.

 
<h1><?= $this->translate('Your Profile'); ?></h1>
 
<?php if($this->values) : ?>
<h3><?= $this->translate('You just submitted the following values'); ?>:</h3>
<ul>
  <?php foreach ($this->values as $value) <img src='http://www.oplabo.com/wp-includes/images/smilies/icon_confused.gif' alt=':?' class='wp-smiley' /> >
<li>
    <?= $this->escape($value); ?>
  </li>
 
  <?php endforeach; ?>
</ul>
 
<?php else : ?>
    <?= $this->form; ?>
<?php endif; ?>
 
<script type="text/javascript">
    var djConfig = {
    isDebug:true, parseOnLoad:true
    };
</script>
<script type="text/javascript" 
    src="<?= $this->baseUrl . '/js/dojo/dojo.js'?>">
</script>
<script type="text/javascript">
// sumbit the form 
var formSubmit = function(e){
    // prevent the form from actually submitting
    e.preventDefault(); 
    // submit the form in the background    
    dojo.xhrPost({
        url: "<?=$this->url(array('action'=>'validate'))?>/format/json",
        form: "profileForm",
        handleAs: "json",
        handle: function(data,args){
            if(typeof data == "error")
            {
                console.warn("error!",args);
            }
            else if (data == "true")
            {
                clearFormError();
                alert("OK!");
            }
            else
            {
                // show our response 
                console.log(data);
                json = eval("(" + data + ")");
                clearFormError();
                for (elem in json)
                {
                    msg = "
<ul>";
                    for (err in json[elem])
                    {
                        msg += "
<li>" + json[elem][err] + "</li>
 
";
                    }
                    msg += "</ul>
 
";
                    dojo.byId(elem + "_error").innerHTML = msg;
                }
            }
        }
    });
};
dojo.addOnLoad(function(){
    var theForm = dojo.byId("profileForm");
    // another dojo.connect syntax: call a function directly    
    dojo.connect(theForm,"onsubmit",formSubmit);
});
function clearFormError()
{
    var myForm = dojo.byId('profileForm');
    var elements = myForm.elements;
    for (var i = 0; i < elements.length; i++)
    {
        if (dojo.byId(elements[i].name + "_error"))
        {
            dojo.byId(elements[i].name + "_error").innerHTML = "";
        }
        else if(dojo.byId(elements[i].name))
        {
            div = document.createElement("div");
            div.setAttribute("id", elements[i].name + "_error");
            dojo.byId(elements[i].name).parentNode.appendChild(div);
        }
    }
}
</script>

3.Check
Let's access the web server and check the validation using Zend_Form and Ajax.
Reference
About the method processAjax of Zend_Form, Please see the manual.

History
Date Content
2008/4/28 Published
2008/4/28,29 Bugs in javascript of view were fixed.
2008/4/30 Added reference about processAjax method.

Comments:14

JI Sánchez 08-04-28 (Mon) 23:52

Hi!

Excellent post, i’m working in a form with similar behavior.

i’ve a question , what is ‘AjaxContext’?

You should submit your posts at http://www.zftutorials.com/Zend_Form.

regards,

oplabo 08-04-29 (Tue) 1:11

Actually I’m not sure about it.
But according to Programmer’s Reference Guide of ZF(7.8.4.3),
it facilitates returning responses to XmlHttpRequests.
Please see the manual for more detail information.
Thanks.

JI Sánchez 08-05-03 (Sat) 3:34

Thanks a lot!

elGringo 08-12-05 (Fri) 22:28

Hi!
I’m trying to use this example. It’s ok while validation has errors. I can see the error messages and etc.
But when all fields is correct, i just can see “OK!” alert window. No data submitted in this case.
Can you help me please? :)

oplabo 08-12-08 (Mon) 13:03

Hello.
I think it’s correct…
Because after the client program submit the form data, it is validated by the server side program and the result is sent back to the client. If there’s no error, the client program will show the “OK” message.
If you pointed out another problem, please comment again.
Thank you.

Willem Luijk 09-02-17 (Tue) 4:02

What to do with the java code when the form is loaded by an ajax call? How do i dynamically load the script?

oplabo 09-02-17 (Tue) 11:49

There’s some ways to load javascript dynamically.
If you can use jquery, you can do it with the following code.
$(‘#some-container’).html(script_html);
If you can’t, please search another way according to your environment.
Thank you.

Willem Luijk 09-02-18 (Wed) 6:02

I am in search for a nice Zend Framework integration with a total one-page ajax solution where many forms are loaded and unloaded directed by a mainmenu just like native apps. The problem is to place the javascript code in the right places.
I have researched many options like jQuery, packaging and dynamically loading .js by dojo. I cant find nice example that describe its integration. Do you have some?

oplabo 09-02-18 (Wed) 9:42

Thank you for your comment.
I don’t know about a nice Zend Framework integration too.
But I think you can create your own view helper.
If you want to use Zend_Dojo_View_Helper_ContentPane, create your contentpane helper just replacing ‘dijit.layout.ContentPane’ with ‘dojox.layout.ContentPane’ of Zend_Dojo_View_Helper_ContentPane and change the class and function name.
Because dojox.layout.ContentPane allows to execute scripts.
It will be like the following.

class My_Dojo_View_Helper_ContentPaneWithScript
    extends Zend_Dojo_View_Helper_DijitContainer
{
    protected $_dijit  = 'dojox.layout.ContentPane';
    protected $_module = 'dojox.layout.ContentPane';

    public function contentPaneWithScript(
        $id = null, $content = '',
        array $params = array(), array $attribs = array())
    {
        if (0 === func_num_args()) {
            return $this;
        }

        return $this->_createLayoutContainer(
            $id, $content, $params, $attribs
        );
    }
}

And you need to add view helper path with the following code.

$view()->addHelperPath('My/Dojo/View/Helper', 'My_Dojo_View_Helper');

In your view, you can use the above helper like the following.

	echo $this->contentPaneWithScript(
		'formPane',
		'',
		array('region' => 'bottom', 'href'=>'yourFormUrl'),
		array('style' => 'background-color: lightgray;')
	);

If you use layout, you need to disable it manually.

Ivan 09-04-16 (Thu) 9:31

Thanks for the tutorial.

I have got it going very well. But when I put in a CAPTCHA, processAjax() doesn’t validate it. Would you please tell me how to validate CAPTCHA as well?

Ivan

oplabo 09-04-21 (Tue) 17:53

I think it is difficult to use processAjax() in that case.
But you can replace all form elements like the following code.
(I’m not sure that it is practical.)

    // in the controller
    public function validate2Action()
    {
        $form = $this->getProfileForm();
        if ($this->getRequest()->isPost())
        {
            if ($form->isValid($_POST))
            {
                $this->_helper->json->sendJson(true);
            }
        }
        echo $form;
        exit;
    }
// in the script tag
// sumbit the form
var formSubmit = function(e){
    // prevent the form from actually submitting
    e.preventDefault();
    // submit the form in the background
    dojo.xhrPost({
//        url: "< ?=$this->url(array('action'=>'validate'))?>/format/json",
        url: "< ?=$this->url(array('action'=>'validate2'))?>",
        form: "profileForm",
//        handleAs: "json",
        handleAs: "text",
        handle: function(data,args){
            if(typeof data == "error")
            {
                console.warn("error!",args);
            }
            else if (data == "true")
            {
                alert("OK!");
            }
            else
            {
                var div = document.createElement("div");
                div.innerHTML = data;
                dojo.byId("profileForm").innerHTML = div.firstChild.innerHTML;
            }
        }
    });
};
Mat 09-09-04 (Fri) 7:55

Hello oplabo,

In echo to what elGringo wrote, I’m getting a hard time understanding when the form is actually processed once it’s validated. On the client side, an ‘OK’ message is displayed.
But when does the server process the data to perform actions on it?

In your example, the profileAction() method of the controller is only called once at the beginning, and is never called when all the fields are validated.

Am I missing something?

Sathesh 09-12-31 (Thu) 10:20

Thanks for the tutorial. It’s great.

Prototype people read this:

For the people who wish to do the same thing in prototype JS, add these lines when you receive the response (the prototype AJAX request will be regular one and need no special modifications),

var response = t.responseText.evalJSON();
json = eval( ‘(‘ + response + ‘)’ );

and then change all the ‘dojo.byId’ to $ . That’s it. Hope this will be useful to someone.

Thanks,

Sathesh

ravi 10-08-06 (Fri) 19:54

Hi!
I’m trying to use this example. It’s ok while validation has errors. I can see the error messages and etc.
But when all fields is correct, i just can see “OK!” alert window. No data submitted in this case.
Can you help me please? :)

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://www.oplabo.com/article/36/trackback
Listed below are links to weblogs that reference
Validation of Zend_Form(Ajax version) from Open Programming Laboratory

Home > Zend_Form > Validation of Zend_Form(Ajax version)

Japanese
Search
Feeds

Return to page top