0
votes

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:
  • A dialog that pops up which includes the zend form.
  • Form should have validation.
  • Form should create dynamic text element when "new moderator" is clicked.
  • On form submission.

    If an error occurs during validation show the errors on the 
         popped up dialog and let user fix the error. 
    On success redirect the user to the parent page that calls the popup dialog.
    
What I have right now:
  • A form where I put validations on element creation.
  • A view element that has a declarative dijit dialog where I "echoed" the zend form.
  • A button that will fire and show the dijit dialog.
  • A controller that validates form data and add form errors if any.
Problem
  • Validation set on element creation is not being fired and shown in form.
  • Where and how will I add the creation of new element when the "new moderator" button is clicked.

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.

1
anybody run into the same situation above that has answers? please help..I'm thinking this could be done through ajax call and add the errors on the dialog but I don't know how to add errors/new element on the dialog form. An example will be much appreciated. Thanks - thinkvantage

1 Answers

1
votes

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}