How to submit a form with an image in CakePHP

Say Geese!

CakePHP is in many ways an awesome framework. It does lots of things for you automagically, and makes development quite pleasant on most days. However, there are a few places where the framework displays irritating glitches.

One of those unlucky places is when you want to use an image as the submit button for your forms.

The official $form helper documentation lists the various methods available for creating HTML forms in CakePHP. In there, it mentions that you can make $form->end() use an image, by coding the image as the first parameter of the method:

[cc lang="php"]
//in your ctp file

echo $form->create(‘Person’, array(‘target’=> ‘_parent’,'action’ => ‘save’, ‘name’ =>’saveForm’) );
echo $form->input(‘name’);
echo $form->input(‘surname’);
echo $form->input(‘nickname’);
echo $form->end(‘Save.png’); //Note that the image must reside in your webroot/img folder.
?>
[/cc]

When you do that, the $form->end() method creates the following for you (where baseurl is your Dispatcher::baseUrl() value) :
[cc lang="html"]

[/cc]

This may sometimes be exactly what you want. But there’s a caveat here – consider the following:
[cc lang="php"]
//in your ctp file

$options = array('div'=>false,’name’ => ‘save’,'onclick’ => “foo();”);
echo $form->create(‘Person’, array(‘target’=> ‘_parent’,'action’ => ‘save’, ‘name’ =>’saveForm’) );
echo $form->input(‘name’);
echo $form->input(‘surname’);
echo $form->input(‘nickname’);
echo $form->end(‘Save.png’,$options);
.
.

?>
[/cc]

In the code snippet above, I add some options to the $form->end() method. Most importantly – I try and add an onclick= attribute to the image. I want something to happen just before the form is submitted.
But Cake is not happy to oblige. In fact, the resulting xhtml for both of the previous snippets is the same:
[cc lang="html"]

[/cc]

Cake, apparently, disregards the $options array if it receives an image name as $form->end() ‘s first parameter.
Frustration ensues.

Luckily though, we don’t have to use $form->end() to create a submit element for the form. Cake also has the $form->submit() method, which allows us to play a bit with the options and come up with a solution:

[cc lang="php"]
//in your ctp file

$options = array('div'=>false,’name’ => ‘save’,'onclick’ => “foo();”);
echo $form->create(‘Person’, array(‘target’=> ‘_parent’,'action’ => ‘save’, ‘name’ =>’saveForm’) );
echo $form->input(‘name’);
echo $form->input(‘surname’);
echo $form->input(‘nickname’);
echo $form->submit(‘Save.png’,$options);
.
.

?>
[/cc]

The $form->submit method honors the $options array. We don’t even have to tell it that the type of the submit element is an image – the method works it out all by itself, resulting in:
[cc lang="html"]

[/cc]
and all is well on this front.

And just one Security.php note

While the code in the last snippet above works, it will fail you if you use the Security component.
With the Security component, Cake adds tokens to each form it creates.
When the user submits the form back to the server, Cake can check that the token submitted matches the token created, and know that it did in fact generate the form. This (and other methods) provide some protection against CSRF attacks.

However, these tokens are only generated for forms created and closed with the $form->create() .. $form->end() methods. The snippet above does not use $form->end() – so while it works, the form is going to be useless if you use the Security component.

This is easy to fix – just add $form->end() to ensure that the token generation is called correctly:
[cc lang="php"]
//in your ctp file

$options = array('div'=>false,’name’ => ‘save’,'onclick’ => “foo();”);
echo $form->create(‘Person’, array(‘target’=> ‘_parent’,'action’ => ‘save’, ‘name’ =>’saveForm’) );
echo $form->input(‘name’);
echo $form->input(‘surname’);
echo $form->input(‘nickname’);
echo $form->submit(‘Save.png’,$options);
echo $form->end();
.
.

?>
[/cc]
and ther you have it- Submitting a CakePHP form with an image, with an onclick= attribute configured, and as a bonus – with the Security token generated (if you’re using the Security component).

4 thoughts on “How to submit a form with an image in CakePHP

  1. Ayo Akinyemi

    Thanks.
    Used this;
    submit(‘submit’, array(‘type’ => ‘image’, ‘src’ =>
    $this->webroot . ‘img/myimage.jpg’, ‘height’ => ’15′, ‘width’ => ’13′)); ?>

    But yours is more cleaner.

  2. Scott

    This worked for me:

    I created a custom button using an image in my under app/webroot/img that uses inline style for specifying size and changing the position to center

    $options=array(‘type’=>’Make secure payment’, ‘type’=>’image’, ‘style’=>’width:200px; height:80px; display:block; margin-left:auto; margin-right:auto;’);
    echo $this->Form->submit(‘/img/axiaepaysecurebuttongray_med.png’, $options);
    echo $this->Form->end();

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>