XPages and Me

My Journey into XPages Development

Replicating the Notes Client “Allow Values Not in List” function used by Dialog List and Combobox on a XPage form (Part 1 – Create the reusable Custom Control)

I had a requirement to allow users to enter values that are not in the list of keywords. As some of you might know, this is not an option in XPages. My first tries to provide for this functionality were rather crude and the clients didn’t like it. So, after reading this post on the Inner Ring Solutions blog,  I came up with the following solution, which can be reused on any form for single value and multi-value fields.

Step 1 – Add Property Definitions

Create a Custom Control, name it ccSYS_frmElementAddNotInList (or anyway you like, I just like to give my design elements meaningful names). To be able to use it on any of your forms, we need to define some properties. Go to the “Property Definition” tab and add the following properties:

Name: Type: Editor: Parameters: Comment:
oUIDoc com.ibm.xsp.model.ModelDataSource Data Source Picker The NotesXSPDocument of your form (Data Source)
sMultiValue String ComboBox Yes
No
sFieldName String -none-
sLinkLabel String -none-
sButtonLabel String -none-
sPartialUpdate String -none- The name of the element on your page that you’d like to have refreshed after you added the new value.

Step 2 – Add two Div controls

Hint: If you can’t find the Div control in the list of Container Controls, simply double-click on “Other” and a dialog box will open with a list of control categories. Open the category “Container Controls” and you’ll see the Div control:

Name the first Div something like “divNotInListLink” and the second one “divNotInListField”.

Now we need to enter css style attributes for both of them. Open the “All Properties” tab and scroll to the end. Copy the following css statements into the field “style”:

Style for Div 1: display:block-inline; clear: both;margin-top:7px;
Style for Div 2: display:none;

Step 3 – Add link to toggle “Add value not in List” field and button

Drag-and-Drop a link control into the first Div “divNotInListLink”, give it a name (i.e. actToggleNotInList) and for the label select “Compute value…”:

Image 2

In the script editor, enter the following code:

if (compositeData.sLinkLabel != null){
	compositeData.sLinkLabel;
}
else{
	if(compositeData.sMultiValue == "Yes"){
		"Click here to add values not in the list.";
	}
	else{
		"Click here to enter value not in the list.";
	}
}

The code checks, if a value for the property “sLinkLabel” had been set. If so, the link label will display that. If not, the code checks if the Custom Control is for a single or multi-value field and displays the corresponding label text.

Next, click on the Events tab and select the “onclick” event. Select “Client” and “Script Editor”:

Image 3

Then, enter the following client-side JavaScript code:

var oDivNotinList = document.getElementById("#{id:divNotInListField}");
var displayStyle = oDivNotinList.style.display;
if (displayStyle == "none"){
	oDivNotinList.style.display = "inline";
} else {
	oDivNotinList.style.display = "none";
}

This will hide or display the field and add button we are going to add in the next step. Lastly, click on the All Properties tab, scroll down to the “styling” section and enter the following css statement into the field “style”: text-align:left

Step 4 – Add Field and Button

Drag-and-drop an Edit Box and beside it a Button into the second Div “divNotInListField”, your Custom Control should look like this:

Image 4

Select the field and name it “iTxtNotInListValue”. Select the “All Properties” tab, scroll down to the section “styling” and enter the following css statement into the “style” field: margin-top:7px;width:50%

Next, select the button and name it “actAddValue”. For the label, we use a computed value again like for the link. In the script editor, enter the following code:

if (compositeData.sButtonLabel != null){
	compositeData.sButtonLabel;
}
else{
	"Add Value";
}

This code does something similar like the code for the link label. It checks if a value had been passed on for the variable “sButtonLabel”. If that is the case, the passed on value will be displayed as the button label, otherwise you’ll see “Add Value”. This code makes sure that your link and button will always have a label and won’t be blank, should you forget to pass on information for the labels.

Now we have to add another css statement. Please select the All Properties tab, scroll down to the “styling” section and enter the following css statement into the “style” field: margin-top:5px;

Tip: You might want to adjust any of the css statements used here to better fit your application’s needs.

 Next, we are going to add code to the button’s “onclick” event. CSJS to make sure something has been entered into the field and SSJS to update the field on the form. Click on the “Events” tab, select the “onclick” event, the tab “Client” and the option “Script Editor”. Then enter the following code:

if (dojo.byId("#{id:iTxtNotInListValue}").value == ""){
	alert("Please enter a value.");
	return false;
}

This code checks if the field “iTxtNotInListValue” has a value and if not, prompts the user to please enter something. Now for the SSJS code. Select the tab “Server” and again the option “Script Editor” and enter the following code:

//Declarations
	//Notes Objects
	var oDocCurrent:NotesXspDocument = compositeData.oUIDoc;

	//String
	var sField:String = compositeData.sFieldName;
	var sValue:String = getComponent("iTxtNotInListValue").getValue();
	var sCurrentValue:String = "";

//If the field is a multivalue field, we need to add the entered value
	if(compositeData.sMultiValue == "Yes"){

		sCurrentValue = @Implode(oDocCurrent.getItemValue(sField), ",");

		sCurrentValue += "," + sValue;

	//Update field
		oDocCurrent.replaceItemValue(sField, @Unique(@Explode(sCurrentValue,",")));
	}

//If the field is just a single value field, replace value
	else{
		oDocCurrent.replaceItemValue(sField, sValue);

		//Reset field "iTxtNotInListValue"
		getComponent("iTxtNotInListValue").setValue("");
	}

//Reset field "iTxtNotInListValue"
	getComponent("iTxtNotInListValue").setValue("");

The code checks if the option for multi-value was selected and if so, adds the value to the list of values of the field we are using, otherwise it will just replace the current value of your field, if it is single-value. You might notice that I am using @Implode / @Explode rather than working with an array. I ran into some issues with using the array and switched to this method.

Set the “Server Options” to “Partial Updates” and click on “Select Element…”. In the dialog box, select “Specify element ID” and then click on the blue diamond beside the field to open the Script Editor and to enter the following code:

compositeData.sPartialUpdate

This will read the value of the property “sPartialUpdate” and refresh the part of the form that was defined here.

The custom control is done and we can now use it on our form, which I’ll explain in Part 2.

Let me know what you think.

Advertisements

3 responses to “Replicating the Notes Client “Allow Values Not in List” function used by Dialog List and Combobox on a XPage form (Part 1 – Create the reusable Custom Control)

  1. Mark Leusink December 3, 2013 at 10:16 am

    I’d say that’s an awesome start for this blog. Nice job! Hope to see more stuff like this in the future.

  2. DavidLeedy (@DavidLeedy) December 3, 2013 at 12:07 pm

    Wow. this looks cool. Looking forward to the next part.

  3. Steve Zavocki December 3, 2013 at 4:49 pm

    You won’t regret doing this, once you write it down and share it, you own it. I started blogging 10 months ago, and it has been well worth it. Like Mark said, this is an awesome start.

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: