jQuery in XPages #7 – Pines Notify

In this article I will demonstrate how to implement a cool notification technique using Pines Notify.  This small (7k min) js library provides a wealth of flexibility and a feature set second to none. It can use multiple different CSS libraries (bootstrap, jQueryUI and others) so integration into your site is quick and simple.

Introduction

Pines Notify is a notification popup capability which is easily integrated into a website. Like most jQuery plugins there is a methods to instantiate the capability and the ability to pass in multiple parameters.  There are certainly other popup style plugins but this is easy to grasp and the examples are very good.

We are going to look at how to make some complex function popups like these…

Examples of Pines Notify popups
Examples of Pines Notify popups

Demonstration

There are two demonstration pages this week

The first demonstration is a basic port of the Pines Notify buttons from the original example into an XPage.

The second demonstration shows how the Pines Notify could be used in a real application

Download 

Click on the link to download the complete jQuery in XPages demonstration database (including Pines Notify).

Pines Notify

Pines Notify provides a basic shell for popup creation and the capability for multiple custom configurations. A “popup” by default is created on the top right of the screen and disappears after a fixed period of time. The the position, CSS, length of time shown, transparency, contents, callbacks and other features can be controlled through the use of parameters. There are too many to mention in one article but they can all be seen at the example website.

Sample Notification
Sample Notification

Adding Pines Notify to an XPage

The Pines Notify download contains the .js files (readable and minified) and a basic css file. These are easily added to our database as files in the WebContent folder.

Adding Pines Notify js and css fields to our database
Adding Pines Notify js and css fields to our database

Once we have added the js and css files to the database they can be added to our XPage as a resource(s)

	<xp:this.resources>
		<xp:script src="js/jquery.pnotify.min.js" clientSide="true"></xp:script>
		<xp:styleSheet href="css/jquery.pnotify.default.css"></xp:styleSheet>
	</xp:this.resources>

jQuery UI and jQuery

Pines Notify uses the jQuery library and jQuery UI CSS for display. These are added to the XPage as additional resources

	<xp:this.resources>
		<xp:script src="js/jquery-1.7.1.min.js" clientSide="true"></xp:script>
		<xp:styleSheet href="css/jquery.custom-theme/images/jquery-ui-1.8.18.custom.css"></xp:styleSheet>
	</xp:this.resources>

Using Pines Notify

Pines Notify has a basic format for activating. Here is a sample button from the website:

<button class="btn source" onclick="$.pnotify({
 	pnotify_title: 'Regular Notice',
 	pnotify_text: 'Check me out! I\'m a notice.'
});">Regular Notice</button>

In this format the button does not work correctly when added to an XPage as it causes a page refresh when clicked. To turn this into an functioning button we must use an <xp:button> like this one

<xp:button value="xPages Lower Timer" id="button1" styleClass="btn source">
<xp:eventHandler event="onclick" submit="false">
	<xp:this.script>
		<![CDATA[$.pnotify({
			pnotify_title: 'Regular Notice',
		 	pnotify_text: 'Check me out! I\'m a notice.'
		});]]>
	</xp:this.script>
</xp:eventHandler>
</xp:button>

The Pines Notify examples website gives us the code we need to create each button

Taking the sample code from the Pines Notify examples page
Taking the sample code from the Pines Notify examples page

And to convert this to our XPages button we just need to copy and paste this code and insert it into the <![CDATA[ code section above. Using this we can quickly and easily convert the examples into functioning XPages buttons.

Pinning Notifications

By default all Notifications have the ability to “pin” them to the screen. Should they contain information the user wishes to retain, they can do so

Pinning your notification
Pinning your notification

Closing Notifications

By default all notifications can be closed before they fade out using the X in the notification

Stacking notifications

Pines Notify notifications always stack on top of each other, so you never have to worry about position or overlaying issues, they will organize themselves nicely.

Showing all notifications

By default there is a bar added to the screen which allows user to see the last and/or all previous notifications.

Showing all previous notificaitons
Showing all previous notificaitons

Working this into XPages functionality

Javascript alert boxes have been used since the start of the web but they require a user click and an unnecessary interaction from the user if the point of the notification is just that – to notify the user of something.

In our XPages applications we could potentially notify the user after:

  • Successful REST update from the server
  • partialRefresh completion
  • form submission
  • Pager completion
  • General application workflow progress
  • Validation failure

really the possibilities are endless and really up to you the developer.

Examples

My demonstration site examples page has illustrated a number of buttons taken directly from the website and I have also added some notifications to the other jQuery in XPages examples (linked in through the menu).

On my second Demonstration page There are 4 simple examples of real application uses for Pines Notify

Dojo Toaster Widget

On the XPages server without the need for jQuery you can use the dojo toaster widget to provide a notification capability. You should take a look at Chris Toohey’s well written article on Mastering the Dojo Toaster for XPages to get a comparison.

Thanks

To Alan Hurt for pointing me in the direction of this plugin 🙂

Re-styling dynamic content with jQuery Mobile

We are going to quickly look at how using trigger(“create”) can solve the problem of adding dynamic content to a jQuery Mobile application within an XPage.

I will get to writing an article on jQuery Mobile in the future but in the mean time here is something which I came across – how do you re-style the page when new content is created?

Problem

How to re-style newly added content in a jQuery Mobile application.

Situation

I have an acceptance form which I am creating in my XPage application. I have a mobile only view which is determined using a re-direct based on the browser’s user.agent when the device access the application.

jQuery Mobile acceptance form
jQuery Mobile acceptance form

Users are able to add an unknown number of guests. To achieve this functionality I am inserting a new row into the Guest Name table using normal jQuery

$('[id$=add]').click(function() { // when you click the add link
        $('[id$=theTable] tr:last').before('<tr><td><input name="person"'+i+' id=person'+i+' type="text" value="" /></td><td><label id="label'+i+'" for="check'+i+'">Yes</label><input type=checkbox name=check1 id=check'+i+'></td><td><center><img border=0 id=img'+i+' onclick="removeInput(this.id)" src="images/badge-circle-cross-24-ns.png"></center></td></tr>');
        i++;
    });

Unfortunately when I do this out of the box the sweet looking jQuery mobile look and feel is not applied to the new content.

(This problem also occurs if you perform a partialRefresh on the content) and you get something not so nice looking

Adding dynamic content does not style well
Adding dynamic content does not style well

Solution

Fortunately the guys at jQuery Mobile, smart fellows that they are, overcome this issue very easily with a simple one line command which re-applies the mobile style to any element within the supplied container.

Selecting the parent table and applying .trigger(“create”) solves the problem nicely, and it does it so fast it is imperceptible to the naked eye.

$('[id$=theTable]').trigger("create")

And here’s the result – this “looks” so good I would almost rather replace the desktop browser version of this application and have everyone use this look and feel!

jQuery mobile page with the correct styling applied
jQuery mobile page with the correct styling applied

I am amazed I got a response from google……

And now I look silly 😀

happy with the result though

 

The Blogger Team removals@google.com
7:58 AM (6 hours ago)

to me
Hello,

Thanks for reaching out to us!

We have received your complaint. Upon recent review of the website(s)
mentioned in your complaint, we were unable to locate the allegedly
infringing content on the page(s) in question. If this matter is still a
concern, please reply to this email with detailed information to enable us
to locate the allegedly infringing content.

Regards,
The Google Team

LotusLearns steps over the line

LotusLearns reposted my entire article on watermark.js without my consent and even though there is a link back to the blog I take great exception to this unethical behaviour. The fact that there is adverts on this site and someone else may make money out of my content is gawling.

I copy other people’s ideas and code all the time and then re-purpose them with my own, new ideas. That is how we evolve culturally.

Look at my article and you will how to appropriately credit other people for their work. Ethically it is the right thing to do and I would expect anyone to do the same with my content.

I always link to the original with a comment and a name
I never copy and paste content without stating as such
I do not claim the idea as my own.

Lotus Learns has crossed the line with my blog content and many other people’s content and needs to be stopped.

I have reported it and so should you if you are affected

http://support.google.com/blogger/bin/request.py?hl=en&blog_URL=http:%2F%2Fwww.lotuslearns.com%2F&contact_type=main_tos&rd=1&blog_ID=5508407431819307136

In contrast http://planetlotus.com has my full consent to link to and re-publish my work. I signed up for it and gave my permission.

This is the ONLY site which I allow to do that.

Read my copyright statement on the about page if you are in any doubt. I specifically state you can reuse my CODE, I do not say you can reuse all my words without my consent.

I have asked for content to be removed. If it is I will re-word this article to say thank you for doing the right thing.

LotusLearns does not have my consent to republish my content and never will.

Pushing data to an XPage from the server – HTML5 eventSource

Introduction

We are going to look at the new HTML5 eventSource capability. Adapting the articles (posted here) and (posted here) I am goign to show you how to send data from the server to your XPage without using ajax to initiate the communication. I have the feeling there is a lot to learn in this area and we are just scratching the surface.

Browser Support

Yep – it is HTML5 which means no IE right now – Chrome should support this but my copy does not – so right now this demonstration is only tested and working in the latest version of FireFox.

Demonstration

The results of this article are demonstrated here, and I strongly suggest you use some kind of plugin to watch the traffic as the values chance – quite fascinating. Right click – View Source and see for yourself – no ajax! no jQuery, nothing fancy, just HTML5 in action!

http://demo.xomino.com/xomino/xPlay.nsf/xHTML5ServerSent.xsp

Server output

I have modified Stephan Wissel’s xAgent XSnippet to create a simple data stream using server-side output. Calling this xAgent through the web generated the following simple data output as seen here through Firefox HTTPFox plugin.

The thing to highlight is the Content-Type text/event-stream

xAgent output
xAgent output
<?xml version="1.0" encoding="UTF-8"?>
<!-- XPage which is not rendered but returns data like XML, JSON, etc.     -->
<!-- More: http://www.wissel.net/blog/d6plinks/shwl-7mgfbn                 -->

<xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false">
  <xp:this.afterRenderResponse>
	<![CDATA[#{javascript:
		var externalContext = facesContext.getExternalContext();
		var writer = facesContext.getResponseWriter();
		var response = externalContext.getResponse();

		// set content type, e.g. ...
		response.setContentType("text/event-stream");

		response.setHeader("Cache-Control", "no-cache");

		// read parameters, e.g. ...
		var param = context.getUrlParameter("myParam");

		// write HTML output e.g. ...
		writer.write("data: the number is "+@Random());

		writer.endDocument();
	}]]>
  </xp:this.afterRenderResponse>
</xp:view>

HTML5 JavaScript

In our xPage we create some JavaScript to instantiate and then listen to the eventSource
First of all we test to see if the EventSource is supported in this browser

		if(typeof(EventSource)!=="undefined") {

		else {
			dojo.byId("#{id:serverData}").innerHTML="Whoops! Your browser doesn't receive server-sent events.";
		}]]>

Using the following code we subscribe to the EventSource (xSendHTML5Data_1.xsp is the xPage described above)

			var eSource = new EventSource("xSendHTML5Data_1.xsp");

And then when we receive a message from the server we act on it

			eSource.onmessage = function(event) {
				//write the received data to the page
				dojo.byId("#{id:serverData}").innerHTML = event.data;
			};

This all comes together as the following ScriptBlock in the page

	<xp:scriptBlock id="scriptBlock1">
		<xp:this.value><![CDATA[//check for browser support
		if(typeof(EventSource)!=="undefined") {
			//create an object, passing it the name and location of the server side script
			var eSource = new EventSource("xSendHTML5Data_1.xsp");
			//detect message receipt
			eSource.onmessage = function(event) {
				//write the received data to the page
				dojo.byId("#{id:serverData}").innerHTML = event.data;
			};
		}
		else {
			dojo.byId("#{id:serverData}").innerHTML="Whoops! Your browser doesn't receive server-sent events.";
		}]]>
		</xp:this.value>
	</xp:scriptBlock>

Stopping the source

We are able to stop the source using eSource.close() that will stop the data being sent. I added mine in a button

	<xp:button id="button1" value="Stop the Source">
		<xp:eventHandler event="onclick" submit="false">
			<xp:this.script><![CDATA[eSource.close()]]></xp:this.script>
		</xp:eventHandler></xp:button>

Changing the refresh time

We are able to change the refresh time by returning the retry value in millisecond along with our data

writer.write("retry: 2000\ndata: the number is "+@Random());
setting the refresh time 2000ms
setting the refresh time 2000ms

Specifying an event name

This mercilessly ripped directly from the article – I have not done anything with the event listeners yet, but here the next thing I want to look at….using the data returned from the server to trigger events in the browser without having to parse the return string and take action on it – that’s a huge performance gain and distributes the tasks….more to come on that in the near future….

For example, the following server output sends three types of events, a generic ‘message’ event, ‘userlogon’, and ‘update’ event:

data: {"msg": "First message"}\n\n
event: userlogon\n
data: {"username": "John123"}\n\n
event: update\n
data: {"username": "John123", "emotion": "happy"}\n\n
With event listeners setup on the client:

source.addEventListener('message', function(e) {
  var data = JSON.parse(e.data);
  console.log(data.msg);
}, false);

source.addEventListener('userlogon', function(e) {
  var data = JSON.parse(e.data);
  console.log('User login:' + data.username);
}, false);

source.addEventListener('update', function(e) {
  var data = JSON.parse(e.data);
  console.log(data.username + ' is now ' + data.emotion);
}, false);

Enjoy 🙂

Demonstration

http://demo.xomino.com/xomino/xPlay.nsf/xHTML5ServerSent.xsp

QR code with your picture in it !

While researching the next jQuery in XPages article I came across a QR code designer page which allows you to add your own image into the code itself.

http://www.patrick-wied.at/projects/qr-designer/

You need to use the latest Chrome or FF browsers to get the full effect as he uses Drag and Drop to pull in the image but you can make something like this – how cool is that !!

QR code with your truly in the picture
QR code with Marky in the picture

jQuery in XPages #5 – jQueryUI (Accordion)

This week we are going to look at one of the capabilities offered by the jQueryUI website, that accordion. I am going to walk through how I added it to my demo website (because the menu was getting too large). jQueryUI is a jQuery plugin – it extends jQuery using the $selector.doSomething() notation.

We are going to turn a long inflexible menu

Old demo.xomino.com menu
Old demo.xomino.com menu

into this

jQueryUI Accordion Menu
jQueryUI Accordion Menu

Demonstration

To see the new menu in action go to demo.xomino.com

Download

You can download the sample database for all the jQuery in XPages article from here or the demo website.

jQueryUI

jQueryUI is a website which “provides abstractions for low-level interaction and animation, advanced effects and high-level, themeable widgets, built on top of the jQuery JavaScript Library, that you can use to build highly interactive web applications.

What that means for you and I is “a set of really cool visual effects to add to your website really easily” 🙂

The jQueryUI website is very easy to use and a lot of fun to look over. There are multiple demonstrations of everything from accordions, to popup boxes, to date pickers, to sliders, to tabs and many other of the capabilities similarly found within the dojo toolkit.

Individual Packages

In an analogous way to dojo, each of the different capabilities jQueryUI provides can be individually added to the webpage or you can select the ones you need and combine them into one single js file. Adding the capability is just a different process from dojo.

Building your jQueryUI download bundle
Building your jQueryUI download bundle

Themeroller

jQueryUI comes with many pre-built styles

jQueryUI styles
jQueryUI styles

Using the Themeroller you can modify these styles to match your own websites style (in my case oneui2.1_onyx). I happen to like the darkness ui (I am sure it is nothing psychological) and they go nicely together but we are going to adapt the theme to match onyx.

The Accordion

The accordion is created by adding a number of jQuery effects together. If you break it down, what is happening when you click on the header is that the open panel is being reduced in size to zero at the same time as the panel the user clicked on is being opened. There are many jQuery accordion knockoffs from the original – some are really sweet like RhinoSlider and may appear in later articles..

How does it work?

Check out the how does it work article to see how I put all this together

jQuery in XPages #5 – jQueryUI (Accordion) – How does it work?

In this article I will show you how to add a jQueryUI accordion to your XPage as a menu.

Demonstration site

This article is published in conjunction with the original post and the demonstration site

Download

The sample database is available from the link above and (here)

Rolling my theme

Using the jQueryUI themeroller I modified the darkness ui theme to match the colors used by the oneui2.1_onyx CSS which the site now uses

Marky's Rolled theme

Once complete I downloaded the theme via the download builder. I included everything in the download because if I use jQueryUI at a later date I don’t want to have to go through this again – it is a demo site after all and page load time is not on my list of priorities (or I am lazy).

Being serious for a moment:

If you are going to use only one of the capabilities included in the builder for production you should remove everything else. The difference can be as much as over 150k and that will make a huge difference in pageload time.

The download

The contents of the jquery-ui-1.8.18.custom.zip are the necessary javascript and css files to create the visual effect and stylize the webpage. The folder content must be maintained with the structure and the css files refer to the images within the folder structure. You can change this at your own risk but I strongly suggest you don’t. The contents of the folder are as follows:

  • js folder
    • jquery-ui-1.8.18.custom.min.js
    • jquery-1.7.1.min.js
  • css
    • custom-theme
      • jquery-ui-1.8.18.custom.css
      • images
        • 14 images supporting the style

Adding the files to your database

The js file and the css file should be dragged and dropping into the WebContent folder of your database. Visible from the package explorer view of your database.

Adding the jQuerUI files to your database WebContent folder
Adding the jQuerUI files to your database WebContent folder

Adding the file references to your XPage

Within my demo database I have a commonContainer Custom Control that controls my look and feel. I am going to add the file references to that custom control in the following manner. In the source panel at the top of the page I add a reference to each of the necessary js and css files (the paths are relative the XPage)


Adding the Accordion to the menu

Currently the menu is created using this XML markup

<ul>
	<li><strong>#1 High Charts</strong></li>
	<li></li>
	<li></li>
	<li>
</li>
</ul>
etc etc.........

which generates the following HTML when viewed through the webpage

<div class="lotusMenu">
<div class="lotusBottomCorner">
<div class="lotusInner">
<ul>
	<li><a id="view:_id1:_id2:link9" class="xspLink" href="SampleDB/jQInX.zip">Download the Sample DB</a></li>
</ul>
<ul>
	<li><strong>#1 High Charts</strong></li>
	<li><a id="view:_id1:_id2:link1" class="xspLink" href="/xomino/jQinX.nsf/xFruit_Data.xsp">Binding to a Data Table</a></li>
	<li><a id="view:_id1:_id2:link2" class="xspLink" href="/xomino/jQinX.nsf/xFruit.xsp">Binding to a View Panel</a></li>
	<li><a id="view:_id1:_id2:link3" class="xspLink" href="http://www.highcharts.com/demo" target="_blank">Highcharts.com Demos</a></li>
</ul>
<ul>
	<li><strong>#2 Labelify</strong></li>
	<li><a id="view:_id1:_id2:link4" class="xspLink" href="/xomino/jQinX.nsf/xLabelify.xsp">Visual Field Enhancement</a></li>
</ul>
 etc.....</div>

looking at the jQueryUI Accordion example page the menu is created from HTML looking like this….

<div id="accordion">
<h3><a href="#">Section 1</a></h3>
<div>Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.</div>
<h3><a href="#">Section 2</a></h3>
<div>Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.</div>
</div>

The critical thing to grasp is that the HTML for each part of the must eventually look like this

<h3><a href="#">Section 1</a></h3>
<div>Text of the link - can be HTML here</div>

And my menu currently does not – time for some basic re-coding. Not hard just tedious (and like the good programmer I am – I am so glad I planned out the website before I started coding it) (*coughs politely*) As this menu is going to grow each week (I assume) it would be foolish to hard code it every week – so I am going to create some documents to represent the menu items and using a Repeat Control I am going to display the documents as HTML to build the Accordion.

Creating the Menu documents

I am going to use a “menu” form to create the documents (not worth an XPage as I am doing this through the client on the back end), and a vwMenu view. The form is very basic (like I said – this is back end only for me, not a production-worthy creation).

Simple menu creation form
Simple menu creation form

The view is categorized with the HTML I am going to need already written into the view columns. Because some of the links are to external websites we have to make a check and if so include the whole URL and not a relative one to the XPage

vwMenu Columns

To generate the HTML for the menu I used a repeat control – I use the repeat control to @DbColumn() the first column of vwMenu and then for each value in that list I am @DbLookup() the values in the 2nd column.

I was doing this with a computed text field and that initially caused me a problem. As you can see from the image below there is a lot more HTML generated that I need for the accordion…..there are way too many SPANS and DIVS

<span class="xspTextComputedField">
</span>
<h3><a href="#">#1 HighCharts</a></h3>
<div>
<a href="/xomino/jQinX.nsf/xFruit_Data.xsp">Binding to a Data Table</a>

<a href="/xomino/jQinX.nsf/xFruit.xsp">Binding to a View Panel</a>

<a href="http://www.highcharts.com/demo">Highcharts.com</a></div>
<span class="xspTextComputedField">
</span><span class="xspTextComputedField">
</span>
<h3><a href="#">#2 Labelify</a></h3>
<div>
<a href="/xomino/jQinX.nsf/xLabelify.xsp">Visual Field Enhancement</a></div>
<span class="xspTextComputedField">
</span><span class="xspTextComputedField">
</span>
<h3><a href="#">#3 Masked Input</a></h3>
<div>
<a href="/xomino/jQinX.nsf/xMaskedInput.xsp">Visual Field Enhancement</a></div>
<span class="xspTextComputedField">
</span><span class="xspTextComputedField">
</span>
<h3><a href="#">#4 prettyPhoto</a></h3>
<div>
<a href="/xomino/jQinX.nsf/xPrettyPhoto.xsp">A lighbox</a></div>
<span class="xspTextComputedField">
</span><span class="xspTextComputedField">
</span>
<h3><a href="#">#5 jQueryUI</a></h3>
<div>
<a href="http://jqueryui.com/demos/accordion/#collapsible">jQueryUI.com accordion</a></div>
<span class="xspTextComputedField">
</span>

This would not work for the accordion which needs a very specific format to work – so thanks to Mark Leusink – I have a new XPages *Best Friend Forever* – disableTheme=”true”.

To remove the <span id=”blah” and return to the HTML I really want from the view there are two steps:

  1. Remove the id from the field
  2. In the All Properties tab select disabledTheme=true
remove the id and select disableTheme=true
remove the id and select disableTheme=true

And this gives us the final code to make the menu


								<![CDATA[#{javascript:@DbColumn(@DbName(), "vwMenu", 1)}]]>

									<![CDATA[#{javascript:
										var temp = vwMenuCol1Repeat;
										var temp1 = "
<h3><a href=\"#\">"+temp+"</a></h3>
"
										temp1+"
<div>"+@Implode(@DbLookup(@DbName(), "vwMenu", temp, 2))+"</div>
"
									}]]>

I added a DIV wrapper to the Menu HTML so that the jQuery function would have an object I could select on. The selector uses [id$=menuContainer] rather than my x$ function just for variety. [id$=] selects all elements which finish with menuContainer. Activating the accordion plugin inside of a scriptblock at the bottom of the page completes the menu code.


									<![CDATA[ 									$(function() { 										$( "[id$=menuContainer]" ).accordion({ 											collapsible: true} 										}); 									}); 								]]>

and we have a menu……with two remaining issues……

  1. The links are black – being inherited from the lotusui class in the Oneui stylesheet
  2. The 1st Highcharts panel always opens (not the section we clicked on)

To remove the black links we add a style to the control to override the oneUI black links

 .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited {
 color: #FFFFFF !important;
 }
 .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited {
 color: #FFFFFF !important;
 }
 .lotusMenu h3 {line-height: 0.3}
 

To overcome the panel not opening as a user would expect it, we are going to use a scoped Variable, scoped only to this page. We are going to set the menuOpen viewScope variable in the preloading of the page – in this case

	<![CDATA[#{javascript:viewScope.menuOpen=3}]]>

and activate the panel with the scoped variable in the accordion build code – active: #{viewScope.menuOpen}.


									<![CDATA[ 									$(function() { 										$( "[id$=menuContainer]" ).accordion({ 											collapsible: true, 											active: #{viewScope.menuOpen} 										}); 									}); 								]]>

and we have a new menu 🙂

The accordion menu

Demonstration site

This article is published in conjunction with the original post and  demonstration site

PS

I know I am going to run out of space on this accordion menu within 10 articles or so – an excuse for a new article? 😉

XPages CSJS timing issue – what is ‘this’ ?

Problem

The JavaScript object represented by ‘this’ does not appear to be as expected.

The problem is caused because of the way that XPages adds events to DOM objects through the <xp:eventHandler>

The Situation

I wanted to pass the id from a button to a function. Outside of XPages I would normally acheive this by passing a reference to the button(this) to a function (saySomething in this case) and then extracting the id from the object passed:

function saySomething(obj){
	alert("This is my object - "+this
		+"nnThis is my id - "+
		this.id)
}
Describing 'this' when passed from a button to a function
Describing ‘this’ when passed from a button to a function
	<button id="markyButton" onclick="saySomething(this)"></button>

In this case I am passing the “this” object to the function.

this

is an object reference to the DOM element which it was generated from – for some serious stuff on ‘this’ check out this article

http://www.quirksmode.org/js/this.html

XPages fail 😦

However when I add the JavaScript to the XPages button and add the code through the GUI Designer interface

Adding JavaScript through the XPages GUI
Adding JavaScript through the XPages GUI

I do not get the expected result when I click on the button……

Not what we expected
Not what we expected

The Explanation…

The reason this happens is because of the way that XPages assigns events to objects in the webpage. If you have ever looked at the source of an XPages you will almost certainly have seen a whole load code like this at the end of the page

XSP.addOnLoad(function() {
XSP.attachEvent(".....
}

and this is how the XPage adds the event to the object – in the case of this example the XPages creates our button in the HTML but as you can see there is no onclick event initially assigned to it

		<button class="lotusBtn" type="button" name="view:_id1:_id2:_id37:button1" id="view:_id1:_id2:_id37:button1">Click This</button>

and then at the bottom of the web page source code we can see the assignment of the event after during the “addOnLoad” which means after the page has loaded.

<script type="text/javascript">

function view__id1__id2__id37__id40_clientSide_onclick(thisEvent) {
alert("This is my object - "+this+"nnThis is my id - "+this.id)

}

XSP.addOnLoad(function() {
XSP.attachEvent("view:_id1:_id2:_id37:_id40", "view:_id1:_id2:_id37:button1", "onclick", view__id1__id2__id37__id40_clientSide_onclick, false, 2);
});

</script>

What is happening?

The XPage is adding the function “view__id1__id2__id37__id40_clientSide_onclick” to the “onclick” event of the “view:_id1:_id2:_id37:button1” DOM element (our button in this case).

The nuances of this are subtle but important – the code is not adding “alert(whetever)” to the onclick event it is adding a function call to the onclick event.

So. when the button is clicked the function view__id1__id2__id37__id40_clientSide_onclick executes it’s code and in that situation ‘this’ no longer refers to the button.

The difference is clear when we look at the resulting code side by side

<button value="or Click this" id="button3" onclick='alert("This is my object - "+this+"nnThis is my id - "+this.id)'></button>

or

<button value="or Click this" id="button3" onclick='view__id1__id2__id37__id40_clientSide_onclick()'></button>

“this” is never passed to the view__id1__id2__id37__id40_clientSide_onclick() function and therefore any reference to the button is lost.

When the function executes – “this” refers to the function (which isn’t an object) and therefore we get the window (the webpage) as a failover.

The solution

If you need to do something like this then add the onclick event to the source pane.

Here is the XML markup for the XPages generated event (which fails me)

		<xp:button value="Click This" id="button1">
			<xp:eventHandler event="onclick" submit="false">
				<xp:this.script>
					<![CDATA[alert("This is my object - "+this+"\nThis is my id - "+this.id)]]>
				</xp:this.script>
			</xp:eventHandler>
		</xp:button>

and the XML markup  for the manually added onclick event (which works)

		<xp:button value="or Click this" id="button2"
			onclick='alert("This is my object - "+this+"\nThis is my id - "+this.id)'>
		</xp:button>

The demonstration

Here is a simple demo of the problem and the solution

jQuery in XPages #4 – prettyPhoto

This week we are going to look at a lightbox. A lightbox is a capability whereby the user clicks on a thumbnail image and the full size image is displayed on the screen. There are many of them, but I chose prettyPhoto because it also includes videos and flash plugins which makes it more flexible. So here goes….

prettyPhoto

prettyPhoto provides the developer an easy way to create a powerful visual effect on the webpage, whereby the user is able to view a slideshow of images.

A user sees a group of thumbnails

A group of thumbnails
A group of thumbnails

and is able to interact with them like this

Using prettyPhoto you can also embed a youtube video effectively within your page without it taking up real-estate

prettyPhoto is very easy to use within your XPages – this example uses 8.5.3 attributes for the links but you can actually achive this effect by just pasting the HTML into your XPages source.

To see how the effect is created check out the How does this work article…. 🙂