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:
<?php
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.
?>
When you do that, the $form->end() method creates the following for you (where baseurl is your Dispatcher::baseUrl() value) :
This may sometimes be exactly what you want. But there’s a caveat here – consider the following:
<?php
$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);
.
.
<script type="text/javascript">
function foo() {
//do anything
}
</script>
?>
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:
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:
<?php
$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);
.
.
<script type="text/javascript">
function foo() {
//do anything
}
</script>
?>
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:
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:
<?php
$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();
.
.
<script type="text/javascript">
function foo() {
//do anything
}
</script>
?>
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).
Popularity: 57% [?]
2 Responses to How to submit a form with an image in CakePHP
Leave a Reply Cancel reply
Recent Comments
- Medovarszki: This post saved my hair from falling out but yeah, I beat my head against the wall now too
- Shehryar: Probably the ebst spring web mvc tutorial I have read, explain everything in great detail. i loved it, this...
- armand: You do not resize the image. You just display it smaller using html tag attributes. It would be nice to...
- COTP: ** Just to clarify, in CakeErrorController.php (the copy in app/Controller/) public function beforeRender() {...
- COTP: For CakePHP 2.0+, you can copy lib/Cake/Controller/CakeErrorC ontroller.php to app/Controller/CakeErrorCon...
- Medovarszki: This post saved my hair from falling out but yeah, I beat my head against the wall now too
Categories
- Android (1)
- appengine (3)
- Be nice to your users (6)
- CakePHP (13)
- General (5)
- Googlemaps (3)
- Java (11)
- javaScript (4)
- jQuery (11)
- Seam (2)
- Security (4)
- Spring MVC (1)
- Spring Webflow (2)
- User Interface (5)
- Wordpress (2)
Archives
- January 2012 (2)
- December 2011 (1)
- July 2011 (2)
- June 2011 (4)
- May 2011 (1)
- December 2010 (3)
- November 2010 (1)
- August 2010 (2)
- July 2010 (2)
- June 2010 (4)
- May 2010 (4)
- April 2010 (5)
- March 2010 (3)

Thanks.
Used this;
submit(‘submit’, array(‘type’ => ‘image’, ‘src’ =>
$this->webroot . ‘img/myimage.jpg’, ‘height’ => ’15′, ‘width’ => ’13′)); ?>
But yours is more cleaner.
Thanks.
I was searching the solution for that problem. And you have helped me.