Introducing jQuery thickbox pop-up
In this tutorial I will show you an easy way to create a thickbox using jQuery thickbox lib. At first, make sure you are familiar with the thickbox and take a look at the examples tab. We will create our pop-up feature basing on the iFramed Content section.
Install jQuery thickbox
The first thing you need to do is installing the software, of course. I want to make this tutorial as easy as possible, so just run the following commands from the project root directory:
wget http://jquery.com/demo/thickbox/thickbox-code/thickbox-compressed.js -O web/js/thickbox-compressed.js wget http://jquery.com/demo/thickbox/thickbox-code/thickbox.css -O web/css/thickbox.css wget http://jquery.com/src/jquery-latest.pack.js -O web/js/jquery-latest.pack.js wget http://jquery.com/demo/thickbox/images/loadingAnimation.gif -O web/images/loadingAnimation.gif
After the files are downloaded, you need to make symfony include them into the generated output. One of the possible ways is to edit your application/config/view.yml file:
stylesheets: [ ..., thickbox.css ] javascripts: [ ..., jquery-latest.pack.js, thickbox-compressed.js ]
The thickbox is already installed in your symfony project.
Basic usage
To make everything elegant, add 2 routes to your application/config/routing.yml file:
index_popup: url: /popup param: { module: main, action: popup } basic_popup: url: /basic-popup param: { module: main, action: basicPopup }
The first route is just a demo action to demonstrate thickbox and you can the index_popup action with the following url:
http://local_sf_test/popup
The second route executes an action that shall be displayed inside the popup. Now we shall create the index_popup action inside the application/modules/main/actions/actions.class.php file:
/** * Executes popup action * * @param sfRequest A request object */ public function executePopup(sfWebRequest ) { }
and a link executing our basic popup - add the following code into your application/modules/main/templates/popupSuccess.php file:
<a class="thickbox" href="<?php echo url_for('@basic_popup') ?>?keepThis=true&TB_iframe=true&height=100&width=400">run basic popup!</a>
It's already working - if you press this link in the development mode, you'll get the symfony error Action "main/basicPopup" does not exist. - but generated in the thickbox. Now we're only left to create this action - create the file application/modules/main/templates/basicPopupSuccess.php file:
<h1>basic popup example</h1>
and the last thing - the basicPopup action inside the application/modules/main/actions/actions.class.php file:
/** * Executes basic popup action * * @param sfRequest A request object */ public function executeBasicPopup(sfWebRequest ) { }
The logic is very simple - only two things to be done:
- The string ?keepThis=true&TB_iframe=true&height=100&width=400 is added to the end of the link's href attribute to pass some extra parameters to the thickbox. Those parameters can be easily modified, according to thickbox documentation.
- The link has to have the CSS thickbox class
As we can see, the web debug toolbar is not fitting well here, therefore we may disable it by adding the following code to the executeBasicPopup action:
sfConfig::set('sf_web_debug', false);
This would display the popup without web debug no matter if the production or development controller is running:
Advanced usage
Above example could only display some static content. But it's not all that symfony thickbox integration can do - for example, you can embed symfony forms inside a popup. Create new action inside the application/modules/main/actions/actions.class.php file:
/** * Executes advanced popup action * * @param sfRequest A request object */ public function executeAdvancedPopup(sfWebRequest $request) { sfConfig::set('sf_web_debug', false); // disable sf_web_debug $this->form = new ExampleForm(); // create the form object if ($request->isMethod('post')) { $this->form->bind($request->getParameter('example_form')); if ($this->form->isValid()) { // do some business logic $this->getUser()->setFlash('notify', 'this message will be displayed inside the popup'); return $this->renderPartial('main/message'); } } return $this->renderPartial('example_partial'); }
and a new route inside application/config/routing.yml file, corresponding to the new action:
advanced_popup: url: /advanced-popup param: { module: main, action: advancedPopup }
update the popupSuccess.php file:
<a class="thickbox" href="<?php echo url_for('@basic_popup') ?>?keepThis=true&TB_iframe=true&height=100&width=400">run basic popup!</a> <a class="thickbox" href="<?php echo url_for('@advanced_popup') ?>?keepThis=true&TB_iframe=true&height=100&width=400">run advanced popup!</a>
Now it's up to you to create a form class (the easiest way is to use a model form generated class) and display all its fields inside the _example_partial.php file:
<style> #form {background: #d3e5f4; padding:5px 15px; color:#1f3037;} /* some other CSS to be used by the popup form */ </style> <div id="form"> <form action="" method="post"> <?php echo $form->renderHiddenFields() ?> <?php echo $form['example_field']->renderError() ?> <label class="label" for="example_form_example_field">example label</label> <?php echo $form['example_field']->render() ?> <input type="submit" value="submit" /> </form> </div>
The last thing to be created is the file to be used as the message partial, _message.php:
<span>example message</span>
Live app example
After clicking this button:
the following popup is displayed:
the form validation errors are displayed:
and finally the submission message is displayed:
Nice thank you!
ReplyDeleteGreat! Also love the little wgets - nice touch!
ReplyDeleteGreat, thanks! Just what I needed! Works like a charm.
ReplyDeleteThank you!
ReplyDeletemuch appreciated.
how to redirect to home page after form successfully submit
ReplyDeleteI haven't tried it, but a quick look at the thickbox docs (http://jquery.com/demo/thickbox/) gave an idea to use the tb_remove() function. This is what I'd try to do: if the form passed the validation without any errors (successful submit) call the tb_remove after the page is loaded, e.g. $(document).ready( tb_remove() ). But I haven't tested it...
ReplyDeleteHow can i use this for editing an object? How pass original object into form?
ReplyDeleteTry to modify the executeAdvancedPopup method. Instead of creating a new (empty) form, instantiate it with an existing model object, using $request parameters.
Delete