Skip to main content link. Accesskey S

The useful resource for IBM Lotus Domino XPages development

Submit Search


Home > Dojo > Work with Dojo
xpageswiki.com
is maintained by 
Julian Buss.
You can hire me.

Work with Dojo

ShowTable of Contents

Include Dojo libraries


To use certain dojo functionalities like the dijit.dialog you have to inlcude them in your XPage, see http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Client_Side_JavaScript_Libraries_in_XPages.htm.

In short: add a new resource "dojo module" to your XPage and enter the name of the dojo module.

Execute your code after page loads


Do NOT place some script somewhere in your page with uses dojo features in the hope that your scripts runs after the page is loaded.
You have to use dojo.addOnLoad() for that purpose:

<script type="text/javascript">
var init = function() {
  alert("my own code which uses dojo stuff and should be executed after the page was loaded");
}

dojo.addOnLoad(init);
</script>


You should place this code somewhere at the bottom of your XPage or custom control (to be exact, it just needed to be executed after the dojo core was loaded).

Accessing DOM nodes


Use dojo.byId() to get some element like a DIV or an input field or a list item.
XPages elements (like a panel or an input field) have an ID (=name in the XPage editor). Unfortunately, you cannot access these elements by these IDs in dojo client scripts. That's because the name of a XPage component is dynamically prefixed with other stuff at runtime before becoming an ID (look at the source of a XPage in the browser!).

In events of XPage components you can use "#{id:XPage component name}", which will be replaced by the actual ID of that component at runtime.

Example: create a panel and give it the name "myPanel". Create a button and in the on click event write:

dojo.byId("#{id:myPanel}").innerHTML = "found it!"

Accessing XPage components in all kind of client scripts


The "#{id:...}" construct does not work for example in client side javascript libraries.
There you can se a CSS selector with dojo.byId() like this:

elem = dojo.query("[id$='myPanel']")[0];
elem.innerHTML = "found it with by using a CSS3  selector"


dojo.query() returns an array (!) of DOM nodes by using CSS 3 selectors (see www.w3.org/TR/css3-selectors). Because it's an array, you need "[0]" to access the first element of it.

More about accessing nodes with a query


Some common usages of dojo.query():

dojo.query("div") ' returns all div elements
dojo.query("div[id='one'])[0] ' returns the div element with id "one"
dojo.query("div.someClass") ' returns all divs having the css class "someClass"
dojo.query(".someClass") ' returns all elements having the css class "someClass"
dojo.query("div[id*='someid']) ' returns all divs having an id in which "someid" occurs
dojo.query("[id$='someid']) ' returns all divs having an id which ends on "someid" 
dojo.query("[id^='someid']) ' returns all divs having an id which starts with "someid"

Type checking


Use the following functions to check if a variable has a certain type:

isString(value)
isArray(value)
isFunction(value)
isObject(value) ' true for an object, including Array, Function or null

String utilities


Trim a string:
dojo.trim(s)


Fill up a string:
dojo.string.pad(s, count, char)


Substitution:
dojo.string.substitution("here is one param ${0} and here is another ${1}", ["param1", "param2"])

Array processing


No, Array.indexOf is NOT supported in all browsers. Use dojo instead:

Get index of one element:
dojo.indexOf(array, element, startIndex)


Get last index:
dojo.lastIndexOf(array, element, startIndex)


Check if all elements of an array fits a condition:
dojo.every(array, function(x) {return x == y})  ' returns true if all elements in the array are equal to y


Iterate over elelents:
dojo.forEach(array, function(x) {do something with x})


Transform elements:
dojo.map(array, function(x) {return x + 1}) ' increments all elements of the array by 1


Filter elements out of an array:
dojo.filter(array, function(x) {return x == y}) ' leaves all elements in the array which are equal to y


Modify HTML of an element


dojo.byId("#{id:someXPagePanel}").innerHTML = "some html";
dojo.byId("someOtherHTMLElement").innerHTML = "some html";

Modify the style of an element


Example: hide div with the id 'mydiv':
dojo.style(dojo.byId('mydiv'), {display: 'none'});


Add a CSS class to an element:
dojo.addClass(dojo.byId('mydiv'), 'someCssClass');


Remove a CSS class from an element:
dojo.removeClass(dojo.byId('mydiv'), 'someCssClass');


Get position of one element and set the position of another element


var pos=dojo.coords("elementid", true);
dojo.byId("#{id:otherelement}").style.top = (pos.y+20)+"px";
dojo.byId("#{id:otherelement}").style.display = "block";


pos.x=position from the left
pos.y=position from the top
pos.w=width of the element
pos.h=height of the element
dojo.coords(param1, param2) -> param2=true -> include scrolling in height, param2=false -> compute height without scrolling

Use specialized input elements

NumberSpinner


You can convert an edit box to a dojo number spinner by writing this code in the source of the XPage, at the end:

<script type="text/javascript">
	var f = function() {
		elem = dojo.query("[id$='tmpNr']")[0];
		v = elem.value;
		var d = new dijit.form.NumberSpinner({constraints:{min:1,max:999},style: "width:55px;"}, elem)
		d.setValue(v);
	}
	dojo.addOnLoad(f);
	</script>


Replace "tmpNr" with the name of your edit box.
See http://www.dojotoolkit.org/book/dojo-book-0-9/part-2-dijit/form-validation-specialized-input/number-spinner for more information about the NumberSpinner.

Slider


You can use the dijit.slider to push number values to a XPages edit box, from where you do further processing.
A slider looks like this:


Add the "dojo.form.Slider" module to your XPage:


The slider itself is wrapped into a div tag like this:

<div id="horizontalSlider" dojoType="dijit.form.HorizontalSlider" value="7" 
minimum="1" maximum="90" discreteValues="90" 
intermediateChanges="false" showButtons="false"
onChange="dojo.query('[id$=sliderValue]')[0].value = arguments[0];
dojo.query('[id$=bRefreshView]')[0].click()"
style="width:250px">

<ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" 
style="height:1em;font-size:75%;color:gray;">
<li>Label 1</li>
<li>Label 2</li>
<li>Label 3</li>
<li>Label 4</li>
</ol>

</div>


Attributes in the div tag:
value: the default value
minimun: minimum value of the slider
maximal: maximum value of the slider
intermediateChanges: set to true if the onChange event should run on every mouse movement of the slider, the to false if onChange should only run after the user moved the slider and releases the mouse.
showButtons: set to true if you want up/down buttons
onChange: Client JavaScript to execute, the slider value is in "arguments[0]"

You need to store the slider value into a XPage control.
Create an edit box with code like this:

<xp:inputText id="sliderValue" value="#{sessionScope.sliderValue}" style="display:none">									
</xp:inputText>


Note the first element in the javascript in the onChange event of the div:
dojo.query('[id$=sliderValue]')[0].value = arguments[0]


This gets the DOMNode of our edit box and stores the slider value in it. You can make that visible if you remove "display:none" from the edit box's style.

And finally, you can even do a page refresh if the slider's value changed. For that, we need help from a hidden button:

<xp:button value="Label" id="bRefreshView" style="display:none">
<xp:eventHandler event="onclick"
	submit="true" refreshMode="partial" id="eventHandler8" refreshId="viewPanel">
</xp:eventHandler></xp:button>


Note the "display:none" style, remove it when you want to see the button.
The second part of the div's javascript clicks that button when the slider changed:

dojo.query('[id$=bRefreshView]')[0].click()


In a nutshell, the logic goes as follows:

- user changes slider
- onChange event runs and executes the javascript
- first part of the javascript stores the slider's value into the XPage edit box
- second part clicks the hidden button to do a page refresh so that you can react on the changed value to, for example, filter a view by using a fulltext search.

Note: this works in Notes 8.5.1 or higher. For 8.5.0 you are not allowed to use the dojoType attribute in the div tag.

Create effects

fadeIn a div

  • create a div
  • set css of that div to "opacity:0" and "filter:alpha(opacity=0)"


In the Client JS (!) of for example a button you can use

var fadeIn = dojo.fadeIn({node: "#{id:mydiv}",duration: 250});
fadeIn.play();

wipe in and other animations


Note: you need to include the dojo.fx package in your XPage (all properties -> resources -> add DojoModule -> "dojo.fx"

- create a div
- set css of that div to "display:none" as INLINE css as follows:

<div id="mydiv" style="display:none">some content</div>


Important! Use "style=..." to define the display:none property, do not write that in an external CSS file or the animation will not work (bug in Dojo).

Then use the following client Javascript to wipein:

dojo.fx.wipeIn({node:'mydiv',duration:1000}).play();

other nice effects working the same


- wipeOut
- slideRight: dojo.fx.slideTo({node: "animDiv",duration: 1000, left: 300, top: 80});
- slideLeft: dojo.fx.slideTo({node: "animDiv",duration: 1000, left: 0, top:80});

combine effects


var fadeOut = dojo.fadeOut({node: "animDiv",duration: 1000});
var wipeOut = dojo.fx.wipeOut({node: "animDiv",duration: 1000});
var slideRight = dojo.fx.slideTo({node: "animDiv",duration: 1000, left: 300, top: 80});
  
dojo.fx.combine([fadeOut, wipeOut, slideRight]).play();

do something after the effect has played


You can execute some function after an effect (like the fadeIn) has played:

var fadeIn = dojo.fadeIn({
  node: "#{id:mydiv}",
  duration: 250,
  onEnd: function() {
    alert("effect finished!");
  }
});
fadeIn.play();


There are more events:

beforeBegin: runs before the animation starts (synchron)
onBegin: runs after animation started (asynchron)
onPlay: runs while the animation plays (synchron)
onAnimate: runs for every step of the animation

Work with events


You can use Dojo to connect to events (like onclick or mouseover), which makes handling events easier.

1.) connect to an event

dojo.connect(elem, "eventname", function (e) { ...code... })


2.) using event's properties in your function:

connect to the event like this:

function myEventFunction(someparam, event) {
...code...
}

dojo.connect(dojo.byId("myid"), "onclick", function (e) { myEventFunction("someparam", e); })


Then you can use the following properties of the event object:

- event.target - the element that generated the event
- event.currentTarget - the current target
- event.layerX - the x coordinate, relative to the event.currentTarget
- event.layerY - the y coordinate, relative to the event.currentTarget
- event.pageX - the x coordinate, relative to the view port
- event.pageY - the y coordinate, relative to the view port
- event.relatedTarget - For onmouseover and onmouseout, the object that the mouse pointer is moving to or out of
- event.charCode - For keypress events, the character code of the key pressed
- event.keyCode - for keypress events, handles special keys like ENTER and spacebar.
- event.charOrCode - a normalized version of charCode and keyCode, which can be used for direct comparison for alpha keys and special keys together. (added in 1.1)

(taken from Dojo campus )

3.) events you can connect to

- onclick - the user clicked a node
- onfocus - a node received focus
- onblur - a node was 'blurred', or otherwise lost focus
- onchange - an input value was changed
- onkeypress - fired when the user presses a key
- onkeydown - shouldn't be necessary to be used... all key presses go to onkeypress
- onkeyup - fired when the user releases a key
- onmouseover - a node was hovered (warning: may fire more than you'd like because of bubbling)
- onmouseout - a node was un-hovered
- onmouseenter - a normalized version of onmouseover that wont fire more than you'd like (only on first enter)
- onmouseleave - a normalized version of onmouseout that wont fire more than you'd like (only once when leaving)
- onsubmit - a form has been submitted

4.) especially useful: onmouseenter, onmouseleave

Using mouseover/mouseout has it's problems when you use them on an element which contains other elements. The dojo "onmouseenter" / "onmouseleave" do what you expect: they fire when the mouse goes in the area of an element, and when it leaves that area (while mouseover / mouseout may fire again and again and again while the mouse moves in the element's area).


Use a panel as dijit Dialog


1.) Create a panel on your XPage.

2.) In the source view, wrap the <xp:panel>...</xp:panel> tags with:

<div id="myDialog" style="display:none">...</div>


3.) Put the following function in some client javascript library:

function dialog_create(id) { 
  var dialogWidget = dijit.byId(id);
  if( dialogWidget ) dialogWidget.destroyRecursive(true);
  dialogWidget = new dijit.Dialog( { }, dojo.byId(id)); 
  var dialog = dojo.byId(id);
  dialog.parentNode.removeChild(dialog); 
  var form = document.forms[0]; form.appendChild(dialog); 
  dialogWidget.startup(); 
}


4.) At the end of your XPage, put this javascript:

<script>dojo.addOnLoad(function() {dialog_create("myDialog")}):


5.) Open the dialog with

dijit.byId("myDialog").show();


6.) Inside your dialog's panel you can put a button to hide the dialog with:

dijit.byId("myDialog").hide();


(thanks to Mark Hughes for the dialog_create function!).

BACKGROUND:

You can add a 'dojoType="dijit.Dialog"' to your xp:panel tag, and this will create a dojo Dialog - but then you cannot work with fields and partial updates inside that dialog. That's because dojo moves the dialog's div into another context (to be exact: out of Domino's <form> element).

The dialog_create function gets the dialog's div and adds it back to a place into the DOM tree where Domino can "see" it.

Tooltips


You can use the dijit.Tooltip, see Dec's posting here: http://www.qtzar.com/blogs/qtzar.nsf/d6plinks/DSLH-7TWNY2

Basically, it's quite simple:

1.) include the dojo module "dijit.Tooltip":

<xp:this.resources>
		<xp:dojoModule name="dijit.Tooltip"></xp:dojoModule>
	</xp:this.resources>


2.) write a div like this:

<div dojoType="dijit.Tooltip" style="display:none" 
connectId="id-of-element-to-connect-the-tooltip-to">
here is my tooltip
</div>


Options for the div:

- position="x" with x = "above", "below", "before" or "after"
- showDelay="x" with x as an integer, how many milliseconds after hover over the element the tooltip should display
- you can modify the look of your tooltip when you use another div inside the tooltip-div and format that div with CSS. Example:

<div dojoType="dijit.Tooltip"  
connectId="id-of-element-to-connect-the-tooltip-to">
<div style="width:200px;background-color:red">
here is my tooltip,
200px width and with red background.
</div>
</div>

Use dojox lightbox


The dojox package contains a lightbox to nicely show an photo.
Basic usage: include the dojox.image.Lightbox module in your XPage, set "dojoParseOnLoad" and "dojoTheme" to "true" and add HTML like this:

<a href="bigimage.jpg" dojoType="dojox.image.Lightbox"><img src="smallimage.jpg"></a>


with "bigimage.jpg" as the full sized version of your photo, and "smallimage.jpg" as the thumbnail.

Important: for whatever reason a CSS file is NOT automatically included, so the lightbox will not work as expected. You have to localize the "lightbox.css" and add it to your XPage manually.

Disable default dojo


You can disable the loading of the default Dojo, for example in order to use a more recent version of Dojo.
In the Package Explorer in Domino Designer open your database and find the WebContent/WEB-INF/xp.properties file.
Edit the file and add:

xsp.client.script.libraries=none

More information and links


Here are some useful links for Dojo:

Getting started with Dojo - excellent article on developerworks
Dojo Campus Feature Explorer (does not show everything Dojo has)
Dojo Reference Documentation


Created by Anonymous on Jun 5, 2009 11:03:16 AM

I've used Dojomino in other web projects, which means the Dojo frameworks are in a Domino database. Has anyone worked out how to use a resource from a different Domino database?

I have modified some Dojo elements, and having a Domino database template makes deployment easier, so I would prefer to use that format.

Any thoughts would be welcomed.

Paul Withers


Created by Julian Buss on Jul 28, 2009 11:23:32 AM

Paul, starting from 8.5.0, Dojo is delivered with the Domino server and all Dojo files are in the Domino's data directory.

So you don't need to care about that anymore :-)


Created by Anonymous on Aug 26, 2009 2:31:01 PM

What are your thoughts on how Domino will continue to upgrade to a newer Dojo releases? Dojo is now 1.3.2 but Domino supports 1.0. I am using R7 servers with Dojo 1.3.2 and wondering how Domino will keep up with new releases of Dojo?


Created by Julian Buss on Sep 10, 2009 8:56:15 PM

yes, they will. Domino 8.5.1 contains Dojo 1.3.x


Created by Anonymous on Oct 24, 2009 12:34:35 PM

Q1: Is it possible to disable dojo totally from an xpage and use jQuery instead?

Q2: how can I disable all the default css loaded from an xpage

Q3: what is best practice to include dojo based js scriptlibrary on a xpage


Created by Julian Buss on Oct 25, 2009 12:18:52 AM

Q1: no

Q2: don't know any way to do that, perhaps via custom theme

Q3: xpage -> all properties -> resources -> include new dojo resource


Created by Anonymous on Dec 13, 2010 6:15:15 PM

Is it possible to place an Xpage in edit mode using CSJS? It seems to me that the problem with using dialogs to edit fields on an xpage can be worked around if I can put the page in edit mode then call the dialog.


Created by Julian Buss on Dec 29, 2010 11:52:41 AM

yes, pretty simple, actually. Create a xp:button which sets the doc to editmode, give the id of for example "seteditmode". Add the property style="display:none" to the button.

In CSJS you can then use something like: dojo.byId("#{id:seteditmode}").click()


Created by Anonymous on Jan 15, 2011 10:16:26 AM

How do I use dojo 1.5.0 on Domino 8.5.2 on a single application?


Created by Julian Buss on Jan 19, 2011 8:13:27 AM

I believe there is a documentation for that in the FileSendr projekt on OpenNTF - download it at OpenNTF and have a look there.


Created by Anonymous on Apr 5, 2011 9:39:05 PM

Stupid question here:

On "Use a panel as dijit Dialog" Step 4 is that passthru hmtl?? where do you enable?


Created by Xls on Jul 19, 2011 11:39:01 PM

How do I add this to my view, since the viewColumn id is always the same, I actually want to show a picture of the person on mouse-over in a people view (data source view).


Created by Alex Elliott on Nov 26, 2012 1:34:56 AM

Great article but I never knew about the 'onlick' event.

Does this event fire off each time you lick the screen? ;)


Created by Julian Buss on Jan 24, 2013 7:43:04 PM

'onlick'... LOL... fixed, thanks Alex.


Add Comment

Name:
Comments:
How to take your XPages App to the iPhone, iPad, Android: use Domino To Go!
Do you look for an XPages Workflow solution? Take YouAtNotes Workflow.