Improved form handling in CakePHP 1.3

Here is a typical, simple form done with cake’s form helpers:

echo $this->Form->create('Article', array('action' => 'test'));

echo $this->Form->input('Article.title');
echo $this->Form->input('Article.body');
echo $this->Form->input('Article.user_id', array('type' => 'hidden'));

echo $this->Form->end('Add Aricle with Tags and Comment');

Which outputs the following HTML:

<form id="ArticleTestForm" method="post" action="/articles/test" accept-charset="utf-8">
    <fieldset style="display:none;">
        <input type="hidden" name="_method" value="POST" />
    </fieldset>
    <div class="input text">
        <label for="ArticleTitle">
            Title
        </label>
        <input name="data[Article][title]" type="text" maxlength="50" value="" id="ArticleTitle" />
    </div>
    <div class="input textarea">
        <label for="ArticleBody">
            Body
        </label>
        <textarea name="data[Article][body]" cols="30" rows="6" id="ArticleBody">
        </textarea>
    </div>
    <input type="hidden" name="data[Article][user_id]" value="" id="ArticleUserId" />
    <div class="submit">
        <input type="submit" value="Add Aricle with Tags and Comment" />
    </div>
</form>

This is fine and all, but one thing worth noting is that default behavior is wrapping each element in a div, and in some cases this may not be desirable. Either a legacy CSS or a front-end developer preference, might require the form to be structured (wrapped) differently.

Let’s see how we can set some defaults for our form with CakePHP 1.3., while simplifying the code a little at the same time by using the inputs() method…

 echo $this->Form->create('Article', array('action' => 'test', 
                                              'inputDefaults' => array(
                                                'div' => array('tag' => 'p'),
                                                'before' => '-- goes before the label --',
                                                'after' => '-- goes after the input --')));    
    
echo $this->Form->inputs(array('Article.title', 
                                               'Article.body', 
                                               'Article.user_id' => array('type' => 'hidden')), 
                                      array('legend' => 'Article submit'));

echo $this->Form->end('Add Aricle');

Which produces:

<form id="ArticleTestForm" method="post" action="/articles/test" accept-charset="utf-8">
    <fieldset style="display:none;">
        <input type="hidden" name="_method" value="POST" />
    </fieldset>
    <fieldset>
        <legend>
            New Article
        </legend>
        <p class="input text">
            -- goes before the label --
            <label for="ArticleTitle">
                Title
            </label>
            <input name="data[Article][title]" type="text" maxlength="50" value="" id="ArticleTitle" />
           -- goes after the input --
        </p>
        <p class="input textarea">
            -- goes before the label --
            <label for="ArticleBody">
                Body
            </label>
            <textarea name="data[Article][body]" cols="30" rows="6" id="ArticleBody">
            </textarea>
           -- goes after the input --
        </p>
        <input type="hidden" name="data[Article][user_id]" value="" id="ArticleUserId" />
    </fieldset>
    <div class="submit">
        <input type="submit" value="Add Aricle" />
    </div>
</form>

Of course for a simple form this may not be a very significant improvement, but having the ability to set defaults for the entire form and relying on some automagic for the rest, certainly makes one’s life easier.