Share

LinkedIn

Modal Windows and Sitecore - How to Give Content Authors More Flexibility

Some time ago, one of our clients expressed a need to use modal dialogs to display biographical information about the members of their governance committee.

The expected end result was to produce a modal dialog (a kind of pseudo-popup, often referred to as a “lightbox”) whenever certain links are clicked.  The dialog needed to display text in the title bar and rich text content in the dialog window’s body.

Being a big fan of jQuery for front-end functionality, I wanted to create a solution that used the excellent jQuery UI library and a customized jQuery Themeroller skin that matched the site design.  Additionally, I felt the solution needed to be easy for content authors to implement without developer intervention and provide some kind of value to non-JavaScript clients—including search engine web crawlers.

In this article, I’ll break down my solution for you and provide a few recommendations along the way.

UI Framework: jQuery UI
This solution doesn’t hinge on the use of JQuery UI.  You can use whatever alternative library you prefer.  I’m a fan of jQuery and jQuery UI, so that’s what I chose.  If you choose other tools, my code can serve as a basic guideline.

Head out to the jQuery UI site (www.jqueryui.com).  Use the Themeroller to create a color scheme and style that compliments your site design.  When your theme is ready, click “Download theme”.

Sitecore development
 
Next, determine which of the UI and Effects libraries you’ll actually need.  In my case, I selected as few components as possible, as I wanted to keep this feature fairly lightweight.

Sitecore development
 
Download your custom library and implement those assets into your Sitecore project.

Tip: Be sure to use jQuery in NoConflict mode to avoid interference with Sitecore’s JavaScript library of choice.

Content for your Dialogs
We’re going to need a place to store our dialog content.  Let’s start with an new Item Template.  We’ll call our template “Content Dialog”.  A “Title” and “Body” field should be sufficient.

Sitecore development
 
Tip: You’ll probably want to provide a common location in your Sitecore content tree for all of these Author-created Content Dialog items to reside.  This folder should have Content Dialog in the Insert Options, so make life easier for your Authors :)

Rendering your Content Dialog Items
With our Content Dialog template created, go ahead and create some rendering components.

Note: Remember, one of our objectives is to create a solution that gracefully “degrades” when JavaScript is not enabled on the client.  This is why we want our Content Dialog items to render as pages, instead of a different approach using web services to populate our dialogs.

For your rendering, you’ll want something fairly minimalistic since the contents of page are to be displayed in the body of the modal window.  You probably don’t want your site’s navigation menus, footer, breadcrumbs, images and the like being loaded along with your modal dialog content—do you?

Here’s an example of how your rendering should be formatted:

<a href="/">< Back to the site!</a><br />
<div id="dialog">
<div id="dialog-title">This is the title</div>
<div id="dialog-body"><p>This is the RTE body content</p></div>
</div>

Note: Notice the DIV element with id=”dialog”?  The JavaScript we’re about to write will only load the contents of that element into the dialog body.  Anything outside of that container, such as the “Back to the site” link, will be visible only to those non-JavaScript clients.  Understanding this will be helpful if you want to lightly dress-up the page and make it more practical for any site visitors or spiders that stumble upon the full page version.  Just remember, even though your dialog will only display the contents of the dialog DIV container, the entire page rendering will be downloaded first—so, try not to make it too heavy.

The Fun Part: Client-side Code
Let’s code!  Open a common or global JavaScript file that you use throughout your site and include the following code.  There is probably room for optimization in the code below, but it works very nicely for my client.

//a globally-scoped variable to hold the reference to our dialog
var contentDialog;
  
//when the document/DOM is loaded...
jQuery(document).ready(function () {
    //call our initializer
    InitializeContentDialogs();
});
  
function InitializeContentDialogs() {
    //if we haven't created our DIV yet...
    if (contentDialog == null) {
        //create it, add it to the DOM inside the body element, and store a reference to the DIV
        contentDialog = jQuery("<div id=\"ContentDialog\"></div>").appendTo("body");
    }
  
    //foreach A element on the page, having class="content-dialog"...
    jQuery("a.content-dialog").each(function () {
        //wire-up a click event handler
        jQuery(this).click(function () {
            //when clicked, grab the value of the href attribute (and fix spaces)
            var href = jQuery(this).attr("href").replace(/\s/g, "%20");
            //clear-out our contentDialog DIV, use AJAX to load the href into the DIV
            //and execute the following anonymous function when AJAX request is complete...
            jQuery(contentDialog).html("").load(href + " #dialog", function (r, s, x) {
                var title;
                //if there was an error...
                if (s == "error") {
                    //set dialog content to display an error message
                    title = "Error: " + x.status + " " + x.statusText;
                    jQuery(contentDialog).html("<div class=\"error\"><p>Sorry! There was a problem loading the resource: " + href + "</p></div>");
                } else {
                    //otherwise, find the "dialog-title" element, hide it and use its content as the dialog's title
                    title = jQuery(this).find("#dialog-title").css("display", "none").html();
                }
                //Display our dialog!
                jQuery(contentDialog).dialog({ width: '550px', modal: true, title: title });
            });
            //prevent browser from following the href
            return false;
        });
    });
}

Giving Authors the Power
Our primary goal is to give our Authors the ability to implement these dialogs throughout their site.  In our solution, all our Authors really need is a CSS style.  Open your Editor.css file and add the following:

a.content-dialog {
}

You’ll notice we’re not actually applying any styles here.  We don’t necessarily need any.  Although, you could add some styling that gives a site visitor a visual indication that this link is different from others.  The core objective is simply to give the author a named style, which they can apply to their links throughout the site as desired.

Our new CSS class addition can now be assigned to links, either when working with General Link fields or in the Rich Text Editor’s Hyperlink Manager.

Sitecore development
 
Test It!
Here are the steps:

  1. Create a new Content Dialog item in your content tree and fill-in your content.
  2. Edit or create a page that has a Rich Text or General Link field.

  3. Create a link that points to your recently created Content Dialog item and assign the “content-dialog” class to the link.

That’s it.  Browse to the test page and enjoy the fruits of your labor!

Sitecore development

Sitecore development, Sitecore custom code

Comments

Add a Comment

*
*

Please confirm you are human by typing the text you see in this image:

Chiali said: 3/31/2014 at 2:02 PM

Hi,
Thanks for the post. I'm fairly new to sitecore, have solid html knowledge.
I just assign to a task of trigger the modal dialog window from rich text editor. I have follow your instruction til template “Content Dialog”. where should I put the rendering file and so on...
I know I sounds like have no idea about sitecore...:(

plz help! thanks!

Nathan Leach said: 4/8/2014 at 9:24 AM

Sorry for the delayed response! By now, you've probably worked through your issue already, but in case you haven't ...

You can place the file according to whatever your typical conventions are for your project. So long as the rendering or sublayout item that you add to Sitecore is configured properly (so that it can locate your file and/or rendering logic) and you assign the renderings to the presentation details of your items (usually assigned to the Standard Values of your Content Dialog template), then it should work fine.

The objective is to make those new Content Dialog items render to a browser, like any other page on your site but more minimally, so that jQuery can grab the rendered page and display it inside the dialog.

I hope this helps!