Posts Tagged: ‘JSF’

Quick-n-Dirty: Manipulation von UI Komponenten via SSJS (2)

3. November 2011 Posted by Sven Hasselbach

Ist einer der Items durch einen Mehrfachwert definiert worden,  muss das entsprechende Item anders behandelt werden. Eine Definition wie folgt…

<xp:comboBox id="comboBox1">
   <xp:selectItems>
      <xp:this.value><![CDATA[#{javascript:
         var vItem = new java.util.Vector();
         vItem.add("A|1");
         vItem.add("B|2");
         vItem.add("C|3");
         vItem
      }]]></xp:this.value>
   </xp:selectItems>
</xp:comboBox>

…ist auch intern als Array zu behandeln. Eine Funktion, die mit beiden Item-Typen umgehen kann (auch im Mix), kann dann wie folgt aufgebaut sein:

function getSelectableValues( id ) {
   var ComboBox = getComponent( id );
   var ChildrenList:java.util.ListIterator;
   ChildrenList = ComboBox.getChildren().listIterator()
   while (ChildrenList.hasNext()) {
      var Child = ChildrenList.next();     
      if( typeof( Child ) == 'com.ibm.xsp.component.UISelectItemsEx' ){
         var hlp = Child.getValue();
         for( var i=0; i< hlp.length; i++ ){
            print( hlp[i].getLabel() + "|" + hlp[i].getValue() );
            hlp[i].setLabel("ABC" + i );
            hlp[i].setValue("123" + i );
            hlp[i].setDisabled(true);
         }
         Child.setValue(hlp);
      }
      if( typeof( Child ) == 'com.ibm.xsp.component.UISelectItemEx' ){
         print( Child.getItemLabel() + "|" + Child.getItemValue() );
      }
   }
}

getSelectableValues( 'comboBox1' );

[Fett: Wenn Änderungen am Mehrfachwert-Item vorgenommen werden, muss das Item nach der Bearbeitung mit "setValue()" erneuert werden]

Die Namen der Methoden sind ohne “Item” zu verwenden, z.B. setItem() anstelle von setItemValue().

Quick-n-Dirty: Manipulation von UI Komponenten via SSJS

3. November 2011 Posted by Sven Hasselbach

Serverseitig lassen sich die die Items einer Auswahlbox (z.B. eine Combobox, Listboxen, usw.) auslesen und ggf. manipulieren. Hier eine Combobox mit drei Items:

<xp:comboBox id="comboBox1">
   <xp:selectItem itemLabel="A" itemValue="1"></xp:selectItem>
   <xp:selectItem itemLabel="B" itemValue="2"></xp:selectItem>
   <xp:selectItem itemLabel="C" itemValue="3"></xp:selectItem>
</xp:comboBox>

Um via SSJS die Items der UI Komponente und deren Eigenschaften zu erhalten, kann man wie folgt darauf zu greifen:

function listSelectableValues( id ) {
   var cBox = getComponent( id );
   var cList:java.util.ListIterator;
   cList = ComboBox.getChildren().listIterator();
   while (ChildrenList.hasNext()) {
      var c = ChildrenList.next()
      print ("Label: " + c.getItemLabel() );
      print ("Value: " + c.getItemValue() );
      print ("IsDisabled: " + c.isDisabled() );
   }
}

listSelectableValues( 'comboBox1' );

Auf der Serverkonsole werden nun die Eigenschaften der drei Items ausgegeben.

Natürlich lassen sich die Items auch manipulieren:

<xp:button value="Label" id="button1">
   <xp:eventHandler event="onclick" submit="true"
      refreshMode="partial" refreshId="comboBox1">
      <xp:this.action><![CDATA[#{javascript:
         var cBox = getComponent( 'comboBox1' );
         var cBoxChildren = cBox.getChildren();
         var cBoxChild = cBoxChildren.get(0);

         // --- disablen
         cBoxChild.setItemDisabled(true);

         // --- das Label ändern
         cBoxChild.setItemLabel("DISABLED");

         // --- den Value ändern
         cBoxChild.setItemValue("disabled");
      }]]></xp:this.action>
      </xp:eventHandler>
</xp:button>

Der Button führt einen PartialRefresh auf die ComboBox aus, deaktiviert das erste Item (es ist nicht mehr selektierbar) und ändert sowohl das Label als auch den Wert des ersten Items.

Der Fluch des Partial Refreshs

30. Oktober 2011 Posted by Sven Hasselbach

Bei der Architektur von Web 2.0-Applikationen gibt es ein paar Besonderheiten zu beachten, die es im “alten” Web nicht gegeben hat, denn der konzeptionelle Ansatz, durch die AJAX-gestützten Abfragen nur einzelne Segmente einer Webseite zu laden (und diese Abfragen im Hintergrund durchzuführen), kann sich zu einem grundlegenden Problem entwickeln: Zum Einen leidet die Benutzbarkeit einer Applikation, denn das Verlinken der Inhalte ist nicht möglich, zum Anderen können Suchmaschinen die Seiten nicht oder nur noch teilweise indizieren.

Zum Erläuterung des Problems hier eine kleine Denksportaufgabe: Wie verlinke ich eine bestimmte Seite, z.B. die zweite Seite des XPages-Developer-Forums? Das Verlinken eines Beitrages stellt kein Problem dar, aber die zweite Seite zu verlinken ist nicht möglich.

Im “guten alten Web”, bei dem die Webseiten immer komplett geladen und die Optionen zum Großteil über URL-Parameter gesteuert werden, existiert als Nebeneffekt automatisch eine Möglichkeit, ein Bookmark zu setzen, wie z.B. hier: Domino 8.5 Forum, Seite 2, Kategorisierung eingeklappt.

Auch ist es für die Bots der Suchmaschinen viel einfacher, allen Verlinkungen innerhalb einer Webseite zu folgen, denn hinter dem Link verbirgt sich eine (neue) Seite, die es ebenfalls zu indizieren gilt.

Im Falle von XPages-Applikationen gibt es diese Möglichkeiten nicht Out-Of-The-Box. Man kann hier getrost vom “Fluch des Partial Refreshes” sprechen kann, denn so muß die Google-Spezifikation für durchsuchbare AJAX-Applikationen in die XPages händisch eingebaut werden. Und das für jeden Pager, jede Aktion, jeden Serverseitigen Link…

Um die Funktionalität der Bookmarks wieder herzustellen, kann der URL Hash “angezapft” werden; dieser muß jedoch via Javascript gesetzt bzw. ausgewertet werden. Eine Hilfe hierfür bietet der Dojo Toolkit mittels dojo.hash. Die Variante der URL Manipulation OHNE ein Neuladen der Webseite ist auch mit älteren Browsern möglich; mit HTML 5 ist die Möglichkeit geschaffen worden, die URL wirklich manipulieren zu können. Eine nette Implementierung findet sich auch unter https://github.com/balupton/history.js. Die HTML 5 – Variant e ist Serverseitig auswertbar, da sich die URL-Parameter ohne Reload der Seite setzen lassen (und im HTTP Request übertragen werden). Aber leider ist diese Funktionalität nicht in älteren Browser verfügbar.

Will man kompatibel bleiben, bleibt also nur der Weg über den URL-Hash. Im Falle eines Seitenaufrufs über ein Bookmark muß der Hash-Part der URL im Client ausgewertet werden, denn der Hash wird NICHT via HTTP Request übertragen (und damit auch nicht Serverseitig auswertbar). Erst nach dieser Auswertung können diese Informationen z.B. mit einen Partial Refresh übertragen werden.

Eine Beispiel-Implementation ist in Arbeit und wird bei Gelegenheit veröffentlicht.