How do you use the Selected property of the navigator? - xpages

I've spent days trying to figure this out and I give up.
I am a LotusScript programmer and have been trying to learn XPages. All of the examples and sample programs I've studied only touch on pieces of this.
Can someone explain to me step by step how to use the Selected property of the Extension Library Navigator control?
I have created my own custom control based on the layout control from the Extension Library and created a custom property called navigationPath. I also created a navigator custom control that has 5 Page Link Nodes. In the "Selected" property of each Page Link Node, I put the following SSJS:
if(compositeData.navigationPath == "/Home/ApplicationPool"){
return true
}else{
return false
}
/Home/ApplicationPool corresponds to the value I put in the "Selection" property of the particular Page Link Node.
In each layout custom control, I set the "navigationPath" property to compositeData.navigationPath.
What did I miss?

there is a selected and selection property and they mean very different things and can't be used at the same time. In the code example in your question above you are using the selected property which is the wrong one in this case.
Your treeNodes in the navigator should be setup to use the selection property, this is a RegEx value that is used to see if it matches the value passed into the application layout via the custom property.
<xe:navigator id="navigator1" expandable="true" expandEffect="wipe">
<xe:this.treeNodes>
<xe:pageTreeNode label="nodeName" page="/page.xsp" selection="/Home/ApplicationPool" />
</xe:this.treeNodes>
</xe:navigator>
As you can see you don't need to use any SSJS to evaluate a true/false outcome. Just match the value in the treeNode to the one in the XPage's applicationLayout control.
If your using tabs in the layout titleBar then you can set a selection property there also that uses the format /Home/.* which will make that tab highlighted for every XPage that have /Home/ at the start of it's navigationpath custom property. Don;t forget it is RegEx so any valid RegEx statement can be used here adding more power to this particular property.

For the tree nodes in the navigator control you define the name of the xpage to open and then the related selection. Example:
<xe:pageTreeNode page="/text.xsp" selection="/Home/Test" label="Test page">
</xe:pageTreeNode>
For the individual xpages using the applicationLayout you define a value for navigationPath. If this value matches an entry in one of the tree nodes the naviagor control, then the corresponding menu item will be highlighted in the browser. The best way to define the value of the navigationPath is by using a custom property (as you are using). Here's an example of that:
<xe:applicationLayout id="applicationLayout1">
<xe:this.configuration>
<xe:oneuiApplication navigationPath="${javascript:compositeData.navigationPath}" ...
You can see examples of using all this in the Extension Library Teamroom and Discussion templates.
Based on my explanation on how to use it, I can see that you are not using the selection property on the navigation control correct. You just need to define a unique value for each tree node (which then will be used if it matches navigationPath on the individual xpages).
So for your specific example change your selection property to just return: "/Home/ApplicationPool"

Related

Application layout combobox.SelectedValue for SearchBar

How can I get the value of SearchBar in Application Layout?
If I have more than one criteria to search (in application layout) how to get the current (selected) value of combobox near the SearchBar?
Have a look on the picture above.
The basic assumption behind the search bar with options is that you'll submit the search information to another XPage. For instance;
<xe:this.searchBar>
<xe:appSearchBar
pageName="/search1.xsp">
<xe:this.options>
<xe:basicLeafNode
label="People"
submitValue="people">
</xe:basicLeafNode>
<xe:basicLeafNode
label="Buildings"
submitValue="buildings">
</xe:basicLeafNode>
</xe:this.options>
</xe:appSearchBar>
</xe:this.searchBar>
Such a markup will create a combobox with two options. When the user submits the search string, it will navigate to /search1.xsp?search=SomeValue&option=buildings. Therefore, you will process those values inside the target page.
In such a case I guess you'll want to decide which view to be searched according to the search option. What I do is generally having a single XPage for search results and different custom controls for different views. You might use a switch or dynamic control component depending on the case. Alternatively, you can use the dynamic view panel component to switch between different views.
If you prefer different search pages for different search options (i.e. searchPeople.xsp and searchBuildings.xsp), you'll have two options. You can design an intermediate page to redirect the user to the desired page or you can create your own search box there. So you don't generally need to have the option value within the page.
BTW, that value is available at the Client-side JavaScript. That's a <select> element and its id is "the id of the application layout control" + "_searchopt". You can refer to the client-side object with dojo.byId("#{id:applicationLayout1}_searchopt").
Hope this helps.

How to pass var variable to custom control

I want to create a generic action bar custom control with Save, Edit, Delete, ... buttons.
How can I pass var variable from xpage to a custom control?
Update
I successfully transferred document object to custom control and I can Save the changes made in document, but I can't delete it with same object.
Update:
<xp:this.action>
<xp:executeScript
   script="#{javascript:compositeData.datasrc.save()}">
</xp:executeScript>
</xp:this.action>
Delete is not working:
<xp:deleteDocument
message="Do you want to delete?"
var="#{javascript:compositeData.datasrc}">
<xp:this.name><![CDATA[#{javascript:var page = sessionScope.get("prevview");
return (page=='')?'home.xsp':page}]]> </xp:this.name>
</xp:deleteDocument>
I tried also with:
var="#{javascript:compositeData.datasrc.getDocument()}">
but also didn't work.
When you define a custom control, you can specify control properties. These properties then show up in the property editor when you insert the custom control into an XPage or another control. You can specify the data type and allow them to repeat.
This is saver than to rely on scoped variables. Check Chris' introduction and the XPages 101 session or and many more for inspiration
You can do it for example with a Scoped Variable. If the variable value is specific to that XPage (and user) viewScope is probably the best.
The above options are the best way to do that, but keep in mind that if you define a variable in a scriptblock or somewhere else in the Xpage, you will be able to access this variable from your code in the CustomControl, too. I think that's because the XPage und the custom Controls are kind of merged when compiled. Keep that in mind, this can lead to very nasty problems, especially with recycling issues.
What is the purpose of this variable ? If its a variable to control which buttons are being shown it would be best to create properties for each button / section. These properties can be computed to either return true or false.
If you want to pass the code that a button should execute I would advice you to generate button bars for the most common locations ( aka actions ) and add custom buttons on the button bar by using a facet (Editable area its called in the designer) .On this facet you'll drag a panel on which the buttons are being placed.

Can you compute which custom control to use?

Think "computed subform", but in Xpages.
On one of my custom controls, depending on a certain value, I want to either present a custom control that renders a drop-down list using a combobox or renders an input box with a type-ahead.
This is on a custom control that renders a view, with all view configuration choices handled by a document rather than design, so several different views utilize the same custom control.
For example: I have a By Status view using the custom control that has status as the first column and we use a combobox to allow the user to select which Status value to filter by. Another view is sorted by Requisition number and I want to use a type-ahead instead of the combobox.
My preference is to use the same dynamic view custom control for both and have a formula that determines which of the two (comboBox or inputText) to use. How do I compute which custom control to load?
(Credit for the dynamic view control goes to Scott Good's folks over at Teamworks Solutions.)
During it's life cycle, an XPage exists in two places. First of all a representation of the XPage's relevant components is stored on the server. Then the page goes through a lifecycle, retrieving properties from documents, checking which components should be rendered, retrieving the data for any repeating control such as a View Panel etc., and passing the relevant HTML to the browser. The browser is the second place it exists.
So you can't compute a custom control as such. All you can do is set the loaded property, and loaded needs to be based on a non-dynamic calculation such as a viewScope variable, the current XPage name, a view name stored on the XPage etc. What you would have difficulty doing would be using a different custom control based on data on that row entry.
The other option is the Dynamic Content control or Switch control from the Extension Library. Both are similar to using the loaded property, in that you're putting both custom controls on the page and choosing which to display.
From what you're describing, the loaded property should cover what you need.
Some time back I saw this question on StackOverflow where the author had used Include Page control (xp:include) to include custom controls using pageName attribute based on formula.
<xp:include>
<xp:this.pageName><![CDATA[${javascript:sessionScope.ccPageName + ".xsp";}]]> </xp:this.pageName>
</xp:include>
Similar to the technique described by Paul Withers in his answer the attribute of pageName is also computed on page load.

Conditional Client Side Validation?

I have a radio button group that gets it's values using an #Dblookup. In addition to the name to appear in the radio button group, the document also has a field to determine if another field on the xPage should be displayed or not.
If the field is displayed then it should be required.
I can do the conditional validation just fine in SSJS using an #DbLookup to lookup the document selected in the radio button group.
But I would like to be able to do it CS so it is faster and so it looks like my other validations. Is there anyway to do this?
If a field is not rendered then the node will not exist in the DOM. Your CS javascript would need to examine the DOM and look for the node, normally by looking for a specific ID. As Xpages changes the ID's sent to the browser your validation function would either need to be computed so it would know what ID to look for or you would need to look for it in some other unique way ( like add a css class name to just that field and then do a DOM search for nodes with that class name )
Once you can determine if the field has been rendered then you can run your usual CS validation routine against the other field.
If you're using client-side validation throughout your app, setting the required property on the field should achieve what you need.
If not, it may be worth looking at the Extension Library Dojo Validation Text Box. All the Extension Library Dojo control run client-side validation, even if validation is set as server-side at application level. Bear in mind that for the Dojo Validation Text Box, just setting the required property is not enough. You need to add more specific validation.
After that, the key is to ensure the partial refresh event on your radio group is set to skip validation. I haven't tried, but I believe that should achieve what you need.

How do you keep Title Bar tabs active in the Application Layout Control?

I have an application that makes use of the Application Layout Control. The UI has two tabs defined in the Title Bar section. The UI also contains a Navigator control in the sidebar that allows users to select links to open other pages. What I am having troubles with is keeping the current tab set as the active tab when users click on links in the current navigator.
The "configuration" property of the Application Layout Control is a complex type, which in turn supports all the properties that define the layout itself. One of those properties is "navigationPath". If Netflix used this control on their site, the value of that property when viewing the movie information page for Ghostbusters might look something like:
/home/genres/comedies/541018
So this property can be thought of as a way of describing the page's current location in the "site map" using *nix filepath syntax.
Each titleBarTab is also a complex type; one of its properties is "selection". This property is intended to be given a value that matches part or all of the current navigationPath for the overall layout. So, continuing the Netflix example, you might define your tabs like this:
<xe:this.titleBarTabs>
<xe:pageTreeNode
page="/genre.xsp"
label="Action"
queryString="genre=action"
selection="/home/genres/action/*" />
<xe:pageTreeNode
page="/genre.xsp"
label="Comedy"
queryString="genre=comedies"
selection="/home/genres/comedies/*" />
<xe:pageTreeNode
page="/genre.xsp"
label="Drama"
queryString="genre=dramas"
selection="/home/genres/dramas/*" />
</xe:this.titleBarTabs>
On the page for Ghostbusters, then, because navigationPath property for the layout matches the pattern defined for the selection property of the pageTreeNode with a label of "Comedy", that tab will appear selected, but the others will not.
Also perhaps worthy of note is that the layout configuration also includes a property called "defaultNavigationPath". The value of this property will be compared against the selection property of each titleBarTab if the navigationPath property has no value. So you typically want to set this to a path that would cause the first tab to appear selected.
Bruce, if I am reading this right, I ran into a similar problem a while back. Does this help at all? Setting a sessionScope variable for a TitleBar tab

Resources