Reg Exp
Web Design
Notes Client
Search Bar Conditionally Shown in OneUI Application Layout
I was working on an application that used a custom control for the layout. That way, the layout could be shared among all my XPages. The customer wanted to have search capabilities (full text search) within the application. The search made sense when in a view, but didn't make sense within an individual document. So I wanted to hide the Search Bar when in a document and show it when in a view.

I could have duplicated the layout custom control and had "layoutView" and "layoutDoc" custom controls with the only difference being the Search Bar. But I was in a learning mood and decided to try to conditionally show/hide the Search Bar in one layout. I added a Property Definition called viewToSearch to the layout custom control. I would use that to pass in the name of the XPage to be searched or I would pass in "x" if the Search Bar wasn't to be shown.

First, I tried simply computing whether the Search controls would be shown within the OneUI Application Layout. It turns out there's a diamond for computing that value, but it never sticks. You can only toggle it on or off.

Turns out there is a facet for the search bar that can be used.

So, inside <xe:applicationLayout> add (or use the existing, if you already have one) <xe:this.facets>. The facet key is "SearchBar". I wanted to mimic the existing search bar functionality exactly, so I used a handy debugger and inspected all the HTML that was generated when the regular search bar was used. It was a table - one cell for the input field, a second cell for the search icon. I added a table, assigned the correct facet key, put the conditional rendering on it, and it works like a charm. Here's my XPage source:
<xp:table xp:key="SearchBar" styleClass="lotusLayout" cellspacing="0" role="presentation">
<xp:this.rendered><![CDATA[#{javascript:(compositeData.viewToSearch != "x")}]]></xp:this.rendered>
<xp:inputHidden id="searchViewName" defaultValue="#{javascript:compositeData.viewToSearch}"></xp:inputHidden>
<xp:inputHidden id="searchDbPath" defaultValue="#{javascript:webDbName()}"></xp:inputHidden>
<xp:inputText id="searchBox" styleClass="lotusText lotusInactive" style="height: auto;"
value="Search..." onfocus="if(this.value=='Search...'){this.value=''}"
onkeypress="var kc=event.keyCode?event.keyCode:event.which;if(kc==13){_xspAppSearchSubmit(); return false}"
<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[function _xspAppSearchSubmit(){
var val=XSP.getFieldValue(XSP.getElementById('#{id:searchBox}'));
var searchDbPath=XSP.getFieldValue(XSP.getElementById('#{id:searchDbPath}'));
var searchViewName=XSP.getFieldValue(XSP.getElementById('#{id:searchViewName}'));
var loc='/'+searchDbPath+'/'+searchViewName+'?search='+encodeURIComponent(val);
<span class="lotusBtnImg">
<a class="lotusSearchButton" onclick="javascript:_xspAppSearchSubmit(); return false;">
<img src="/oneuiv2/images/blank.gif" alt="submit search"> </a>

The only thing to point out is that webDbName() is a server-side JavaScript function that computes the path to the current database. Everything else pretty well came from the HTML generated by the regular search button.