Combining Modalbox & CakePHP

demo included!I’m pretty sure this can be implemented more elegantly, but I’ll describe my attempt to unite Modalbox with CakePHP 1.2.

First example – a modal box view
This example shows the steps I’ve taken to flavour a freshly baked cake app with modalbox. The starting point is a customer model, a controller and some basic index, view and edit views.
Showing a cakephp view in a modalbox, is just a few snippets away. Just make sure you include prototype, scriptaculous and the modalbox javascript and the modalbox css file in the default layout…

/app/views/layouts/default.ctp:
echo $html->css('modalbox');
echo $javascript->link('prototype');
echo $javascript->link('scriptaculous.js?load=effects');
echo $javascript->link('modalbox');

Then create the appropiate link to the view you want to load inside the modalbox. For example, if you want to show customer details from the customers/index.ctp view:

# ...somewhere in the loop that lists customers:
echo $html->link('View', array('action' => 'view', $customer['Customer']['id']), array('title' => 'Customer details', 'onclick' => "Modalbox.show(this.href, {title: this.title, width: 400}); return false;"));

Make sure you use the RequestHandler component so that the customer view is displayed in the ajax.ctp instead of the default.ctp layout. You can do this by making sure the following line is in /app/app_controller.php:

var $components = array('RequestHandler');

And… there you go! When you click the view link, the modalbox slides in, while the rest of the page dims to gray. When you hit the escape button, click the little ‘X’ or click anywhere in the gray area, the modal box slides back where it came from.

Ok, now forms!

This is where the example pages don’t seem to apply anymore. Or… this is where my concept of AJAX, CakePHP, Modalbox, etc. is fundamentally wrong… you tell me!

By calling an ‘edit’ view instead of the ‘view’ view, you’ve got yourselves a form inside the modalbox! Also very nice!
After submitting the edit form, you’ll get redirected to the index page again. That’s when the form validates.
Wait until you omit a required field. Instead of the index page, you get redirected to the edit form itself rendered in the ajax layout. There’s no single line of code yet that makes sure that the form will end up in the same modalbox.

To solve this, you need to replace the $form->create call in the edit view by $ajax->form. The form, starting with the tag generated by the Ajax helper, will submit using XMLHttpRequest instead of a normal HTTP request. In this way, the modalbox stays open and will be filled with whatever the form returns!

This was the form-helper call:

echo $form->create('Customer');

…and the ajax-helper equivalent:

echo $ajax->form('edit', 'post', array(
    'model'    => 'Customer',
    'url'      => array( 'controller' => 'customers', 'action' => 'edit'),
    'update'   => 'MB_content'
));

In order to make the Ajax helper available in the view, make sure you have included it in the controller:

var $helpers    = array('Html','Javascript', 'Ajax');

I’m still wondering why the calls aren’t a little bit more alike…

This brings us one step closer…. or one step too far??
All content will be rendered inside the modalbox. We need to tell modalbox when it’s not needed anymore. For example, when the form validated.

This can be done with a small javascript function that we define in the Default.ctp layout:

function closeModalbox()
{
	if ($('closeModalbox')) {
		// hide the modal box
		Modalbox.hide();
		// refresh the current page
		location.reload(true);
	} else {
		// resize to content (in case of validation error messages)
		Modalbox.resizeToContent()
	}
	return true;
}

The function checks if there’s a div element with id=”closeModalbox”. If that is the case, it will close the modalbox and refresh the current page. Which, in itself is not so Ajax….(but it works great!)
If it can’t find the div element, it will resize the modalbox to it’s fresh content. To make sure the function is called, we can hook it into the Ajax form by adding the following line to the options array:

'complete' => 'closeModalbox()'

In the edit view, we need to make sure that the closeModalbox-div is echoed conditionally:

if (isset($closeModalbox) && $closeModalbox) echo "<div id='closeModalbox'></div>";

The $closeModalbox variable is, in his turn set from the controller after the data is successfully saved.

Last, but not least…. it’s relatively simple to be able to fall back to a non-ajax form.

Demo
And since you probably allready lost the overview, here’s the complete source code and…. a demo!

24 Responses to “Combining Modalbox & CakePHP”

  1. Aaron Thies says:

    I have been trying to get a simple form work with Ajax in Cake. Can you post/send me you code, but with the Modalbox stuff removed? just a bare bones example?

  2. Jeremy Hoo says:

    You dropped me a lines last year when I was having problems intergrating modalbox with cahephp 1.2. Well I would have to say you are a life saver the above example was spot on, and have managed to use modalbox in many cakephp 1.2 applications since.

    Many thank for your time and effort.

  3. Nice… but i have a problem with a search form, when i click on the submit everything is ok, but if i click in the table (standard 1.2 paginator) it don’t use the ajax form call… any way of forcing the paginator to use ajax to make the call?

  4. Cem says:

    Hi ;
    Is it possible to validate the form in the modalbox with ajax too because in your codes the form ends with the form end method . Which I guess wont call the validation errors in ajax.

  5. Mike says:

    Excellent Tutorial!

    This made the whole process so simple. Thanks a bunch :)

  6. atul kale says:

    when I use modelbox in i.e. , I cann’t work.

  7. Cem says:

    hi How can I build Modalbox forms with file upload does anyone have an idea ?

  8. prabhaswara says:

    hi.. thx for your article…
    can i add horizontal sroll in modal box?

  9. dave says:

    you can send a form ajax without reloading the page and have it update the content on the page

  10. ezekfred says:

    nice work,
    but has anyone managed to use modalbox and fckeditor? because everything works fine till you want to save the editor content…
    thx

  11. Seyiox says:

    Nice work!
    Been having some trouble getting cake wizard component working with the wizard feature of modalbox.
    keeps returning missing controller error. (in the real sense, it sees the action as a controller somehow ;-(
    Some help would be nice

  12. Bram says:

    @Sayiox: Seems like the wrong url is requested, have you installed firebug? With firebug you can exactly find out what requests are done.

  13. anil says:

    Dear Sir,
    Can you please upload controller and view code in detail ?

  14. krupesh patel says:

    Great Job,
    It really works great!
    Now will u plz explain me how to perform live search with ajax because i have tried so much on it but i can’t so plz can u help me.

  15. Alexandro says:

    Hi, nice work, im trying to get it works but instead modalbox im using Moodalbox from (http://www.e-magine.ro/web-dev-and-design/36/moodalbox/), in the code of the form I change MB_content for mb_contents because thats the div where Moodalbox load the body content but it doenst work. When I click submit button nothing happens, any idea of what the problem is¿?

  16. Alexandro says:

    Hi again, I figure out the problem it seems to be that prototype and mootools have conflicts thats why ajax doenst work…

  17. dimmer says:

    Thank you a lot! It work fine. A most useful and full article for a whole time i’m learning cake.

  18. spheroid says:

    Is it possible to open a modalbox when a button is clicked? i.e. send form results to modalbox when button is clicked??

  19. chris says:

    I did the exact steps, but no modal popup shows. I even then went to just the modal popup (no cake stuff). static link from the modalpopup site and pasted it into a view and nothing happened. No jscript errors. but no popup?

  20. Paul Gardner says:

    Back at the start of the year I used this tutorial to get me started with using ModalBox in CakePHP. I then took the idea a little further, but it has taken me until now to put a tutorial and demo together.

    You can see this at http://webbedit.co.uk/blog_posts/view/tutorial-cakephp-modalbox-crud

  21. theotherdy says:

    Any ideas on how to deal with closing Modalbox when the view being shown inside the Modalbox is from a different controller e.g in a blog, list of comments is shown on posts/edit/1. Edit button next to first comment opens Modalbox containing comments/edit/1. When the submit button is clicked, comments_controller.php could set $closeModalbox in a comments view. However, I need $closeModalbox set in posts/edit.ctp. Without this, I can close the Modalbox using function closeModalbox() in posts/edit/1 but I can’t find any way not to close it if there are validation errors. Any ideas very gratefully received.
    Thanks

  22. tricksterex says:

    Can i sort table list by ajax in ModalBox window?

  23. Rahul says:

    I have been using this tool and I have some questions.

    1. I have a page that is bit lengthy, so is there any way i can scroll the page down.
    2. I am unable to focus to next textbox when i press the tab button.
    3. I have introduced javascript validations that are not working with this modal when the page opens in modalbox window.

    any help would be highly appreciable.

  24. James Rudio says:

    Hello, I came across this blog post while searching for help with JavaScript. I’ve recently switched browsers from Opera to Mozilla Firefox 3.1. Now I seem to have a issue with loading JavaScript. Every time I browse page that requires Javascript, the page freezes and I get a “runtime error javascript.JSException: Unknown name”. I can’t seem to find out how to fix it. Any aid is greatly appreciated! Thanks

Leave a Reply