thinkvantage
thinkvantage

Reputation: 21

Zend form inside dijit dialog on submit validation

I'm fairly new with creating a web application and would like to seek help regarding dojo and zend framework. I'm having problems with validation on form submission and also need to create dynamic element when a button inside the form (add new moderator button) is clicked.

What I need is: What I have right now: Problem

Here are my trimmed out code:

Form
class Form_Test
{
    public $processed = false;

    public function init()
    {
        parent::init();
        $this->setAttribs(array('name'=>'test'));
        $this->setAction('/myapp/new')->setMethod('

        $this->addElement('ValidationTextBox', 'topic', array(
            'label'      => 'Topic: ',
            'required' => true,
            'trim'       => true, 
            'validators'  => array("alnum"),
            'filters' => array(new Zend_Filter_StringToLower(),
        new Zend_Filter_StringTrim()
        )
        )
        );
        $this->addElement('SimpleTextArea', 'desc', array(
            'label'      => 'Description: ',
            'trim'       => true
        )
        );
        $this->addElement('ValidationTextBox', 'moderator', array(
            'label'      => 'Moderator: ',
            'required' => true,
            'trim'       => true, 
            'validators'  => array("EmailAddress"),
            'filters' => array(new Zend_Filter_StringToLower(),
        new Zend_Filter_StringTrim()
        )
        )
        );


        $this->addElement('SubmitButton', 'submit', array(
            'label' => 'Create'
        ));
    }
}
View
<button class="myButton" type="button" onclick="dijit.byId('formDialog').show()">
    New Topic
</button> 

<div dojoType="dijit.Dialog" id="formDialog" title="Topic" style="width:500px; height:300px;">
    <?php echo $this->form; ?>
</div>
Controller
public function newAction()
    {

        $form= new Form_Test();
        $this->view->form = $form;
        $form->submit->setLabel('Create');
        $values = $form->getValues();

        if( $this->_request->isPost())
        {
            if($form->isValid($_POST)){        
                $topic = new Application_Model_Topic();
                $result = $topic->createNewTopic($_POST);
                if($result == false){
                   $form->addError($result->error);
                }
            }
        }
        $this->view->form = $form;
        // How to redirect to form if there's error?

        $this->_redirect('/myapp/index');
    }

I've seen some post with creating a dynamic element that uses ajax but it is not using a dijit dialog box on a form and mostly are in jquery where I also don't have any background.

I've already searched on the net but to no avail. Please help me out. Thanks in advance.

Upvotes: 0

Views: 2035

Answers (1)

thinkvantage
thinkvantage

Reputation: 21

I've finally solved this! see below...I hope this helps someone who will run in to the same issues. If you have a more elegant solutions just put yours here.

Handling Forms inside dijit dialog

Validation set on element creation is not being fired and shown in form.

  1. Add a div element which will hold the errors to the dijit dialog before echoing the form.

    View

    <div dojoType="dijit.Dialog" id="formDialog" title="Topic" style="width:500px height:300px;">
        <div id='form-holder' style="overflow: auto; height: 250px;">
            <div id='errors' class='errors'></div>   
            <?php echo $this->form; ?>
        </div>
    </div>
    
  2. On form submission call the controller via xhrpost and do not redirect to anything. The formerrors for zend will be populated with errors. (I have my controller return a success/fail status)
  3. Retrieve the zend formerrors, format it and append to the created div element.

    View

    var xhrArgs = {url: "your controller action",
           form: dojo.byId("your form"),
           handleAs: "json",
           load: function(data) {
                if(data['success']==false){
                     destroyErrorList(); //will remove errors previously set
                     dojo.place(formatError(data['error']),
                                       dojo.byId("errors"),'last');
                }else{
                     // on success redirect back to the page
                     window.location = "redirect url";
                }
           },
           error: function(error) {
                 console.log(error);
           }
      };
      dojo.xhrPost(xhrArgs);
    

Where and how will I add the creation of new element when the "new moderator" button is clicked.

  1. Add a hidden field to your form which will hold the "moderator id"

    Form

    $this->addElement('hidden', 'id', array('value' => 1);
    
  2. Add a preValidation function to your form which will be used later when the form is submitted as per (http://www.jeremykendall.net/2009/01/19/dynamically-adding-elements-to-zend-form/) blogpost.

    Form

    public function preValidation(array $data) {
       // Search $data for dynamically added fields using findFields callback
       foreach ($newFields as $fieldName) {
       // strip the id number off of the field name and use it to set new order
       }
    }
    
  3. onClick action of the "new moderator" button retrieve the hidden id and dynamically create a new textbox for adding the moderator email.

    View

    function addModeratorField() {
        var id = parseInt(dojo.byId("id").value);
        var newTextBox =  new dijit.form.TextBox({id:'moderator_'+id, name:'moderator_'+id});
        dojo.byId("moderators_holder").appendChild(newTextBox.domNode);
        dojo.parser.parse(dojo.byId('moderator_'+id));//dijitize the textbox
    
        // Increment and store id
        dojo.byId("id").value = parseInt(id) + 1;
    }
    
  4. On your controller when form is submitted before doing anything on post data

    Controller

    // Form has been submitted - run data through preValidation() to populate the new fields
    $form->preValidation($_POST);
    if($form->isValid($_POST)){//do something}
    

Upvotes: 1

Related Questions