XPages and Me

My Journey into XPages Development

Dabbling in Bootstrap and Font Awesome Part 8: DB Profile and Theme

As I’ve mentioned in my previous post, I have a DB Profile document where I can set the Bootstrap navbar type, navbar look, navbar container and the content container I’d like to use across my whole application. It also contains a setting for the Bootstrap field size (read more here) and in this post, I am going to explain how I reference and use that setting in my theme.

One great thing about using themes in XPages is, you can use actual SSJS to compute settings in your theme, making your application even more flexible. Obviously, this is not limited to just Bootstrap and XPages.

Note: The themes I use in my Bootstrap applications were inspired by a NotesIn9 video by Tim Tripcony, some of you might recognize it.

In a theme, you can already apply styling classes to XPages controls. This is very helpful especially while using Bootstrap, as it takes care of the need of having to apply base classes to your controls every time you add one to your custom control or XPage. For instance: A button in Bootstrap always needs the base class “btn”. Obviously you can add more style classes to further format your button, but “btn” is mandatory, so, why not applying that base class as a default thru your theme?

So, how do you do it? By adding the following lines to you theme:

<control>
	<name>Button.Command</name>
	<property mode='concat'>
		<name>styleClass</name>
		<value>btn</value>
	</property>
</control>

In this case, we add the style class “btn” to any button we use in our application. Obviously, if you don’t use Bootstrap, you can replace “btn” with any style class name that you use.

But how do you figure out the names of the controls? Thanks to Julian Buss, you can find them here.

As you’ve probably guessed, there are many more property options, but that is a topic for a different post, so, on with this one.

Here is my theme setting for a ComboBox:

<!-- Combo Box -->
<control>
	<name>ComboBox</name>
	<property
		mode='concat'>
		<name>styleClass</name>
		<value>${javascript://Declarations
			//Notes Objects
			var oView:NotesView = database.getView('$vwSYSLookupKeywords');
			var oDocDBProfile:NotesDocument = oView.getDocumentByKey('.DBProfile', true);

			//String
			var sStyleClass:String = '';

			//Check if a DB Profile was found.
			//If not, just display default NavBar
			if(oDocDBProfile == null){
				'form-control';
			}
			else{

				//Make sure the fields 'iTxtFieldSize' is not empty.
				//If it is, just display default 'form-control'
				if(oDocDBProfile.getItemValueString('iTxtFieldSize') == ''){
					'form-control';
				}
				else{
					sStyleClass = 'form-control'

				//Check the selected field size
					switch (oDocDBProfile.getItemValueString('iTxtFieldSize')){

					//Static
						case 'Large':
							sStyleClass += ' input-lg';
						break;

					//Fixed
						case 'Small':
							sStyleClass += ' input-sm';
						break;
					}	//switch (oDocDBProfile.getItemValueString('iTxtFieldSize'))

					sStyleClass;

				}	//if(oDocDBProfile.getItemValueString('iTxtFieldSize') == '')
			}	//if(oDocDBProfile == null)
		}</value>
	</property>
	<property
		mode='override'>
		<name>showReadonlyAsDisabled</name>
		<value>#{true}</value>
	</property>
</control>

Confused yet ;o) ?

It is actually relatively simple to add to your theme. All you have to do is to write the JavaScript code somewhere, where you can use the Script Editor prompt, then switch to “Source” pane and copy the whole script block (without the <![CDATA[ tag) and paste it in between value tags in your theme. But let me step you thru it.

Step 1: Add setting to you theme

Open your Bootstrap theme and add the following lines:

<control>
	<name>ListBox</name>
	<property
		mode='concat'>
		<name>styleClass</name>
		<value></value>
	</property>
	<property
		mode='override'>
		<name>showReadonlyAsDisabled</name>
		<value>#{true}</value>
	</property>
</control>

So, what does that do? The first property tag will add a style class to the list box control, which we will set thru SSJS. The second property tag will make sure that in read mode, the control is shown as disabled, adding the disabled tag to the control and rendering it Bootstrap style.

Step 2: Create SSJS

What I do is, I open an empty custom control and use the “beforePageLoad” event to write the SSJS:

Image 1

In the Script Editor prompt, type in the following code, which will check your DB Profile settings for the field size and then apply the matching style classes.

Note: You might have to change the view name, lookup key and field names in the code, based on how you named yours

//Declarations
	//Notes Objects
	var oView:NotesView = database.getView('$vwSYSLookupKeywords');
	var oDocDBProfile:NotesDocument = oView.getDocumentByKey('.DBProfile', true);

	//String
	var sStyleClass:String = '';

	//Check if a DB Profile was found.
	//If not, just display default NavBar
	if(oDocDBProfile == null){
		'form-control';
	}
	else{

		//Make sure the fields 'iTxtFieldSize' is not empty.
		//If it is, just display default 'form-control'
		if(oDocDBProfile.getItemValueString('iTxtFieldSize') == ''){
			'form-control';
		}
		else{
			sStyleClass = 'form-control'

		//Check the selected field size
			switch (oDocDBProfile.getItemValueString('iTxtFieldSize')){

			//Static
				case 'Large':
					sStyleClass += ' input-lg';
				break;

			//Fixed
				case 'Small':
					sStyleClass += ' input-sm';
				break;
			}	//switch (oDocDBProfile.getItemValueString('iTxtFieldSize'))

			sStyleClass;

		}	//if(oDocDBProfile.getItemValueString('iTxtFieldSize') == '')
	}	//if(oDocDBProfile == null)

Click on OK to close the prompt.

Step 3: Copy and Paste

Switch to the “Source” view and look for the “” tag. Select everything from after “”:

Image 2

Image 3

Press CTRL+c to copy it.

Next, go back to your theme, put the cursor in between the “” tag and press CTRL+v:

Image 4

The last thing we need to do is to replace the # before “{javascript” with a $. This means that the style class will be “Computed on Page Load” instead of “Compute Dynamically” (# = Compute Dynamically; $ = Computed on Page Load).

Change this…

Image 5

To this…

Image 6

And you are all set.

Here is the complete section of my theme that automatically applies styles to controls. It also includes a setting for view panels:

	<!-- START: Add default style classes to controls -->
		<!-- View Panel -->
			<control>
				<name>DataTable.ViewPanel</name>
				<property mode='concat'>
					<name>dataTableStyleClass</name>
					<value>table table-condensed table-hover</value>
				</property>
			</control>

		<!-- Button -->
			<control>
				<name>Button.Command</name>
				<property mode='concat'>
					<name>styleClass</name>
					<value>btn</value>
				</property>
			</control>

		<!-- Fields -->
			<!-- Combo Box -->
			<control>
				<name>ComboBox</name>
				<property
					mode='concat'>
					<name>styleClass</name>
					<value>${javascript://Declarations
						//Notes Objects
						var oView:NotesView = database.getView('$vwSYSLookupKeywords');
						var oDocDBProfile:NotesDocument = oView.getDocumentByKey('.DBProfile', true);

						//String
						var sStyleClass:String = '';

						//Check if a DB Profile was found.
						//If not, just display default NavBar
						if(oDocDBProfile == null){
							'form-control';
						}
						else{

							//Make sure the fields 'iTxtFieldSize' is not empty.
							//If it is, just display default 'form-control'
							if(oDocDBProfile.getItemValueString('iTxtFieldSize') == ''){
								'form-control';
							}
							else{
								sStyleClass = 'form-control'

							//Check the selected field size
								switch (oDocDBProfile.getItemValueString('iTxtFieldSize')){

								//Static
									case 'Large':
										sStyleClass += ' input-lg';
									break;

								//Fixed
									case 'Small':
										sStyleClass += ' input-sm';
									break;
								}	//switch (oDocDBProfile.getItemValueString('iTxtFieldSize'))

								sStyleClass;

							}	//if(oDocDBProfile.getItemValueString('iTxtFieldSize') == '')
						}	//if(oDocDBProfile == null)
					}</value>
				</property>
				<property
					mode='override'>
					<name>showReadonlyAsDisabled</name>
					<value>#{true}</value>
				</property>
			</control>

			<!-- List Box -->
			<control>
				<name>ListBox</name>
				<property
					mode='concat'>
					<name>styleClass</name>
					<value>${javascript://Declarations
						//Notes Objects
						var oView:NotesView = database.getView('$vwSYSLookupKeywords');
						var oDocDBProfile:NotesDocument = oView.getDocumentByKey('.DBProfile', true);

						//String
						var sStyleClass:String = '';

						//Check if a DB Profile was found.
						//If not, just display default NavBar
						if(oDocDBProfile == null){
							'form-control';
						}
						else{

							//Make sure the fields 'iTxtFieldSize' is not empty.
							//If it is, just display default 'form-control'
							if(oDocDBProfile.getItemValueString('iTxtFieldSize') == ''){
								'form-control';
							}
							else{
								sStyleClass = 'form-control'

							//Check the selected field size
								switch (oDocDBProfile.getItemValueString('iTxtFieldSize')){

								//Static
									case 'Large':
										sStyleClass += ' input-lg';
									break;

								//Fixed
									case 'Small':
										sStyleClass += ' input-sm';
									break;
								}	//switch (oDocDBProfile.getItemValueString('iTxtFieldSize'))

								sStyleClass;

							}	//if(oDocDBProfile.getItemValueString('iTxtFieldSize') == '')
						}	//if(oDocDBProfile == null)
					}</value>
				</property>
				<property
					mode='override'>
					<name>showReadonlyAsDisabled</name>
					<value>#{true}</value>
				</property>
			</control>

			<!-- Password Field -->
			<control>
				<name>InputField.Secret</name>
				<property
					mode='concat'>
					<name>styleClass</name>
					<value>${javascript://Declarations
						//Notes Objects
						var oView:NotesView = database.getView('$vwSYSLookupKeywords');
						var oDocDBProfile:NotesDocument = oView.getDocumentByKey('.DBProfile', true);

						//String
						var sStyleClass:String = '';

						//Check if a DB Profile was found.
						//If not, just display default NavBar
						if(oDocDBProfile == null){
							'form-control';
						}
						else{

							//Make sure the fields 'iTxtFieldSize' is not empty.
							//If it is, just display default 'form-control'
							if(oDocDBProfile.getItemValueString('iTxtFieldSize') == ''){
								'form-control';
							}
							else{
								sStyleClass = 'form-control'

							//Check the selected field size
								switch (oDocDBProfile.getItemValueString('iTxtFieldSize')){

								//Static
									case 'Large':
										sStyleClass += ' input-lg';
									break;

								//Fixed
									case 'Small':
										sStyleClass += ' input-sm';
									break;
								}	//switch (oDocDBProfile.getItemValueString('iTxtFieldSize'))

								sStyleClass;

							}	//if(oDocDBProfile.getItemValueString('iTxtFieldSize') == '')
						}	//if(oDocDBProfile == null)
					}</value>
				</property>
				<property
					mode='override'>
					<name>showReadonlyAsDisabled</name>
					<value>#{true}</value>
				</property>
			</control>

			<!-- Text Field -->
			<control>
				<name>InputField.EditBox</name>
				<property
					mode='concat'>
					<name>styleClass</name>
					<value>${javascript://Declarations
						//Notes Objects
						var oView:NotesView = database.getView('$vwSYSLookupKeywords');
						var oDocDBProfile:NotesDocument = oView.getDocumentByKey('.DBProfile', true);

						//String
						var sStyleClass:String = '';

						//Check if a DB Profile was found.
						//If not, just display default NavBar
						if(oDocDBProfile == null){
							'form-control';
						}
						else{

							//Make sure the fields 'iTxtFieldSize' is not empty.
							//If it is, just display default 'form-control'
							if(oDocDBProfile.getItemValueString('iTxtFieldSize') == ''){
								'form-control';
							}
							else{
								sStyleClass = 'form-control'

							//Check the selected field size
								switch (oDocDBProfile.getItemValueString('iTxtFieldSize')){

								//Static
									case 'Large':
										sStyleClass += ' input-lg';
									break;

								//Fixed
									case 'Small':
										sStyleClass += ' input-sm';
									break;
								}	//switch (oDocDBProfile.getItemValueString('iTxtFieldSize'))

								sStyleClass;

							}	//if(oDocDBProfile.getItemValueString('iTxtFieldSize') == '')
						}	//if(oDocDBProfile == null)
					}</value>
				</property>
				<property
					mode='override'>
					<name>showReadonlyAsDisabled</name>
					<value>#{true}</value>
				</property>
			</control>

			<!-- Text Area -->
			<control>
				<name>InputField.TextArea</name>
				<property
					mode='concat'>
					<name>styleClass</name>
					<value>${javascript://Declarations
						//Notes Objects
						var oView:NotesView = database.getView('$vwSYSLookupKeywords');
						var oDocDBProfile:NotesDocument = oView.getDocumentByKey('.DBProfile', true);

						//String
						var sStyleClass:String = '';

						//Check if a DB Profile was found.
						//If not, just display default NavBar
						if(oDocDBProfile == null){
							'form-control';
						}
						else{

							//Make sure the fields 'iTxtFieldSize' is not empty.
							//If it is, just display default 'form-control'
							if(oDocDBProfile.getItemValueString('iTxtFieldSize') == ''){
								'form-control';
							}
							else{
								sStyleClass = 'form-control'

							//Check the selected field size
								switch (oDocDBProfile.getItemValueString('iTxtFieldSize')){

								//Static
									case 'Large':
										sStyleClass += ' input-lg';
									break;

								//Fixed
									case 'Small':
										sStyleClass += ' input-sm';
									break;
								}	//switch (oDocDBProfile.getItemValueString('iTxtFieldSize'))

								sStyleClass;

							}	//if(oDocDBProfile.getItemValueString('iTxtFieldSize') == '')
						}	//if(oDocDBProfile == null)
					}</value>
				</property>
				<property
					mode='override'>
					<name>showReadonlyAsDisabled</name>
					<value>#{true}</value>
				</property>
			</control>
	<!-- END: Add default style classes to buttons and fields -->

Enjoy!

Advertisements

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: