Many of you would already know that Dojo is JavaScript framework of the choice for Zend Framework. However, Zend framework itself is very loosely coupled that you can use whatever JavaScript framework you are comfortable in. As part of my previous project we were already using YUI, so it was the best idea that while Zend Framework was our choice for our next project, we should stick to the JavaScript framework in which we already have developed our expertise i.e. YUI. As part of developing an Ajax based form, it takes a bit of time to take your head around but it works exactly as the JavaScript should work with PHP i.e. unobtrusive way. The deal is simple, the whole point of using a MVC architecture is that, you have different layers of presentation, controlling and business logic, that makes your code easier to maintain and develop upon, same should be the case of JavaScript you will be using in your application. Just a note that I am using Zend Framework 1.10 for this mini-tutorial.
Let’s get to work!
Say you have a form in your forms directory which extends Zend_Form class:
<?php class Forms_Product_Values extends Zend_Form { public function init() { // Set the method for the display form to POST $this->setMethod('post'); $this->addElement('text','my_timestamp',array( 'filters'=>array('StringTrim'), 'required'=>true, 'label'=>'Time Stamp' )); $this->addElement('text','my_value',array( 'filters'=>array('StringTrim'), 'required'=>true, 'label'=>'Currency Value' )); // Add the submit button $this->addElement('button', 'values', array( 'ignore' => true, 'label' => 'Modify', )); } } ?>
public function valuesAction(){ $form = new Forms_Product_Values(); $request = $this->getRequest(); // Check to see if this action has been POST'ed to. if ($this->getRequest()->isPost()) { // Now check to see if the form submitted exists, and // if the values passed in are valid for this form. if ($form->isValid($request->getPost())) { //do whatever you want to do } } $this->view->form = $form; // disable layouts for this action: $this->_helper->layout->disableLayout();}
<?=$this->form?>
<!-- Combo-handled YUI JS files: --> <script type="text/javascript" src="http://yui.yahooapis.com/combo?2.8.1/build/yahoo-dom-event/yahoo-dom-event.js&2.8.1/build/connection/connection-min.js&2.8.1/build/selector/selector-min.js"></script><script type="text/javascript">function fnCallback(e) {sUrl = e.currentTarget.id; //controller name is the same as button name;var nodes = YAHOO.util.Selector.query('input');//prepare the data in query string format var data = ""; for (var i = 0; i< nodes.length; i++) { data += nodes[i].name+"="+nodes[i].value; if(i != nodes.length-1){ data += "&"; } }var div = document.getElementById("responseDiv");var handleSuccess = function(o) { //upon successful response we embed the response text into responseDiv on our HTML page div.innerHTML = o.responseText; YAHOO.util.Event.addListener("submitButton", "click", fnCallback); }; var handleFailure = function(o){ //if the request if failed, we need to log the event if(o.responseText !== undefined){ div.innerHTML = "Failed request to the server. Please try again."; } }; var handleEvent = { start:function(eventType, args){ }}; var callback = { //on start call back calls the handle event which starts showing ajax loader image customevents:{ onStart:handleEvent.start }, success:handleSuccess, //parameter to define which function to use on success failure:handleFailure, //parameter to define which function to use on failure timeout:1500 //timeout is 1500ms, can be extended from here }; var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, data); } function init(){ YAHOO.util.Event.addListener("values", "click", fnCallback); } YAHOO.util.Event.onDOMReady(init);<div id="responseDiv"><?=$this->form?></div>
See, no rocket science, however, couple of things to note, I am using a different approach here to remember controller name, I have assigned the same name to the button as the controller i.e. ‘values’, on click event the listener fires fnCallback function and then I read what is the id of the button, hence I know which controller is this and that is all I need as sUrl (the URL which I need to call, you may also need to concatinate “../../”+e.currentTarget.id), another approach you can use is to echo the controller name in a hidden span or div in the view and then just read it from the JavaScript on click or if you can come up with any other approach, kindly post in comments of this tutorial for others to use.
Then is the YAHOO.util.Selector.query(‘input’), the beauty of YUI become handy here, as in this form I only have input elements I want to read, however, if you want to read say for example all the select and textarea elements, it is simple, just use this YAHOO.util.Selector.query(‘input’, ‘select’, ‘textarea’), now you know how to harvest your inputs from your form, you pull that on into the data variable and make the normal Ajax request through connection manager utility of YUI. The only bit remains here is, because your controller action is same, when you will send a request to it, your whole form will regenerate itself (which is intentional as in the controller I am actually making a database call and I want to show that whatever user has modified is actually in the database now) so you will loose the listener which you attached earlier to the button, you have to add it again on receiving the response, however, in this example, I have hard-coded it, you may want to send it dynamically with function call so that your function become totally dynamic and you could use same with all of your forms, I leave that upto you!
Happy Coding!
First off… Thanks for this! But I’d wish that everyone who writes tutorials and posts code, would stop using short tags like <?=. It would save some time if I didn't have to replace them.
The example doesn't work for me though. And I don't know why yet. I'll try to find out. It would help if you added a working online example or a screenshot. Then we would at least know what it's supposed to do.
Thanks anyways!
Boss khuda ka khof kroo…koi aisy chez likha kroo jo insaan smg b lay
hahahaha waqas you are right bus wese guzra magaz se