Component-oriented
web framework
<!DOCTYPE html>
<html lang="en-US"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite">
<cc:interface>
<cc:attribute name="photos" />
<!-- plugin configuration -->
<cc:attribute name="selector" />
[ ... snip ... ]
<cc:attribute name="dialogClass" />
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}:div">
<ui:repeat value="#{cc.attrs.photos}" var="photo">
<a rel="gallery" href="#{photo.full}" title="#{photo.title}">
<img src="#{photo.thumb}" alt="#{photo.title}" />
</a>
</ui:repeat>
</div>
<h:outputScript library="javax.faces" name="jsf.js"/>
<h:outputScript library="composite/com.jquery" name="jquery-1.7.2.min.js"/>
<h:outputScript library="composite/com.jqueryui/js" name="jquery-ui-1.8.19.custom.min.js"/>
<h:outputScript library="composite/com.github.blueimp/js" name="load-image.js"/>
<h:outputScript library="composite/com.github.blueimp/js" name="jquery.image-gallery.js"/>
<h:outputStylesheet library="composite/com.jqueryui/css/ui-lightness" name="jquery-ui.custom.css"/>
<h:outputStylesheet library="composite/com.github.blueimp/css" name="jquery.image-gallery.css"/>
<h:outputScript>
var pluginOptions = {};
! '#{cc.attrs.selector}' || (pluginOptions.selector = '#{cc.attrs.selector}');
[ ... snip ... ]
! '#{cc.attrs.dialogClass}' || (pluginOptions.dialogClass = '#{cc.attrs.dialogClass}');
jQuery(function() {
$(document.getElementById('#{cc.clientId}:div')).imagegallery(pluginOptions);
});
</h:outputScript>
</cc:implementation>
</html>
<!DOCTYPE html>
<html lang="en-US">
<ui:composition template="/resources/template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:s="http://richfaces.org/sandbox/composite">
<ui:define name="body">
<h:form id="form">
Some sample of the component:
<s:imagegallery photos="#{galleryBean.photos}"/>
</h:form>
</ui:define>
</ui:composition>
</html>
@ManagedBean
@RequestScoped
public class GalleryBean {
private List<FlickrPhoto> photos;
public GalleryBean() {
photos = new ArrayList<FlickrPhoto>();
photos.add(new FlickrPhoto("title a", "http://flickr.com/a..."));
photos.add(new FlickrPhoto("title c", "http://flickr.com/c..."));
photos.add(new FlickrPhoto("title d", "http://flickr.com/d..."));
...
}
public List<FlickrPhoto> getPhotos() {
return photos;
}
<cc:interface>
<cc:attribute name="value" />
<cc:attribute name="showOn" />
<cc:attribute name="dateFormat" />
<cc:attribute name="buttonImageOnly" />
</cc:interface>
<cc:implementation>
<h:inputText id="input" value="#{cc.attrs.value}" />
<h:outputScript library="javax.faces" name="jsf.js"/>
<h:outputScript library="composite/com.jquery" name="jquery-1.7.2.min.js"/>
<h:outputScript library="composite/com.jqueryui/development-bundle/ui" name="jquery.ui.core.js"/>
<h:outputScript library="composite/com.jqueryui/development-bundle/ui" name="jquery.ui.widget.js"/>
<h:outputScript library="composite/com.jqueryui/development-bundle/ui" name="jquery.ui.datepicker.js"/>
<h:outputStylesheet library="composite/com.jqueryui/css/ui-lightness" name="jquery-ui.custom.css"/>
<h:outputScript>
var pluginOptions = {
buttonImage: "#{request.contextPath}/javax.faces.resource/calendar.gif.jsf?ln=composite/org.richfaces",
buttonImageOnly: "#{"true" eq cc.attrs.buttonImageOnly}"
}
! '#{cc.attrs.showOn}' || (pluginOptions.showOn = '#{cc.attrs.showOn}');
! '#{cc.attrs.dateFormat}' || (pluginOptions.dateFormat = '#{cc.attrs.dateFormat}');
jQuery(function() {
$(document.getElementById('#{cc.clientId}:input')).datepicker(pluginOptions);
});
</h:outputScript>
</cc:implementation>
<s:datepicker buttonImageOnly="true" dateFormat="yy-mm-dd" showOn="both"/>
<input class="hasDatepicker" id="form:j_idt16:input" name="form:j_idt16:input" type="text">
<img src="/composite-demo/javax.faces.resource/calendar.gif.jsf?ln=composite/org.richfaces" class="ui-datepicker-trigger">
<script type="text/javascript" src="/composite-demo/javax.faces.resource/jsf.js.jsf?ln=javax.faces"></script>
<script type="text/javascript"
src="/composite-demo/javax.faces.resource/jquery-1.7.2.min.js.jsf?ln=composite/com.jquery">
</script>
<script type="text/javascript"
src="/composite-demo/javax.faces.resource/jquery.ui.core.js.jsf?ln=composite/com.jqueryui/development-bundle/ui">
</script>
<script type="text/javascript"
src="/composite-demo/javax.faces.resource/jquery.ui.widget.js.jsf?ln=composite/com.jqueryui/development-bundle/ui">
</script>
<script type="text/javascript"
src="/composite-demo/javax.faces.resource/jquery.ui.datepicker.js.jsf?ln=composite/com.jqueryui/development-bundle/ui">
</script>
<script type="text/javascript">
var pluginOptions = {
buttonImage:"/composite-demo/javax.faces.resource/calendar.gif.jsf?ln=composite/org.richfaces",
buttonImageOnly:"true"
}
!'both' || (pluginOptions.showOn = 'both');
!'yy-mm-dd' || (pluginOptions.dateFormat = 'yy-mm-dd');
jQuery(function () {
$(document.getElementById('form:j_idt16:input')).datepicker(pluginOptions);
});
</script>
<cc:interface componentType="org.richfaces.sandbox.composite.UITabs">
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<h:inputHidden id="selected" value="#{cc.selected}" />
<ul>
<ui:repeat var="tab" value="#{cc.tabChildren}"> <!-- #{cc.children} broken see: JAVASERVERFACES-2099 -->
<li>
<a href="##{tab.clientId}">#{tab.attributes['title']}</a>
</li>
</ui:repeat>
</ul>
<cc:insertChildren />
</div>
<h:outputScript library="javax.faces" name="jsf.js"/>
<h:outputScript library="composite/com.jquery" name="jquery-1.7.2.min.js"/>
<h:outputScript library="composite/com.jqueryui/development-bundle/ui" name="jquery.ui.core.js"/>
<h:outputScript library="composite/com.jqueryui/development-bundle/ui" name="jquery.ui.widget.js"/>
<h:outputScript library="composite/com.jqueryui/development-bundle/ui" name="jquery.ui.tabs.js"/>
<h:outputStylesheet library="composite/com.jqueryui/css/ui-lightness" name="jquery-ui.custom.css"/>
<h:outputScript>
var pluginOptions = { selected: '#{cc.selected}' }
$(function() {
var widget = $(document.getElementById('#{cc.clientId}'));
// initialize the plugin
widget.tabs(pluginOptions);
// register a tabselect change listener
widget.bind("tabsselect", function(event, ui) {
var selected_input = '#{cc.clientId}' + ':selected';
$(document.getElementById(selected_input)).val(ui.index);
// trigger an ajax update, executing the hiddn input element to update the component state
var options = { execute: selected_input }
jsf.ajax.request(selected_input, null, options);
});
});
</h:outputScript>
</cc:implementation>
@FacesComponent("org.richfaces.sandbox.composite.UITabs")
public class UITabs extends UINamingContainer {
enum PropertyKeys {selected}
public int getSelected() {
return (Integer) getStateHelper().eval(PropertyKeys.selected, 0);
}
public void setSelected(int selected) {
getStateHelper().put(PropertyKeys.selected, selected);
}
public List<UIComponent> getTabChildren() {
List<UIComponent> children = this.getFacet("javax.faces.component.COMPOSITE_FACET_NAME").getChildren();
List<UIComponent> tabChildren = new ArrayList<UIComponent>();
for (UIComponent child : children) {
if (child instanceof UITab) {
tabChildren.add(child);
}
}
return tabChildren;
}
}
<cc:interface componentType="org.richfaces.sandbox.composite.UITab">
<cc:attribute name="title" />
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<cc:insertChildren />
</div>
</cc:implementation>
<s:tabs id="tabs">
<s:tab title="Tab 1">
Hello <b>Tab</b>!!
</s:tab>
<s:tab title="Tab 2">
With nested components:
<br/>
<s:datepicker dateFormat="yy-mm-dd"
showOn="both"
buttonImageOnly="true"/>
</s:tab>
</s:tabs>
Use the RichFaces CDK to build "full-fledged" JSF components with the ease and syntax of JSF 2 composite components
<cdk:root xmlns="http://jboss.org/schema/richfaces/cdk/xhtml-el"
xmlns:cdk="http://jboss.org/schema/richfaces/cdk/core"
xmlns:c="http://jboss.org/schema/richfaces/cdk/jstl/core"
xmlns:cc="http://jboss.org/schema/richfaces/cdk/jsf/composite">
<cc:interface>
<cdk:class>org.richfaces.bootstrap.renderkit.ButtonDropdownRenderer</cdk:class>
<cdk:superclass>org.richfaces.bootstrap.renderkit.ButtonDropdownRendererBase</cdk:superclass>
<cdk:renderer-type>org.richfaces.bootstrap.ButtonDropdownRenderer</cdk:renderer-type>
<cdk:renders-children>true</cdk:renders-children>
<cdk:component-base-class>org.richfaces.bootstrap.component.AbstractButtonDropdown</cdk:component-base-class>
</cc:interface>
<cc:implementation>
<div class="btn-group #{component.vertical ne null ? component.vertical.buttonClass : ''}">
<a data-toggle="dropdown" href="#" cdk:passThrough="on*"
class="btn #{component.severity ne null ? component.severity.buttonClass : ''}
#{component.scale ne null ? component.scale.buttonStyleClass : ''}
#{component.buttonStyle} dropdown-toggle">
#{component.title.concat(' ')}
<span class="caret"></span>
</a>
<ul class="dropdown-menu #{component.horizontal ne null ? component.horizontal.buttonClass : ''}">
<c:forEach var="child" items="#{component.getChildren()}">
<li>
<cdk:call expression="child.encodeAll(facesContext)" />
</li>
</c:forEach>
</ul>
</div>
</cc:implementation>
</cdk:root>
@JsfComponent(
type = AbstractButtonDropdown.COMPONENT_TYPE,
family = AbstractButtonDropdown.COMPONENT_FAMILY,
renderer = @JsfRenderer(type = ButtonDropdownRendererBase.RENDERER_TYPE),
tag = @Tag(name = "buttonDropdown"))
public abstract class AbstractButtonDropdown extends UIPanel implements EventsMouseProps {
public static final String COMPONENT_FAMILY = "org.richfaces.bootstrap.ButtonDropdown";
public static final String COMPONENT_TYPE = "org.richfaces.bootstrap.ButtonDropdown";
@Attribute
public abstract String getTitle();
@Attribute
public abstract String getButtonStyle();
@Attribute
public abstract BootstrapSeverity getSeverity();
@Attribute
public abstract BootstrapSize getScale();
@Attribute
public abstract HorizontalPosition getHorizontal();
@Attribute
public abstract VerticalPosition getVertical();
}
<b:buttonDropdown title="Primary" severity="primary">
<h:link value="heroUnit"
outcome="/component/heroUnit/index.xhtml" />
<h:link value="tabbable"
outcome="/component/tabbable/index.xhtml"/>
<h:link value="buttonGroup"
outcome="/component/buttonGroup/index.xhtml"/>
<h:link value="navbar"
outcome="/component/navbar/index.xhtml"/>
</b:buttonDropdown>