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.

Tuesday, 21 October 2014

Reusable Rich Text Field

In a previous blog post I described a first setup for a reusable Bootstrap Text Field. In this post I describe a first setup for a reusable Bootstrap Rich Text Field including a Bootstrap CKEditor Skin.

Steps for creating a reusable Bootstrap Rich Text Field.

1. Custom Control
First create a new Custom Control for a reusable Bootstrap Rich Text  Field (inputRichText).


2. Property Definitions
The next step is to create some new properties.
In this example, I use the following properties for a reusable Bootstrap Rich Text Field.
- dataSource (Object)
- fieldName (String)
- fieldLabel (String)
- helpText (String)
- required (Boolean, True of False)


3. Reusable Rich Text Field
After creating the properties the reusable Bootstrap Rich Text Field can be build up.
Similar to using a reusable Bootstrap Text Field we need to make the contents of the control dynamic by referencing the custom control properties and create a dynamic field binding of the input / rich text control using Expression Language.

A. Label (computed - property fieldLabel)

<xp:label styleClass="col-sm-2
control-label" for="inputRichText1" value="${compositeData.fieldLabel}"/>


B. Field inputRichText1
In this example I am using the BootstrapCK Skin for the CKEditor4.
For more information about using a CKEditor Skin see the blog post BootstrapCK4 Skin for CKEditor.
In order for this to work you need to declare an own xspCKEditor-instance on your Custom Control.

<xp:scriptBlock id="scriptBlockCKEditor">
<xp:this.value>
      <![CDATA[
         require( ['dojo/_base/declare', 'ibm/xsp/widget/layout/xspCKEditor'], function( declare, xspCKEditor ){
            return declare( 'org.wavin.joldenburger.CKEDITOR', xspCKEditor, {
               constructor: function ckew_ctor(/*Object*/options){
                  CKEDITOR.timestamp = '';
               }
            });    
         });
      ]]>
</xp:this.value>
</xp:scriptBlock>

Code Custom Control for the reusable Bootstrap Rich 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"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:scriptBlock id="scriptBlockCKEditor">
<xp:this.value>
      <![CDATA[
         require( ['dojo/_base/declare', 'ibm/xsp/widget/layout/xspCKEditor'], function( declare, xspCKEditor ){
            return declare( 'org.wavin.joldenburger.CKEDITOR', xspCKEditor, {
               constructor: function ckew_ctor(/*Object*/options){
                  CKEDITOR.timestamp = '';
               }
            });  
         });
      ]]>
</xp:this.value>
</xp:scriptBlock>
<xp:div styleClass="form-group">
<xp:label styleClass="col-sm-2 control-label"
for="inputRichText1" value="${compositeData.fieldLabel}" />
<div class="col-sm-10">
<xp:inputRichText id="inputRichText1"
value="#{compositeData.dataSource[compositeData.fieldName]}"
required="${compositeData.required}"
htmlFilter="identity" htmlFilterIn="identity">
<xp:this.dojoAttributes>
<xp:dojoAttribute name="extraPlugins"
value="autogrow">
</xp:dojoAttribute>
<xp:dojoAttribute name="skin">
<xp:this.value><![CDATA[#{javascript:return @ClientType().equals("Web") ? "bootstrapck,/"+database.getFilePath()+"/bootstrapck/" : ""}]]></xp:this.value>
</xp:dojoAttribute>
<xp:dojoAttribute name="width" value="100%">
</xp:dojoAttribute>
<xp:dojoAttribute value="Full" name="toolbar">
</xp:dojoAttribute>
</xp:this.dojoAttributes>
<xp:this.dojoType><![CDATA[#{javascript:return @ClientType().equals("Web") ? "org.wavin.joldenburger.CKEDITOR" : ""}]]></xp:this.dojoType>
</xp:inputRichText>
<xp:text escape="true" id="computedField2"
styleClass="help-block" value="${compositeData.helpText}"
loaded="${!empty compositeData.helpText}">
</xp:text>
</div>
</xp:div>
</xp:view>

4. Add Custom Control to an XPage
The last step is to add the Custom Control with the reusable Bootstrap Rich Text Field on an XPage.
In this example I added the Custom Control to the XPage with the reusable Bootstrap Text Fields I created in a previous blog post.
The properties of the Custom Control (reusable Bootstrap Rich Text Field) can now be entered.


Also add a dataSource to your XPage.
<xp:this.data>
<xp:dominoDocument var="document1" formName="Contact"></xp:dominoDocument>
</xp:this.data>

Code XPage with the reusable Bootstrap Rich Text Field and reusable Bootstrap Text Fields

<?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" xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:this.data>
<xp:dominoDocument var="document1" formName="Contact"></xp:dominoDocument>
</xp:this.data>
<xc:ccLayoutBootstrap>
<xp:this.facets>
<xp:div xp:key="facetMiddle">
<div class="form-horizontal" id="ex1">
<xp:panel xp:key="facetMiddle">
<div class="page-header">
<h1>
Reusable Bootstrap Fields
<xp:span style="color:rgb(255,255,255)">
</xp:span>
<small>Text / Rich Text Fields</small>
</h1>
</div>
 
    <xc:RBSTextField dataSource="#{document1}"
required="false" fieldLabel="FirstName" fieldName="FirstName"
placeholder="FirstName">
</xc:RBSTextField>
 
    <xc:RBSTextField dataSource="#{document1}"
required="false" fieldLabel="LastName" fieldName="LastName"
placeholder="LastName">
</xc:RBSTextField>
 
  <xc:RBSTextField dataSource="#{document1}"
required="false" fieldLabel="Subject" fieldName="Subject"
placeholder="Enter a Subject">
</xc:RBSTextField>
 
     <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>
</xp:panel>
</div>
</xp:div>
</xp:this.facets>
</xc:ccLayoutBootstrap>
</xp:view>

The final result


Remarks:
This blog post is based on the use of Notes Domino 9.0.1 FP2 including the OpenNTF Bootstrap4XPages plugin. 
In Notes Domino 9.0.1 FP2 the CKEditor is updated to 4.3.2 and Dojo to version 1.9.2.
During testing of the reusable Bootstrap Rich Text Field I encountered the following problem.
When adding an image (from a local drive) in the reusable Bootstrap Rich Text Field when using Dynamic Value Binding (value="#{compositeData.dataSource[compositeData.fieldName])") the following error message appears:



All other functions are working properly including adding an Image URL.


I have tried to find a solution for this problem but until now without success.
At this time I am looking at the documentation about the CKEditor and see if I can find a solution there.
The only (relevant) information I have found so far is this in the  Notes/Domino Fix List:


My findings in this first setup for a reusable Bootstrap Rich Text Field:
Usage of a reusable Bootstrap Rich Text Field works properly when no images (from a local drive) are added to the Rich Text Field.
In the situation that images should be able to be added in the reusable Bootstrap Rich Text Field, Dynamic Value Binding fails.

I tested adding an image without Dynamic Value Binding and this works properly.
The dataSource in this example is 'document1' (compositeData.dataSource)and the Rich Text Field in the documents dataSource is named 'Body' ([compositeData.fieldName]).
So if I change the value value="#{compositeData.dataSource[compositeData.fieldName]}" to value="#{document1.Body}" the problem is 'solved' when adding an image in the Bootstrap Rich Text Field. This is of course not a solution to the problem given the field is no longer 'reusable'.

If anyone has a solution for the above problem then please let me know.
If I find a solution I will update this blog post.

Thursday, 16 October 2014

My appearance on NotesIn9

First, I want to thank David Leedy for the given opportunity for me to take part on NotesIn9.
This is my very first XPages video so please do not be too harsh in criticism :)
The video is about the use of Select2 in XPages applications including Bootstrap.

The video refers to a number of great resources on the Internet.

1. Website Bootstrap4XPages by Mark Leussink


2. Webinar Bootstrap4XPages by Mark Leussink, TLCC and Teamstudio


3. The OpenNTF Bootstrap4XPages plugin OpenNTF Bootstrap4XPages plugin


4. Select2 on GitHub


5. Bootstrap Website


6. x$ jQuery selector for XPages by Mark Roden


I hope you liked my first XPages video.

Wednesday, 15 October 2014

Reusable Bootstrap Text Field

In recent times I regularly work with Bootstrap in XPages applications.
Creating the fields on forms is always a substantial task when working with Bootstrap in XPages.
On the website of Bootstrap4XPages I came along a great post from Mark Leussink about reusable Bootstrap fields.
In his post a referrence to a blog post by Brad Balassaitis was also made about More on Using Dynamic Value Binding to Create a Reusable Field.
In this blog post I describe my first setup/test with a reusable Bootstrap Text Field.

In the example below I have performed the following steps  for creating a reusable Bootstrap Text Field.

1. Custom Control
First create a new Custom Control for a reusable Bootstrap Text Field.


2. Property Definitions (Custom Control)
The next step is to create some new properties. In this example I created the following properties.
- dataSource (Object)
- fieldName (String)
- fieldLabel (String)
- placeholder (String)
- helpText (String)
- required (Boolean)


A. Property dataSource
Create a new property dataSource (new Property).


Select as Type 'Object Data Source' by selecting the Folder icon.


In this example I added a Default Value, 'document1' (Expression Language), for the property dataSource.
According to the blog post by Brad Balassaitis this step isn’t required if you just want to assume the data source name, e.g. if all fields, will be stored on document1.


B. Properties fieldName, fieldLabel, placeholder, helpText and required

Create the property fieldName (String)


Create the property fieldLabel (String)


Create the property placeholder (String)


Create the property helpText (String)


Property required (Boolean, True or False)


3. Reusable Text Field
After creating the properties the reusable Text Field can be build up.
We need to make the contents of the control dynamic by referencing the custom control properties and create a dynamic field binding of the input control using Expression Language.

A. Label (computed - property fieldLabel)

<xp:label styleClass="col-sm-2 control-label" for="inputText1" value="${compositeData.fieldLabel}" />


B. Field inputText1 (Edit Box)

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

In this example the Edit Box is loaded when the property 'placeholder' is not empty.

loaded="${!empty compositeData.placeholder}"


The value is dynamically bind to the property dataSource (document1) and the property fieldName.

value="#{compositeData.dataSource[compositeData.fieldName]}"



Based on the property 'required' input by the user for the Text Field is required or not.
The Default Value in this example is False but can be changed in the Custom Control on the XPage.

required="${compositeData.required}">

Last the attribute placeholder gets the value of the property 'placeholder'.
If empy the Text Field is not loaded.

<xp:attr name="placeholder" value="${compositeData.placeholder}"></xp:attr>

C. Helptekst
The helptekst is optional.
If a helptekst is entered in the propert 'helpText' the text will be placed under the Text Field.

<xp:text escape="true" id="computedField1"
        styleClass="help-block" value="${compositeData.helpText}"
        loaded="${!empty compositeData.helpText}">
</xp:text>

Code Custom Control Reusable 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">
<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>
</xp:div>
</xp:view>

4. Create XPage
The last step is to create an XPage and add the Custom Control with the reusable Text Field on the XPage.
Also add a Data source to the XPage.
The properties of the Custom Control (Text Field) can now be entered.
The property dataSource is computed and is in this example always # document1. The Data source added to the XPage is also document1.
The property fieldLabel is free text. 
The property fieldName is the name of the field from the Data source of the XPage.
In this example the reusable Text Field is bind to document1.Subject.
The properties 'helpText', 'placeholder' and required can also be entered.


The above looks on the web now as follows.


The great advantage of using reusable fields is that a second Text Field can now be added in a very simple way.
The Custom Control can be added again on the XPage. The only thing that is necessary is to fill in the properties of the Custom Control.


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>
<xc:ccLayoutBootstrap>
<xp:this.facets>
<xp:panel xp:key="facetMiddle">
<div class="page-header">
<h1>
Reusable Bootstrap Fields
<xp:span style="color:rgb(255,255,255)">
</xp:span>
<small>Text Field</small>
</h1>
</div>
<xc:RBSTextField dataSource="#{document1}"
required="false" fieldLabel="Subject" fieldName="Subject"
placeholder="Enter a Subject"
helpText="This field in not required">
</xc:RBSTextField>
<xc:RBSTextField dataSource="#{document1}"
required="false" fieldLabel="Country" fieldName="Country"
helpText="Thie field Country is not required"
placeholder="Enter a Country">
</xc:RBSTextField>
<xp:br></xp:br>
</xp:panel>
</xp:this.facets>
</xc:ccLayoutBootstrap>
</xp:view>

I think this is a great way of developing Fields on Forms within XPages applications including Bootstrap.
I will certainly use reusable fields from now on.
In a coming blog post I will look also add other fields, like Rich Text, Combo Boxes and List Boxes (using Select2) and validation of these reusable fields.

New JVM Fix released

New JVM fix released for IBM Domino and Notes 9.0.1 FP2 and 8.5.3 FP5/6

IBM has released a new JVM fix for Domino and Notes related several issue disclosed in the Oracle July 2014 Critical Patch Update.

The version affected are Notes and Domino 9.0.1 Fix Pack 2 and earlier and IBM Notes and Domino 8.5.3 Fix Pack 5/6 and earlier.

You can download the new JVM Fix from this page Security Bulletin: IBM Notes and Domino - Multiple vulnerabilities in IBM Java (Oracle July 2014 Critical Patch Update).


Tuesday, 7 October 2014

IFrames in CKEditor

During the past period I have been asked how an IFRAME can be added in the CKEditor (Rich Text Field) so that, for example, a YouTube video can be played directly from the XPages application.
In this particular situation, the problem was that an instruction video could not been seen in a Teamroom Application after the video (IFRAME) had been added to the Rich Text Field.


The source of the Rich Text Field

<p dir="ltr">Christian Gudemann discusses OpenNTF and the importance of open source</p>
<p dir="ltr">In this interview, Christian Gudemann and Celia Hamilton discuss the recent OpenNTF Board elections, what the OpenNTF board does, why</p>
<p dir="ltr">an open source community is so important to the Notes/Domino space, and what to say to critics who say open source isn&#39;t secure or is low quality.</p>
<p dir="ltr"><iframe allowfullscreen="" frameborder="0" height="315" scrolling="no" src="//www.youtube.com/embed/kTwREsPYQq0" width="560"></iframe></p>

The result was that de video (IFRAME) was not shown in the CKEditor.


The solution can be found in the Rich Text properties htmlFilter and htmlFilterIn.
The property htmlFilter runs when DISPLAYING richtext content and the property htmlFilterIn runs when SAVING richtext content.
The following filters are available:
-  identity: leave it as it is
-  empty: remove all content
-  acf: active content filter, removes potential dangerous HTML and JavaScript
-  striptags: remove all tags, leave only plain text


In order for this to work I set the properties htmlFilter and htmlFilterIn to 'identity' which leaves the input as it is.
The result is that an iframe can be added and the video can be played in the Teamroom.


There will also be other solutions for this problem.
In case you have another solution please let me know and please leave a comment.

Wednesday, 1 October 2014

BootstrapCK4 Skin for CKEditor

After the blog posts about using Select2, FileInput and the Bootstrap DateTimePicker in XPages the CKEditor (Rich Text Field) can not be missing.
In a later blog post all of these plugins will be used to create a new XPages application including the OpenNTF Bootstrap4XPages plugin.
On this topic are already written several blog post, among others, by Sven Hasselbach (Website/Blog) and Oliver Busse (Website/Blog).
This blog post is more or less a kind of summary of all these posts.

If you work with Bootstrap in XPages one of the first things you notice is that the CKEditor (Rich Text Field) doesn't have a nice Bootstrap look and feel.
In this blog post I will show how the BootstrapCK4 Skin for the CKEditor can be added in an XPages application.
This became especially interesting for me after installing Notes Domino 9.0.1 FP2.
The CKEditor is updated in Notes Domino 9.0.1 FP2 to 4.3.2 and Dojo is updated to 1.9.2.
So in this case I wanted a nice Bootstrap look and feel for the CKEditor in my XPages application and also I wanted to test if the BootstrapCK4-Skin for the CKEditor, combined with Notes Domino 9.0.1 FP2 and the OpenNTF Bootstrap4XPages plugin, is still working properly.

Standard when you use Bootstrap in an XPages application the CKEditor looks like this:


How to add a Skin to the CKEditor

1. Download the Bootstrap CK-Skin for CKEditor4
You can download the BootstrapCK4-Skin from the CKEditor website : CKEditor Skins


Download the files to your PC and extract the downloaded files.

2. Web-Content Folder
Add the extracted bootstrapck folder to the WebContent Folder in the Package Explorer.


3. Implement the Bootstrap CK-Skin
For the implementation see the Sven Hasselbach's blog post : Bootstrap Skin for CKEditor

First you need to declare an own xspCKEditor-instance on your XPage.
As mentioned by Sven Hasselach in his blog post this is required to remove an URL parameter, which is added automatically and will break the references.
I use a Custom Control for this and add this Custom Control to an XPage.

Sample Code Custom Control

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:scriptBlock id="scriptBlockCKEditor">
<xp:this.value>
      <![CDATA[
         require( ['dojo/_base/declare', 'ibm/xsp/widget/layout/xspCKEditor'], function( declare, xspCKEditor ){
            return declare( 'org.wavin.joldenburger.CKEDITOR', xspCKEditor, {
               constructor: function ckew_ctor(/*Object*/options){
                  CKEDITOR.timestamp = '';
               }
            });  
         });
      ]]>
</xp:this.value>
</xp:scriptBlock>
</xp:view>

4. Create a new XPage
Add a Rich Text Field to the XPage.
In the Rich Text Field you have to overwrite the dojoType of your RichText control and add a dojoAttribute for the Skin. The path has to be appended after the name of the skin.

<xp:dojoAttribute name="skin">
<xp:this.value><![CDATA[#{javascript:return @ClientType().equals("Web") ? "bootstrapck,/"+database.getFilePath()+"/bootstrapck/" : ""}]]></xp:this.value>
</xp:dojoAttribute>

Further you have to set the default Dojo Type which should be used to create this control in the browser (this is your own xspCKEditor-instance).

<xp:this.dojoType><![CDATA[#{javascript:return @ClientType().equals("Web") ? "org.wavin.joldenburger.CKEDITOR" : ""}]]></xp:this.dojoType>

Remark
In Notes Domino 9.0.1 FP2 Dojo is updated to 1.9.2..
The Dojo Attribute toolbarType has been changed to toolbar.
If you updated to Notes Domino 9.0.1. FP1/FP2 and you are using Richt Text Fields with the Dojo Attribute toolbarType have a look at the XSnippet by Oliver Busse - Solving problems with CKEditor in 9.0.1FP1 and/or FP2 and his video Troubleshooting FP2's CKEditor issue .

Sample Code XPage with some additonal Dojo Attributes

<?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>
<xc:ccLayoutBootstrap>
<xp:this.facets>
<xp:panel xp:key="facetMiddle">
<div class="page-header">
<h1>
BootstrapCK-Skin
<xp:span style="color:rgb(255,255,255)">.</xp:span>
<small>CKEditor4</small>
</h1>
</div>
<xp:br></xp:br>
<xp:inputRichText id="inputRichText1"
value="#{document1.Body}">
<xp:this.dojoAttributes>
<xp:dojoAttribute name="extraPlugins"
value="autogrow">
</xp:dojoAttribute>
<xp:dojoAttribute name="skin">
<xp:this.value><![CDATA[#{javascript:return @ClientType().equals("Web") ? "bootstrapck,/"+database.getFilePath()+"/bootstrapck/" : ""}]]></xp:this.value>
</xp:dojoAttribute>
<xp:dojoAttribute name="width" value="100%">
</xp:dojoAttribute>
<xp:dojoAttribute value="Full" name="toolbar">
</xp:dojoAttribute>
</xp:this.dojoAttributes>
<xp:this.dojoType><![CDATA[#{javascript:return @ClientType().equals("Web") ? "org.wavin.joldenburger.CKEDITOR" : ""}]]></xp:this.dojoType>
</xp:inputRichText>
<xp:br></xp:br>
<xc:ccBSCKE></xc:ccBSCKE>
<xp:br></xp:br>
</xp:panel>
</xp:this.facets>
</xc:ccLayoutBootstrap>
</xp:view>

The final result:


We have now a nice Bootstrap look and feel CKEditor and it also works great in Notes Domino 9.0.1. FP2 combined with the OpenNTF Bootstrap4XPages plugin.