!Panel maximieren
{{{
    toggleFull: function(panel) {
      if (panel.className == 'full') {
        panel.className = panel.fullSizeOrig.className;
        window.scrollTo(panel.fullSizeOrig.scrollX, panel.fullSizeOrig.scrollY);
        document.body.style.overflow = 'auto';
        panel.fullSizeOrig = null;
      } else {
        panel.fullSizeOrig = {
          className: panel.className,
          scrollX: window.scrollX,
          scrollY: window.scrollY
        };
        panel.className = 'full';
        document.body.style.overflow = 'hidden';
        window.scrollTo(0, 0);
      }
    }
}}}

!Sublisten
{{{
    <rich:dataTable value="#{outers}" var="outer">
      <f:facet name="header">
        <rich:columnGroup>
          <rich:column>
            <h:outputText value="1"/>
          </rich:column>
          <rich:column>
            <h:outputText value="2"/>
          </rich:column>
          <rich:column>
            <h:outputText value="3"/>
          </rich:column>
        </rich:columnGroup>
      </f:facet>

      <rich:column rowspan="#{outer.inners.size + 1}">
        <h:outputText value="1 (outer)"/>
      </rich:column>
      <rich:column colspan="2" style="padding: 0; border: 0;"/>

      <rich:subTable value="#{outer.inners}" var="inner">
        <rich:column>
            <h:outputText value="2 (inner)"/>
        </rich:column>
        <rich:column>
            <h:outputText value="3 (inner)"/>
        </rich:column>
      </rich:subTable>
    </rich:dataTable>
}}}

!Paging DataModel für DataTable
{{{
public class PageableDataModel extends SerializableDataModel {
  private Long rowKey;

  @Override
  public Long getRowKey() {
    return rowKey;
  }
  @Override
  public void setRowKey(Object key) {
    this.rowKey = (Long)key;
  }

  @Override
  public int getRowIndex() {
    return 0;
  }
  @Override
  public void setRowIndex(int rowIndex) {
  }

  @Override
  public Object getWrappedData() {
    throw new UnsupportedOperationException();
  }
  @Override
  public void setWrappedData(Object data) {
    throw new UnsupportedOperationException();
  }

  @Override
  public int getRowCount() {
    return backend.size();
  }

  @Override
  public Object getRowData() {
    if (rowKey == null)
      return null;
    return backend.get(rowKey);
  }

  @Override
  public boolean isRowAvailable() {
    return backend.containsKey(rowKey);
  }

  @Override
  public void walk(FacesContext context, DataVisitor visitor, Range range, Object argument) throws IOException {
    SequenceRange sequenceRange = (SequenceRange)range;
    int firstRow = sequenceRange.getFirstRow();
    int toIndex = sequenceRange.getFirstRow() + sequenceRange.getRows();
    for (int index = firstRow; index < toIndex; ++index) {
        Data data = backend.get(index);
        visitor.process(context, data.getKey(), argument);
    }
  }

  @Override
  public void update() {
  }

  @Override
  public SerializableDataModel getSerializableModel(Range range) {
    return this;
  }
}
}}}

!Validierung prüfen bei Ajax-Submit im Modal-Panel
Facelet:
{{{
<rich:modalPanel id="modalPanel">
    <h:form id="form">
        <h:inputText value="#{bean.value}"/>
        ...
        <a4j:commandButton value="Submit"
            oncomplete="if (#{i:validated()}) Richfaces.hideModalPanel('modalPanel');"
    </h:form>
</rich:modalPanel>
}}}
Funktion:
{{{
  public static boolean validated() {
    Severity severity = FacesContext.getCurrentInstance().getMaximumSeverity();
    return severity == null || severity == FacesMessage.SEVERITY_INFO;
  }
}}}
intersult.taglib.xml:
{{{
	<function>
		<function-name>validated</function-name>
		<function-class>com.intersult.Functions</function-class>
		<function-signature>boolean validated()</function-signature>
	</function>
}}}

!Aktuelle Table Page merken
{{{
<rich:dataScroller page="#{bean.page}"/>
}}}