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.
You can see the screens from the demonstration site.
1.Create Controller
Create the file
application/constorllers/IndexController.php
with the following content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
<?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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
<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) :?> <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. |
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,
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.
Thanks a lot!
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? 🙂
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.
What to do with the java code when the form is loaded by an ajax call? How do i dynamically load the script?
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.
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?
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.
And you need to add view helper path with the following code.
In your view, you can use the above helper like the following.
If you use layout, you need to disable it manually.
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
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.)
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?
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
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? 🙂