全部もりもり書いてSeamカスタムタグをつくる
繰り返し系のタグで、「リストの中から1つ前の値が欲しい」時があるわけです。
1つ前の値と比較して、違っていたらxxする…とか。
福岡県 | ||
---|---|---|
北九州市 | ||
name | age | sex |
taro | 40 | MAN |
jiro | 35 | MAN |
福岡市 | ||
name | age | sex |
hana | 20 | WOMAN |
大分県 | ||
別府市 | ||
name | age | sex |
aiko | 18 | WOMAN |
これをSeamで出力しようとすると、dataListやdataTable等の繰り返しタグを入れ子にして、
この例だと3段階の入れ子?にしないといけません。
リストの1つ前の値が取れれば、入れ子にせずにdataList1つだけで
できるのになぁ。
というわけでつくってみました。
こんな感じのタグです。
<rich:dataList2 var="u" preVar="p" value="#{users}"> <s:div rendered="ここにEL式でuとpを使って比較"> … </s:div> … </rich:dataList2>
preVar属性に、前回(1繰り返し前)にvar属性で指定されたオブジェクトが入ります。
以下が、拡張タグ
org.richfaces.component.html.HtmlDataList2
package org.richfaces.component.html; import java.util.Iterator; import java.util.Map; import javax.faces.context.FacesContext; import javax.faces.el.ValueBinding; import javax.faces.model.DataModel; import org.richfaces.component.UIDataList; /** * @author tagawaman * */ @SuppressWarnings("all") public class HtmlDataList2 extends UIDataList { private String _title; private String _rowClasses; private String _footerClass; private String _dir; private String _styleClass; private String _style; private String _lang; private String _type; private String _columnClasses; private String _headerClass; private String _preVar; public static final String COMPONENT_TYPE = "org.richfaces.DataList2"; public static final String COMPONENT_FAMILY = "org.richfaces.DataList2"; public HtmlDataList2() { _title = null; _rowClasses = null; _footerClass = null; _dir = null; _styleClass = null; _style = null; _lang = null; _type = null; _columnClasses = null; _headerClass = null; _preVar = null; setRendererType("org.richfaces.DataList2Renderer"); } public void setTitle(String __title) { _title = __title; } public String getTitle() { if (null != _title) return _title; ValueBinding vb = getValueBinding("title"); if (null != vb) return (String) vb.getValue(getFacesContext()); else return null; } public void setRowClasses(String __rowClasses) { _rowClasses = __rowClasses; } public String getRowClasses() { if (null != _rowClasses) return _rowClasses; ValueBinding vb = getValueBinding("rowClasses"); if (null != vb) return (String) vb.getValue(getFacesContext()); else return null; } public void setFooterClass(String __footerClass) { _footerClass = __footerClass; } public String getFooterClass() { if (null != _footerClass) return _footerClass; ValueBinding vb = getValueBinding("footerClass"); if (null != vb) return (String) vb.getValue(getFacesContext()); else return null; } public void setDir(String __dir) { _dir = __dir; } public String getDir() { if (null != _dir) return _dir; ValueBinding vb = getValueBinding("dir"); if (null != vb) return (String) vb.getValue(getFacesContext()); else return null; } public void setStyleClass(String __styleClass) { _styleClass = __styleClass; } public String getStyleClass() { if (null != _styleClass) return _styleClass; ValueBinding vb = getValueBinding("styleClass"); if (null != vb) return (String) vb.getValue(getFacesContext()); else return null; } public void setStyle(String __style) { _style = __style; } public String getStyle() { if (null != _style) return _style; ValueBinding vb = getValueBinding("style"); if (null != vb) return (String) vb.getValue(getFacesContext()); else return null; } public void setLang(String __lang) { _lang = __lang; } public String getLang() { if (null != _lang) return _lang; ValueBinding vb = getValueBinding("lang"); if (null != vb) return (String) vb.getValue(getFacesContext()); else return null; } public void setType(String __type) { _type = __type; } public String getType() { if (null != _type) return _type; ValueBinding vb = getValueBinding("type"); if (null != vb) return (String) vb.getValue(getFacesContext()); else return null; } public void setColumnClasses(String __columnClasses) { _columnClasses = __columnClasses; } public String getColumnClasses() { if (null != _columnClasses) return _columnClasses; ValueBinding vb = getValueBinding("columnClasses"); if (null != vb) return (String) vb.getValue(getFacesContext()); else return null; } public void setHeaderClass(String __headerClass) { _headerClass = __headerClass; } public String getHeaderClass() { if (null != _headerClass) return _headerClass; ValueBinding vb = getValueBinding("headerClass"); if (null != vb) return (String) vb.getValue(getFacesContext()); else return null; } public void setPreVar(String __preVal) { _preVar = __preVal; } public String getPreVar() { if (null != _preVar) return _preVar; ValueBinding vb = getValueBinding("preVar"); if (null != vb) return (String) vb.getValue(getFacesContext()); else return null; } protected void setupVariable(FacesContext faces, DataModel localModel, boolean rowSelected) { Map attrs = faces.getExternalContext().getRequestMap(); if (rowSelected && isRowAvailable()) { setupVariable(getPreVar(), attrs, getNowVariable(getVar(), attrs)); setupVariable(getVar(), attrs, localModel.getRowData()); setupVariable(getStateVar(), attrs, getComponentState()); setupVariable(getRowKeyVar(), attrs, getRowKey()); } else { removeVariable(getPreVar(), attrs); removeVariable(getVar(), attrs); removeVariable(getStateVar(), attrs); removeVariable(getRowKeyVar(), attrs); } } private Object getNowVariable(String var, Map attrs) { return var != null ? attrs.get(var) : null; } private void setupVariable(String var, Map attrs, Object rowData) { if (var != null) attrs.put(var, rowData); } private void removeVariable(String var, Map attrs) { if (var != null) attrs.remove(var); } public Object saveState(FacesContext context) { Object values[] = new Object[12]; values[0] = super.saveState(context); values[1] = _title; values[2] = _rowClasses; values[3] = _footerClass; values[4] = _dir; values[5] = _styleClass; values[6] = _style; values[7] = _lang; values[8] = _type; values[9] = _columnClasses; values[10] = _headerClass; values[11] = _preVar; return ((Object) (values)); } public void restoreState(FacesContext context, Object state) { Object values[] = (Object[]) (Object[]) state; super.restoreState(context, values[0]); _title = (String) values[1]; _rowClasses = (String) values[2]; _footerClass = (String) values[3]; _dir = (String) values[4]; _styleClass = (String) values[5]; _style = (String) values[6]; _lang = (String) values[7]; _type = (String) values[8]; _columnClasses = (String) values[9]; _headerClass = (String) values[10]; _preVar = (String) values[11]; } public String getFamily() { return "org.richfaces.DataList2"; } }
org.richfaces.renderkit.html.DataList2Renderer
package org.richfaces.renderkit.html; import java.io.IOException; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import org.ajax4jsf.renderkit.*; import org.richfaces.component.UIDataList; import org.richfaces.renderkit.AbstractListRenderer; /** * @author tagawaman * */ public class DataList2Renderer extends AbstractListRenderer { public DataList2Renderer() { } private String convertToString(Object obj) { return obj != null ? obj.toString() : ""; } private String convertToString(boolean b) { return String.valueOf(b); } private String convertToString(int b) { return b == -2147483648 ? "" : String.valueOf(b); } private String convertToString(long b) { return b == -9223372036854775808L ? "" : String.valueOf(b); } protected Class getComponentClass() { return org.richfaces.component.UIDataList.class; } public void doEncodeBegin(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException { ComponentVariables variables = ComponentsVariableResolver.getVariables(this, component); doEncodeBegin(writer, context, (UIDataList) component, variables); } public void doEncodeBegin(ResponseWriter writer, FacesContext context, UIDataList component, ComponentVariables variables) throws IOException { String clientId = component.getClientId(context); writer.startElement("ul", component); getUtils().writeAttribute(writer,"class","dr-list rich-datalist " + convertToString(component.getAttributes().get("styleClass"))); getUtils().writeAttribute(writer, "id", clientId); getUtils().writeAttribute(writer, "type", component.getAttributes().get("type")); getUtils().encodeAttributesFromArray(context, component, new String[] { "dir", "lang", "onclick", "ondblclick", "onkeydown", "onkeypress", "onkeyup", "onmousedown", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "style", "title", "xml:lang" }); } public void doEncodeChildren(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException { ComponentVariables variables = ComponentsVariableResolver.getVariables(this, component); doEncodeChildren(writer, context, (UIDataList) component, variables); } public void doEncodeChildren(ResponseWriter writer, FacesContext context, UIDataList component, ComponentVariables variables) throws IOException { encodeRows(context, component); } public boolean getRendersChildren() { return true; } public void doEncodeEnd(ResponseWriter writer, FacesContext context, UIDataList component, ComponentVariables variables) throws IOException { writer.endElement("ul"); } public void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException { ComponentVariables variables = ComponentsVariableResolver.getVariables(this, component); doEncodeEnd(writer, context, (UIDataList) component, variables); ComponentsVariableResolver.removeVariables(this, component); } }
org.richfaces.taglib.DataList2Tag
package org.richfaces.taglib; import javax.faces.component.UIComponent; import org.ajax4jsf.webapp.taglib.HtmlComponentTagBase; /** * @author tagawaman * */ public class DataList2Tag extends HtmlComponentTagBase { private String _footer; private String _rowClasses; private String _stateVar; private String _componentState; private String _rowKeyVar; private String _footerClass; private String _ajaxKeys; private String _rowKey; private String _rowIndex; private String _var; private String _rows; private String _type; private String _columnClasses; private String _header; private String _first; private String _headerClass; private String _preVar; public DataList2Tag() { _footer = null; _rowClasses = null; _stateVar = null; _componentState = null; _rowKeyVar = null; _footerClass = null; _ajaxKeys = null; _rowKey = null; _rowIndex = null; _var = null; _rows = null; _type = null; _columnClasses = null; _header = null; _first = null; _headerClass = null; _preVar = null; } public void setFooter(String __footer) { _footer = __footer; } public void setRowClasses(String __rowClasses) { _rowClasses = __rowClasses; } public void setStateVar(String __stateVar) { _stateVar = __stateVar; } public void setComponentState(String __componentState) { _componentState = __componentState; } public void setRowKeyVar(String __rowKeyVar) { _rowKeyVar = __rowKeyVar; } public void setFooterClass(String __footerClass) { _footerClass = __footerClass; } public void setAjaxKeys(String __ajaxKeys) { _ajaxKeys = __ajaxKeys; } public void setRowKey(String __rowKey) { _rowKey = __rowKey; } public void setRowIndex(String __rowIndex) { _rowIndex = __rowIndex; } public void setVar(String __var) { _var = __var; } public void setRows(String __rows) { _rows = __rows; } public void setType(String __type) { _type = __type; } public void setColumnClasses(String __columnClasses) { _columnClasses = __columnClasses; } public void setHeader(String __header) { _header = __header; } public void setFirst(String __first) { _first = __first; } public void setHeaderClass(String __headerClass) { _headerClass = __headerClass; } public String get_preVar() { return _preVar; } public void set_preVar(String preVar) { this._preVar = preVar; } public void release() { super.release(); _footer = null; _rowClasses = null; _stateVar = null; _componentState = null; _rowKeyVar = null; _footerClass = null; _ajaxKeys = null; _rowKey = null; _rowIndex = null; _var = null; _rows = null; _type = null; _columnClasses = null; _header = null; _first = null; _headerClass = null; _preVar = null; } protected void setProperties(UIComponent component) { super.setProperties(component); setStringProperty(component, "rowClasses", _rowClasses); setStringProperty(component, "stateVar", _stateVar); setStringProperty(component, "componentState", _componentState); setStringProperty(component, "rowKeyVar", _rowKeyVar); setStringProperty(component, "footerClass", _footerClass); setStringProperty(component, "ajaxKeys", _ajaxKeys); setStringProperty(component, "rowKey", _rowKey); setIntegerProperty(component, "rowIndex", _rowIndex); setStringProperty(component, "var", _var); setIntegerProperty(component, "rows", _rows); setStringProperty(component, "type", _type); setStringProperty(component, "columnClasses", _columnClasses); setIntegerProperty(component, "first", _first); setStringProperty(component, "headerClass", _headerClass); setStringProperty(component, "preVar", _preVar); } public String getComponentType() { return "org.richfaces.DataList2"; } public String getRendererType() { return "org.richfaces.DataList2Renderer"; } }
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd"> <faces-config> <component> <description /> <component-type>org.richfaces.DataList2</component-type> <component-class> org.richfaces.component.html.HtmlDataList2 </component-class> <component-extension> <component-family>org.richfaces.DataList2</component-family> <renderer-type> org.richfaces.DataList2Renderer </renderer-type> </component-extension> </component> <render-kit> <render-kit-id>HTML_BASIC</render-kit-id> <renderer> <component-family>org.richfaces.DataList2</component-family> <renderer-type> org.richfaces.DataList2Renderer </renderer-type> <renderer-class> org.richfaces.renderkit.html.DataList2Renderer </renderer-class> </renderer> </render-kit> </faces-config>
rich.taglib.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "http://java.sun.com/dtd/facelet-taglib_1_0.dtd"> <facelet-taglib xmlns="http://java.sun.com/JSF/Facelet"> <namespace>http://richfaces.org/rich</namespace> <tag> <tag-name>dataList2</tag-name> <component> <component-type>org.richfaces.DataList2</component-type> <renderer-type> org.richfaces.DataList2Renderer </renderer-type> </component> </tag> </facelet-taglib>
rich.tld
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>1.2</tlib-version> <jsp-version>1.2</jsp-version> <short-name>rich</short-name> <uri>http://richfaces.org/rich</uri> <display-name>RichFaces</display-name> <description>RichFaces components</description> <tag> <name>dataList2</name> <tag-class>org.richfaces.taglib.DataList2Tag</tag-class> <body-content>JSP</body-content> <description /> <attribute> <name>title</name> <rtexprvalue>false</rtexprvalue> <description> Advisory title information about markup elements generated for this component </description> </attribute> <attribute> <name>rowClasses</name> <rtexprvalue>false</rtexprvalue> <description> A comma-delimited list of CSS style classes that is applied to popup table rows. A space separated list of classes may also be specified for any individual row. The styles are applied, in turn, to each row in the table. For example, if the list has two elements, the first style class in the list is applied to the first row, the second to the second row, the first to the third row, the second to the fourth row, etc. In other words, we keep iterating through the list until we reach the end, and then we start at the beginning again </description> </attribute> <attribute> <name>stateVar</name> <rtexprvalue>false</rtexprvalue> <description> The attribute provides access to a component state on the client side </description> </attribute> <attribute> <name>componentState</name> <rtexprvalue>false</rtexprvalue> <description> It defines EL-binding for a component state for saving or redefinition </description> </attribute> <attribute> <name>rowKeyVar</name> <rtexprvalue>false</rtexprvalue> <description> The attribute provides access to a row key in a Request scope </description> </attribute> <attribute> <name>rendered</name> <rtexprvalue>false</rtexprvalue> <description> If "false", this component is not rendered </description> </attribute> <attribute> <name>footerClass</name> <rtexprvalue>false</rtexprvalue> <description> Space-separated list of CSS style class(es) that are be applied to any footer generated for this table </description> </attribute> <attribute> <name>dir</name> <rtexprvalue>false</rtexprvalue> <description> Direction indication for text that does not inherit directionality. Valid values are "LTR" (left-to-right) and "RTL" (right-to-left) </description> </attribute> <attribute> <name>id</name> <rtexprvalue>false</rtexprvalue> <description> Every component may have a unique id that is automatically created if omitted </description> </attribute> <attribute> <name>styleClass</name> <rtexprvalue>false</rtexprvalue> <description> Corresponds to the HTML class attribute </description> </attribute> <attribute> <name>ajaxKeys</name> <rtexprvalue>false</rtexprvalue> <description> This attribute defines rows that are updated after an AJAX request </description> </attribute> <attribute> <name>rowKey</name> <rtexprvalue>false</rtexprvalue> <description> RowKey is a representation of an identifier for a specific data row </description> </attribute> <attribute> <name>style</name> <rtexprvalue>false</rtexprvalue> <description> CSS style(s) is/are to be applied when this component is rendered </description> </attribute> <attribute> <name>var</name> <rtexprvalue>false</rtexprvalue> <description> A request-scope attribute via which the data object for the current row will be used when iterating </description> </attribute> <attribute> <name>preVar</name> <rtexprvalue>false</rtexprvalue> <description> A request-scope attribute via which the data object for the pre-row will be used when iterating </description> </attribute> <attribute> <name>value</name> <rtexprvalue>false</rtexprvalue> <description> The current value for this component </description> </attribute> <attribute> <name>rows</name> <rtexprvalue>false</rtexprvalue> <description> A number of rows to display, or zero for all remaining rows in the table </description> </attribute> <attribute> <name>lang</name> <rtexprvalue>false</rtexprvalue> <description> Code describing the language used in the generated markup for this component </description> </attribute> <attribute> <name>type</name> <rtexprvalue>false</rtexprvalue> <description> Corresponds to the HTML DL type attribute </description> </attribute> <attribute> <name>columnClasses</name> <rtexprvalue>false</rtexprvalue> <description> Comma-delimited list of CSS style classes that are be applied to the columns of this table. A space separated list of classes may also be specified for any individual column. If the number of elements in this list is less than the number of columns specified in the "columns" attribute, no "class" attribute is output for each column greater than the number of elements in the list. If the number of elements in the list is greater than the number of columns specified in the "columns" attribute, the elements at the position in the list after the value of the "columns" attribute are ignored </description> </attribute> <attribute> <name>first</name> <rtexprvalue>false</rtexprvalue> <description> A zero-relative row number of the first row to display </description> </attribute> <attribute> <name>headerClass</name> <rtexprvalue>false</rtexprvalue> <description> Space-separated list of CSS style class(es) that are be applied to any header generated for this table </description> </attribute> <attribute> <name>binding</name> <rtexprvalue>false</rtexprvalue> <description> The attribute takes a value-binding expression for a component property of a backing bean </description> </attribute> </tag> </taglib>
したほうがいいのかも。時間があったら継承にしなおそっと。