Archive | Dijit RSS for this section

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.

Advertisements

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

Dojo in XPages – 21: Displaying Images with a ThumbnailPicker

If you have images attached to a document in an XPages application, you can display a scrolling series of them with the ThumbnailPicker widget. In this post, I’ll show how to include the required dojo modules and dynamically populate the picker with a list of images.

Dojo in XPages Series

Dojo in XPages — All Blog Posts

ThumbnailPicker Widget

The ThumbnailPicker widget can display images horizontally or vertically and it provides controls to page through the images. If you have a document with multiple image attachments, it can be a handy way to display thumbnails of them.

Here’s an example of each orientation from my test page.

Dojo21_1

Including Required Dojo Resources

The ThumbnailPicker widget is part of dojox; it’s already on the Domino server and can be used on the page by adding a few resources and a div to render it.

There are two dojo modules and one dojo stylesheet required in order to make this work.

You need the ThumbnailPicker module, the ItemFileReadStore module (to supply the list of images to the widget), and a stylesheet to display it properly.

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

Providing Data

The ThumbnailPicker requires an ItemFileReadStore to provide the image information.

The structure generally looks like this:

imageItemStore.data = {
  identifier: 'title',
  label: 'Images',
  items: [
    {
      thumb: "http://server.com/mypicture.jpg",
      title: "title 1"
    },
    {
      thumb: "http://server.com/mypicture2.jpg",
      title: "title 2"
    }
  ]
};

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 2 gets the list of attachment names with @AttachmentNames().

Line 4 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 7 and 8 set up objects that are required by the data store for the ThumbnailPicker. The itemNameMap object defines the property that points to the image “thumbnail” (in quotes because we’re not really using a thumbnail — we’ll just display the actual attachment as a thumbnail). The request object doesn’t need any parameters in this case. That’s used when making remote requests.

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

Lines 22-26 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 (which you see when you hover your mouse over the image).

Line 29 finds the div with the id thumbnailDisplay and connects the data store to it in order to initialize it.

// Get an array of attachment names.
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"};
var request= {};

// 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.title = 'Image: ' + fileNames[i];
  
  imageData.items.push(newItem);
}

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

// Initialize the Thumbnail Picker 
dijit.byId('thumbnailDisplay').setDataStore(imageStore, request, itemNameMap);

Rendering the ThumbnailPicker

Here’s how you can set up a passthru HTML div tag to become the ThumbnailPicker.

<div id="thumbnailDisplay" dojoType="dojox.image.ThumbnailPicker"
  size="500" data-dojo-props="isHorizontal:true">
</div>

The key is the dojoType attribute. When the dojo parser runs, it looks for these dojoType attributes and generates dijits. So, if you use this method, you’ll need to enable the page’s Trigger Dojo parse on load property to ensure that the parser runs when the page loads. (Otherwise, it won’t generate the dijit.)

Dojo21_2

As you can see in the page source above, this adds the attribute dojoParseOnLoad="true" to the xp:view tag.

Now, you’ve got what you need to generate the ThumbnailPicker.

Another option for Rendering the ThumbnailPicker

In addition to passthru HTML, we can also render the ThumbnailPicker with an xp:div tag.

You can achieve the same output by setting the dojo type to dojox.image.ThumbnailPicker and adding attributes for the size, etc. (Click on the picture to enlarge it.)

Dojo21_3

After you do that, you would just need to change the last line of the onClientLoad code to retrieve the XPages-generated client-side ID for the div.

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

ThumbnailPicker Size

The size attribute generally defines the width (or height, if vertical) of the picker.

There’s also a numberThumbs attribute that’s supposed to define the number of images to display, but I did not have much success in getting it to take effect.

Resizing the Images

By default, this will dispay the images in their original sizes. Fortunately, with some CSS, you can resize them to make them consistent.

For my example, I created another stylesheet and included it as a page resource, based on an example found in the Dojo documentation.

.thumbWrapper img {
  height: 100px;
  max-width: 75px;
}
.thumbOuter.thumbHoriz, .thumbHoriz .thumbScroller {
  height: 100px;
}

Displaying the ThumbnailPicker Vertically

In the div tag shown above, there’s a data-dojo-props attribute with a value of "isHorizontal:true". That property isn’t required, as that’s the default, but it shows how you can easily change the orientation of the display. If you set that property to false, it will display the picker vertically.