JavaServer Faces: Integrationsstrategien für AJAX
Kommentare

Listing 5
———————————————————————-
package net.wessendorf.jm.faces.ajax.component.simple;
import java.io.IOException;
import java.util.Map;
import javax.faces.component.*;
import

Listing 5
----------------------------------------------------------------------
package net.wessendorf.jm.faces.ajax.component.simple;
import java.io.IOException;
import java.util.Map;
import javax.faces.component.*;
import javax.faces.context.*;
import javax.faces.render.Renderer;
import net.wessendorf.jm.faces.ajax.common.JSHelper;

public class InputSuggestRenderer extends Renderer {

  private final static String DIV_ID = "results";
  public void decode(FacesContext context, UIComponent component) {
    ExternalContext external = context.getExternalContext();
    Map params = external.getRequestParameterMap();
    UIInput input = (UIInput) component;
    String clientId = input.getClientId(context);
    String submittedValue = (String)params.get(clientId);
    input.setSubmittedValue(submittedValue);
  }
  public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
    this.encodeResources(context, component);
    super.encodeBegin(context, component);
    ResponseWriter out = context.getResponseWriter();
    String clientId = component.getClientId(context);
    out.startElement("input", component);
    out.writeAttribute("name", clientId, null);
    out.writeAttribute("id", clientId, null);
    out.writeAttribute("autocomplete", "off", null);
    out.endElement("input");

    out.startElement("div", null);
    out.writeAttribute("id", DIV_ID, null);
    out.writeAttribute("class", "ajax", null);
    out.endElement("div");

    out.startElement("script", null);
    out.writeAttribute("type", "text/javascript", null);
    out.writeText("ntry {n" +
      "new Ajax.Autocompleter('"+component.getClientId(context)+"', '"+DIV_ID+"', '"+component.getAttributes().get("resourceURL")+"');n" +
      "} catch(e) {n" +
        "alert(e.message);n"+
      "}", null);
    out.endElement("script");
  }
  private void encodeResources(FacesContext context, UIComponent component) throws IOException {
    JSHelper.addJavaScript(InputSuggestRenderer.class, "controls.js", "resourcefilter?script=", context);
    ...
  }
}

Die Methode encodeBegin() generiert das notwendige HTML. Als Erstes wird das Eingabefeld gerendert, dessen autocomplete-Attribut auf off gesetzt wird. Nach der Ausgabe des

-Elements folgt der interessanteste Teil, die JavaScript-Anweisung zum Absenden des AJAX-Requests. Der Autocompleter-Klasse werden innerhalb des Renderers dynamisch die drei Parameter übergeben. Die ID des Eingabefeldes wird durch die Anweisung component.getClientId(context) gewonnen. Für das
-Element wird dessen ID aus der Konstante DIV_ID ausgelesen und die URL des Servlets wird über die Map-Datenstruktur der Methode getAttributes() direkt aus der JSF-Komponente ausgelesen. Die Renderer-Klasse hat noch eine weitere Methode, die private Methode encodeResources(). Sie nutzt die eigens implementierte Hilfsklasse JSHelper, um die Ressourcen wie CSS- oder JavaScript-Dateien auszuliefern. Die statischen Methoden addJavaScript() und addCSS() machen nichts anderes, als URLs für JavaScript oder CSS zu rendern. Die Auslieferung erfolgt über einen Servlet-Filter. Die Idee zu einem Servlet-Filter für die Auslieferung von Ressourcen stammt aus dem Apache-MyFaces-Projekt. Allerdings sei angemerkt, dass ein Servlet-Filter innerhalb einer Portlet-Umgebung zu Problemen führen kann. Doch nun fragt sich der angehende Component Writer: „Wohin mit den JavaScript- und CSS-Dateien?“. Die Antwort ist einfach: sie werden im gleichen Paket abgelegt wie die Klassen der AJAX-Komponente. Das hat den Vorteil, dass der Component Writer eine einzige JAR-Datei, statt etlicher Dateien, ausliefert. Konfiguriert wird die Komponente innerhalb der faces-config.xml-Datei.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -