<p:dialog header="Modal Dialog" widgetVar="dlg2" modal="true" height="100">
<h:outputText value="This is a Modal Dialog." />
</p:dialog>
Kito Mann (@kito99), Virtua, Inc.
Principal Consultant at Virtua (http://www.virtua.com)
Training, consulting, architecture, mentoring
PrimeFaces, JSF, Java EE, Web Components, Polymer, Liferay, etc.
Official US PrimeFaces partner
Author, JavaServer Faces in Action
Founder, JSF Central (http://www.jsfcentral.com)
Co-host, Enterprise Java Newscast (http://enterprisejavanews.com)
New site: http://knowesis.io
Internationally recognized speaker
JavaOne, JavaZone, Devoxx, Devnexus, NFJS, etc.
JCP Member
JSF, MVC, JSF Portlet Bridge, Portlets
Component models have been popular since the early ninenties
Visual Basic
Delphi
PowerBuilder
WinForms
Windows Presentaiton Framework
ASP.NET
Swing
JavaFX
JavaServer Faces
Tapestry
In the browser, component suites must invent their own models:
YUI
KendoUI
Bootstrap
jQuery UI
Wijmo
PrimeUI
Infragistics
Reusable UI functionality
Within a single application
Across multiple applications
You can focus on the core application functionality
Underlying platform (OS, browser) doesn’t have one
Standard web framework for Java EE
Component-based
Builds a server-side component tree representing the page
Components render necessary HTML, JavaScript, CSS
Includes basic web application features
<p:dialog header="Modal Dialog" widgetVar="dlg2" modal="true" height="100">
<h:outputText value="This is a Modal Dialog." />
</p:dialog>
Web components bring a native component model to HTML
<paper-action-dialog backdrop autoCloseDisabled layered="false">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<paper-button affirmative autofocus>Tap me to close</paper-button>
</paper-action-dialog>
Custom Elements
HTML Templates
HTML Imports
Shadow DOM
(Custom CSS Properties)
Chrome/Android and Opera support everything
IE doesn’t support anything
All other browsers support HTML Templates
Browser vendors in agreement on Custom Elements and Shadow DOM
Custom Elements in development or recently released for Edge, Safari, and Firefox
Shadow DOM
"Under consideration" for Edge; likely to be added later
HTML Imports only supported in Chrome
"Under consideration" for Edge; not planned in Firefox and Safari
polyfill
[pol-ee-fil]
noun
In web development, a polyfill (or polyfiller) is downloadable code which provides facilities that are not built into a web browser. It implements technology that a developer expects the browser to provide natively, providing a more uniform API landscape. For example, many features of HTML5 are not supported by versions of Internet Explorer older than version 8 or 9, but can be used by web pages if those pages install a polyfill. Web shims and HTML5 Shivs are related concepts.
— Wikipedia
webcomponents.js
Polyfill for all specs created by Polymer group at Google
webcomponents-lite.js excludes shadow DOM
webcomponents.js browser support
~ Indicates support may be flaky.
Library for building web components from Google
Most popular way of writing them
Extensive feature set
Extensive set of tools
build, deployment, testing, etc.
Developed by and used internally by Google
Used in over 500 Google projects
Over 1 billion users
Over 4,000 custom web components
Examples: Chrome, Play, Fi, YouTube Gaming, and Translate
Used in over 4 million web pages
Heavily promoted (Polymer Summit, Polycasts, etc.)
Server-side
Java only
Components render HTML markup
Unaware of browser’s DOM
Does not (usually) integrate well with client-side app frameworks
demo
Attribute/property transparency
Event system
Lifecycle events
Named child components (facets)
Server-side templating (Facelets)
Separate tag handlers (Facelet tags) that build component tree
@FacesComponent(value = "org.webfaces.ComponentModelDemo")
public class ComponentModelDemo extends UINamingContainer {
public String getMessage() {
return (String)super.getStateHelper().get("message");
}
public void setMessage(String message) {
super.getStateHelper().put("message", message);
}
...
}
ComponentModelDemo comp;
...
comp.getAttribute("message") == com.getMessage();
<span>#{cc.attrs.message}</span> == <span>#{cc.message}</span>
UI events
<h:commandButton actionListener="#{demoController.handleActionEvent}"
value="Fire Action Event"/>
@Named
public class DemoController {
...
public void handleActionEvent(ActionEvent e) {
this.setMessage("Action event fired by " + e.getComponent().getClientId());
}
...
}
Made possible by system event bus
<ui:composition xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:jsf="http://xmlns.jcp.org/jsf" xmlns:f="http://xmlns.jcp.org/jsf/core">
<cc:interface componentType="org.webfaces.ComponentModelDemo">
...
</cc:interface>
<cc:implementation>
<f:event type="preRenderComponent" listener="#{cc.preRender}"/>
...
</cc:implementation
</ui:composition>
@FacesComponent(value = "org.webfaces.ComponentModelDemo")
public class ComponentModelDemo extends UINamingContainer {
public void preRender(ComponentSystemEvent event) {
System.out.println("Inside preRender event");
}
...
}
demo
Syntax used for JSF views and components
Uses tag handlers which generate JSF component tree
Several additional features
Full-fledged templating, includes, decorators, etc.
Client-side (browser)
Server-side (Node; experimental)
Components are part of the DOM (subclass HTMLElement
)
Works with different client-side app frameworks
Properties must be mapped to attributes manually
Client-side resource/dependency handling (HTML Imports)
Integration with native DOM events
Lifecycle callbacks
Named child components (slots with Shadow DOM)
Client-side templating (Template element)
get message() {
return this.hasAttribute('message');
}
set message(message) {
if (message) {
this.setAttribute('message', message);
}else{
this.removeAttribute('message');
}
}
/** Fires when an attribute was added, removed, or updated */
attributeChangedCallback(attr, oldVal, newVal) {
if (attr === 'message') {
let messageElement = this.shadowRoot.querySelector('#message');
messageElement.innerText = newVal;
}
}
demo
demo
class ComponentModelDemo extends HTMLElement {
...
/** Fires when an instance was inserted into the document */
connectedCallback() {
};
/** Fires when an instance was removed from the document */
disconnectedCallback() {
};
/** Fires when an attribute was added, removed, or updated */
attributeChangedCallback(attr, oldVal, newVal) {
if (attr === 'message') {
let messageElement = this.shadowRoot.querySelector('#message');
messageElement.innerText = newVal;
}
}
/** Fires when the element is moved to a new document */
adoptedCallback() {
}
}
demo
demo
Syntactic sugar
Client-side data binding
Mixins / behaviors
Two-way data binding
Declarative event handling
Property observation
Use web components in a JSF app
Write web components using JSF
demo
Slides and sample app: https://github.com/kito99/webfaces
Polymer project: https://www.polymer-project.org/1.0/
Webcomponents.org: http://webcomponents.org/
JSF @ zeef https://jsf.zeef.com/bauke.scholtz
Virtua (training, consulting, development): http://virtua.tech