Archive | May 2014

The Differences Between The resource and resources Tags in an XPages Theme

If you’ve modified a theme, you’ve almost certainly used resource tags to include stylesheets and client-side JavaScript libraries. Each resource tag specifies a single resource to include. However, you can also use the resources tag to include multiple resources. In this post, I’ll explain the differences and a caveat.

resource Tags

Most themes only make use of resource tags because they’re what’s demonstrated by the examples. When you create a new theme, these comments are included by default:

<theme extends="webstandard" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="platform:/plugin/com.ibm.designer.domino.stylekits/schema/stylekit.xsd" >
  <!-- 
    Use this pattern to include resources (such as style sheets
    and JavaScript files that are used by this theme.
  -->
  <!--
    <resource>
      <content-type>text/css</content-type>
      <href>mystylesheet.css</href>
    </resource>
  -->

If I have a stylesheet named myStylesheet.css, it’s very easy to tweak that example to include it in my theme.

<resource>
  <content-type>text/css</content-type>
  <href>myStylesheet.css</href>
</resource>

I can also include a client-side JavaScript library like this:

<resource>
  <content-type>application/x-javascript</content-type>
  <href>csjsMyClientJSLibrary.js</href>
</resource>

Each resource tag defines a single resource. It has child tags to define the content type and the path to the resource.

The resources Tag

The resource tags work well, but you can also use a single resources tag instead and there are a few reasons that this is advantageous.

If you’ve looked in the source of an XPage or custom control where you included one or more resources, you’ve noticed that there’s a this.resources tag that includes a line for each individual resource.

For example, in a test database, I created an SSJS script library and a stylesheet and included them as resources on an XPage. This is how they are included in the page source within an xp:this.resources tag:

<xp:this.resources>
  <xp:script src="/ssjsMyLibrary.jss" clientSide="false"></xp:script>
  <xp:styleSheet href="/myStylesheet.css"></xp:styleSheet>
</xp:this.resources>

With the resources tag, you can use a similar syntax in the theme.

There are a few benefits:

1) Succinct syntax

Especially as the theme grows to include a lot of resources, it is nicer to have a less verbose syntax so you can review the contents of the theme more easily.

All of the same properties are available as with the resource tag, they’re just specified as attributes rather than as child tags.

2) Ability to include server-side resources

The resource tag can only include client-side resource (client-side JavaScript libraries, stylesheets, dojo modules,etc), but the resources tag can include SSJS libraries and resource bundles as well.

This makes it much easier to deploy those resources application-wide.

Tip for Specifying Resources in the Theme

There isn’t a simple way to add resources to the theme, but here’s how to streamline the process:

  1. Add the resources to an XPage or custom control
  2. View the source of the page and copy the block to the theme (and remove it from the page)
  3. Remove xp: and xp:this. from the tags
<resources>
  <script src="/ssjsMyLibrary.jss" clientSide="false"></script>
  <styleSheet href="/myStylesheet.css"></styleSheet>
</resources>

This works, but it’s a good idea to specify the type attribute (for example type=”text/javascript”) as well.

Caveat – Avialability of SSJS Library on Page Events

There is an important caveat to loading SSJS libraries this way. The theme is loaded during the Render Response phase of the JSF lifecycle, so SSJS libraries loaded by the theme will not be available to page events that happen before that phase. Therefore, if you need to execute library functions on page-level events that happen earlier (beforePageLoad and afterPageLoad), you will need to include them on the page and not in the theme. SSJS libraries loaded by the theme are available to the beforeRenderResponse and afterRenderResponse events.

Advertisements

Dojo in XPages – 26: Combining Badge with LightboxNano

In the last two posts, I showed how to implement a Badge to display a set of thumbnail images with some animation as well as the LightboxNano widget to display an image in a specialized dialog. In this post, I’ll show how to combine the two so you can create the badge and add the ability to click on any thumbnail to see the full-sized image in a dialog when clicked.

Dojo in XPages Series

Dojo in XPages — All Blog Posts

Sample Widget

The effect that we’re going for is to have the badge to display the set of thumbnail images and animate them, but have the ability to see any of the thumbnails full-sized.

Dojo_26_A

The source also shows a variation on how to define a LightboxNano widget declaratively, rather than programmatically, as shown in a previous post.

1) Include Required Resources

We’ll need to include two dojo modules (dojox.Image.Badge and dojox.Image.LightboxNano) and the image.css stylesheet on the page.

<xp:this.resources>
  <xp:dojoModule name="dojox.image.Badge"></xp:dojoModule>
  <xp:dojoModule name="dojox.image.LightboxNano"></xp:dojoModule>
  <xp:styleSheet href="/.ibmxspres/dojoroot/dojox/image/resources/image.css"></xp:styleSheet>
</xp:this.resources>

2) Set the Page Property to Parse Dojo on Load

Since we’ll use a declarative approach to create both the badge and the lightbox nano widgets, the page’s Trigger Dojo parse on load property must be selected (dojoParseOnLoad="true")

3) Create a Badge DIV and add LightboxNano Images

For the Badge container, add a div with the dojoType set to dojox.image.Badge.

Define the number of rows and columns to display the images with attributes of the div.

The main difference between this and the example in the last post is that we use a tags around each xp:image tag to set up the LightboxNano for each image. The xp:imagetags populate the badge and the a tags open the images in the LightboxNano dialog. (In this example, they are all using images included within the application as image resources.)

If you have separate thumbnail and full-sized images, you should use the thumbnails within the xp:image tags and the full-sized images on the a tag.

<div dojoType="dojox.image.Badge" rows="2" cols="6" cellSize="100" children="img.badgeIMG">

  <a data-dojo-type="dojox.image.LightboxNano" href="nature1.jpg">
    <xp:image url="/nature1.jpg" id="image13" styleClass="badgeIMG"></xp:image>
  </a>
  <a data-dojo-type="dojox.image.LightboxNano" href="nature2.jpg">
    <xp:image url="/nature2.jpg" id="image1" styleClass="badgeIMG"></xp:image>
  </a>
  <a data-dojo-type="dojox.image.LightboxNano" href="nature3.jpg">
    <xp:image url="/nature3.jpg" id="image2" styleClass="badgeIMG"></xp:image>
  </a>

  <!-- Code for 9 additional images in this example left out -->

</div>

Take a look at the previous post on the Badge widget for more information on customizing the badge thumbnail gallery display (size, speed, layout, and timing).

Article Published in The VIEW: Getting Started with XPages Localization

Kathy Brown and I co-wrote an article on getting started with XPages Localization for The VIEW journal (subscription required).

Abstract

The enterprise is global. If your organization stretches across borders or your clients are in other countries, you cannot just develop an application in your native language and expect that to be good enough. XPages allows you to enable localization and provide multiple languages to display to users.

Here in Part 1 of this two-part series, we will discuss localization features built into XPages. We’ll also demonstrate how to enable localization, work with the localization files, and verify that the application is handling localization. Additionally, we provide some helpful tips to make the process easier. In Part 2, we will demonstrate how to extend out-of-the-box functionality by providing a means to translate computed values and other programmatic text.

Dojo in XPages – 25: Badge — A Cool Image Widget that’s Hard to Explain

In this post, I’ll demonstrate how to create the Badge widget to display image thumbnails with size animation within a tabular structure. This is a cool variation of a gallery; it displays rows of image thumbnails and automatically expands and collapses them. (It’s difficult to convey the functionality until you see an example.)

Dojo in XPages Series

Dojo in XPages — All Blog Posts

dojx.Image.Badge

The Dojo documentation says that the Badge widget loops images. That’s pretty much all it says. (The rest of the page is full of lines starting with “TODO:”.)

Maybe they couldn’t figure out how to explain it, either!

Regardless of the lack of documentation, it is very cool widget to work with images. It creates a table-like structure with image thumbnails and it expands them across multiple cells on a seemingly-random basis.

Each image starts out as a thumbnail, but one at a time expands to be double its size (taking up a 2×2 area in the layout, covering 3 other images). It then shrinks back to it’s original place and another image expands.

Here’s an example of 12 images in a 2×6 layout:

Dojo25_A

Here’s an example of the same images in a 4×3 layout:

Dojo25_B

Neither of these screen shots appear to show 12 images, but they’re there. When one image is doubled, it covers 3 other images until it shrinks back down to its original size, and then another one is increased.

This looping through the images is part of the built-in functionality of the Badge widget. This is great for providing some animation on pages that may be open for awhile, but may otherwise be static.

Here are the steps to creating your own Badge widget:

1) Include Required Resources

In order for this to work, you need to make the dojox.Image.Badge module and the Image.css stylesheet available to the page.

<xp:this.resources>
  <xp:dojoModule name="dojox.image.Badge"></xp:dojoModule>
  <xp:styleSheet href="/.ibmxspres/dojoroot/dojox/image/resources/image.css"></xp:styleSheet>
</xp:this.resources>

2) Set the Page Property to Parse Dojo on Load

Since we’ll use a declarative approach to create this widget, the page’s Trigger Dojo parse on load property must be selected (dojoParseOnLoad="true")

3) Create a Badge DIV and Images

For the Badge container, add a div with the dojoType set to dojox.image.Badge.

Define the number of rows and columns to display the images with attributes of the div.

The children property is a selector for the images to display as thumbnails and animate. It should be set to img.[className] where the classname is a class that is applied to all image tags within the div. In this example, I set them to badgeIMG in this example.

<div dojoType="dojox.image.Badge" rows="2" cols="6" children="img.badgeIMG">
  <xp:image url="/nature1.jpg" id="image13" styleClass="badgeIMG"></xp:image>
  <xp:image url="/nature2.jpg" id="image14" styleClass="badgeIMG"></xp:image>
  <xp:image url="/nature3.jpg" id="image15" styleClass="badgeIMG"></xp:image>
  <xp:image url="/nature4.jpg" id="image16" styleClass="badgeIMG"></xp:image>
  <xp:image url="/nature5.jpg" id="image17" styleClass="badgeIMG"></xp:image>
  <xp:image url="/nature6.jpg" id="image18" styleClass="badgeIMG"></xp:image>
  <xp:image url="/nature7.jpg" id="image19" styleClass="badgeIMG"></xp:image>
  <xp:image url="/nature8.jpg" id="image20" styleClass="badgeIMG"></xp:image>
  <xp:image url="/nature9.jpg" id="image21" styleClass="badgeIMG"></xp:image>
  <xp:image url="/nature10.jpg" id="image22" styleClass="badgeIMG"></xp:image>
  <xp:image url="/nature11.jpg" id="image23" styleClass="badgeIMG"></xp:image>
  <xp:image url="/nature12.jpg" id="image24" styleClass="badgeIMG"></xp:image>
</div>

This is all you need to do to set it up! Once you load the page, you should have a live Badge widget.

The next few sections cover attributes that are available for customizing the behavior.

Image Sizing

By default, the thumbnails are 50-pixel squares. If you want to change the size, you can set the cellSize attribute of the Badge div.

This example changes the thumbnail size to 150-pixel squares.

<div dojoType="dojox.image.Badge" rows="2" cols="6" children="img.badgeIMG" cellSize="150">

Dojo25_C

Transition Delay

Another attribute you can change is the delay between resizing images. The default seems to be 2.5-3 seconds, but you can change that with the delay attribute, where you define the value in milliseconds. To extend the delay to 5 seconds, set the delay to 5000.

<div dojoType="dojox.image.Badge" rows="2" cols="6" children="img.badgeIMG" delay="5000">

If you want to annoy your users, set it to 100.

Adding Threads

The thread count is the number of images that are enlarged at a time. The default is 1, but you can increase this with the thread attribute. This can be a cool effect with a larger data set (especially because they don’t all animate at the same time — their timing is offset), but use it wisely; images will often overlap if there are too many threads. Even 3 is too many for my set of 12 images.

Dojo25_D

If you really want to annoy your users, increase the thread count while also drastically decreasing the delay.

More Examples

This Dojo demo page has additional examples of this in use.

Interestingly, if you look at the example in the upper right hand corner of the page, it looks like you can create the same effect with a bunch of div tags, rather than images.

Dojo in XPages – 24: Using a LightboxNano to Display an Attached Image

In the last post, I showed how to create a Lightbox dialog that allows you to cycle through a group of images. In this post, I’ll show how you can create a simpler version that displays a single image with the LightboxNano module.

Dojo in XPages Series

Dojo in XPages — All Blog Posts

LightboxNano

LightboxNano is a lightweight version of a lightbox, designed to display a single image and focus on it by providing an overlay on the rest of the screen.

Dojo24_E_Nano_FullSize

The control is designed to display a thumbnail and preload the larger image (after a few seconds) so it’s ready to display in full size. It automatically resizes the image as needed to ensure that it fits within the browser window.

From the point where you click on the thumbnail, it provides a nice animation to enlarge and center the full image, leaving a small dotted outline in place of the thumbnail. Clicking anywhere on the page will close the image, providing the reverse animation to shrink the image and move it back to the spot of the original link.

Here are a few screen captures of the animation.

Dojo24_B_Nano_Opening

Dojo24_C_Nano_Opening

Dojo24_D_Nano_Opening

In this example, I’ll show how to create a LightboxNano from the first image attached to a document. If you have large images, you can modify it to use a thumbnail version and load the full version asynchronously.

1) Include the Required Dojo Module

All you need is the dojox.image.LightboxNano module

<xp:this.resources>
  <xp:dojoModule name="dojox.image.LightboxNano"></xp:dojoModule>
</xp:this.resources>

2) Add a thumbnail image to the page

Use an Image control to define the path to the image. This example computes the image path for the first file attachment.

<xp:image id="lbNanoImage" style="height:50px;width:50px">
  <xp:this.url>
    <![CDATA[#{javascript:return './0/' + currentDocument.getDocument().getUniversalID() + '/$File/' + @AttachmentNames()[0];}]]>
  </xp:this.url>
</xp:image>

I used inline styles to size the image; otherwise it would display full-sized.

3) Create the Lightbox

With a few lines of code, you can build the image file path with client-side JavaScript and instantiate the LightboxNano.

This code should run on the onClientLoad event of the page.

// Build the URL for the first attachment in this format: DB.nsf.nsf/0/docUNID/$File/attachmentname
var fileName =	"#{javascript:@AttachmentNames()[0];}";
var docID = "#{javascript:currentDocument.getDocument().getUniversalID()}";

// Initialize the LightboxNano and provide the full URL and the id of the image tag displaying the thumbnail
new dojox.image.LightboxNano({
  href: './0/' + docID + '/$File/' + fileName
}, "#{id:lbNanoImage}");

Since this example creates the LightboxNano programmatically (rather than declaratively), you do not need to set the pages parseOnLoad property to automatically render the LightboxNano.

Dojo in XPages – 23: Using a Lightbox to Display Image Attachments

In recent posts, I showed how to create a thumbnail picker and a gallery of attached images on an XPage. In this post, I’ll show how to use the Lightbox widget to display images in a specialized dialog that provides a the ability to cycle through the images.

Dojo in XPages Series

Dojo in XPages — All Blog Posts

Lightbox

The Lightbox widget provides a nice way to focus on an image and display it centered on the screen in a dialog. Whatever portion of the page is unused (vertically) is darkened with an underlay so it stands out.

It is possible to create a link to open an individual image as in a Lightbox, but, in this post, I’m going to focus on how to create a group of images (based on attachments to the current document) in order to create more of a slideshow effect where you can click through the images.

Dojo23_A

The Lightbox displays one image at a time, but, when there is a group of images assigned to it, it also displays controls to move left and right through the images. There is also a button to close the dialog.

Additionally, the up and left arrow keys go back and the down and right arrow keys work go forward. The ESC key closes the dialog.

Generating the Lightbox only requires two steps — including required resources and programmatically creating the Lightbox and providing the list of images.

1) Include Required Resources

The dojox.image.Lightbox module is required, along with a corresponding stylesheet.

<xp:this.resources>
  <xp:dojoModule name="dojox.image.Lightbox"></xp:dojoModule>
  <xp:styleSheet href="/.ibmxspres/dojoroot/dojox/image/resources/Lightbox.css"></xp:styleSheet>
</xp:this.resources>

2) Creating the Lightbox and Providing Images

This code will automatically generate and display the Lightbox based on images attached to the page. Use the code in the onClientLoad event to render the Lightbox immediately or on a button or other client-side event to render it on demand.

Lines 2 and 4 retrieve the names of the file attachments on the current document and put them into an array.

Lines 8-9 programmatically create the Lightbox and initialize it.

Lines 12-14 cycle through the attachment names and add each image to the Lightbox dialog

// Add each attached image to the lightbox
// Build each URL in this format: DB.nsf.nsf/0/docUNID/$File/attachmentname
var fileNames =	"#{javascript:@AttachmentNames();}";
// It comes back as a concatenated string, surrounded by square brackets, to parse into an array
fileNames = fileNames.substring(1, fileNames.length-1).split(', ');
var docID = "#{javascript:currentDocument.getDocument().getUniversalID()}";

// Initialize the Lightbox dialog 
var lbDialog = new dojox.image.LightboxDialog({});
lbDialog.startup();

// Add images to a group
for (var i=0; i< fileNames.length; i++) {
  lbDialog.addImage({ title:'Image: ' + fileNames[i], href:'./0/' + docID + '/$File/' + fileNames[i]}, 'imgGroup');
}

// Display the Lightbox, starting with the first image
lbDialog.show({group:"imgGroup", title:fileNames[0]}); 

Note: if you don’t specify the url for the first image to display, it’ll start with the first one, but display ‘undefined’ for the title. Line 17 passes in the first image title to avoid this.

Automatically Cycling Through the Images

If desired, you can easily add a timer to automatically cycle through the images, using the _nextImage() or _previousImage() methods of the Lightbox.

setInterval(function(){
  lbDialog._nextImage();
}, 3000);

This example works if added right after the code that creates the Lightbox. If you trigger this separately, then replace line 2 with something like this:

dijit.byId("dojoxLightboxDialog")._nextImage();

You’d also have to give the Lightbox widget an ID so you could refer to it this way.

Changing the Color of the Underlay

By default, it will darken the unused area at the end of your page with a black underlay. (This can look odd if you have some content on the page, but not the rest of the page, as only part of the page will be darkened.)

If you want to change the color of the underlay, you can add your own stylesheet and use a rule like this:

.dijitDialogUnderlay._underlay {
  background-color:blue
}

Dojo in XPages – 22: Displaying an Image Gallery of Attachments

In the last post, I showed how to display a scrolling ThumbnailPicker of images attached to a document in XPages. In this post, we’ll look the Gallery widget, which displays thumbnails but also displays a larger version of the selected image.

Dojo in XPages Series

Dojo in XPages — All Blog Posts

Gallery

The Gallery widget combines features of the Dojo ThumbnailPicker and Slideshow widgets. It displays a list of thumbnails, has an area to display a larger version of the selected image, and displays the image title (along with a counter). (Click to see the image larger.)

Dojo 22 - A

You can scroll through the thumbnails and click on a thumbnail to display a larger version of it after fading it in.

When you hover over the larger image area, you see additional controls. You’ll have a “left” arrow if you’re past the first image. You’ll also have a “Play” icon (right arrow) on the right. When clicked, it will start a slide show that will automatically scroll through the images. You can hover again and click the “stop” icon to end the slide show and remain on the current image. (These controls are only visible when hovering over the larger image area; the screen capture does not show the cursor.)

Dojo 22 - B

This is a very similar setup to the ThumbnailPicker — I actually implemented it just by changing the dojo module, changing the div tags’ dojoType, and adding the imageLargeAttr attribute to the image map and to each image object in the data store. However, in order to allow this to stand alone, I’ll show all of the code required to set it up. (For more of an explanation on the code, refer to the previous post.)

Step 1 – Include Dojo Modules and Stylesheet

There are two dojo modules and one dojo stylesheet that need to be included in order for it to work:

<xp:this.resources>
  <xp:dojoModule name="dojo.data.ItemFileReadStore"></xp:dojoModule>
  <xp:dojoModule name="dojox.image.Gallery"></xp:dojoModule>
  <xp:styleSheet href="/.ibmxspres/dojoroot/dojox/image/resources/image.css"></xp:styleSheet>
</xp:this.resources>

Step 2- Add a div to render the gallery

Just add a div tag, give it an id to reference and set the dojoType to dojox.image.Gallery.

<div id="galleryDisplay" dojoType="dojox.image.Gallery"
  data-dojo-props="imageHeight:400, imageWidth:600">
</div>

Step 3 – Set the page to parse dojo on load

This property runs the Dojo parser when the page loads, so it will find the div with the dojoType attribute and generate the dijit.

Dojo21_2

Step 4 – Build the image data store and attach it to the gallery

In order to build this based on attachments on the current document, we want to build that list of items dynamically.

Each image url needs to be built in this format: DB.nsf/0/[docUNID]/$File/[attachmentname]

The code below will build that structure based on the files attached to the current document. It can run in the page’s onClientLoad event.

Line 1 gets the list of attachment names with @AttachmentNames().

Line 3 parses it to be an array, because it is returned to client-side javascript as a string surrounded in square brackets, with each value separated by a comma and a space. [file1.jpg, file2.jpg, file3.jpg]

Lines 6-9 set up objects that are required by the data store for the Gallery. The itemNameMap object defines the property that points to the large image and the “thumbnail” (in quotes because we’re not really using a thumbnail — we’ll just display the actual attachment as a thumbnail).

As shown previously, the data store needs an items property that is an array of objects (each with a large property, a thumb property and a title property). Lines 12-21 build array of objects for the data store.

Lines 23-27 set up the actual ItemFileReadStore object and provide it the data. The identifer property tells it which data property to use for the image title.

Line 32 finds the div with the id galleryDisplayand connects the data store to it in order to initialize it.

var fileNames =	"#{javascript:@AttachmentNames();}";
// It comes back as a concatenated string, surrounded by square brackets, to parse into an array
fileNames = fileNames.substring(1, fileNames.length-1).split(', ');
var docID = "#{javascript:currentDocument.getDocument().getUniversalID()}";

var itemNameMap = {
  imageThumbAttr: "thumb",
  imageLargeAttr: "large"
};

// Build an array of image items for the thumbnail's data store
var imageData = {};
imageData.items = [];
for (var i=0; i< fileNames.length; i++) {
  var newItem = {};
  newItem.thumb = './0/' + docID + '/$File/' + fileNames[i];
  newItem.large = './0/' + docID + '/$File/' + fileNames[i];
  newItem.title = 'Image: ' + fileNames[i];

  imageData.items.push(newItem);
}

// Initialize the data store
var imageStore = new dojo.data.ItemFileReadStore({
  identifier: 'title',
  label: 'Images',
  data: imageData
});

var request= {}; 

// Initialize the Gallery 
dijit.byId('galleryDisplay').setDataStore(imageStore, request, itemNameMap);

If you use an xp:div rather than a passthru HTML div, then the last line will change to this:

dijit.byId('#{id:galleryDisplay}').setDataStore(imageStore, request, itemNameMap);

Changing the Slideshow Interval

You can modify the length of time between automatic advancement of pictures in the slideshow by adding a slideshowInterval property to the data-dojo-props attribute and specifying the number of seconds. There’s only one data-dojo-props attribute — if you already have a property defined, just add the additional property to the comma-separated list.

Here’s an example of the gallery div, with image and interval settings:

<div id="galleryDisplay" dojoType="dojox.image.Gallery"
  data-dojo-props="imageHeight:250, imageWidth:500, slideshowInterval:2">
</div>

Thumbnail Image Size

As shown in the previous post, you can use CSS to define the image size for the thumbnails if you’d like to change the defaults (75px high by 100px max width).

Other Data Stores

The focus of this post was how to use the gallery to display images attached to a document in XPages, but there are also data stores to work with Flickr and Picasa directly. (If you use those with large sets of images, you’ll want to update the request object to specify the count of images per request and, optionally, the starting point.)

https://dojotoolkit.org/reference-guide/1.8/dojox/image/Gallery.html#id4