[an error occurred while processing this directive]

Forums >> Programming >> Proof of Concept (POC) >>
Displaying Messages in a jQuery UI "Window"




Posted:
bvstone

Displaying Messages in a jQuery UI "Window"

 
Displaying Messages in a jQuery UI

We recently updated our website so that when you click on a link to an article or post, instead of loading an entire new page with that article we display it's contents in a "Window" that is created using functions included in jQuery UI.

Now, I saw "Window" in quotes because it's not an actual window, but a HTML/CSS representation of a window.  Either way, it's pretty neat.

The first issue he had was that all the links to the posts and articles looked like this:

http://www.fieldexit.com/forum/display?threadid=255

Just your normal every day standard hyperlink calling an application and passing some data to it (in this case the thread ID).

We didn't want to have to go through each application and link that already exists to update things, so we decided to find a solution using jQuery and jQuery UI.  Not only does will this allow us to customize the experience of visitors, but it will also not disrupt bots and crawlers indexing the site.

The Windowed Solution

From our past adventures with jQuery we know that pretty much anything is possible.  We know that for clicks, keyboard presses, etc we can catch those actions and override them to do what we want.  So, we created a new function and placed it in our document.ready() function:

$(document).ready(function(){

.... other jQuery functions


	displayPostWindow();
}

The "displayPostWindow() function is used to override the action when a user clicks on a hyperlink that leads to a post.  That function is as follows:

function displayPostWindow() {
	$('body').on('click', 'a[href^="/forum/display"]', function(event) {
		event.preventDefault();

		$.ajaxSetup({
			global: false
		});

		if (typeof theDialog == "undefined") {  //check if div already exists
			theDialog = $('<div id="postWindow" />').dialog({
				autoOpen: false,
				resizable: true,
				modal: true,
				width: "90%",
				buttons: [{
					text: "Close",
					click: function() {
						$( this ).dialog( "close" );
					}
				}]
			});
		}
		
		theDialog.html('<img src="/images/loader.gif"/>').dialog('open');
		theDialog.dialog({title: 'Loading content...'});

		var url= $(this).attr('href') + '&heading=n';
		
		$.get(url, function( data ) {
			subject = $(data).find('h3').text();
			theDialog.dialog({title: subject});
			theDialog.html(data).dialog();
		})
		.always(function() {
			$.ajaxSetup({
				global: true
			});
		});
		
	})
}

At first glance this may seem a bit complicated, but it's really not.  Let's break it up into sections.

The first thing that happens is overriding the action that takes place when a user clicks on a hyperlink.  In the past the click would calls the "display" server side program and display the post.  We overrid this action using the following code:

	$('body').on('click', 'a[href^="/forum/display"]', function(event) {
		event.preventDefault();

We are matching only clicks on hyperlinks that actually call the display server program using string matching techniques.  We then use the preventDefault() function to stop the default action (which would be to call the display program).

Next, we turn off the global flag for Ajax requests.  Part of this solution will be using the jQuery get() function which is really a simple wrapper for an Ajax call.  We already had a the blockUI addon set up so that on Ajax calls we display a "Please Wait" page block while we process a request (such as posting a new article).  We don't want this to happen when we retrieve the information for the message to display which is why we use the ajaxSetup() jQuery function:

		$.ajaxSetup({
			global: false
		});

Later we will change this flag back to true so that other functions aren't messed up.

This next piece of code is used to create a Dialog object.  It may look like a lot of work, but we need to make sure we don't duplicate the object.  In the next section we are setting up the Dialog (which is part of jQuery UI) element that is used as the "window".

		if (typeof theDialog == "undefined") {  //check if div already exists
			theDialog = $('<div id="postWindow" />').dialog({
				autoOpen: false,
				resizable: true,
				modal: true,
				width: "90%",
				buttons: [{
					text: "Close",
					click: function() {
						$( this ).dialog( "close" );
					}
				}]
			});
		}
		
		theDialog.html('<img src="/images/loader.gif"/>').dialog('open');
		theDialog.dialog({title: 'Loading content...'});

So, first we check to see if the Dialog object exists.  If not, we create one and set the values for the dialog itself.  Once that is complete we set the value of the dialog window to a loading image as well as set the title of the dialog to state that the data is being loaded.

The next step is to fill the dialog with the actual post information.

		var url= $(this).attr('href') + '&heading=n';
		
		$.get(url, function( data ) {
			subject = $(data).find('h3').text();
			theDialog.dialog({title: subject});
			theDialog.html(data).dialog();
		})
		.always(function() {
			$.ajaxSetup({
				global: true
			});
		});

In order to call the jQuery get() function to retrieve the post information from our web application we need to create the URL to call.  The URL we want to call actually already exists in the link almost exactly how we want it.

Because all of this code is running when a user clicks a hyperlink to view an article or post, we can refer to the link object itself as "$(this)".  In other words, we can work with "this" link that was clicked.

We strip the href value from the link and tack on an extra parameter that will tell our application that when called using this method we don't need to display the header information.  All we want is the post.

We then call the get() function.  Once done all of the HTML, CSS, etc will be in the "data" parameter. 

Because we want our dialog to have a title of the actual subject of the article we use the jQuery find() function to retrieve the subject which in this case is always wrapped in the <h3> container.

We then set the title of the dialog to the subject, and load the dialog object itself with all of the data returned from the get() function.

Finally, we set our Ajax global flag back to true.  In this example we're doing it using the always() callback function of the get() function.  This is so that no matter what happens with the call to the get() function this flag will always get set back.

The Results

The end result is pretty neat!  We now get a pop up window that loads the post much quicker than displaying it as a separate page.  This is mainly because all of the CSS, JavaScript and other resources don't need to be reloaded.

Also, for crawlers and bots indexing the site the actual links still exist and work as they did before.  

We continue to find more and more neat things you can do with jQuery and the hundreds of addons created for it.  It keeps things interesting and fun!

 


Last edited 01/19/2016 at 08:53:20


Posted:
bvstone

RE: New Message Display Method (Implementing jQuery UI)

 
RE: New Message Display Method (Implementing jQuery UI)

We have made a few updates to this method now.  We decided that every time a message is clicked on it isn't always a good idea to show the "pop up" version of the message.  So, in this cases (so far) the full message will be shown instead of the pop up version:

  1. When you click on the title of a message (when viewing the message in a pop up)
  2. When you click the "in reply to" or "thread start" links when viewing a message

We will continue to look into other times this will be done and would love to hear when you feel the pop up version doesn't quite work as good.

How did we do this?  It was actually quite easy.

We first added an attribute to each of the hyperlinks we wanted to bypass the pop up view method as such:

<a href="/forum/display?threadid=/%threadid%/" data-id="showfull">

As you can see we added a data-id attribute of showfull.  (This really could have been anything, but we chose this value).

Next, in our Javascript we added an if statement around the pop up method as such:

function displayPostWindow() {
	$('body').on('click', 'a[href^="/forum/display"]', function(event) {
		
		if ($(this).attr('data-id') != 'showfull') {
			event.preventDefault();
	
            ...
			
		}
		
	})
}

Have we mentioned how much we love jQuery?  :)


Last edited 03/08/2016 at 10:08:12


Reply




Copyright 1983-2017 BVSTools
GreenBoard(v3) Powered by the eRPG SDK, MAILTOOL Plus!, GreenTools for Google Apps, jQuery, jQuery UI, BlockUI, CKEditor and running on the IBM i (AKA AS/400, iSeries, System i).