Ryan Ricard

www topics worth sharing.

Modal Layout Progressive Enhancement With ColdMVC

So you have a link that opens a blank target you would like to open in a modal, eh?

In this example I will present a simple approach using ColdMVC and Progressive Enhancement. What is Progressive Enhancement you ask? That is a hell of a question… and the more you research it, I guarantee you will find an ongoing debate on whether an escalator is Progressive Enhancement or Graceful Degradation. Regardless, the basis of Progressive Enhancement is the approach of building functionality in its simplest form to work in non-modern browsers and then enhancing it to work awesome in modern browsers while Graceful Degradation is the approach of building something awesome for modern browsers and then attempting to accommodate non-modern browsers.

Got it? Good. Let’s get started…

If you are unsure what a layout is, I will defer you to the ColdMVC documentation and a nice post by Tony Nelson about layouts and how they function within ColdMVC:

http://www.coldmvc.com/guide/views/layouts
http://bears-eat-beets.blogspot.com/2010/04/coldmvc-layouts.html

In this example I will be using ColdMVC, jQuery, and jQueryUI to demonstrate how to take a simple link to a blank target and then hijack it to load in a modal with a modal layout.

Along with the addition of a couple JavaScript files, this exercise requires a controller, two layouts, and a couple views.

Here is what your project should look like:

[""]

A quick note before we get started… if you are starting a new project while reading this post, be sure to set ‘datasource=’ equal to blank in your config.ini as we will not be connecting to a datasource.

config.ini
1
2
3
4
5
  [default]
  controller=user
  [development]
  development=true
  datasource=

Let’s get coding…

Here is our standard layout/default.cfm, controller/UserController.cfc, view/user/list.cfm, and view/user/show.cfm prior to enhancment.

layouts/default.cfm
1
2
3
4
5
6
7
8
 Progressive layout enhancement example with ColdMVC

  #renderCSS("reset.css")#
  #renderCSS("style.css")#

  <h1>Default Layout</h1>

  #render()#
controllers/UserController.cfc
1
2
3
4
5
6
7
8
9
10
11
12
13
 /**
  * @accessors true
  * @extends coldmvc.Controller
  * @action list
  * @layout default
  */
  component {

   function list() {}

   function show() {}

  }
view/user/list.cfm
1
 <a href="#linkTo({action='show'})#" target="_blank">Open Me!</a>
view/user/show.cfm
1
 <span>This is my content!</span>

At this point the ‘Open Me!’ link should open the blank target ‘This is my content!’ as demonstrated in the images below…

[""] [""]

Working? Cool! Let’s enhance it!

If you haven’t already, add jQuery and jQueryUI to your application by saving the corresponding JavaScript files to the ‘js’ directory within ‘[your application name]\public’ – if the ‘js’ directory does not exist, create it. ColdMVC has a built-in function renderJS() available on your layouts; renderJS() accepts a JavaScript file name and attempts to retrieve the file from the ‘js’ directory.

Let’s start by updating our standard layout to load jQuery, jQueryUI, and application.js.

layouts/default.cfm
1
2
3
4
5
6
7
8
9
10
11
12
 Progressive layout enhancement example with ColdMVC

  #renderCSS("reset.css")#
  #renderCSS("style.css")#
  #renderCSS("jquery-ui-1.8.13.custom.css")#
  #renderJS("jquery-1.6.1.min.js")#
  #renderJS("jquery-ui-1.8.13.custom.min.js")#
  #renderJS("application.js")#

  <h1>Default Layout</h1>

  #render()#

Now lets add a modal layout.

layouts/modal.cfm
1
2
 <h1>Modal Layout</h1>
  #render()#

To load the correct layout by discerning regular requests from ajax requests, update your controller by adding the function annotation @ajaxLayout and set it to load layouts/modal.cfm

controllers/UserController.cfc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 /**
  * @accessors true
  * @extends coldmvc.Controller
  * @action list
  * @layout default
  */
  component {

   function list() {}

   /**
   * @ajaxLayout modal
   */
   function show() {}

  }

Next let’s update view/list.cfm by adding a class of ‘modal’ to our anchor tag.

view/list.cfm
1
 <a class="modal" href="#linkTo({action='show'})#" target="_blank">Open Me!</a>

Lastly, we need to use JavaScript to hijack clicking of anchor tags with the class ‘modal’.

public/js/application.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
   $(function(){

      //select all anchors with the class modal and iterate through returned array
      $('a.modal').each(function(index, element){

          var $anchor = $(this);
          //set url from anchor href attribute
          var url = $anchor.attr('href');

          //create a document fragement
          $modal = $('<div/>');

          //load the url using ajax
          $.get(url, function(data){
              //populate the document fragement with the returned html
              $modal.html(data);
          })
          .done(function(){

              //add a click event listener to the anchor tag
              $anchor.click(function(event){

                  //prevent default to ensure a blank window is not opened
                  event.preventDefault();

                  //open the modal dialog
                  $modal.dialog({
                      modal: true
                  });

              });

          });

          //finally, insert the document fragement into the DOM
          $modal.appendTo('body');

      });

  });

Ok, let’s check it out. If all is correctly in place.

When ‘Open Me!’ is clicked…

[""]

…The click event should be hijacked and a jQueryUI Dialog should open containing the view/user/show.cfm in the modal layout.

[""]

If JavaScript is disabled in your browser or the link is right clicked and new window/tab is selected, show.cfm should open in our standard layout.

[""]

Yeehaa! We have modal layout Progressive Enhancment with ColdMVC, jQuery, and jQueryUI.

Comments