JSF layout and templating - html

I have a templating search.xhtml page to accept user's search term on the page. After the user click the "Search!" button, the result will be displayed on the same page, below the search box, as shown in the simple code below.
search.xhtml:
<ui:define name="search">
<h:form id="wordForm">
<h:inputText id="word" value="#{wordController.word}" />
<h:commandButton id="search" value="Search!"
action="#{wordController.search}" />
</h:form>
</ui:define>
/*** From here to display the search results!!! ***/
<ui:define name="searchResult">
<h:outputText value="Search Results:"/>
<c:forEach items="#{wordController.wordInfoList}" var="wordInfo">
<h:outputText value="#{wordInfo.display}"
rendered="#{not empty wordInfo.display}" />
<ui:repeat value="#{wordInfo.relatedWords}" var="relatedInfo">
<h:outputLink value="index.xhtml">
<h:outputText value="#{relatedInfo}" />
<f:param name="relatedWord" value="#{relatedInfo}" />
</h:outputLink>
</ui:repeat>
</c:forEach>
/*Edit: Add a f:medatadata tag to accept the parameter "relatedWord" */
<f:metadata>
<f:viewParam id="related" name="relatedWord"
value="#{wordController.word}" />
<f:viewAction action="#{wordController.info()}" />
</f:metadata>
</ui:define>
The layout.xhtml inserts the search.xhtml to the page.
layout.xhtml:
<ui:fragment rendered="#{not empty wordController.word}">
<div id="searchResult">
<ui:insert name="searchResult">
</ui:insert>
</div>
</ui:fragment>
The problem is that, when the user visits the page, even before he clicks the "Search!" button, the search results will be always displayed together with teh search box, although the search result will be empty, except that the string "Search results: " is not empty.
How can I modify this so that before user performs a search, it will only display the search box. and only display the search results together with the search box after the user clicks the search button.
Thank you.

Related

trigger blockui from link within datagrid

I have the below datagrid which displays a list of student names as link.
<h:form id="gsform">
<p:dataGrid var="stuvar" rendered="#{gradeSheetController.listStudent != null}"
value="#{gradeSheetController.listStudent}" columns="5" layout="grid">
<p:commandLink actionListener="#{gradeSheetController.readStudentGradeSheet}"
update=":gsform:gscont, :gsform:buttoncont">
<h:outputText id="stname" style="font-size:16px" value="#{stuvar.studentFirstName}" />
<f:param name="selstudent" value="#{stuvar.studentSeq}" />
</p:commandLink>
</p:dataGrid>
I also have the below blockUI to freeze the screen until backend processing is done, currently used for a Save button.
<p:blockUI block=":entirePageBody" trigger="savebutton">
<h:panelGrid id="blockContent" columns="2">
<h:graphicImage library="images" name="loading.gif" style="margin-right:12px; vertical-align:middle;" />
<h:outputText value="Please wait, data is being processed..." style="white-space:nowrap;" />
</h:panelGrid>
</p:blockUI>
Now, I would also like to trigger the blockUI when the Student name link is clicked. Obviously, since the number of students will be dynamic and being within the datagrid, the code generated includes other aspects to the id like id="gsform:j_idt168:1:stname", id="gsform:j_idt168:2:stname" and so on.
Have no clue how to trigger the blockUI on click of the Student name link within the datagrid, please suggest.
Triggering/Hiding the blockUI from within dataGrid using onclick/oncomplete
<p:dataGrid var="stuvar" rendered="#{gsExamController.listStudent != null}"
value="#{gsExamController.listStudent}" columns="5" layout="grid">
<p:commandLink actionListener="#{gsExamController.readStudentGradeSheet}"
onclick="PF('bui').show()"
oncomplete="PF('bui').hide()"
update=":gsform:gscont, :gsform:remarkcont, :gsform:buttoncont">
<h:outputText style="font-size:16px" value="#{stuvar.studentFirstName}" />
<f:param name="selstudent" value="#{stuvar.studentSeq}" />
</p:commandLink>
</p:dataGrid>
<p:blockUI block=":entirePageBody" trigger="savebutton" widgetVar="bui">
<h:panelGrid id="blockContent" columns="2">
<h:graphicImage library="images" name="loading.gif" style="margin-right:12px; vertical-align:middle;" />
<h:outputText value="Please wait, data is being processed..." style="white-space:nowrap;" />
</h:panelGrid>
</p:blockUI>
A simple solution to your problem is to use Primefaces' selectors.
For example:
<p:commandLink value="Click me." styleClass="blockMeWhenClicked" />
<p:blockUI block=":ElementToBeBlocked" trigger="#(.blockMeWhenClicked)" />

How clean data in <p:overlayPanel ... when is opening or cloasing

<p:overlayPanel appendToBody="true"
id="panel_l#{level.name.hashCode()}
f{filterTypeConfiguration.filterType.name.hashCode()}"
for="conrolForm_l#{level.name.hashCode()}f
#{filterTypeConfiguration.filterType.name.hashCode()}:
button_l#{level.name.hashCode()}f
#{filterTypeConfiguration.filterType.name.hashCode()}"
dynamic="true" >
...
and in overlayPanel I have:
<p:inputText value="#{filterTypeConfiguration.textToSearch}">
<p:ajax id="ajaxFilterSearch" event="keyup" update="overlayForm_l
#{level.name.hashCode()} f#{filterTypeConfiguration.filterType.name.hashCode()}
:select_l#{level.name.hashCode()}
f#{filterTypeConfiguration.filterType.name.hashCode()}"
</p:inputText>
I need clean data in inputText when overlayPanel is opening or closing.
I didn't use p:overlayPanel yet but I am able to trigger p:dialog diaglodReturn event like, I think it should be similar like this
<p:ajax event="dialogReturn" update="#form" listener="#{backing.refreshPage}" />
Or
Example from primefaces showcase, How about add action attribute for button?
<p:commandButton id="imageBtn" value="Basic" type="button" action="#{backing.refresh}" />
<p:overlayPanel id="imagePanel" for="imageBtn" hideEffect="fade">
<p:graphicImage name="/demo/images/nature/nature1.jpg" width="300" />
</p:overlayPanel>

primefaces tabView different tab content with dynamic tabs

I have a problem with tabView. The 1st tab should always display the same content (called search template which is identified with #{not curSearch.isClosable()}. All other tabs are search instances (identified with #{curSearch.isClosable()}
Here is the code:
<p:tabView id="searchTabViewId" var="curSearch" value="#{searchBL.searchInstances}"
activeIndex="#{searchBL.activeTabIndex}" styleClass="searchTabView">
<!-- search template tab -->
<ui:include src="/icarchive/sections/search/firstSearchTab.xhtml">
<ui:param name="curSearch" value="#{curSearch}" />
</ui:include>
<!-- search instances tabs -->
<ui:include src="/icarchive/sections/search/searchInstanceTab.xhtml">
<ui:param name="curSearch" value="#{curSearch}" />
</ui:include>
</p:tabView>
Unfortunately there are methods on the 1st tabs curSearch object called which are used on 2nd and following tabs only. If I do not use the ui:insert it does not change anything.
Anybody knows where is my fault?
Regards
Oliver
This works:
<p:tabView id="searchTabViewId" styleClass="searchTabView" activeIndex="#{searchBL.activeTabIndex}">
<!-- do the iteration over the search instances NOT in the tabView because this will not work with ui:include -->
<c:forEach items="#{searchBL.searchInstances}" var="curSearch">
<p:tab closable="#{curSearch.isCloseable()}">
<f:facet name="title">
<p:graphicImage library="images" name="search_tab.png" height="16" styleClass="tabImage"
rendered="#{not curSearch.isCloseable()}" />
<h:outputText value="#{curSearch.title}" />
</f:facet>
<!-- do not use 2 ui:includes here, the dynamic must be in the src attribute to get it work -->
<ui:include
src="#{curSearch.closeable ? '/sections/search/searchInstanceTab.xhtml' : '/sections/search/firstSearchTab.xhtml'}">
<ui:param name="curSearch" value="#{curSearch}" />
</ui:include>
</p:tab>
</c:forEach>
I had the same problem, only solution i found is wrap include in other component and clamp with render which one is displayed. For initial load if you have ids depending on content you will need to set id prefix so that it does not allow empty id fields:
<p:tabView id="tabsView" dynamic="true" cache="true"
value="#{TabViewController.tabView.openedTabs}" var="tabDefinition" activeIndex="#{TabViewController.tabView.activeIndex}">
<p:ajax event="tabClose" listener="#{TabViewController.onCloseTab}" update="tabsView"/>
<p:ajax event="tabChange" update="tabsView"/>
<p:tab id="tab#{tabDefinition.id}" title="#{tabDefinition.title}" closable="true" action="">
<f:facet name="title">
<h:outputText value="#{tabDefinition.title}"/>
</f:facet>
<p:outputPanel style="display:block" rendered="#{'dataTable'.equals(tabDefinition.type)}">
<ui:include src="dataTable.xhtml">
<ui:param name="dataTableName" value="#{tabDefinition.contentName}"/>
</ui:include>
</p:outputPanel>
<p:outputPanel style="display:block" rendered="#{'form'.equals(tabDefinition.type)}">
<ui:include src="form.xhtml">
<ui:param name="formId" value="#{tabDefinition.id}"/>
<ui:param name="formName" value="#{tabDefinition.contentName}"/>
</ui:include>
</p:outputPanel>
</p:tab>
</p:tabView>

PrimeFaces Accordion panel keyboard focus on current tab command button

I have an accordion panel with few tabs with in a form . Each tab has a command button (I use the update and process attributes to process specific inputs with a tab). I have set the multiple attribute to true on the accordion panel. When the page initially loads the first tab is open by default. If i hit the enter key on the key board then the command button in the first tab has the keyboard focus and the fields are processed. now I leave the first tab open and open another tab and i hit the enter key the keyboard focus is still on the command button on the first tab . I tried using the p:focus with for/context attributes but with no help.
<h:form id="calculatorsNTools">
<p:accordionPanel multiple="true">
<p:tab title="Teenage Check">
<h:inputText id="age1" required="true" label="Age"
value="#{calculatorBacking.age}" validatorMessage="Enter a value">
<f:validateDoubleRange minimum="1" />
</h:inputText>
<p:message for="age1" id="msgage1" />
<h:panelGrid columns="3" id="gridTAresult">
<p:commandButton id="calculateTA"
action="#{calculatorBacking.calculateTA}" value="Calculate"
process="#this,age1"
update="gridTAresult">
</p:commandButton>
<b> Teenage (y/n)</b>
<h:outputLabel id="resultTA" value="#{calculatorBacking.resultTeenAge}"></h:outputLabel>
</h:panelGrid>
</p:tab>
<p:tab title="Retirement Check">
<h:inputText id="age2" required="true" label="Age"
value="#{calculatorBacking.age}" validatorMessage="Enter a value">
<f:validateDoubleRange minimum="1" />
</h:inputText>
<p:message for="age2" id="msgage2" />
<h:panelGrid columns="3" id="gridREresult">
<p:commandButton id="calculateRE"
action="#{calculatorBacking.calculateRE}" value="Calculate"
process="#this,age2"
update="gridREresult">
</p:commandButton>
<b> Retirement (y/n)</b>
<h:outputLabel id="resultRE" value="#{calculatorBacking.resultRetirement}"></h:outputLabel>
</h:panelGrid>
</p:tab>
</p:accordionPanel>
<h:form>
You can use javascript to accomplish what you want. I am not completely sure how to do it on an accordion but on a tabView it would be:
<p:tabView onTabChange="handleTabChange(event, index)">
Then create a javascript function to set the focus:
function handleTabChange(event, index){
if(index == 1){
var opControl = document.getElementById("calculatorsNTools:calculateTA");
opControl.focus();
}
}
You should be able to modify that to what you need for the accordionPanel.

Reset input fields in primefaces

I have a Dialog to input details. At the first time , InputText are empty.
But from the second input, InputText maintain the previous value.
This is my code :
<p:commandButton id="showDialogButton1" type="button" value="add" onclick="dlg1.show()" update="firstname1"/>
<p:dialog id="dialogAjout" header="add department" widgetVar="dlg1" resizable="false">
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="firstname1" value="Libellé :" />
<p:inputText id="firstname1" value="#{departementBean.departement.libelleDepartement}" />
</h:panelGrid>
<p:commandButton id="submitButton1" value="Valider" oncomplete="dlg1.hide();" action="#{departementBean.addDept()}" update="tabView"/>
</p:dialog>
How can I resolve this, please !!
You can use this primefaces component:
http://www.primefaces.org/showcase/ui/misc/resetInput.xhtml
Regarding dialogs in general: don't put them inside forms.
Have this instead: <p:dialog><h:form>...
Regarding update="" values, if your appendToBody is true, put a colon in front of the id (that means it`s in another form).
You should use the following code:
<h:commandButton value="Reset" style="margin-right:20px;">
<p:ajax update="registrationForm" resetValues="true" />
</h:commandButton>
Add resetValues="true" to your commandButton
<p:commandButton resetValues="true" action="#{departementBean.prepareDialog}" id="showDialogButton1" type="button" value="add" oncomplete="dlg1.show()" update=":dialogAjout"/>
modify you open button like this : open dialog in oncomplete and before that update it by adding its id to update attribute and add action method to do the server side logic to actually init the dialog fields (populate / reset)
<p:commandButton action="#{departementBean.prepareDialog}" id="showDialogButton1" type="button" value="add" oncomplete="dlg1.show()" update=":dialogAjout"/>
b.t.w it looks like your dialog located inside your form together with your opening button , this is a "bad practice" move your dialog away from that form and place a new form inside the dialog , e.g <p:dialog><h:form> ...
I solved this question thus
<p:dialog header="myDialog" widgetVar="dlg1" minHeight="40">
<h:outputLabel for="fild1" value="Fill the field" />
<p:password id="fild1" value="#{myBean.attribute}" required="false" label="Field" redisplay="false" /><br />
<p:commandButton action="#{myBean.method()}" value="Send" oncomplete="dlg1.hide()" update="field1" />
</p:dialog>
When I used the attribute update="field1" of p:commandButton.
The value of field p:password will empty after submitting the form.
I tried do the suggestion of Dani but my attribute going empty when I submitted my form and not stayed empty after submit