26 March 2010

jQuery UI Dialogs

Categories:  Web  jQuery  Ajax

How to load a partial of server response document into a jQuery UI Dialog.

I'm building my site using CMS Made Simple. This is typical PHP content management system, with lots of nice and very useful plug-ins. Most of them have a very limited Ajax functions. By creating content you end up in a site that is behaving in old click and wait for full page reload way.

Ajax is todays standards for building Internet services and I would like to have at least limited Ajax functionality on my site.

One of the plug-ins I used was the one called YouTube Player, it lets you easily embedded number of YouTube published films on your site. The way that plug-ins works, is that it lets you list the films and then the user can click on any listed item, cosing the page to reload and show the user embedded movie he chosen. This is good way of behavior but not enough for me. I don't want to force people redirect them self back and forward if they want to see all embedded movies. I would like the movies to be loaded to some kind of floating window that user can move to see other items that are published on my site and close the window anytime he wants, without being redirected anywhere else.

The solution was very simple. When I search the Internet a little bit I found a great and extremely easy to use jQuery Ui API, with great dialog plug-in, which was doing everything I wanted. I decided to use it to change the default behavior of YouTube embedded content.

All I needed to do is to make sure that all the embedded YouTube content will be marked the same way, so I could operate on it using only one simple script.

I will try to keep the solution as far away from actual tool I use, so you could use it in your page no matter how you are building it, using cms or pure html.

First thing I did was editing templates in my YouTubePlayer plug-in. All I had to do is to make sure that every link tag pointing to a page with YouTube film is being marked with same class. Belows example show how the movie links are looking like.

<a title="The Orgin" class="film_link" href="http://www.kardasa.pl/youtubeplayer/detail/The-Orgin/75.html">
<img width="130" height="97" border="0" style="margin: 1px;" title="The Orgin" alt="The Orgin" src="http://img.youtube.com/vi/8Xi8hmVCZZw/1.jpg"> 

As you can see is marked as film_link class. This is very important.

Except the link itself I needed to make sure that the page which loads the movie will load the movie to uniquely marked div tag. I did it also by changing the templates of the plug-in I use. You can see the belows example of generated tags surrounding the embedded film.

<div style="text-align: center;" id="film">
<object width="640" height="480">
<param value="http://www.youtube.com/v/8Xi8hmVCZZw?rel=0&amp;fs=1&amp;loop=0" name="movie">
<param value="transparent" name="wmode">
<param value="true" name="allowFullScreen">
<embed width="640" height="480" wmode="transparent" type="application/x-shockwave-flash" allowfullscreen="true" src="http://www.youtube.com/v/8Xi8hmVCZZw?rel=0&amp;fs=1&amp;loop=0">

As you can see film is surrounded by div with id named film.

After the marking we may come to the real solution. First you need to have jQuery and jQuery Ui API loaded. Add this two lines to your site head section after uploading API script files to your server.

<script type="text/javascript" src="/scripts/jquery-1.4.2.js"></script>
<script type="text/javascript" src="/scripts/jquery-ui-1.8.custom.js"></script>

You also should take care of including jquery-ui CSS style sheet into your site. Consult the API docs.

The next thing to do is write the script that will do the job for us.

View the script source
  1. $.fx.speeds._default = 1000;
  2. $(document).ready(function() {
  3. $('a.film_link').each(function() {
  4. var $link = $(this);
  5. var $dialog = $('<div id="film_dialog"></div>')
  6. .dialog({
  7. autoOpen: false,
  8. width: 660,
  9. height: 'auto',
  10. title: $link.attr('title'),
  11. resizable: false,
  12. modal: true,
  13. show: 'blind',
  14. hide: 'fold'
  15. });
  17. $link.click(function() {
  18. $('#overlay').show();
  19. $('#ajax-indicator').show();
  20. $dialog.load($link.attr('href')+' #film',function(){
  21. $('#ajax-indicator').hide();
  22. $('#overlay').hide();
  23. $dialog.dialog('open');
  24. });
  25. return false;
  26. });
  27. });});

As you can see the script itself is short, thats the advantage of using core API.

Let my now explain line by line how the script works.

The first line is setting up the speed for visual effect that will be used to open and close the dialog windows.

Next line is saying that when the page will be ready it will fire up the defined function.

The function will process every anchor tag marked with class film_link (I said it will be important), and then the currently processed link will be assigned to $link variable.

Next we create a variable called $dialog which will hold our floating dialog window made of div tag with film_dialog id.

Next we pass the parameters to our dialog window, it's width and height, the title which will be taken from our link title, we say the dialog will be modal and we don't want it to open automatically.

We are also choosing the show and hide effects of our dialog window. You can choose any effect you like.

You can check the API docs for full parameters list and available visual effects.

Now we need to say when we want the dialog to open. We want it to open when the user clicks our link, just see the "$link.click" function.

First this function will show the defined in my page "overlay", then it will show defined "ajax-indicator", to let our user know that something is being loaded right now.

Now we will use the load function of our previously defined "$dialog" variable to load the data from the server into our dialog.

As you can see the first parameter of load is an address taken from our link. The "+ #film" will make sure we will not load the whole page. We surly don't want the page header and footer, what we are interested in is our div marked with film id. And that's what will happen here. We directly are asking our load function to load only "#film" marked element.

The second parameter of load function will tell, what to do after information is loaded to our dialog. Here we are hiding ajax-indicator, and opening our dialog.

The last line is very important "return false" will make sure that the link will not be processed the normal way, we will not be redirected to page with the film.

Of course you have to add the script into header section of your page:

<script type="text/javascript" src="/scripts/youtube_dialog.js"></script>

And thats the whole deal. If you want to test it just follow this link and click any of the movies.

I suggest you to do it twice. First with disabled javascripts in your browser, to see how it is working without the script. Then enabling javascript in your browser to see how the script is changing the way that page are being processed.

The best way of adding some Ajax fancy things to your site this way is that if someone will have a javascript disabled, it will still work for him, just the old and in my opinion ugly way.

In the same way I load contacts forms to dialogs on my page.

You can access the script I use on my site on my svn server by following this link.



If you have found something wrong with the information provided above or maybe you just want to speak your mind about it, feel free to leave a comment.
All comments will show up on page after being approved. Sorry for such policy but I want to make sure that my site will be free of abusive or vulgar content. I don't mind being criticized just do it using right words.

Leave a comment