Web Components And PolymerJS

Introduction 

 
You must have tried a lot of ways to develop reusable components or widgets. But what about the components like "video", "audio" or "select" components (tags) of HTML(5)? Did you ever investigate how these components work without exposing its style, script or local DOM structure? Web applications are being developed in various ways depending on the requirements but hardly fulfill the reusability aspect across projects or modules.
 
PolymerJS
  
This article would help up to a certain extent to create and reuse such types of web components which can be instantiated and reused in a similar way how we are instantiating and using other HTML elements.
 

About Web Components

 
Web component is a revolution in web application development. As stated for Introducing Web Components,
 
Web components are a W3C specification to build a standalone component for web applications. It helps developers leverage the development process to build a reusable and reliable component. This problem leads to component-based development.
 
HTML provides a lot of built-in elements like video, audio, button, select, etc. These elements have their own properties, methods, attributes and CSS properties. It also allows to override its styles, but they are limited. Web components are something that allows us to develop our own custom elements that are similar to the above elements or by extending the above elements.
 
Each component has its own life cycle and encapsulated style, script and local DOM which allows interoperability of the components (HTML elements). These components can not only be reused across a single web application but can also be reused in multiple applications.
 
The Web component model is made up of four different specifications:
  1. HTML Templates- This contains markups that are consistent across web pages with the ability to inject dynamic content using JavaScript.
     
  2. Shadow DOM- This is designed to encapsulate DOM and CSS by hiding all child elements behind a shadow root. It defines functional boundaries between the DOM tree and the subtrees hide behind the shadow root. The following screenshot depicts the DOM structure of the “video” tag.
     
    Code
     
  3. Custom Elements- This allows us to create our own custom elements with tailored DOM structure and the ability to style and add behavior logic in our own way.
     
  4. HTML Imports- This allows us to import one HTML file in another HTML file. Using HTML Imports we can import and reuse HTML Templates for Web Components. The following is an example of how to use HTML Import to import HTML files-
    1. <link rel="import" href="bower_components/paper-button/paper-button.html">   
    HTML Imports

About Polymer

 
Polymer library, developed by Google, is a set of polyfills that help you create Web Components on all major modern browsers. It provides an easy-to-use framework for developing and instantiating custom elements in a simplistic fashion very similar to the HTML’s built-in elements like button, audio, video, etc.
 
Custom elements look like this-
  1. <google-map lat="37.790" long="-122.390"></google-map>  
  2. <custom-gallery></custom-gallery>  
As stated in an article, Polymer helps us to develop and render custom elements by-
  • Allowing us to create Custom Elements with user-defined naming schemes. These custom elements can then be distributed across the network and used by others with HTML Imports.
     
  • Allowing each custom element to have its own template accompanied by styles and behavior required to use that element.
     
  • Providing a suite of ready-made UI and non-UI elements to use and extend in your project.

Installing Polymer

 
The recommended way to install Polymer is through Bower. So, prerequisites for installing Polymer through Bower are-
Bower is a package manager that manages dependencies for your project. If you are not familiar with Node.js and Bower, then it is recommended to read the instructions provided in the respective URLs mentioned above to learn how to install and get started with it. It is not necessary to learn everything about Node.js and Bower but knowledge about installation and getting started with would be enough to install and work with PolymerJS.
 

Installing with Bower

 
Run this command from your project root folder using the terminal-
 

bower init

 
This command creates a bower.json file in the root folder of your project. The easiest way to create a bower.json file is to press “enter” continuously for all the prompts after the above command.
 
command
bower.json looks like-
  1. {  
  2.     "name""test-project",  
  3.     "version""0.0.0",  
  4.     "license""MIT",  
  5.     "ignore": ["**/.*""node_modules""bower_components""test""tests"]  
  6. }  
Zip package can be installed from polymerwebsite.
 
The next step is to install Polymer
 
bower install -–save Polymer/polymer#^1.2.0
 
By running above command in a terminal, Bower adds a bower_components/ folder in the root of your project and fills it with Polymer and its dependencies and updates bower.json by adding-
  1. "dependencies": {  
  2.    "polymer""Polymer/polymer#^1.2.0"  
  3. }  

Using Polymer’s Custom Elements

 
The polymer also comes with a rich, predefined set of elements that you can begin taking advantage of immediately. Using polymer’s custom elements in your document typically involves the four easy steps. The following is an example of how to download and use paper-button (one of Polymer’s custom element) in your application:
 
Step 1
 
Download the paper-button Custom Element package via Bower.
 
By running the following Bower Command in a terminal, it will download all required files and folders to your project and add dependencies in the bower.json file as well.
 
bower install -–save PolymerElements/paper-button
 
After running the above command, the dependencies section of bower.json looks like the following.
  1. "dependencies": {  
  2.    "paper-button""PolymerElements/paper-button#~1.0.8",  
  3.    "polymer""Polymer/polymer#^1.2.0"  
  4. }  
Step 2
 
Import Polymer’s “webcomponents.js” and “polymer.html”.
 
Add “webcomponents.js” and “polymer.html” (available in bower_components folder) to the <head> of the index.html. Then you will be ready to use predefined custom elements in your documents.
  1. <script src="bower_components/webcomponentsjs/webcomponents.js"></script>  
  2. <link rel="import" href="bower_components/polymer/polymer.html">  
Step 3
 
Import the corresponding .html file in your document.
 
In this case, the corresponding .html file refers to paper-button.html that is generally located in the bower_components folder (i.e. bower_components/paper-button/paper-button.html).
  1. <link rel="import" href="bower_components/paper-button/paper-button.html">  
Step 4
 
Use the custom element markup anywhere in your document.
 
Like any other HTML element add markup of the custom element. Generally markup name is same as the .html file name. In this case:
 
<paper-button></paper-button>
 
A huge list of predefined sets of custom elements of Polymer is available at the Polymer official website (link mentioned in the reference section). It provides detailed documentation (in Docs section) with Demo. Bower command for each element is also available in the “Bower Command” section in the left panel.
 

Developing a New Custom Element using Polymer

 
Polymer library helps us to develop our own custom elements from scratch which can be assembled to develop new custom elements, extended or reused across projects. Similar to HTML’s built-in elements, Polymer elements:
  • It can be instantiated using the constructor of a custom element or document.createElement or adding markup in the document.
     
  • It can be styled with default styles of external CSS.
     
  • It can have custom behavior logics that can be defined using JavaScript.
     
  • Support custom events handling on changing the attributes of the markup or any update in the values of the properties.
     
  • Support data-binding

Register a custom element

 
A custom element can be registered by using the Polymer function of the Polymer library and passing the prototype as a parameter to it.
 
There are few specifications to define a custom element:
  • It is necessary that the custom element has a property in the prototype
     
  • There should be an id attribute in the <dom-module> tag.
     
  • And the value of id is and name of the custom element file must have the same value to work the custom element properly.
     
  • And this value must contain a dash (-). In this case, it is the hello-world.
Example
  1. <dom-module id="hello-world">  
  2.     <template>  
  3.         <style>  
  4.             /* CSS classes */  
  5.         </style>  
  6.         <!-- Local DOM structure starts here -->  
  7.         <div>  
  8.             <h1>{{proName}}</h1>  
  9.             <!-- Data binding -->  
  10.         </div>  
  11.         <!-- Local DOM structure ends here -->  
  12.     </template>  
  13.     <!-- JavaScript goes here -->  
  14.     <script>  
  15.         var MyElement = Polymer(  
  16.         {  
  17.             is"hello-world",  
  18.             properties:  
  19.             {  
  20.                 propName:  
  21.                 {  
  22.                     type: String,  
  23.                     value: "Hello World!"  
  24.                 }  
  25.             }  
  26.         })  
  27.     </script>  
  28. </dom-module>  
The Polymer function registers the element with the browser and returns a Constructor which can be used to create new instances of the custom elements dynamically. For example-
  1. var el = new MyElement();  
  2. document.body.appendChild(el);  

LifeCycle callbacks

 
A good understanding of the Web components life cycle will enable you to build better applications and optimize the code. For example, if you need to ensure that some code runs before the DOM attached to the document, you need to know where to place the code for that event.
 
So when we instantiate or remove any Web component, the following functions are called during the lifecycle:
  • Created
  • Ready
  • AttributeChanged
  • actoryImpl
  • attached
  • detached
The sequence of the callbacks as it is listed above.
 
facotyImpl method will only be invoked if the element is instantiated using Constructor (see below for instantiation options).
 
attributeChangedmethod will be invoked whenever any attribute is changed. It gets called after ready if there are any default properties set using the “properties” object or “hostAttributes” object of the Polymer prototype. It also gets called if any attribute gets changed dynamically.
 

Instantiation of Custom Element

 
Instances of Custom element can be done in multiple ways-
  • Using document.createElement
    1. var el = document.createElement('hello-world');  
    2. document.body.appendChild(el1);  
  • Using tags in HTML,
    1. <hello-world></hello-world>  
  • Using append of jQuery,
    1. $("body").append("<hello-world></hello-world>");  
  • Using Constructor,
    1. var el = new MyElement();  
    2. document.body.appendChild(el);  

Properties Declaration

 
Properties for the custom elements should be declared in the properties object of the prototype as shown below.
  1. var MyElement = Polymer(  
  2. {  
  3.     is"hello-world",  
  4.     /* public properties should be defined here */  
  5.     properties:  
  6.     {  
  7.         firstName: String,  
  8.         lastName: String,  
  9.         age: Number,  
  10.         userName: "abcd",  
  11.         details:  
  12.         {  
  13.             propName1:  
  14.             {  
  15.                 type: String,  
  16.                 value: "Hello"  
  17.             },  
  18.             propName2:  
  19.             {  
  20.                 type: String,  
  21.                 value: "World"  
  22.             }  
  23.         }  
  24.     }  
  25. })  
The properties object supports some keys for each property. Few of the keys are-
  • Type- type of the property i.e. String, Number, Boolean, Date, Array or Object etc.
     
  • Value- Default value can be set here
     
  • Notify- Type: boolean. If `true`, the property is available for two-way data binding. In addition, an event, propertyName-changed is fired whenever the property changes.
     
  • Observer: Value is provided in the form of String and interpreted as methods that fire on change of the value of the property.
How to change value of properties from outside the component:
 
Value of properties can be changed by using query selector and .propertyName. For example-
  1. $("#myElement").propertyName = "xyz";  

Data-binding

 
Data-binding in Polymer is a process of automatic data synchronization between model and view. For this synchronization, Polymer provides the ability to bind properties to local DOM of the custom elements.
 
A binding is created with a binding annotation (i.e. {{ }} or [[ ]]) in the host elements local DOM template. Here is an example of data-binding using curly braces-
  1. <dom-module id="hello-world">  
  2.     <template>  
  3.         <style>  
  4.   
  5.         </style>  
  6.         <div>  
  7.             <h1>Hello <span>{{firstName}}</span><span>{{lastName}}</span>!</h1>  
  8.             <!-- Data binding -->  
  9.         </div>  
  10.     </template>  
  11.     <script>  
  12.         var MyElement = Polymer(  
  13.         {  
  14.             is"hello-world",  
  15.             properties:  
  16.             {  
  17.                 firstName: String,  
  18.                 lastName: String  
  19.             }  
  20.         })  
  21.     </script>  
  22. </dom-module>  
<hello-world first-name="Sumant" last-name="Mishra"></hello-world>
 
Data-binding in Polymer is not very similar to Angular. There is a significant difference in the way how Polymer handles data-binding and how Angular handles data-binding. For example, unlike AngularJS, each bound property needs to be wrapped with an element (span in the above example). Two properties can not be declared in one dom element.
 
References 
 
Polymer site nails more detail about data-binding. Please visit-
That’s all! For further reading on Web Components and Polymer, I would suggest referring-

Summary

 
In this article, we learned about Web Components And PolymerJS.