Tuesday, 28 October 2014

Font Awesome Icons

There have already been several excellent articles written about the use of Font Awesome in XPages.
In this blog post I focus primarily on the use of Font Awesome in reusable Bootstrap Text Fields. This is a first basic setup and tryout which will be expanded later in upcoming posts on this topic.
Font Awesome gives you scalable vector icons that can instantly be customized — size, color, drop shadow, and anything that can be done with the power of CSS.
For more information and examples I refer to the Font Awesome website.


Steps for creating a reusable Bootstrap Text Field including a Font Awesome icon.

1. Download Font Awesome
The first step is to download the latest version of Font Awesome.
You can download Font Awesome from this website.
Extract the downloaded files and add the Font Awesome files to the WebContent Folder (Package Explorer).
Remark : Font Awesome is not part of the OpenNTF Bootstrap4XPages plugin and must be added separately to an XPages application.


2. Add Font Awesome to your XPages application
To add Font Awesome to an XPages application the only thing required is to add the stylesheet font-awesome.min.css to an XPage, Application Layout or Theme.
In this example I added the stylesheet to an XPage.

<link rel="stylesheet" href="fontawesome/css/font-awesome.min.css"></link>

3. Usage
You can place Font Awesome icons just about anywhere using the CSS Prefix fa and the icon's name, for example fa fa-align-right.
Font Awesome is designed to be used with inline elements.
See for a complete overview of all Font Awesome icons the cheatsheet Every Font Awesome 4.2.0 Icon, CSS Class, & Unicode.

Basic example

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xc="http://www.ibm.com/xsp/custom">
<link rel="stylesheet" href="fontawesome/css/font-awesome.min.css"></link>
<xc:ccLayoutBootstrap><xp:this.facets>
<xp:panel xp:key="facetMiddle">
<div class="page-header">
<h1>
Font Awesome
<xp:span style="color:rgb(255,255,255)">
</xp:span>
<small>The iconic font and CSS toolkit</small>
</h1>
</div>
<div class="btn-group">
  <a class="btn btn-default"><i class="fa fa-align-left"></i></a>
  <a class="btn btn-default"><i class="fa fa-align-center"></i></a>
  <a class="btn btn-default"><i class="fa fa-align-right"></i></a>
  <a class="btn btn-default"><i class="fa fa-align-justify"></i></a>
</div>
<xp:br></xp:br>
</xp:panel>
</xp:this.facets>
</xc:ccLayoutBootstrap>
</xp:view>

However, if we perform a web preview of the above example some error messages appear and the Font Awesome icons are not displayed correctly.


Brad Balassaitis indicates in his Blog Post 'Implementing Font Awesome 4.0.3 in XPages' the cause and the solution for this problem.
Ín order for the Font Awesome icons to work properly in an XPages application we need to remove the part ?v=4.2.0 from the font-awesome.css and the font-awesome.min.css stylesheets.
We can perform this in a very simple and fast way.
Open the appropriate CSS files in the designer and perform a find and replace (Menu Edit - Find / Replace).
Find ?v=4.2.0 and Replace with nothing.
Save the CSS files.


CSS file before Find/Replace
@font-face {
  font-family: 'FontAwesome';
  src: url('../fonts/fontawesome-webfont.eot?v=4.2.0');
  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');
  font-weight: normal;
  font-style: normal;
}

CSS file after Find/Replace
@font-face {
  font-family: 'FontAwesome';
  src: url('../fonts/fontawesome-webfont.eot');
  src: url('../fonts/fontawesome-webfont.eot?#iefix') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff') format('woff'), url('../fonts/fontawesome-webfont.ttf') format('truetype'), url('../fonts/fontawesome-webfont.svg#fontawesomeregular') format('svg');
  font-weight: normal;
  font-style: normal;
}

If we perform a new web preview after the modifications of the CSS files the Font Awesome icons are displayed correctly.


4. Adding Font Awesome icons to a reusable Bootstrap Text Field
There are several possibilities to add a Font Awesome icon to a reusable Bootstrap Text Field.
The preferred method is to add the Font Awesome icon through a Custom Control property for the reusable Bootstrap Text Field.
Each reusable Bootstrap Text Field can get in this manner a different Font Awesome icon.
In this case we have to create new property.
In this example I created the property faicon.


For the dynamic value binding it is possible to use the icon element (<i>).
We also need to use an input-group with an input-group-addon to prepend (or append) the Font Awesome icon to the form-group.

<div class="input-group">
<span class="input-group-addon">
<i class="${compositeData.faicon}"></i>
</span>

Code Custom Control

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:div styleClass="form-group">
<xp:label styleClass="col-sm-2 control-label" for="inputText1"
value="${compositeData.fieldLabel}" />
<div class="col-sm-10">
<div class="input-group">
<span class="input-group-addon">
<i class="${compositeData.faicon}"></i>
</span>
<xp:inputText type="text" id="inputText1"
loaded="${!empty compositeData.placeholder}"
value="#{compositeData.dataSource[compositeData.fieldName]}"
required="${compositeData.required}">
<xp:this.attrs>
<xp:attr name="placeholder"
value="${compositeData.placeholder}">
</xp:attr>
</xp:this.attrs>
</xp:inputText>
<xp:text escape="true" id="computedField1"
styleClass="help-block" value="${compositeData.helpText}"
loaded="${!empty compositeData.helpText}">
</xp:text>
</div>
</div>
</xp:div>
</xp:view>

Another possibility, and this has my preference, is to use a computed Text Field (Content type = HTML).
Big advantage of this method is that the Computed Text Field is actually an xp control, so there a extra possibilities like conditional rendering.
In this case it is possible to use the styleClass for the dynamic value binding.


<div class="input-group">
<span class="input-group-addon">
<xp:text escape="false"id="computedField2"
styleClass="${compositeData.faicon}">
</xp:text>
</span>

Remark : If you use the property tagName = i it is not necessary to put the Content type to HTML.

<div class="input-group">
<span class="input-group-addon">
<xp:text escape="true" id="computedField2"
styleClass="${compositeData.faicon}" tagName="i">
</xp:text>
</span>

Code Custom Control with Computed Text Field

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:div styleClass="form-group">
<xp:label styleClass="col-sm-2 control-label" for="inputText1"
value="${compositeData.fieldLabel}" />
<div class="col-sm-10">
<div class="input-group">
<span class="input-group-addon">
<xp:text escape="false" id="computedField2"
styleClass="${compositeData.faicon}">
</xp:text>
</span>
<xp:inputText type="text" id="inputText1"
loaded="${!empty compositeData.placeholder}"
value="#{compositeData.dataSource[compositeData.fieldName]}"
required="${compositeData.required}">
<xp:this.attrs>
<xp:attr name="placeholder"
value="${compositeData.placeholder}">
</xp:attr>
</xp:this.attrs>
</xp:inputText>
<xp:text escape="true" id="computedField1"
styleClass="help-block" value="${compositeData.helpText}"
loaded="${!empty compositeData.helpText}">
</xp:text>
</div>
</div>
</xp:div>
</xp:view>

The Custom properties on the XPage remains the same.

4. Add Custom Control to an XPage
The last step is to add the Custom Control with the reusable Bootstrap Text Field on an XPage.
The properties of the Custom Control (reusable Bootstrap Rich Text Field) can now be entered, including the Font Awesome icon.


Code XPage

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:this.data>
<xp:dominoDocument var="document1" formName="Contact"></xp:dominoDocument>
</xp:this.data>
<link rel="stylesheet"
href="fontawesome/css/font-awesome.min.css">
</link>
<xc:ccLayoutBootstrap>
<xp:this.facets>
<xp:panel xp:key="facetMiddle">
<div class="form-horizontal" id="ex1">
<div class="page-header">
<h1>
Font Awesome
<xp:span style="color:rgb(255,255,255)">
</xp:span>
<small>The iconic font and CSS toolkit</small>
</h1>
</div>
<xc:RBSTextFieldFA dataSource="#{document1}"
required="false" fieldLabel="FirstName" fieldName="FirstName"
placeholder="FirstName" faicon="fa fa-user">
</xc:RBSTextFieldFA>
<xc:RBSTextFieldFA dataSource="#{document1}"
required="false" fieldLabel="LastName" fieldName="LastName"
placeholder="LastName" faicon="fa fa-user">
</xc:RBSTextFieldFA>
<xc:RBSTextFieldFA dataSource="#{document1}"
required="false" fieldLabel="Subject" fieldName="Subject"
placeholder="Subject" faicon="fa fa-th-large">
</xc:RBSTextFieldFA>
<xc:RBSRichText dataSource="#{document1}"
required="false" fieldLabel="Remarks" fieldName="Body">
</xc:RBSRichText>
<xp:br></xp:br>
<div class="col-sm-2">
</div>
<div class="col-sm-10">
<xp:button value="Save Document" id="button1"
styleClass="btn btn-primary"><span class="glyphicon glyphicon-ok"></span>
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:saveDocument></xp:saveDocument>
<xp:openPage name="/xView.xsp">
</xp:openPage>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button value="Cancel" id="button2"
styleClass="btn btn-warning"><span class="glyphicon glyphicon-remove"></span>
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:openPage name="/xView.xsp"></xp:openPage>
</xp:this.action></xp:eventHandler></xp:button>
</div>
</div>
</xp:panel>
</xp:this.facets>
</xc:ccLayoutBootstrap>
</xp:view>

The final result.


In addition to the described possibilities above there will be other possibilities to accomplish this.
As mentioned, this is a first basic setup and in an upcoming blog post I will describe alternative options.
In the next blog post we first start creating a new database which we need in the ensuing blog posts.

No comments:

Post a Comment