JavaServer Faces and HTML5 Web Components

Synergy?

Kito Mann (@kito99), Virtua, Inc.

Kito D. Mann (@kito99)

  • 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)

Kito D. Mann (@kito99)

UI Components are Everywhere

page with components

UI Components are Everywhere

page with components annotated

UI Components are Everywhere

  • Component models have been popular since the early ninenties

    • Visual Basic

    • Delphi

    • PowerBuilder

    • WinForms

    • Windows Presentaiton Framework

    • ASP.NET

    • Swing

    • JavaFX

    • JavaServer Faces

    • Tapestry

UI Components are Everywhere

  • In the browser, component suites must invent their own models:

    • YUI

    • KendoUI

    • Bootstrap

    • jQuery UI

    • Wijmo

    • PrimeUI

    • Infragistics

Why do We Build Components?

  • Reusable UI functionality

    • Within a single application

    • Across multiple applications

  • You can focus on the core application functionality

Why are there so many different component models?

  • Underlying platform (OS, browser) doesn’t have one

HTML Markup Doesn’t Support Components

page with components source

What is JavaServer Faces?

  • 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

What is JavaServer Faces

pf dialog example1

What is JavaServer Faces

<p:dialog header="Modal Dialog" widgetVar="dlg2" modal="true" height="100">
    <h:outputText value="This is a Modal Dialog." />
</p:dialog>

What is JavaServer Faces?

What is a Web Component?

  • Web components bring a native component model to HTML

What is a Web Component?

polymer paper example1

What is a Web Component?

<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>

Web Components == Collection of HTML5 Standards

  • Custom Elements

  • HTML Templates

  • HTML Imports

  • Shadow DOM

    • (Custom CSS Properties)

Demo

Closing the Browser Gap

  • 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

Closing the Browser Gap

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

Closing the Browser Gap

  • webcomponents.js

    • Polyfill for all specs created by Polymer group at Google

    • webcomponents-lite.js excludes shadow DOM

Closing the Browser Gap

webcomponents.js browser support

polyfill browser support

~ Indicates support may be flaky.

What is Poylmer?

webcomponents stack

Polymer

  • Library for building web components from Google

    • Most popular way of writing them

  • Extensive feature set

  • Extensive set of tools

  • build, deployment, testing, etc.

Polymer

  • 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.)

Polymer Elements

Comparing Component Models

JSF Component Model Features

  • Server-side

    • Java only

  • Components render HTML markup

    • Unaware of browser’s DOM

  • Does not (usually) integrate well with client-side app frameworks

JSF Component Component Features

demo

JSF Component Model Features

  • Attribute/property transparency

  • Event system

  • Lifecycle events

  • Named child components (facets)

  • Server-side templating (Facelets)

    • Separate tag handlers (Facelet tags) that build component tree

Attribute/Property Transparency

Attribute/Property Transparency

@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>

Event system

  • 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());
    }
	...
}

Lifecycle Callbacks

  • Made possible by system event bus

Lifecycle Callbacks

<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>

Lifecycle Callbacks

@FacesComponent(value = "org.webfaces.ComponentModelDemo")
public class ComponentModelDemo extends UINamingContainer {

    public void preRender(ComponentSystemEvent event) {
        System.out.println("Inside preRender event");
    }
	...
}

Named Child Components (Facets)

demo

Server-side Templating (Facelets)

  • Syntax used for JSF views and components

  • Uses tag handlers which generate JSF component tree

  • Several additional features

    • Full-fledged templating, includes, decorators, etc.

Web Components Component Model Features

  • Client-side (browser)

  • Server-side (Node; experimental)

  • Components are part of the DOM (subclass HTMLElement)

  • Works with different client-side app frameworks

Web Components Component Model Features

  • 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)

Properties and Attributes

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;
	}
}

HTML Imports

demo

Integration with Native DOM Events

demo

Lifecycle Callbacks

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() {
	}
}

Named child components (slots with Shadow DOM)

demo

HTML Template

demo

Features provided by libraries like Polymer

  • Syntactic sugar

  • Client-side data binding

  • Mixins / behaviors

  • Two-way data binding

  • Declarative event handling

  • Property observation

Synergy?

  • Use web components in a JSF app

  • Write web components using JSF

Introducing webfaces

demo

Questions?