Symfony World blog is not maintained anymore. Check new sys.exit() programming blog.

symfony popup with jQuery thickbox - beginner's tutorial

Scene from "The Jetsons" by Hanna-Barbera (introduced in 1962)

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
The screenshot below presents the output:




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:


8 comments:

  1. Great! Also love the little wgets - nice touch!

    ReplyDelete
  2. Great, thanks! Just what I needed! Works like a charm.

    ReplyDelete
  3. Thank you!

    much appreciated.

    ReplyDelete
  4. how to redirect to home page after form successfully submit

    ReplyDelete
  5. I 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...

    ReplyDelete
  6. How can i use this for editing an object? How pass original object into form?

    ReplyDelete
    Replies
    1. Try to modify the executeAdvancedPopup method. Instead of creating a new (empty) form, instantiate it with an existing model object, using $request parameters.

      Delete