23.07.2010
dojo and Notes: Article 6 - dojo.fx.Toggler and dojo.behavior - Bind an animation to an event
>>Author: Bernd Hort
>>Ort: Hamburg
URL: http://www.assono.de/blog/d6plinks/dojo-and-Notes-article-6-dojo.fx.Toggler-dojo.behaviorCategory: dojo, Web-Entwicklung, Entwicklung, Lotus Domino
Where we left off in the last article, we continue in this article. The session descriptions that we have hidden the last time with the help of the dojo.fx packages are to be displayed when clicking on the session title again. One click in the session description makes it disappear again. For showing and hiding of HTML elements we use a toggler object from the dojo.fx package. To bind function calls to specific events, we use the dojo.behavior package.
First, as a reminder: This is the HTML code that is returned by the Notes view.
1.
<div class="session" id="Track%201%20-%20Session%203">
2. <span class="sessionNr">Track 1 - Session 3</span>
3. <img class="speakerPicture" src="/Projekte/Konferenzen/dojo.nsf/SpeakerByName/Maureen%20Leland/$File/Ref-maureen-leland.jpg">
4. <h1>Domino Designer and XPages 8.5.1: A Perfect Match!</h1>
5. <span class="speakerName" id="Maureen%20Leland">Maureen Leland</span>
6. <div class="sessionDescription" id="descTrack%201%20-%20Session%203">In 8.5.1, XPages roared into the Notes client and realized the dream of write once, run in both the Web and the Notes client. We'll review the new capabilities in 8.5.1 and how they streamline XPage development, and also take a look at some of the features that will be delivered "next."
7. </div>
8. </div>
As you can see, there is no link
in the session title to call a function.
2. <span class="sessionNr">Track 1 - Session 3</span>
3. <img class="speakerPicture" src="/Projekte/Konferenzen/dojo.nsf/SpeakerByName/Maureen%20Leland/$File/Ref-maureen-leland.jpg">
4. <h1>Domino Designer and XPages 8.5.1: A Perfect Match!</h1>
5. <span class="speakerName" id="Maureen%20Leland">Maureen Leland</span>
6. <div class="sessionDescription" id="descTrack%201%20-%20Session%203">In 8.5.1, XPages roared into the Notes client and realized the dream of write once, run in both the Web and the Notes client. We'll review the new capabilities in 8.5.1 and how they streamline XPage development, and also take a look at some of the features that will be delivered "next."
7. </div>
8. </div>
Let us now have a look at the JavaScript code we need for our task:
//Loads
fx (animation) package
dojo.require("dojo.fx");
//Loads the behavoir package
dojo.require("dojo.behavior");
//Object to hold all description toggler
var descriptionTogglerList = new Object();
function registerDescriptionToggle(headlineNode) {
//calculate an id for the headline
var headlineID = "head" + headlineNode.parentNode.id ;
//and assign it to the element
headlineNode.id = headlineID;
//add style to title for pointer
dojo.style(headlineID, "cursor", "pointer");
//retrieve the description id from the parent node
var descriptionID = "desc" + headlineNode.parentNode.id ;
//create a new toggler
var toggler = new dojo.fx.Toggler({
node: descriptionID,
showFunc: dojo.fx.wipeIn,
hideFunc: dojo.fx.wipeOut
});
//hide the description
toggler.hide();
//store the toggler in the list
descriptionTogglerListheadlineID = toggler;
}
//shows a description
function showDescription(headlineID){
descriptionTogglerListheadlineID.show();
}
//hide a description
function hideDescription(headlineID){
descriptionTogglerListheadlineID.hide();
}
dojo.addOnLoad(function(){
// search for all headlines and register a toggler
dojo.query("div.session h1").forEach(registerDescriptionToggle);
// add the behavior to the sessions headlines to open the description on click
dojo.behavior.add({
"div.session h1": {
onclick: function(evt){
var headlineID = evt.target.id;
showDescription(headlineID);
}
}
});
// add the behavior to the description to close on click
dojo.behavior.add({
"div.session div.sessionDescription": {
onclick: function(evt){
var descriptionID = evt.target.id;
var headlineID = descriptionID.replace(/^desc/g, "head");
hideDescription(headlineID);
}
}
});
dojo.behavior.apply();
});
dojo.require("dojo.fx");
//Loads the behavoir package
dojo.require("dojo.behavior");
//Object to hold all description toggler
var descriptionTogglerList = new Object();
function registerDescriptionToggle(headlineNode) {
//calculate an id for the headline
var headlineID = "head" + headlineNode.parentNode.id ;
//and assign it to the element
headlineNode.id = headlineID;
//add style to title for pointer
dojo.style(headlineID, "cursor", "pointer");
//retrieve the description id from the parent node
var descriptionID = "desc" + headlineNode.parentNode.id ;
//create a new toggler
var toggler = new dojo.fx.Toggler({
node: descriptionID,
showFunc: dojo.fx.wipeIn,
hideFunc: dojo.fx.wipeOut
});
//hide the description
toggler.hide();
//store the toggler in the list
descriptionTogglerListheadlineID = toggler;
}
//shows a description
function showDescription(headlineID){
descriptionTogglerListheadlineID.show();
}
//hide a description
function hideDescription(headlineID){
descriptionTogglerListheadlineID.hide();
}
dojo.addOnLoad(function(){
// search for all headlines and register a toggler
dojo.query("div.session h1").forEach(registerDescriptionToggle);
// add the behavior to the sessions headlines to open the description on click
dojo.behavior.add({
"div.session h1": {
onclick: function(evt){
var headlineID = evt.target.id;
showDescription(headlineID);
}
}
});
// add the behavior to the description to close on click
dojo.behavior.add({
"div.session div.sessionDescription": {
onclick: function(evt){
var descriptionID = evt.target.id;
var headlineID = descriptionID.replace(/^desc/g, "head");
hideDescription(headlineID);
}
}
});
dojo.behavior.apply();
});
Let us step through it one by one
//Loads
fx (animation) package
dojo.require("dojo.fx");
//Loads the behavoir package
dojo.require("dojo.behavior");
In these lines the packages that
we need are loaded.
dojo.require("dojo.fx");
//Loads the behavoir package
dojo.require("dojo.behavior");
For every session title we need a toggler object.
//Object
to hold all description toggler
var descriptionTogglerList = new Object();
To access the objects more easily
we create an object to store them.
var descriptionTogglerList = new Object();
The following function prepares everything for the toggler. The expected parameter is an DOM node representing a session title. This DOM node needs an unique ID. Dojo, like many other JavaScript-Frameworks, makes a lot of use of the IDs. After that we change the CSS style of the node so the users can identify it as a link. Then we create the toggler to hide the session description and store the toggler in our "list" object.
function
registerDescriptionToggle(headlineNode)
{
//calculate an id for the headline
var headlineID = "head" + headlineNode.parentNode.id ;
//and assign it to the element
headlineNode.id = headlineID;
//add style to title for pointer
dojo.style(headlineID, "cursor", "pointer");
//retrieve the description id from the parent node
var descriptionID = "desc" + headlineNode.parentNode.id ;
//create a new toggler
var toggler = new dojo.fx.Toggler({
node: descriptionID,
showFunc: dojo.fx.wipeIn,
hideFunc: dojo.fx.wipeOut
});
//hide the description
toggler.hide();
//store the toggler in the list
descriptionTogglerListheadlineID = toggler;
}
//calculate an id for the headline
var headlineID = "head" + headlineNode.parentNode.id ;
//and assign it to the element
headlineNode.id = headlineID;
//add style to title for pointer
dojo.style(headlineID, "cursor", "pointer");
//retrieve the description id from the parent node
var descriptionID = "desc" + headlineNode.parentNode.id ;
//create a new toggler
var toggler = new dojo.fx.Toggler({
node: descriptionID,
showFunc: dojo.fx.wipeIn,
hideFunc: dojo.fx.wipeOut
});
//hide the description
toggler.hide();
//store the toggler in the list
descriptionTogglerListheadlineID = toggler;
}
Let's take a close look.
//calculate
an id for the headline
var headlineID = "head" + headlineNode.parentNode.id ;
//and assign it to the element
headlineNode.id = headlineID;
To generate an unique ID we use
the ID of the parent element. As shown above, is the <div>
has an ID. So we add a prefix and assign the new ID in the next line to
the HTML node
var headlineID = "head" + headlineNode.parentNode.id ;
//and assign it to the element
headlineNode.id = headlineID;
In this line we add a CSS style to the headline.
//add style to title for pointer
dojo.style(headlineID, "cursor", "pointer");
Dabei benutzen wir zur Identifizierung
gleich die neu erzeugte ID.
dojo.style(headlineID, "cursor", "pointer");
The ID of the session description has the same pattern as the session title.
//retrieve
the description id from the parent node
var descriptionID = "desc" + headlineNode.parentNode.id ;
However, the ID is already in the original
HTML code available.
var descriptionID = "desc" + headlineNode.parentNode.id ;
The dojo.fx.Toggler takes care of the animations to show and hide the element.
//create
a new toggler
var toggler = new dojo.fx.Toggler({
node: descriptionID,
showFunc: dojo.fx.wipeIn,
hideFunc: dojo.fx.wipeOut
});
The construct of the class dojo.fx.Toggler
needs an configuration object. The property "node" holds the
ID or the DOM node which should be animated. The properties "showFunc"
and "hideFunc" are for the animation classes from the dojo.fx-Package.
var toggler = new dojo.fx.Toggler({
node: descriptionID,
showFunc: dojo.fx.wipeIn,
hideFunc: dojo.fx.wipeOut
});
The method to hide is called immediatley.
//hide
the description
toggler.hide();
toggler.hide();
In JavaScript there is no list construction, as in Lotus Script. However, we don't need it. Any object can be used as a list. The property names can be used like the keys in a list. Beside the known notation object.property there is another valid notation object"property". This notation can be used if the key would not be a valid JavaScript name. This technique is also known as "Associative Array".
//store the toggler in the list
descriptionTogglerListheadlineID = toggler;
In
our case, so we store the generated toggler under the ID of the headline
in the descriptionTogglerList object.
descriptionTogglerListheadlineID = toggler;
The following two functions can access the corresponding toggler object directly with the use of the ID of the session title.
//shows
a description
function showDescription(headlineID){
descriptionTogglerListheadlineID.show();
}
//hide a description
function hideDescription(headlineID){
descriptionTogglerListheadlineID.hide();
}
function showDescription(headlineID){
descriptionTogglerListheadlineID.show();
}
//hide a description
function hideDescription(headlineID){
descriptionTogglerListheadlineID.hide();
}
To make all this work, we have some more code to the dojo.addOnLoad function.
dojo.addOnLoad(function(){
// search for all headlines and register a toggler
dojo.query("div.session h1").forEach(registerDescriptionToggle);
// add the behavior to the sessions headlines to open the description on click
dojo.behavior.add({
"div.session h1": {
onclick: function(evt){
var headlineID = evt.target.id;
showDescription(headlineID);
}
}
});
// add the behavior to the description to close on click
dojo.behavior.add({
"div.session div.sessionDescription": {
onclick: function(evt){
var descriptionID = evt.target.id;
var headlineID = descriptionID.replace(/^desc/g, "head");
hideDescription(headlineID);
}
}
});
dojo.behavior.apply();
});
First of all we search for all
the session headlines and for each call the function registerDescriptionToogle.
// search for all headlines and register a toggler
dojo.query("div.session h1").forEach(registerDescriptionToggle);
// add the behavior to the sessions headlines to open the description on click
dojo.behavior.add({
"div.session h1": {
onclick: function(evt){
var headlineID = evt.target.id;
showDescription(headlineID);
}
}
});
// add the behavior to the description to close on click
dojo.behavior.add({
"div.session div.sessionDescription": {
onclick: function(evt){
var descriptionID = evt.target.id;
var headlineID = descriptionID.replace(/^desc/g, "head");
hideDescription(headlineID);
}
}
});
dojo.behavior.apply();
});
In the next step, we use the dojo.behavior package. With dojo.behavior.add () we add a new behavior. For this we need a behavior object. The behavior object is at first a little weired. The property name is a CSS selector. The associated property is in turn an event handler object. Where the property name is the event and the associated property contains the method to be executed events.
Both the sesson titles (div.session h1) and the session descriptions (div.session div.sessionDescription) gets an event handler. The function for closing the session description needs a regular expression to get from the ID of the session description to the ID of the session title. Thats because the toggler can only be accessed in the list object by the ID of the headline.
The line dojo.behavior.apply () is particularly important. Without this call the "behavior" only would be defined, but never used.
After all the theory you can see it in action here. In the sample database belonging to this series of articles you can find the content of this article in the form "webSpeedAgendaing-Step 4 | SpeedAgendaing-4" and the JavaScript library "SpeedAgendaing-Step4.js".
In the next article we will continue with the example so that a click on the session title closes an open session description.

Comments