jQuery in XPages #12 – Flip.js (animated context changing)

In this article I will demonstrate how you can easily add a custom “Flip” to show different data on your XPage. This is a stylistic decision you have to make when creating your XPage. If you have a lot of Static data to fit on the screen and your user is ok not seeing all the same data at the same time this is a nice looking transition from one context to another.

Demonstration

The XPages integration of Flip.js is demonstrated here

Download

The demonstration database can be downloaded from the link above or from here

Flip.js

Introduction

Flip.js is a simple plugin which facilitates an aesthetically pleasing transition between data contexts on your XPage. The jQuery Plugin is capable of “flipping” context in 4 directions and also reverting back to the previous context display.

For more information flip.js check out their website – http://lab.smashup.it/flip/

Example

In my example I took the existing code which created my highcharts demo  and instead of showing both the data and the chart at the same time – I am flipping between them. This is a very simple demo and yet created a dynamic effect on the page for very little overhead (12k, 5k minified). As you can see from the video above the transition is “cute” and adds something appealing to the site.

How does it work

The demonstration site uses jQuery, jQueryUI which are already added to my demo site through a theme and the following files.

  • js/jquery.flip.js
  • css/flip_099.css

These files are added to the database via the WebContents folder as described in previous articles within this series.

jQuery and jQueryUI are referenced through the database theme as follows:

<theme extends="oneuiv2.1_onyx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="platform:/plugin/com.ibm.designer.domino.stylekits/schema/stylekit.xsd" >
	<resource>
		<content-type>application/x-javascript</content-type>
		<href>jquery-1.7.1.min.js</href>
 	</resource>
	<resource>
		<content-type>application/x-javascript</content-type>
		<href>js/jquery-ui-1.8.18.custom.min.js</href>
 	</resource>
 	<resource>
		<content-type>text/css</content-type>
		<href>css/custom-theme/jquery-ui-1.8.18.custom.css</href>
	</resource>
</theme>

The Flip.js files are added to the XPage via the following script/link files

	<script src="js/jquery.flip.js" clientSide="true"></script>
	<link rel="stylesheet" href="css/flip/flip_099.css" />

The XPage contains two main display elements – the flipbox and the the flipPad which controls the flipbox. As you can see from the code below the flipbox contains my chart data by default. The anchor tags have the following attributes:

  • rel
    • The direction of the flip (rl = right left, lr, ud=up down, du)
  • thePanel
    • The idTag of the element whose innerHTML will be displayed in the flip
<div id="flipPad">
	<a href="#" class="left" rel="rl" thePanel="panelFlip1" title="Show Chart" style="padding-right: 20px">
		Show Chart
	</a>
	<span>     </span>
	<a href="#" class="right" rel="lr" thePanel="panelFlip4" title="Show Data">Show Data</a>
</div>
<div id="flipbox" style="background: white; color: black">
	<xc:formFlip_Fruit_Data_Table></xc:formFlip_Fruit_Data_Table>
</div>

The Flip.js capabilities are then controlled by binding the jQuery functions to the anchor tags:

$(function(){
	$("#flipPad a").bind("click",function(){
		var $this = $(this);
		var thePanel = '[id$="'+$this.attr("thePanel")+'"]'
		$("#flipbox").flip({
			direction: $this.attr("rel"),
			color: '#FFFFFF',
			content: $(thePanel).html()
		})
		return false;
	});
})

Here’s the English version of what’s happening in the above function:

  • For all a in the #flipPad
    • Bind the click event of the anchor tag to do the following:
    • Get the “thePanel” attribute from the anchor tag
      • [id$=”‘+$this.attr(“thePanel”)+'”]’ equates to
        • [id$=”panelFlip1″]
    • When the click event happens
      • Flip the flipbox in the “rel” direction
      • color the background white (returns from the gray flip color)
      • display the html() of the selected panel

And finally the panels on the XPage containing the chart and the data are custom controls (slightly modified from the original demonstration for this purpose)

	<xp:panel id="panelFlip1" style="display:none">
		<xc:formFlip_Fruit_Data></xc:formFlip_Fruit_Data>
	</xp:panel>

	<xp:panel id="panelFlip4" style="display:none">
		<xc:formFlip_Fruit_Data_Table></xc:formFlip_Fruit_Data_Table>
	</xp:panel>

Conclusion and The Next Step

As you can see form the demo this is a quick and simple, effective, way to add some animation to your XPage and kick things up a bit for the user. This demonstration uses static data which in many cases works, but in others you might want to retain the XPage functionality in your flip…..

The limiting factor for this demonstration is that it uses a COPY of the HTML within the panel container – what that means if that if you have a viewPanel with a pager, it will not work in this context because you are copying the HTML the XPage gets very confused if you try and then do something functional with it.

What would be a major step up would be to modify the plugin code to replace the flipbox with the object itself and not a copy of the HTML container. In that way you would be able to move the viewPanel and all its functionality in and out of the flip and it would retain all the paging functionality.

  • You’d need to create a container holding div with the panel objects within it.
  • You’d them pop the panel objects off the container object and append them to the flipbox
    • be careful that the select the whole panel and not the contents (a viewPanel creates an outer table around itself)
    • Suggest that each “panel” is wrapped with a div you know the id of – that way you don’t have to worry about all the dynamic HTML the XPage creates for the control.
  • when the user “flips”, you programmatically pop the panel in the flipbox back to the container and pop in the new object from the container

I am fairly positive that can be done but there are only so many hours in the day 🙂

jQuery in XPages #11 – Joyride.js (How to add a website feature tour)

In this article I will demonstrate how you can easily create a website feature tour using the Joyride.js jQuery plugin and XPages. When releasing a new site or new features within a site it is always a good idea to let your users know what’s new and why. This can be done in a number of ways, but Joyride provides a fun and interactive way of showing the new information and can be linked to the wiki or other more formal documentation you create with a release.

Demonstration

The XPages integration of Joyride.js is demonstrated here

Download

The demonstration database can be downloaded from the link above or from here

Joyride.js

Introduction

Have you ever released a new XPage or website and wanted to visually guide a user around the new features or capabilities? Well now you can with Joyridejs in your XPage.

“Joyride gives you everything you need to call out new features in your app or website. Joyride is extremely flexible and lets you take control of how people interact with your tour. ” – http://www.zurb.com/playground/jquery-joyride-feature-tour-plugin

Example

Example – Using my previous article about prettyPhoto.js as an example I can highlight to sections in a visually appealing way and guide new users around the page.

prettyPhoto original XPage
prettyPhoto original XPage

Becomes and interactive site with descriptions and popups showing users around:

Joyride introduction to the site #1
Joyride introduction to the site #1
Joyride introduction to the site #2
Joyride introduction to the site #2

How does it work?

We first have to add our libraries and CSS to the database. I have started to move away from using xp:resources in my source code because the XPage is trying to load the files every time we build and save the XPage which slows down development. I am using the <script> and </link> tags directly within the XPage source itself.

The files are added to the database in the WebContents folder as described in previous articles within this series

	<script src="js/jquery-1.7.2.min.js" clientSide="true"></script>
	<script src="js/jquery.joyride-1.0.3.js" clientSide="true"></script>
  	<link rel="stylesheet" href="css/JoyRide/joyride-1.0.3.css"/>
  	<link rel="stylesheet" href="css/JoyRide/demo-style.css"/>

This plugin is controlled by creating an ordered-list of the elements you wish to highlight and within that list you state the contents of the popup for that element.

The attributes of the list elements controls the functionality of the Joyride:

  • data-id
    • The idTag of the element you wish to display this popup on “addNew”
  • data-text
    • What do you want displayed in the button “Next”
  • class
    • Styling information
  • <h2>
    • The Title of the popup
  • <p>
    • the Text (or HTML) within the popup
  • data-options
    • Gives you more control of the look/feel of the popup “tipLocation:top;tipAnimation:fade”
  	<ol id="joyRideTipContent">
  	  <li data-id="addNew" data-text="Next" class="custom">
  	    <h2>Add a New Image</h2>
  	    <p>Apparently this functionality is available in the live demo :)</p>
  	  </li>
  	  <li data-id="clickOnOne" data-text="Click ME" data-options="tipLocation:top;tipAnimation:fade">
  	    <h2>A simple Lightbox</h2>
  	    <p>You can produce a lightBox Slide show of the images by clicking on one of these</p>
  	  </li>
  	  <li data-id="seeYouTube" data-text="Next">
  	    <h2>See YouTube</h2>
        <p>Clickin on the NotesIn9 image will show you an example of the prettyPhoto running a YouTube video</p>
  	  </li>
  	  <li data-id="inLine" data-text="Close">
  	    <h2>View Inline Content</h2>
        <p>Clickin on the NotesIn9 image will show you an example of the prettyPhoto running a YouTube video</p>
  	  </li>
  	</ol>

At the end of the code we add the activation of the Joyride – this can also be added to a button on the form if you don’t want it loading when the page loads.

	$(window).load(function() {
		$(this).joyride();
	});

Options

Joyride.js comes with a lot of options for changing the presentation of the popups – you will also notice that some of these options are stored within the data-options of the controller ordered-list. It provides another layer of flexibility for being able to control all the popups in the same way or individually depending on what effect you are looking for.

/* Setting your options to override the defaults */
$(this).joyride({
  'tipLocation': 'bottom',         // 'top' or 'bottom' in relation to parent
  'scrollSpeed': 300,              // Page scrolling speed in ms
  'timer': 2000,                   // 0 = off, all other numbers = time(ms )
  'startTimerOnClick': true,       // true/false to start timer on first click
  'nextButton': true,              // true/false for next button visibility
  'tipAnimation': 'pop',           // 'pop' or 'fade' in each tip
  'tipAnimationFadeSpeed': 300,    // if 'fade'- speed in ms of transition
  'cookieMonster': true,           // true/false for whether cookies are used
  'cookieName': 'JoyRide',         // choose your own cookie name
  'cookieDomain': false,           // set to false or yoursite.com
  'tipContainer': body,            // Where the tip be attached if not inline
  'inline': false,                 // true/false for inline positioning
  'tipContent': '#joyRideContent', // The ID of the <ol> used for content
  'postRideCallback': $noop,       // a method to call once the tour closes
  'postStepCallback': $noop        // A method to call after each step
});

Something to think about
You don’t want to show the tour to every user every time for the first week of the new website. There are a number of ways you could control this – how you do it is really up to you….

  • Provide the users a “Click Here” button to take the tour
  • Provide user an opt out option and track their selection in a notesdocument or a cookie.
    • When the user enters the application check the option and do not render the window.joyride() script to start the tour.

Conclusion

In less than 1 hour I was able to knock up the demonstration page for this article – in the real world though you would add this tour option into the website planning from the start. The tags which the tour is displayed on are not going to affect the site if they are not used and can be added as part of the overall design from the start.

These popups are also a very good way of providing helptext to a user.

This is a very simple and very useful plugin which I know has lots of applicability to our applications and customers.

jQuery 1.8 coming soon with Optional Modules (smaller downloads)

If you look at the git site for jQuery 1.8 you will see that they are breaking the core jQuery code in separate modules so that you can do a custom build, based on what you need.

What this means is that you will be able to reduce the download size of the current 93k for the min.js version and exclude the “modules” you do not need.

Want a lighter weight jQuery 1.8? You can have it !

https://github.com/jquery/jquery#modules-new-in-18

Starting in jQuery 1.8, special builds can now be created that optionally exclude or include any of the following modules:

  • ajax
  • css
  • dimensions
  • effects
  • offset

How would you say Hello World in jQuery? (from Taking Notes podcast #157)

Today I recorded the Taking Notes podcast episode 157 with Bruce Elgort and Julian Robichaux and Bruce asked me “so how would someone get started in jQuery – you know like a Hello World kinda example” and I had to say – well you wouldn’t do that in jQuery – you would just do a JavaScript alert.

<script>
	alert('Hello World')
</script>

A better beginner example would be to use a selector to get all the blank fields on a form, turn them red and notify the user. It is a good question though and I will write an article on that in the near future…..

So what about Hello World in a jQuery plugin?

In hindsight, though I guess you could do what Bruce asked for – and if you HAD to….then you could use Pines Notify and do something like this, but I don’t think that is quite what he meant and this is not the beginners example he was looking for 🙂

Add your Pines Notify library and CSS to your XPage (just like in the previous article)

	<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: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>

And then Create your Hello World notification

			<xp:button value="Hello World Example" id="button3" styleClass="btn source">
				<xp:eventHandler event="onclick" submit="false">
					<xp:this.script>
						<![CDATA[$.pnotify({
					pnotify_title: 'Just for Bruce and Julian!',
					pnotify_text: 'Hello World.',
					pnotify_type: 'error'
					});]]>
					</xp:this.script>
				</xp:eventHandler>
			</xp:button>

Giving me what Bruce asked for 🙂

helloWorld using Pines Notify
helloWorld using Pines Notify

In all seriousness – thank you so much to Bruce and Julian for giving me the opportunity to be a guest in the Taking Notes Podcast – it was a blast and I know I join an elite group of people who’ve had the pleasure in the last 7 years 🙂

Marky

HTML5 – Battery Status – in your XPage!

I saw this article yesterday and I wanted to test it in XPages – no issues – but it only works in the latest version of FIREFOX 13 – it is just amazing what your browser is going to be able to do in the (near) future.

http://www.smartjava.org/content/html5-access-battery-status-through-javascript

Demonstration in an XPage (Firefox 13 only)

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

With the power plugged in

Battery Status through HTML5
Battery Status through HTML5

With the power plugged out

Battery Status through HTML5 (no power connected)
Battery Status through HTML5 (no power connected)

Not my work

I fully admit this is a complete rip-off and none of this code is my own – I just stuck it into an XPage to see if it would work

XPages Extension Library Book – it just makes you better!

In this article I will review the new XPages Extension Library book by IBM Press.

Introduction

If you are using or going to use XPages in your organization you need to get the Extension Library – it is already included in 8.5.3 UP1 and in the future it is just going to be part of the standard install and we won’t even consider it an “add on”.

And if you are a developer using the Extension Library, like you should, then you NEED to buy this book and read it. I am not understating that fact, you need to buy it, otherwise you are doing yourself and your company a disservice. What I realized very quickly was that I thought I knew the Extension Library, when in fact I had only scratched the surface and how much more functionality I could be taking advantage of. I have used many parts of the Extension Library now for a few months and I have stolen re-used parts of the example database like the REST services and basically copied and pasted them. I never really understand what they were and how the worked, but didn’t need to either………my loss apparently.

So what’s it do for me?

It just makes you better – and unless you improve and get better, someone else’s going to be doing your job for you!

What this book does is it breaks down all those sections you see every day in the Control Palette and explains it in simple to understand manner.

Extension Library controls in your Designer Control Palette
Extension Library controls in your Designer Control Palette

For example…

  • Chapter 2 – Installation and deployment, written from the perspective of someone who’s had to do it, a LOT and you know they know what they are talking about.
  • Chapter 4 – Forms Dynamic Content and More contains a section on the Dynamic Content control – that is the equivalent of computed Subforms – who knew!! Excellent !!
  • Chapter 5 – Dojo made easy– this does an excellent job of explaining how dojo is integrated into the XPage designer client with good examples!!
    • and I still prefer jQuery, but now I have an even better understanding of why 🙂
  • Chapter 9 – The Application’s Layout has a history of OneUI and while I still think it is massively over complicated for what it needs to be, there are clear explanations of how it breaks down and how you can manipulate each separate section for your evil needs
  • Chapter 11 – REST services took my knowledge from 10% to 90% in an hour. Soooooo many applications for this capability, I *really* wish I had had this 10 years ago!
  • Chapter 12 – XPages gets relational – oh yes it does baby!
  • Chapter 13 – Get Social – I would love to get social and now I know how to – (but I am not social and will now go back in my corner and cry)

 

Talk to me like a person – not a machine

You know when you add an ExtLib custom control to your XPage and you see the “All Properties” and 95% of the explanation seems alien speak to you? This book provides the “real person” explanation of the property and what it does for you. Laying all the properties out together in one place also makes is a whole lot easier to understand the control, its purpose and how you use it!

details on client - que?
details on client – que?

Is really IBM speak for….

oooh that's what it means
oooh that’s what it means

 

The Authors

To varying levels I have gotten to know the authors of this book over the last few months and they a genuinely some of the best people you could ever hope to meet. They wrote this book because they are just like you and me – developers – and they want to spread their knowledge and make the whole community better.

Conclusion

This book was written by developers for developers and like I said, you owe it to yourself and your company to check it out. The cost of the book is less than an hour’s worth of your time to your company and unless you are an XPage ÜberGenius already, you cannot help but learn from this book and it will pay for itself the first day you really sit down and read it.

Go Buy it ! No buts, just go buy it.

Keeping your jQuery interface updated when using an XPages pager – XSP.addOnLoad()

In this article I will describe how the judicious use of SCRIPT tags XSP.addOnLoad() can keep your jQuery UI enhancements applied when used with a pager control and a repeat control. This article is a follow on from the original article Using jQuery to add table interactivity to your XPage .

Introduction

First of all – many thanks to Jeremy Hodge who pointed me in this direction !

In the original article I demonstrated how you can add some interactivity to a table with a few lines of jQuery. But there is a catch – when you use a pager and it reloads the data table, the jQuery enhancements are not reapplied to the table and the effect is lost 😦

Adding table interactivity to an XPage data table
Adding table interactivity to an XPage data table

Pager’s and partial refresh.

In this case we have a pager control and repeat control which looks something like this

<xp:div id="internalDiv">
	<xp:pager layout="Previous Group Next"
		partialRefresh="true" id="pager1" for="repeat1">
	</xp:pager>
	<table id="tabRepeat" cellpadding="5"
		style="width: 100%">

	<xp:repeat id="repeat1" rows="5" value="#{view1}" var="myPeople">
		TABLE ROWS HERE
	</xp:repeat>
	</table>
</div>

and when the pager it clicked to go to another page it refreshes itself and everything up to the 1st DIV parent – in this case xp:div id=”internalDiv”

When clicking on page 2, a partialRefresh is executed and internalDiv is refreshed. Any and all jQuery DOM manipulations are lost and not re-applied to the new code.

Interactivity lost after pager partialRefresh :(
Interactivity lost after pager partialRefresh 😦


XSP.addOnload()

XSP.addOnLoad() (Page 181-182 of the Portable Command Guide) allows us to trigger a JavaScript function once the object being worked on is Complete. This is in comparison to a normal SCRIPT tag which will not always be triggered when inserted into a DOM (depending on browser).
What’s also nice is that this function will not trigger until the load is complete. Analogous to the $(document).ready() jQuery function we need to make sure everything is loaded before we take action.

NOTE

XSP.addOnLoad() creates a listener function reference for the XSP.onLoad function and as such does not require the () at the end of the function name as you would normally expect.

So by adding an XSP.addOnLoad function call at the end of the DIV means that the jQuery is always called at the end of every partialRefresh,

<script>
function niceRows(){
	$(".reveal TR:odd").css('background', '#DDDDFF')
	$(".reveal TR").hover(function(){
		  $(this).css('cursor', 'pointer' ).toggleClass("active");
	});
}
</script>

<xp:div id="internalDiv">
	<xp:pager layout="Previous Group Next"
		partialRefresh="true" id="pager1" for="repeat1">
	</xp:pager>
	<table id="tabRepeat" cellpadding="5"
		style="width: 100%">

	<xp:repeat id="repeat1" rows="5" value="#{view1}" var="myPeople">
		TABLE ROWS HERE
	</xp:repeat>
	</table>

	<script>
		XSP.addOnLoad(niceRows)
	</script>

</div>
interactivity is retained even after paging
interactivity is retained even after paging

jQuery .slideToggle() – enhancing user experience *and* reducing code

In this article I will demonstrate how the jQuery .slideToggle() method can create a better user experience within your XPage *and* makes your code easier to maintain than using SSJS to achieve the same goal.

Demonstration

The effect is demonstrated here

Introduction

Many use cases require information to be hidden from a user depending on the current state of the web form they are working on. Upon the desired trigger, more information is made available to them. This is a simple demonstration on how to make a better user experience and also reduce your code. In this case I have demonstrated how to show and hide a viewPanel. When displayed all the normal pager functionality continues to work and both examples maintain the state of the pager.

,slideToggle() demo page
,slideToggle() demo page

.slideToggle()

.slideToggle() is a core jQuery method which acts on a specified container. It performs the following

  1. binds two other core methods, .slideUp() and .slideDown()
  2. toggles the style, display: block and display: none

in its simplest form you would use something like this

<xp:div styleClass="reveal" id="showDiv">
	Your stuff HERE
</xp:div>

and then at the bottom of your XPage markup you’d add

<script>
	$(".reveal").slideToggle('slow')
</script>

This would very simply animate the expansion of the section and when it was clicked again it would animate the collapse of the section. This is really nice because we do not have to programmatically track the state of the display.

To do the same thing in SSJS we have to track the state of the display. I do this by adding an attribute to the div programmatically and tracking a viewScope variable. This is also 8.5.3 code only because I need to add an attribute to the xp:div.

<xp:div styleClass="reveal" id="showDiv">
		<xp:this.attrs>
			<xp:attr name="style">
				<xp:this.value><![CDATA[#{javascript:"display: "+viewScope.showPanel}]]></xp:this.value>
			</xp:attr>
	Your stuff HERE
</xp:div>

I would then use a button with the following markup to track the current state and then onclick change the state and partialRefresh

<xp:button value="SSJS Partial Refresh" id="button1">
	<xp:eventHandler event="onclick" submit="true"
		refreshMode="partial">
		<xp:this.action>
			<xp:executeScript>
				<xp:this.script><![CDATA[#{javascript:sTemp = viewScope.showPanel == "none" ? "block" : "none"; viewScope.showPanel = sTemp}]]></xp:this.script>
			</xp:executeScript>
		</xp:this.action>
	</xp:eventHandler>
</xp:button>

You also have to consider there is a round trip to the server every time an SSJS button is clicked which on a slow connection can be detrimental to the user experience.

partialRefresh() round-trip to the server and back
partialRefresh() round-trip to the server and back

Even in this simplistic example you can see that there is more code to maintain in the SSJS version and advantages to using the jQuery version.

Conclusion

jQuery can make both your user experience and your maintainability easier when used judiciously.