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.

2 comments:

  1. Wonderful! I will definitely use this. Something about web development Philippines please. Thanks!

    ReplyDelete
  2. Great. Exactly what I am looking for. Thanks.

    ReplyDelete