dojo und Notes: Artikel 6 - dojo.fx.Toggler und dojo.behavior - Animation an bestimmte Ereignisse knüpfen

von Bernd Hort,
assono GmbH, Standort Hamburg,

Wo wir im letzten Artikel aufgehört haben, geht es in diesem Artikel weiter. Die Sessionbeschreibungen, die wir beim letzten Mal mit Hilfe des dojo.fx-Packages ausgeblendet haben, sollen beim Klick auf die Sessionüberschrift wieder eingeblendet werden. Wenn in die Sessionbeschreibung geklickt wird, soll diese wieder ausgeblendet werden. Für das Ein- und Ausblenden von Elementen gibt es im dojo.fx-Package den Toggler. Um Funktionsaufrufen an bestimmte Ereignisse zu binden, verwenden wir das dojo.behavior-Package.

Zunächst einmal als Erinnerung: Der HTML-Code, der von der Notes Ansicht zurückgeliefert wird, sie wie folgt aus.

<div class="session" id="Track%201%20-%20Session%203">
	<span class="sessionNr">Track 1 - Session 3</span>
	<img class="speakerPicture" src="/Projekte/Konferenzen/dojo.nsf/SpeakerByName/Maureen%20Leland/$File/Ref-maureen-leland.jpg">
	<h1>Domino Designer and XPages 8.5.1:	A Perfect Match!</h1>
	<span class="speakerName" id="Maureen%20Leland">Maureen Leland</span>
	<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."
	</div>
</div>

Wie man sehen kann, gibt es in Sessiontitel keinen Link, der eine Funktion aufruft.

Schauen wir uns jetzt einmal den JavaScript-Code an, den wir für unsere Aufgabe benötigen:

//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();		
});

Gehen wir einmal der Reihe nach durch.

//Loads fx (animation) package
dojo.require("dojo.fx");
//Loads the behavoir package
dojo.require("dojo.behavior");

Hier werden die notwendigen Packages geladen.

Pro Sessiontitel benötigen wir ein Toggler-Objekt.

// Object to hold all description toggler
var descriptionTogglerList = new Object();

Damit wir die Toggler-Objekte nach besser ansprechen können, erzeugen wir zunächst ein Objekt, in dem wir nachher die einzelnen Toggler speichern können.

Die nachfolgende Function bereitet alles für die Toggler vor. Übergeben wird ihr jeweils ein HTML Knoten, der einen Sessiontitel enthält. Zunächst einmal muss der HTML Knoten eine eindeutige ID erhalten. In dojo, wie in den meisten anderen JavaScript-Frameworks, wird viel mit IDs gearbeitet. Danach verändern wir den CSS-Style, so dass der HTML-Knoten auch als Link zu erkennen ist. Danach erzeugen wir den Toggler, verstecken die Sessionbeschreibung und speichern den Toggler in unserem "Listen"-Objekt.

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;			
}

Schauen wir uns das mal ein wenig genauer an.

//calculate an id for the headline
var headlineID = "head" + headlineNode.parentNode.id ;
//and assign it to the element
headlineNode.id = headlineID;

Um an eine eindeutige ID zu gelangen, benutzen wir die ID des Elternelementes. Wie oben zu sehen ist, hat das <div> eine ID. Wir versehen es mit einem Präfix und weisen in der nächsten Zeile den HTML-Knoten die neu erzeugte ID zu.

In dieser Zeile fügen wir lediglich die CSS-Eigenschaft zu der Überschrift hinzu.

//add style to title for pointer
dojo.style(headlineID, "cursor", "pointer");

Dabei benutzen wir zur Identifizierung gleich die neu erzeugte ID.

Die ID der Sessionbeschreibungen ist nach dem gleichen Muster aufgebaut.

//retrieve the description id from the parent node
var descriptionID = "desc" + headlineNode.parentNode.id

Allerdings ist die ID bereits im ursprünglichen HTML-Code vorhanden.

Der dojo.fx.Toggler übernimmt das Ein-/Ausblenden.

//create a new toggler
var toggler = new dojo.fx.Toggler({
	node: descriptionID,
	showFunc: dojo.fx.wipeIn,
	hideFunc: dojo.fx.wipeOut
});

Der Konstruktor der Klasse dojo.fx.Toggler erwartet ein Konfigurationsobjekt. In der Eigenschaft "node" wird die ID oder der Knoten des HTML Elementes übergeben, auf das der Toggler angewendet werden soll. Die Eigenschaften "showFunc" und "hideFunc" beinhalten die Animationsklassen aus dem dojo.fx-Package, die jeweils zum Ein- und Ausblenden aufgerufen werden sollen. Die Methode zum Ausblenden wird unmittelbar aufgerufen.

//hide the description
toggler.hide();

In JavaScript gibt es keine Listenkonstruktion, so wie in LotusScript. Allerdings sind  sie auch nicht notwendig. Jedes Objekt kann als Liste verwendet werden. Dabei entsprechen die Eigenschaftennamen den Schlüsseln bei Listen. Dabei macht man sich zu Nutze, dass neben der bekannten Schreibweise object.eigenschaft auch die Schreibweise object"eigenschaft" erlaubt ist. Diese Schreibweise ist besonders gut, wenn die Schlüssel Zeichen enthalten, die als Eigenschaftsname nicht verwendet werden dürfen. Diese Technik wird auch als "Assoziatives Array" bezeichnet.

//store the toggler in the list
descriptionTogglerListheadlineID = toggler;

In unserem Fall speichern wir also den erzeugten Toggler unter der ID der Headline in dem descriptionTogglerList-Objekt.

Die beiden nachstehenden Funktionen zum Ein- bzw. Ausblenden können direkt über die ID des Sessiontitels auf die zugehörigen Toggler zugreifen.

//shows a description
function showDescription(headlineID){
				descriptionTogglerListheadlineID.show();
}

//hide a description
function hideDescription(headlineID){
				descriptionTogglerListheadlineID.hide();
}

Damit die oben definierten Funktionen greifen können, müssen wir im dojo.addOnLoad ein bisschen was tun.

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();		
});

Zunächst werden mit dojo.query alle Sessiontitel gesucht und jewails die Funktion registerDescriptionToogle aufgerufen. Somit haben wir die Toggler definiert.

Im nächsten Schritt nutzen wir das dojo.behavior-Package. Mit dojo.behavior.add() fügen wir ein neues Verhalten zu. Dazu erzeugen wir ein Behavior-Objekt. Das Behavior-Objekt ist im ersten Moment ein wenig ungewöhnlich. Als Eigenschaftsname wird ein CSS Selektor definiert. Die zugehörige Eigenschaft wiederum ist ein Eventhandler-Objekt. Wobei jeweils die Eigenschaftsname die Events sind, auf die regiert werden soll. Die zugehörige Eigenschaft enthält die Methode, die beim Auslösen des Events ausgeführt werden soll.
Sowohl die Sessontitel (div.session h1) als auch die Sessionbeschreibungen (div.session div.sessionDescription) erhalten entsprechende Händler. Beim Aufruf für das Schließen der Beschreibung,  muss über einen regulären Ausdruck aus der ID der Sessionbeschreibung auf die ID des Sessiontitels geschlossen werden, weil die Toggler in der Liste über die ID der Headline zugeordnet werden.

Die Zeile dojo.behavior.apply() ist besonders wichtig. Ohne diese Aufruf würde das "Verhalten" zwar definiert werden, aber niemals zur Anwendung kommen.

Wer bis hier durchgehalten hat, kann sich das fertige Ergebnis live ansehen. In der zu dieser Artikelserien gehörenden Beispieldatenbank finden sie den Inhalt dieses Artikels in der Maske "webSpeedAgendaing-Step 4|SpeedAgendaing-4" und der JavaScript Bibliothek "SpeedAgendaing-Step4.js".

Im nächsten Artikel werden wir das Beispiel dahingehend weiterführen, dass die Sessionbeschreibung beim wiederholten Klick auf den Sessiontitel sich wieder schließt.

Fachbeitrag IBM Domino JavaScript Entwicklung

Sie haben Fragen zu diesem Artikel? Kontaktieren Sie uns gerne: blog@assono.de

Sie wollen eine individuelle Lösung? Kontaktieren Sie uns

Weitere interessante Artikel

Sie haben Fragen? Wir sind für Sie da.

Wir verwenden Ihre Daten, um Sie einmalig per E-Mail zu kontaktieren. Wir geben Ihre Daten nicht an Dritte weiter. Siehe: Datenschutzhinweise
assono GmbH

Standort Kiel (Zentrale)
assono GmbH
Lise-Meitner-Straße 1–7
24223 Schwentinental

Standort Hamburg
assono GmbH
Bornkampsweg 58
22761 Hamburg

Telefonnummern:
Zentrale: +49 4307 900 407
Techn. Hotline: +49 4307 900 403
Vertrieb: +49 4307 900 402

E-Mail-Adressen:
kontakt@assono.de
bewerbung@assono.de