XPages and Me

My Journey into XPages Development

Dabbling in Bootstrap and Font Awesome Part 6-8: re(Use) Me! (Panel)

The Bootstrap panel can be used, to nicely organize content on your web page. In this post, I will show you how to create a reusable custom control for the panel.

Step 1: Add Property Definitions

Create a new custom control and give it a meaningful name (I’ve named mine ccSYS_BS_Panel). Open the “Property Definition” tab and add the following property definitions:

Name: panelLayout
Type: string
Editor: ComboBox
Parameters: header
footer
both
none
Default Value: none
Description: Select the layout of your panel. Display a panel with:
– a Header
– a Footer
– both
– none (only panel body will be displayed)

Default value is none

Required Field: yes
Name: panelStateClass
Type: string
Editor: ComboBox
Parameters: panel-default
panel-primary
panel-success
panel-info
panel-warning
panel-danger
Default Value: panel-default
Description: Make a panel more meaningful to a particular context by adding any of the contextual state classes.

Default: panel-default

Required Field: yes

Next, add a group and name it “headerSettings”. Click on the tab “Visible” and enter the following JavaScript expression:

panelLayout == 'header' || panelLayout == 'both';

This will make sure, that the group is only visible, if you’ve selected “header” or “both” for panelLayout. Now add the following properties to the group:

Name: panelTitle
Type: string
Editor: – none –
Parameters: – none –
Default Value: – none –
Description: Enter text to be displayed as the panel’s title
Required Field: no
Name: panelTitleType
Type: string
Editor: ComboBox
Parameters: h1
h2
h3
h4
h5
h6
plain
Default Value: plain
Description: Select how the panel title is going to be rendered. You can select h-tags (h1-h6) or none to display plain text.

Default is plain

Required Field: no

Your “Property Definitions” tab should now look like this:

Image 1

Step 2: Add and configure controls

Add the following controls to your custom control:

4 x XPages Divs
2 x Computed Fields
2 x Editable Areas

Select the first Div and give it a name (I’ve named mine divPanel). Open the tab “Style” and click on the blue diamond beside “Class” and select “Compute value…”. In the script editor prompt, select “JavaScript (Server Side)” as the language and “Compute on Page Load” as the condition, then enter the following JavaScript code:

'panel ' + compositeData.panelStateClass

This will add the style class “panel”, plus the state class you’ll select for panelStateClass to the Div. Click on “OK” to close the script editor.

If you switch to the “Source” tab of your Custom Control, the XML markup for this Div should now look like this:

<xp:div
	id="divPanel"
	styleClass="${javascript:'panel ' + compositeData.panelStateClass}">
</xp:div>

 

Select the second Div and open the “All Properties” tab. Under the section “basics” enter a name for the Div into the field “id” (I’ve named mine divPanelHeading). Beside the field “loaded”, click on the blue diamond and select “Compute value…”. In the script editor prompt, select “Expression Language” as the language, then enter the following expression:

compositeData.panelLayout eq 'header' || compositeData.panelLayout eq 'both'

This will make sure, the Panel Header will only be displayed, if you’ve selected either “header” or “both” for the property definition “panelLayout”. Click on “OK” to close the script editor.

Scroll all the way down to the “styling” section and enter “panel-heading” into the field “styleClass”. The XML markup for the second Div should now look like this:

<xp:div
	id="divPanelHeading"
	styleClass="panel-heading"
	loaded="${compositeData.panelLayout eq 'header' || compositeData.panelLayout eq 'both'}">
</xp:div>

 

Select the third Div and give it name (I’ve named mine divPanelBody). Open the “Style” tab and enter “panel-body” into the field “Class”. The XML markup for the third Div should now look like this:

<xp:div
	id="divPanelBody"
	styleClass="panel-body">
</xp:div>

 

Select the fourth Div and open the “All Properties” tab. Under the section “basics” enter a name for the Div into the field “id” (I’ve named mine divPanelFooter). Beside the field “loaded”, click on the blue diamond and select “Compute value…”. In the script editor prompt, select “Expression Language” as the language, then enter the following expression:

compositeData.panelLayout eq 'footer' || compositeData.panelLayout eq 'both'

This will make sure, the Panel Footer will only be displayed, if you’ve selected either “footer” or “both” for the property definition “panelLayout”. Click on “OK” to close the script editor.

Scroll all the way down to the “styling” section and enter “panel-footer” into the field “styleClass”. The XML markup for the fourth Div should now look like this:

<xp:div
	id="divPanelFooter"
	loaded="${compositeData.panelLayout eq 'footer' || compositeData.panelLayout eq 'both'}"
	styleClass="panel-footer">
</xp:div>

 

Select the first Computed Field and open the “All Properties” tab. Under the section “basics” enter a name for the Computed Field into the field “id” (I’ve named mine idTxtPanelTitleHTag). Beside the field “loaded”, click on the blue diamond and select “Compute value…”. In the script editor prompt, select “Expression Language” as the language, then enter the following expression:

compositeData.headerSettings.panelTitleType != 'none'

This will make sure, that this particular Computed Field will only be displayed, if you’ve selected something other than “none” for the property definition “panelTitleType”. Click on “OK” to close the script editor.

Beside the field “tagName”, click on the blue diamond and select “Compute value…”. In the script editor prompt, select “Expression Language” as the language, then enter the following expression:

compositeData.headerSettings.panelTitleType

This will apply the proper h-tag based on your selection for the property definition “panelTitleType”. Click on “OK” to close the script editor.

Under the section “data”, click on the blue diamond beside the field “value”. In the script editor prompt, select “Expression Language” as the language and “Compute on Page Load” as the condition, then enter the following expression:

compositeData.headerSettings.panelTitle

Click on “OK” to close the script editor, scroll down to the section “styling” and type “panel-title” into the field “styleClass”. The XML markup for the first Computed Field should now look like this:

<xp:text
	escape="true"
	id="idTxtPanelTitleHTag"
	styleClass="panel-title"
	tagName="${compositeData.headerSettings.panelTitleType}"
	loaded="${compositeData.headerSettings.panelTitleType != 'none'}"
	value="${compositeData.headerSettings.panelTitle}">
</xp:text>

 

Select the second Computed Field and open the “All Properties” tab. Under the section “basics” enter a name for the Computed Field into the field “id” (I’ve named mine idTxtPanelTitle). Beside the field “loaded”, click on the blue diamond and select “Compute value…”. In the script editor prompt, select “Expression Language” as the language, then enter the following expression:

compositeData.headerSettings.panelTitleType == 'none'

This will make sure, that this particular Computed Field will only be displayed, if you’ve selected “none” for the property definition “panelTitleType”. Click on “OK” to close the script editor.

Under the section “data”, click on the blue diamond beside the field “value”. In the script editor prompt, select “Expression Language” as the language and “Compute on Page Load” as the condition, then enter the following expression:

compositeData.headerSettings.panelTitle

Click on “OK” to close the script editor. The XML markup for the second Computed Field should now look like this:

<xp:text
	escape="true"
	id="idTxtPanelTitle"
	loaded="${compositeData.headerSettings.panelTitleType == 'none'}"
	value="${compositeData.headerSettings.panelTitle}">
</xp:text>

 

Select the first Editable Area, enter “callbackPanelContent” into the field “Name” and “panelContentFacet” into the field “Facet name”. The XML markup for the first Editable Area should now look like this:

<xp:callback
	facetName="panelContentFacet"
	id="callbackPanelContent">
</xp:callback>

 

Select the second Editable Area, enter “callbackPanelFooter” into the field “Name” and “panelFooterFacet” into the field “Facet name”. The XML markup for the first Editable Area should now look like this:

<xp:callback
	facetName="panelFooterFacet"
	id="callbackPanelFooter">
</xp:callback>

 

Step 3: Rearrange Controls

In the “Outline” view, drag-and-drop the Editable Area “callbackPanelContent” into the Div “divPanelBody” and the Editable Area “callbackPanelFooter” into the Div “divPanelFooter”

Next, drag-and-drop the Computed Fields into the Div “divPanelHeading”

Finally, drag-and-drop the Divs “divPanelHeading”, “divPanelBody” and “divPanelFooter” into the Div “divPanel”. Your Custom Control’s XML markup should now look like this:

<?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:div
		id="divPanel"
		styleClass="${javascript:'panel ' + compositeData.panelStateClass}">
		<xp:div
			id="divPanelHeading"
			styleClass="panel-heading"
			loaded="${compositeData.panelLayout eq 'header' || compositeData.panelLayout eq 'both'}">
			<xp:text
				escape="true"
				id="idTxtPanelTitleHTag"
				styleClass="panel-title"
				tagName="${compositeData.headerSettings.panelTitleType}"
				loaded="${compositeData.headerSettings.panelTitleType != 'none'}"
				value="${compositeData.headerSettings.panelTitle}">
			</xp:text>
			<xp:text
				escape="true"
				id="idTxtPanelTitle"
				loaded="${compositeData.headerSettings.panelTitleType == 'none'}"
				value="${compositeData.headerSettings.panelTitle}">
			</xp:text>
		</xp:div>
		<xp:div
			id="divPanelBody"
			styleClass="panel-body">
			<xp:callback
				facetName="panelContentFacet"
				id="callbackPanelContent">
			</xp:callback>
		</xp:div>
		<xp:div
			id="divPanelFooter"
			loaded="${compositeData.panelLayout eq 'footer' || compositeData.panelLayout eq 'both'}"
			styleClass="panel-footer">
			<xp:callback
				facetName="panelFooterFacet"
				id="callbackPanelFooter">
			</xp:callback>
		</xp:div>
	</xp:div>
</xp:view>

 

Step 4: Add Design Definition

Select the Custom Control in the “Outline” view, open the tab “Design Definition” and past the following XML markup into it:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
	<xp:panel>
		Bootstrap Panel<br></br>
		<xp:callback facetName="panelContentFacet"></xp:callback>
		<xp:callback facetName="panelFooterFacet"></xp:callback>
	</xp:panel>
</xp:view>

 

When you use the panel custom control, you’ll only see “Bootstrap Panel” and the two slots to plug in your panel’s body and footer content, without cluttering up your screen

There you go, enjoy!

Advertisements

2 responses to “Dabbling in Bootstrap and Font Awesome Part 6-8: re(Use) Me! (Panel)

  1. Gracie Bruyere @ Bootstrap Themes January 5, 2015 at 5:33 am

    Hey there, I couldn’t find a twitter account on your website, do you have one?
    Thanks Gracie Bruyere

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: