JSF - Problem with #ViewScope - jsf

I have a page that load (in a panelGroup) two different page, due to the login status (logged, not logged). This is the main switch :
template.xhtml P.S. selector.page is "homepage" as default
<h:panelGroup layout="block" styleClass="contenitore">
<h:panelGroup layout="block">
<h:panelGroup layout="block" styleClass="menu_table" id="login">
<ui:insert name="login_homepage" />
</h:panelGroup>
<h:panelGroup layout="block" id="content">
<c:catch>
<ui:include src="/#{selector.page}/#{selector.page}.xhtml" />
</c:catch>
</h:panelGroup>
</h:panelGroup>
</h:panelGroup>
homepage.xhtml
<h:panelGroup rendered="#{!user.loggedIn}">
<h:panelGroup layout="block" styleClass="content_title">
Homepage
</h:panelGroup>
</h:panelGroup>
<h:panelGroup rendered="#{user.loggedIn}">
<ui:include src="/profile/profile.xhtml" />
</h:panelGroup>
login
<ui:define name="login_homepage">
<h:form id="formLogin" prependId="false">
<h:inputHidden value="#{selector.page}" id="page" />
<h:panelGroup rendered="#{!user.loggedIn}">
<h:outputScript name="jsf.js" library="javax.faces" target="head" />
<h:outputLabel styleClass="menu_span" value="Username" />
<h:inputText value="#{user.nickname}" id="nickname" />
<h:outputLabel styleClass="menu_span" value="Password" />
<h:inputSecret value="#{user.password}" id="password" />
<h:outputLabel styleClass="menu_span">
<h:commandButton value="Login" action="#{user.checkLogin}">
<f:ajax event="action" execute="nickname password page" render=":login :content err"/>
</h:commandButton>
</h:outputLabel>
</h:panelGroup>
<h:panelGroup rendered="#{user.loggedIn}">
<h:outputLabel styleClass="menu_title" value="LOGGED" />
</h:panelGroup>
</h:form>
</ui:define>
profile.xhtml
<h:panelGroup layout="block" id="profileContent">
<h:form id="formProfile">
<h:outputScript name="jsf.js" library="javax.faces" target="head" />
<h:panelGroup rendered="#{profileSelector.profilePage=='main'}">
<ui:include src="/profile/profile_main.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{profileSelector.profilePage=='edit' || profileSelector.profilePage=='editConfirm'}">
<ui:include src="/profile/profile_edit.xhtml" />
</h:panelGroup>
</h:form>
</h:panelGroup>
ProfileSelector is #ViewScope scoped. When i load the page and im logged, it initialize the ProfileSelector bean. Else, if i'm not logged and i do the login, it change the Content from homepage to profile, but the Bean is not initalized. So, how can i inizialize this bean when im not logged?
I think the code above is sufficent to understand the problem.
Cheers

A similar bug
http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-928

<c:catch>
<ui:include src="/#{selector.page}/#{selector.page}.xhtml" />
</c:catch>
The problem is that you are using JSTL elements which break #ViewScope use alternative.

Related

JSF Form Validation

I am trying to persist a form in JSF page with many inputs. in parallel I added client side validation to process before entering to the actionLisner method.
The issus is that if I make the commandbutton inside <h:form> and outside <p:panel> the validation is OK but the action does not do anything (if all the fiels are validated). If I make the commandbutton inside <p:panel> the opposite happens, the validation does not work anymore and even if some fiels are empty, the method in actionListner is called.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<ui:composition template="/template.xhtml">
<ui:define name="title">
<h:outputText value="Entretien annuel - Personnel d'Agence">
</h:outputText>
</ui:define>
<ui:define name="body">
<div align="center">
<h:form id="CollaborateurViewForm">
<h:panelGroup id="display">
<p:panel header="Détails du Collaborateur">
<p:panelGrid columns="2" rendered="#{collaborateurController.selected !=
null}">
<h:outputText value="#{bundle.ViewCollaborateurLabel_idCollaborateur}"/>
<h:outputText value="#{collaborateurController.selected.idCollaborateur}"
title="#{bundle.ViewCollaborateurTitle_idCollaborateur}"/>
</p:panelGrid>
</p:panel>
</h:panelGroup>
</h:form>
</div>
<h:form id="testForm" >
<p:panel id="entretienFormPa" header="Entretien annuel - Personnel d'Agence">
<div align="center">
<p:panelGrid columns="2">
<p:panel header="Détails de l'entretien">
<p:outputLabel for="collaborateursItem" value="Entretien mené par :"/>
<p:selectManyMenu id="collaborateursItem" filter="true" filterMatchMode="contains"
showCheckbox="true"
value="#{entretienController.entretienMenePar}">
<p:ajax process="#this"/>
<f:selectItems id="entretienMenePar" value="#
{collaborateurController.itemsAvailableSelectMany}"
var="entretienMeneParItem"
itemValue="#{entretienMeneParItem}"/>
</p:selectManyMenu>
</p:panel>
</p:panelGrid>
<p:panel header="Saisie des notes de l'entretien">
<p:tabView>
<p:tab title="#{bundle.Personnel_Organisation_Commerciale}">
<h:panelGrid columns="2" cellpadding="10" cellspacing="10">
<p:outputLabel value="#
{bundle.Personnel_Organisation_Commerciale_Comprehension}" for="noteItem11"/>
<p:selectOneButton id="noteItem11" value="#
{entretienController.note11}"
required="true"
requiredMessage="#
{bundle.NoteEntretien_Requise}">
<f:selectItems value="#
{entretienController.listeNotesPossibles}"
var="noteItem"
itemValue="#{noteItem}"/>
<p:ajax process="#this"/>
</p:selectOneButton>
<p:outputLabel
value="#{bundle.Personnel_Organisation_Commerciale_Actions}" for="noteItem12"/>
<p:selectOneButton id="noteItem12" value="#
{entretienController.note12}"
required="true"
requiredMessage="#
{bundle.NoteEntretien_Requise}">
<f:selectItems value="#
{entretienController.listeNotesPossibles}"
var="noteItem"
itemValue="#{noteItem}"/>
<p:ajax process="#this"/>
</p:selectOneButton>
<p:outputLabel for="commentaireOrgaCom" value="Commentaire de suivi : " style="font-weight: bold"/>
<p:inputTextarea id="commentaireOrgaCom" value="#{entretienController.commentaireOrgaCom}"
rows="4" cols="50">
<p:ajax process="#this"/>
</p:inputTextarea>
</h:panelGrid>
</p:tab>
</p:tabView>
</p:panel>
<p:tabView>
<p:tab title="#{bundle.Da_Divers}">
<div align="center">
<p:outputLabel for="diagnosticItem" value="Diagnostic : " />
<p:inputTextarea id="diagnosticItem" value="#
{entretienController.diagItem}" rows="8" cols="67" required="true"
requiredMessage="#{bundle.Diagnostic_Requis}">
<p:ajax process="#this"/>
</p:inputTextarea>
</h:panelGrid>
</div>
</p:tab>
</p:tabView>
</div>
</p:panel>
<div align="right">
<p:commandButton id="saveEntretienButton" value="Enregistrer"
process="entretienFormPa" update="entretienFormPa" immediate="true"
actionListener="#
{noteEntretienController.saveEntretienActionPa(entretienController,
collaborateurController)}">
<p:confirm header="Confirmation" message="Etes-vous sûr de vouloir
enregistrer l'entretien ?" />
</p:commandButton>
<p:commandButton value="Retour" action="Details"
ajax="false" />
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade">
<p:commandButton value="Oui" type="button" styleClass="ui-confirmdialog-yes" />
<p:commandButton value="Non" type="button" styleClass="ui-confirmdialog-no" />
</p:confirmDialog>
</div>
</h:form>
</ui:define>
</ui:composition>
</html>
I also tried to add validateClient="true" on the commandButton
Thank in advance !
UPDATE :
I resolved the issue without knowing what was the source. I go back to the initial example given on primefaces showcase, I added my fields one by one. Know all is good

PrimeFaces nested form inside p:dialog with appendTo="#(body)

I have this fragment:
<h:form id="form">
<!-- other content -->
<p:panel id="panel" header="test">
<p:inputText id="input1" value="#{viewScope.prop1}" required="true" />
<p:commandButton id="button1" process="#form" update="#form #widgetVar(dialog)"
oncomplete="PF('dialog').show()" value="ok" />
</p:panel>
<!-- other content -->
</h:form>
<p:dialog id="dialog" header="dialog" widgetVar="dialog" modal="true">
<h:form id="form2">
<p:inputText id="input2" value="#{viewScope.prop1}" required="true" />
<p:commandButton id="button2" process="#form" update="#form" value="ok" />
</h:form>
</p:dialog>
and all is working as expected.
What I'd like to achieve is this:
<h:form id="form">
<!-- other content -->
<!-- fragment start -->
<!-- this fragment will be on its own file and included via ui:include (or inside composite component) -->
<p:panel id="panel" header="test">
<p:inputText id="input1" value="#{viewScope.prop1}" required="true" />
<p:commandButton id="button1" process="#form" update="#form #widgetVar(dialog)"
oncomplete="PF('dialog').show()" value="ok" />
</p:panel>
<p:dialog id="dialog" header="dialog" widgetVar="dialog" modal="true" appendTo="#(body)">
<h:form id="form2">
<p:inputText id="input2" value="#{viewScope.prop1}" required="true" />
<p:commandButton id="button2" process="#form" update="#form" value="ok" />
</h:form>
</p:dialog>
<!-- fragment end -->
<!-- other content -->
</h:form>
but I unsuccessfully tried some combination of process and update for button1 resulting in process anything... input1 is even resetting...
So, how to build a p:dialog that can be shipped inside a fragment or a composite comp and that is excluded from outside form?
Note that using:
<h:form id="form">
<!-- other content -->
<ui:include src="panel.xhtml" />
<!-- other content -->
</h:form>
<ui:include src="dialog.xhtml" />
is not an acceptable solution.
I'm on JSF 2.2.8 (mojarra) and PF 5.1
Finally, I found a way using OmniFaces, with <o:moveComponent /> :
page:
<h:form id="form">
<!-- other content -->
<ui:include src="/fragment/with/inner/form.xhtml" />
<!-- other content -->
</h:form>
fragment:
<ui:composition>
<p:inputText id="outerText" value="#{viewScope.text}" />
<p:commandButton id="openButton" process="#form" update="#widgetVar(testDialog)"
oncomplete="PF('testDialog').show()" value="open" />
<o:moveComponent id="move" for=":#{facesContext.viewRoot.clientId}" destination="ADD_LAST">
<h:form id="innerForm">
<p:dialog id="dialog" widgetVar="testDialog" header="test dialog">
<p:inputText id="innerText" value="#{viewScope.text}" />
<f:facet name="footer">
<p:commandButton id="confirmButton" process="#form" update=":form"
oncomplete="if(!args.validationFailed) PF('testDialog').hide()"
value="submit" />
</f:facet>
</p:dialog>
</h:form>
</o:moveComponent>
</ui:composition>
This will cause some warning:
WARNING Unable to save dynamic action with clientId 'form:innerForm:dialog' because the UIComponent cannot be found
WARNING Unable to save dynamic action with clientId 'form:innerForm:innerText' because the UIComponent cannot be found
WARNING Unable to save dynamic action with clientId 'form:innerForm:confirmButton' because the UIComponent cannot be found
because the restored components are not re-removed on subsequent RESTORE_VIEW for postback.
These warnings, as for my experiments, are harmless and could be safely ignored.
However I opened a pull request to eventually fix it.
Only use one form inside of dialog. Work fine for me.
<h:body>
<h:form id="OneFormId">
<!-- Some content -->
</h:form>
<p:dialog id="MyDialogId" header="My Header Info"
widgetVar="MyWidgetVarName" modal="true" appendTo="#(body)">
<h:form id="MyFormId">
<p:outputPanel>
<p:messages id="MyMsgId" autoUpdate="true" />
<h:panelGrid columns="2">
<h:outputLabel for="usr" value="User:" />
<p:inputText id="usr" value="#{MyManageBeanName.MyProperty}"
required="true" requiredMessage="User is required." />
</h:panelGrid>
<p:separator />
<h:panelGrid columns="2">
<p:commandButton value="Save" id="MyBtnSaveId"
styleClass="ui-priority-primary" icon="ui-icon-circle-check"
process="#form" />
<p:commandButton value="Cancel" id="MyBtnCancelId"
onclick="PF('MyWidgetVarName').hide()"
styleClass="ui-priority-primary" icon="ui-icon-close"
process="MyBtnCancelId" />
</h:panelGrid>
</p:outputPanel>
</h:form>
</p:dialog>
<h:form id="OtherFormId">
<!-- Some content -->
</h:form>

JSF datatable, tomahawk radio

I'm attempting to use a t:radio in my rich:datatable but it's always complaining about the fact that it can't find the component. I did some googling and I have to declare the full name, but I actually think I'm doing that.
Anyone can point me what I'm doing wrong? The code (I'm not going to give a minified version because I'm guessing it's going wrong with the compositions):
letterDetailTemplate.xhtml:
<h:form id="generateLetterForm">
<ui:include src="addStandardLetterMain.xhtml" />
<ui:include src="addStandardLetterText.xhtml" />
<ui:include src="buttons.xhtml" />
</h:form>
addStandardLetterText.xhtml (the radio button is over here, in the slrDataTable):
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:e="http://minfin.regondes2/entity"
xmlns:ccffdecorate="http://java.sun.com/jsf/composite/ccffdecorate"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:l="http://minfin.regondes2/layout"
xmlns:o="http://omnifaces.org/ui"
xmlns:t="http://myfaces.apache.org/tomahawk">
<ui:param name="entityBB" value="#{letterBB}" />
<ui:param name="type" value="Dossier.Letter" />
<l:screenzone id="addStandardLetterTextPanel"
title="#{AppMessages[type.concat('.addStandardLetterText.title')]}">
<h:outputStylesheet name="letterText.css" library="stylesheets" />
<h:outputScript name="letter.js" library="scripts" />
<a4j:region>
<a4j:outputPanel id="letterTextPanel">
<h:inputTextarea id="letterText" name="letterText"
value="#{entityBB.entity.text}" styleClass="letterText" />
<script type="text/javascript">
language: '#{screen.locale.language}'
CKEDITOR.replace( 'generateLetterForm:letterTex', {
});
</script>
</a4j:outputPanel>
<h:panelGroup styleClass="rButtonPanelAlignLeft" layout="block"
rendered="#{dossierContextBB.dossierContext == 'EDIT'}">
<a4j:commandButton
value="#{AppMessages[type.concat('.add.region')]}"
actionListener="#{entityBB.findAvailableRegionStandardLetters()}"
render="slrPopupFormPanel" limitRender="true" status="ajaxStatus"
onclick="LETTER.CKUpdate()"
oncomplete="#{rich:component('addStandardLetterRegion')}.show();" />
</h:panelGroup>
</a4j:region>
<rich:popupPanel id="addStandardLetterRegion" modal="true"
onmaskclick="#{rich:component('addStandardLetterRegion')}.hide()"
autosized="true">
<f:facet name="header">
<h:outputText
value="#{AppMessages['Dossier.Letter.StandardLetter.region.popup.title']}" />
        </f:facet>
<f:facet name="controls">
<h:outputLink value="#"
onclick="#{rich:component('addStandardLetterCentrum')}.hide(); return false;">
X
</h:outputLink>
</f:facet>
<a4j:outputPanel id="slrPopupFormPanel">
<t:selectOneRadio id="slrOption"
value="#{standardLetterBB.selected}" layout="spread"
converter="#{standardLetterBB.converter}">
<f:selectItems value="#{entityBB.availableStandardLetterText}"
var="standardLetter" itemLabel="" itemValue="#{standardLetter}" />
</t:selectOneRadio>
<rich:dataTable id="slrDataTable"
value="#{entityBB.availableStandardLetterText}"
var="standardLetter" noDataLabel="No standard letters found"
rowKeyVar="index">
<rich:column headerClass="ListTitle">
<t:radio for="generateLetterForm:slrDataTable:slrOption" index="#{index}" />
</rich:column>
<e:column entity="#{standardLetter.dossierType}" type="#{type}"
property="type" />
<e:column entity="#{standardLetter}" type="#{type}"
property="numbering" />
<e:columnTranslatable entity="#{standardLetter}" type="#{type}"
property="text" />
</rich:dataTable>
</a4j:outputPanel>
<div class="rButtonPanel">
<h:commandButton value="#{AppMessages['general.action.add']}">
<a4j:ajax event="click" execute="generateLetterForm"
listener="#{entityBB.addMotivationToReport}"
oncomplete="#{rich:component('addStandardLetterRegion')}.hide()"
render="reportMotivationTextPanel" limitRender="true" />
</h:commandButton>
<a4j:commandButton value="#{AppMessages['general.action.cancel']}"
onclick="#{rich:component('addStandardLetterRegion')}.hide()"
limitRender="true" immediate="true" bypassUpdates="true" />
</div>
</rich:popupPanel>
</l:screenzone>
Note that this view works and renders and displays the data from the backingbean when I remove the t:radio.
The errormessage I'm getting is:
SEVERE: java.lang.IllegalStateException: Could not find component 'generateLetterForm:slrDataTable:slrOption' (calling findComponent on component 'generateLetterForm:slrDataTable:0:j_idt258')
javax.faces.FacesException: java.lang.IllegalStateException: Could not find component 'generateLetterForm:slrDataTable:slrOption' (calling findComponent on component 'generateLetterForm:slrDataTable:0:j_idt258')
Change for="generateLetterForm:slrDataTable:slrOption" to for=":generateLetterForm:slrOption" and specify id for your t:radio in datatable also. Don't forget the ":" before generateLetterForm.

JSF2 - Primefaces - Partial update with command button not works when updating a nested panel

I’m trying to update a part of my page using the following command:
<p:commandButton id="bntNewAddress" immediate="true"
value="New Address" disabled="false" icon="ui-icon-document"
process="#this" update=":main_form:createPanelDetailsAddress"
action="#{issuerComponent.initAddNewAddress}">
</p:commandButton>
When I click the button, the panel "createPanelDetailsAddress" is not updated. On the other side when I use update=":main_form”, the panel is updated (but all other panels inside the main_form are updated also)
The panel I want to update is included in a panel named “createPanel”.
Could anyone have idea why update=":main_form:createPanelDetailsAddress" doesn't work in my case ?
I use primefaces3.5 and Mojarra JSF 2.1.7
Here is the code I used:
public String initAddNewAddress(){
renderCreatePanelDetailsAddress = true;
return null;
}
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui" template="/template.xhtml">
<ui:define name="content">
<h:form id="main_form">
<p:panel id="createPanel" rendered="true">
<p:messages id="msgCreate" />
<p:panel id="createPanelDetails"
header="#{issuerMsgs['issuer.createArea.title']}">
<h:panelGrid border="0" columns="6">
<h:outputText value="#{issuerMsgs['issuer.issuerCode.title']}:" />
<p:inputText required="true"
value="#{issuerComponent.updateIssuer.issuerCode}"
label="issuer_issuerCode">
</p:inputText>
<h:outputText value="#{issuerMsgs['issuer.description.title']}:" />
<p:inputText required="true"
value="#{issuerComponent.updateIssuer.description}"
label="issuer_description">
</p:inputText>
</h:panelGrid>
</p:panel>
<p:spacer height="10" />
<p:panel id="panelListAddress"
header="#{addressMsgs['address.createArea.title']}">
<p:dataTable id="addresslist" var="address"
value="#{issuerComponent.addressList}" paginator="false" rows="10">
<p:column>
<f:facet name="header">
<h:outputText value="#{addressMsgs['address.tel.title']}" />
</f:facet>
<h:outputText value="#{address.tel}" />
</p:column>
</p:dataTable>
<p:spacer height="22" width="0" />
<p:commandButton id="bntNewAddress" immediate="true"
value="New Address" disabled="false" icon="ui-icon-document"
process="#this" update=":main_form:createPanelDetailsAddress"
action="#{issuerComponent.initAddNewAddress}">
</p:commandButton>
</p:panel>
<p:panel id="createPanelDetailsAddress"
header="#{addressMsgs['address.createArea.title']}"
rendered="#{issuerComponent.renderCreatePanelDetailsAddress}">
<ui:include src="createAddress.xhtml"></ui:include>
<p:commandButton value="Add"
rendered="#{issuerComponent.renderBtnAddAddress}" disabled="false"
icon="ui-icon-document" process="#this,createPanelDetailsAddress"
update=":main_form" action="#{issuerComponent.addNewAddress}"
actionListener="#{addressComponent.addNewComposite}">
<f:setPropertyActionListener
value="#{addressComponent.updateAddress}"
target="#{issuerComponent.address}" />
</p:commandButton>
</p:panel>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
Your update will fail because
rendered="#{issuerComponent.renderCreatePanelDetailsAddress}"
will evaluate to false the first time the view is rendered. As a result the component is not in the DOM tree the first time the view is rendered.
Ajax updates work by locating a specific component (by id) in the DOM and replacing it with new markup. Your panel was never in the DOM to begin with, so there's nothing to update with ajax.
To remedy, you need to wrap the <p:panel/>with another component and make that component the target of your ajax update
<p:outputPanel id="container" layout="none">
<p:panel id="createPanelDetailsAddress" header="# addressMsgs['address.createArea.title']}" rendered="#issuerComponent.renderCreatePanelDetailsAddress}">
<ui:include src="createAddress.xhtml"></ui:include>
<p:commandButton value="Add"
rendered="#{issuerComponent.renderBtnAddAddress}" disabled="false"
icon="ui-icon-document" process="#this,createPanelDetailsAddress"
update=":main_form" action="#{issuerComponent.addNewAddress}"
actionListener="#{addressComponent.addNewComposite}">
<f:setPropertyActionListener
value="#{addressComponent.updateAddress}"
target="#{issuerComponent.address}" />
</p:commandButton>
</p:panel>
</p:outputPanel>

PrimeFaces button in Tab Doesn't Navigate

I'm developing this project using JSF 2.0, NetBeans 6.9.1, GlassFish 3.1, Mojarra 2.0.3, and PrimeFaces 2.2-RC2.
My question is similar to this question, but even though I was able to make one of my buttons work, the other one does not. Here's my situation: I have a dataTable with a column containing two links, one to edit line data, one to view line data. Clicking either the "Edit" or "View" link takes you to a detail page with <h:panelGrid> components inside <p:tabView> components. My detail page has two <p:tabView> components, one for editing, one for just viewing data. Which one you see depends on the <c:if> statements. The button in the first <p:tabView> on the page (by that I mean first working your way down from the top) works as I would like it to, this happens to be the "Edit" component. The button in the other <p:tabView> does not work. I set up break points and went through the debugger, the second button doesn't seem to fire an ActionEvent regardless of what I try. Here's my code for the page:
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="id" value="#{userDetailBean.selectedUserId}" />
<f:viewParam name="action" value="#{userDetailBean.view}" />
</f:metadata>
</ui:define>
<ui:define name="main_base_content_top">
<h:form>
<p:toolbar>
<p:toolbarGroup align="left">
<h:commandButton value="Return to User List" action="user_grid" />
</p:toolbarGroup>
</p:toolbar>
</h:form>
</ui:define>
<ui:define name="main_base_content">
<c:if test="#{empty userDetailBean.view}">
<h:form>
<table align="center">
<tr>
<td>
<p:tabView>
<p:tab title="#{msgs.UserDetailTabTitle}">
<h:panelGrid columns="4">
<h:outputLabel value="#{msgs.UserDetailFirstName}" for="fname" />
<h:inputText id="fname" value="#{userDetailBean.firstName}" />
<h:outputLabel value="#{msgs.UserDetailJobTitle}" for="jtitle" />
<h:inputText id="jtitle" value="#{userDetailBean.jobTitle}" />
<h:outputLabel value="#{msgs.UserDetailLastName}" for="lname" />
<h:inputText id="lname" value="#{userDetailBean.lastName}" />
<h:outputLabel value="#{msgs.UserDetailEmployeeId}" for="empid" />
<h:inputText id="empid" value="#{userDetailBean.id}" />
<h:outputLabel value="#{msgs.UserDetailDateOfHire}" for="doh" />
<h:inputText id="doh" value="#{userDetailBean.DOH}" />
<h:outputLabel value="#{msgs.UserDetailLocation}" for="location" />
<h:inputText id="location" value="#{userDetailBean.location}" />
<h:outputLabel value="#{msgs.UserDetailStatus}" for="status" />
<h:inputText id="status" value="#{userDetailBean.status}" />
<h:inputHidden /> <h:inputHidden /> <h:inputHidden /> <h:inputHidden /> <h:inputHidden />
<h:outputLabel value="#{msgs.UserDetailComments}" for="comments" />
<h:inputTextarea id="comments" value="#{userDetailBean.comments}" />
<h:inputHidden />
<p:commandButton ajax="false" action="#{userDetailBean.submitChanges()}" value="Submit Changes" />
</h:panelGrid>
</p:tab>
</p:tabView>
</td>
</tr>
</table>
</h:form>
</c:if>
<c:if test="#{! empty userDetailBean.view}">
<h:form>
<table align="center">
<tr>
<td>
<p:tabView>
<p:tab title="#{msgs.UserDetailViewTabTitle}">
<h:panelGrid columns="4">
<h:outputLabel value="#{msgs.UserDetailFirstName}" for="fname" />
<h:outputText id="fname" value="#{userGridBean.selectedUser.firstName}" />
<h:outputLabel value="#{msgs.UserDetailJobTitle}" for="jtitle" />
<h:outputText id="jtitle" value="#{userGridBean.selectedUser.jobTitle}" />
<h:outputLabel value="#{msgs.UserDetailLastName}" for="lname" />
<h:outputText id="lname" value="#{userGridBean.selectedUser.lastName}" />
<h:outputLabel value="#{msgs.UserDetailEmployeeId}" for="empid" />
<h:outputText id="empid" value="#{userGridBean.selectedUser.id}" />
<h:outputLabel value="#{msgs.UserDetailDateOfHire}" for="doh" />
<h:outputText id="doh" value="#{userGridBean.selectedUser.DOH}" />
<h:outputLabel value="#{msgs.UserDetailLocation}" for="location" />
<h:outputText id="location" value="#{userGridBean.selectedUser.location}" />
<h:outputLabel value="#{msgs.UserDetailStatus}" for="status" />
<h:outputText id="status" value="#{userGridBean.selectedUser.status}" />
<h:inputHidden /> <h:inputHidden /> <h:inputHidden /> <h:inputHidden /> <h:inputHidden />
<h:outputLabel value="#{msgs.UserDetailComments}" for="comments" />
<h:outputText id="comments" value="#{userGridBean.selectedUser.comments}" />
<h:inputHidden /> <h:inputHidden /> <h:inputHidden />
<p:commandButton onclick="submit()" ajax="false" action="#{userDetailBean.navigation()}" value="Retur to User Grid" />
</h:panelGrid>
</p:tab>
</p:tabView>
</td>
</tr>
</table>
</h:form>
</c:if>
</ui:define>
</ui:composition>
</body>
I've tried everything I can think of for the second button: ajax="false"; onclick="submit()"; ajax="false" onclick="submit"; I've tried implicit navigation with a redirect as well as a navigation rule with a redirect. The action methods userDetailBean.submitChanges() and userDetailBean.navigate() both return the same string, which corresponds to a navigation rule in my faces-config file. The submitChanges method gets called, but my navigate method does not. I'm not filling the fields with any data at this point, I'm just trying to get the basic navigation to work. Why isn't my commandButton on the second tabView working?
Another reason that a commandbutton isn't been invoked is that the rendered attribute of the button or one of its parents evaluated false during apply request values phase of the form submit.
You have actually none, but those <c:if> tags does similar thing, only during view build time instead of view render time. The view params are not applied during building the view, but only thereafter. That's exactly why #{userDetailBean.view} is always empty.
I have never used such a construct with <c:if>, but I've had similar views like this where this all just works with a #ViewScoped bean where the rendering property is been applied on a fullworthy JSF component instead of <c:if>.
As first step, get rid of <c:if>s and move their tests into rendered attribute of the <h:form>s they are wrapping:
<h:form rendered="#{empty userDetailBean.view}">
...
</h:form>
<h:form rendered="#{not empty userDetailBean.view}">
...
</h:form>
If in vain (I guess that this will fail because you aren't using ajax and the viewparams are not preserved) and the bean is indeed #RequestScoped, then you need to mark it #ViewScoped to preserve the rendering conditions.
Related questions:
JSF h:commandLink is not being invoked
Unrelated to the problem, I'd rather use <h:panelGroup /> instead of <h:inputHidden /> to "fill" the empty cells of the table. They are cheaper to encode and decode and also ends in better HTML.

Resources