Featured Post

Writing DQL statements

Today I would like to focus on something, what Doctrine 1.x users know, but it looks a little bit different – Doctrine Query Language (DQL) statements. In the last tutorial we had had working Album Controller, which was using Doctrine Entity Manager, to get the Album data. Now we will focus on...

Read More

SubForms example in Zend Framework 1.x

Posted by evolic | Posted in Programming, Web development | Posted on 22-04-2013

Tags: , , , , , , , , ,

0

Today I would like to write something about SubForms available in Zend Framework 1.x.
Currently we have Zend Framework 2 released, and there is some similar solution called Form Collections with completely new approach.

I will take care that new feature from Zend Framework 2 in the close future, but in this article I would like to share some good looking and good working example of using SubForms from Zend Framework 1.x

SubForm example page in HTML5

SubForm example page in HTML5

Currently I am working on the project made with Zend Framework 1.x and I think that real example could be useful to people, who want to learn something about Zend_Form_SubForm.

Overview

SubForms are very useful when we need more advanced forms, where some elements(s) are placed more than once, for example – we can have many categories related to one article.

In this post I will demonstrate sample (Internet Shop) basket with a list of products and their’s prices and quantities. Our form looks like at the screenshot placed above.

So let begin!

Synopsis

By reading this article you will learn:

  • how to setup dynamically constructed form based on data provided by the user,
  • add custom decorators to the form and it’s elements,
  • create/delete additional elements with JavaScript and have them processed by the form class when submitted.

The form

As I mentioned above, the form models sample basket from Internet Shop. So we have:

  • list of products, their prices and quantities,
  • and also the contact part: name, e-mail address, town, post code and street.

At first I would like to talk about the idea being behind of the Zend_Form_SubForm.

Array notation in HTML form elements

So, let say we have a Zend SubForm and we want to reuse the same elements in our page multiple times, for this example I am going to use Products, a Product belongs to an Order and the Order can have more than one Product.

Basically part of form could looks like this:

Zend_Form_SubForm class is intended to create code like that, where single form element can show multiple times.

Let’s see how to create such very simple SubForm:

Next step is to replace the array array(1, 2, 3) with the real values, which are gathered in the Controller class.

Controller class

And as mentioned above, the array (/application/forms/SubForm.php):

is replaced by Session values (/application/forms/SubForm.php):

SubForm templates

Now is time to make our example more extended and flexible. In our controller we have two products types by default: ‘__template__‘, ‘new‘ (/application/controllers/IndexController.php).

  • __template__ – our template SubForm, which we will be cloning to add more products,
  • new – sample product row.

Then, we need to hide our template subform by setting CSS style: display: none; (/application/forms/SubForm.php).

Adding ‘Add’ and ‘Remove’ buttons

To every product we should add Remove button, and below the products list, attach button Add product.

The code for that is as follow:

For buttons, we remove Label decorator, which is completely redundant in that case.

Form decorators

By default, Zend Framework uses <dl> tag and Zend_Form_Decorator_DtDdWrapper class, which decorates form elements with <dt> and <dd> tags.

We can overwrite this default behaviour by setting own decorators for the form and it’s elements.

I prefer to display form as unordered list (<ul>) and here are decorators to achieve that kind of functionality.

At the beginning we need to decorate form tag:

Form elements will have following decorators:

And at the end – decorators for the SubForm element:

JavaScript buttons handlers

The last thing in this tutorial is to add JavaScript handlers for our Remove and Add product buttons.
All is done with jQuery.

At first let’s see how to setup onclick events:

Code is quite simple. Now let’s add more action and program Remove button, which in fact removes appropiate li tag, which is grand parent for the button tag.

Code for products adding is a little more advanced. It uses previously prepared template, which is cloned and updated to use unique input names.

Let’s have a look for that code:

We are inserting templated part just before the last element of the list, because the last element contains Add product button.

We are using here function makeUnique(newElm), which updates input names and ids, replacing string __template__ with current time number, which makes it unique.

Below you can check the code of that JavaScript function:

For that of you, who would like to apply this tutorial with real application and use data gathered from the database I pasted modified version of the JavaScript function: makeUnique(newElm, id) below:.

I hope this tutorial was useful and readable to you.

A little more advanced example than described in this article, can be tested live at dedicated web page.

SubForm with errors and other debugging information

SubForm with errors and other debugging information

Live demo

I published this sample application demonstrating usage of the Zend_Form_SubForm class, adding some debugging data e.g. $_POST, information about validation result, error messages, filtered form values at the below link:
http://zf1-subform-example.comyr.com/index/subform

Grab the code

You can download the source code from the discussed application from the GitHub:
https://github.com/evolic/subform

References

Write a comment