header containing h:link and h:commandLink wont work? - jsf-2

I have this weird situation. I have a jsf 2.0 application, with template pages.
on the header I have some links with h:link to keep the url bookmarkability and h:commandLink that I use to signin and signout.. the problem is when I navigate to a specific page via h:link
let say the url become bla.jsf?uName=dino then once I'm in bla.jsf?uName=dino I click the signout button that should take me to signout.jsf wont work. in stead, it takes me to bla.jsf page without ?uName=dino.
I have no nested h:form and everything seems normal to me. is there any suggestion why its behaving like this ?
I'm sure you are asking if I have h:form on h:commandLink. yes I do have that too.here is my code:
<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:p="http://primefaces.prime.com.tr/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<div class="floatRight">
<h:form id="firstFormHeader" prependId="false">
<p:autoComplete id="searchInputId" size="40" style="z-index: 20;" value="#{autoComplete.text}" completeMethod="#{autoComplete.complete}"/>
<h:commandButton value="#{label.search}" action="#{autoComplete.getSearchedVideo}" />
<p:watermark for="searchInputId" value="#{label.search}" />
</h:form>
</div>
<div style="z-index: 1;" id="topsection">
<div style="position:relative; bottom:-51px;">
<div id="menu" style="height:37px;" class="title ui-widget-header">
<h:panelGrid border="0" columns="2" style="float: left;">
<h:column>
<h:panelGrid columns="2">
<h:column>
<h:form id="secondFormHeader" prependId="false" >
<h:selectOneMenu id="videoGenereHeaderId" value="#{homePageVideoLoader.videoCategory}" required="true" onchange="submit()" valueChangeListener="#{homePageVideoLoader.getSelectedCatagoryList}">
<f:selectItem id="item0" itemLabel="#{select.category}" itemValue="" />
<f:selectItem id="item1" itemLabel="#{select.animation}" itemValue="23" />
<f:selectItem id="item2" itemLabel="#{select.autos}" itemValue="15" />
<f:selectItem id="item3" itemLabel="#{select.comedy}" itemValue="10" />
<f:selectItem id="item4" itemLabel="#{select.documentary}" itemValue="19" />
<f:selectItem id="item5" itemLabel="#{select.drama}" itemValue="4" />
<f:selectItem id="item6" itemLabel="#{select.education}" itemValue="16" />
<f:selectItem id="item7" itemLabel="#{select.hiphop}" itemValue="5" />
<f:selectItem id="item8" itemLabel="#{select.guragigna}" itemValue="12" />
<f:selectItem id="item9" itemLabel="#{select.news}" itemValue="6" />
<f:selectItem id="item10" itemLabel="#{select.oldies}" itemValue="7" />
<f:selectItem id="item11" itemLabel="#{select.reggae}" itemValue="8" />
<f:selectItem id="item12" itemLabel="#{select.harari}" itemValue="13" />
<f:selectItem id="item13" itemLabel="#{select.oromigna}}" itemValue="14" />
<!-- <f:selectItem id="item7" itemLabel="#{select.entertainment}" itemValue="ent" />
<f:selectItem id="item8" itemLabel="#{select.gaming}" itemValue="gam" />
<f:selectItem id="item9" itemLabel="#{select.health}" itemValue="hea" />
<f:selectItem id="item10" itemLabel="#{select.howto}" itemValue="how" /> -->
<f:selectItem id="item14" itemLabel="#{select.music}" itemValue="3" />
<f:selectItem id="item15" itemLabel="#{select.politics}" itemValue="18" />
<!-- <f:selectItem id="item13" itemLabel="#{select.nonprofit}" itemValue="non" />
<f:selectItem id="item14" itemLabel="#{select.blog}" itemValue="blo" />
<f:selectItem id="item15" itemLabel="#{select.animals}" itemValue="anm" />
<f:selectItem id="item16" itemLabel="#{select.science}" itemValue="sci" />
<f:selectItem id="item17" itemLabel="#{select.sport}" itemValue="spo" />
<f:selectItem id="item18" itemLabel="#{select.travel}" itemValue="tra" /> -->
</h:selectOneMenu>
</h:form>
</h:column>
<h:column>
<h:outputText rendered="#{userAuthentication.userLogged and userAuthentication.user.usersValid}" value="#{label.hello} "/>
<h:link rendered="#{userAuthentication.userLogged and userAuthentication.user.usersValid}" value="#{userAuthentication.user.usersFirst}" outcome="userhome?uName=#{userAuthentication.user.usersUname}">
</h:link>
</h:column>
</h:panelGrid>
</h:column>
</h:panelGrid>
<h:panelGrid border="0" columns="2" styleClass="menuPostion">
<h:column>
<h:link outcome="home" value="#{label.home}" /> |
<h:link outcome="upload" value="#{label.upload}" /> |
<h:form id="thridFormHeader" prependId="false" >
<h:commandLink rendered="#{userAuthentication.userLogged}" value="#{label.signout}" action="#{userAuthentication.doSignOut}" immediate="true"/>
</h:form>
<h:link rendered="#{!userAuthentication.userLogged}" value="#{label.createAccount}" outcome="registration" />
<h:outputText rendered="#{!userAuthentication.userLogged}" value=" | "/>
<h:link rendered="#{!userAuthentication.userLogged}" value="#{label.signin}" outcome="signin" />
</h:column>
<h:column>
<h:form prependId="false" id="languageForm">
<h:selectOneMenu value="#{language.localeCode}" onchange="submit()"
valueChangeListener="#{language.countryLocaleCodeChanged}">
<f:selectItems value="#{language.countriesInMap}" />
</h:selectOneMenu>
</h:form>
</h:column>
</h:panelGrid>
</div>
</div>
</div>
</ui:composition>
The second <h:form> is the one that does not work.
Update: sorry is not working. it is not even going to doSignOut method..
once I reach the page bla.jsf?uName=dino
and see the source code regarding the signout link it shows me
<form id="j_idt31" enctype="application/x-www-form-urlencoded" action="/myapp/content/bla.jsf" method="post" name="j_idt31" target="">
...
and obviously bla.jsf gives me error message because it's waiting for uName to have a value.
why it is doing so? is it a bug ?
Also, you might have noticed that I have h:selectOneMenu that send data to the bean when the value changes, but once I'm on bla.jsf?uName=dino and try to change the value of h:selectOneMenu it wont work for it does not redirected to the bean for some reason so is h:commandLink yet h:link(s) work fine.. how can I can resolve it BalusC.. Thank you so much for taking the time and answering by the way

The <h:commandLink> is nested inside a <h:form> whose HTML-generated <form action> URL defaults to the current request URL. It's basically a link which uses JavaScript to submit that form. As the form's action defaults to the current request URL, you don't see a change in the request URL. Technically, it's working perfectly fine.
If you want to change the request URL after submit, then you need to send a redirect. You can do that by adding faces-redirect=true parameter to the outcome value:
public String doSignOut() {
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "signout?faces-redirect=true";
}
Or when you're still using the old fashioned <navigation-case> in faces-config.xml, then you need to add a <redirect /> entry.

with the help of great BalusC I was able to find my solution. my code was not working because it was menubar so every time the page changes the header or the menubar stay the same which means the form wont be changed.
I do not know why but rather than using h:link I used h:commandLink with combination of f:setPropertyActionListener to send the uName, then on the server side I did this
public String goToUserHomePage(){
methodNM = CLASS_NAME+".goToUserHomePage()";
log.info("in " + methodNM);
System.out.println("in " + methodNM);
System.out.println("in " + methodNM+"-------------------------"+user.getUsersUname());
return "userhome?uName="+user.getUsersUname()+"&faces-redirect=true";
}
by doing so every links whether with h:commandLink or h:link works fine

Related

Updates not reflected back on form submission

I am using primefaces.
In the java side, I have a modelView. ModelView has a list of modules. Each module has a list of variables.
.
.
.
<h:form id="DynamicWebPageForm">
<p:growl id="msgs" showDetail="true" />
<h3>Dynamic Loading with Accordion Panel</h3>
<p:outputLabel for="selectModule" value="Select Module: " />
<p:selectOneMenu id="selectModule" value="#{modelView.selectModel}">
<p:ajax listener="#{modelView.onModelChange}" update="modulesAP" />
<f:selectItems value="#{modelView.modelselectItems}" />
</p:selectOneMenu>
<p:accordionPanel id="modulesAP" multiple="true" value="#{modelView.modules}" var="v1">
<p:tab id = "modulesTab" title="#{v1.name}: Rating - #{v1.rating}">
<p:dataTable styleClass="borderless" value="#{v1.moduleVariables}" var="c1">
<p:column>
<p:row>
<p:panelGrid columns="2" styleClass="borderlessPanelGrid">
<h:outputLabel styles="50%" value="#{c1.name}" />
<p:inputText styles="50%" value="#{c1.value}" />
</p:panelGrid>
</p:row>
</p:column>
</p:dataTable>
<p:commandButton value="Submit" update=":DynamicWebPageForm:msgs modulesTab modulesAP" actionListener="#{modelView.saveData}" process = ":DynamicWebPageForm" />
</p:tab>
</p:accordionPanel>
</h:form>
Any update in the inputText is not getting reflected back on form submission. What could be the issue?
Set cache="false" (and maybe dynamic="true") on your <p:accordionaPanel/>
The accordionPanel defaults to cache="true" (can't understand why), which would explain why you're seeing stale values

Primefaces dialog + commandButton

I'm trying to use primefaces <p:dialog> combined with <p:commandButton>. In my .xhtml page I have a picklist and commandButton which is used to show a dialog. Dialog displays datatable with target values from picklist. Dialog has two buttons: cancel and submit. My problem is that submit button is not fired. What's strange, commandButton out of dialog works.
Here's my .xhtml:
<body>
<ui:composition template="./../resources/mainTemplate.xhtml">
<ui:define name="content">
<h:form>
<p:dialog id="dlg" header="#{messages.chooseSkillLevel}" widgetVar="dlg" modal="true" dynamic="true">
<h:dataTable value="#{editSkills.skillsAndLevels}" var="skillslevel">
<h:column>
#{skillslevel.skill.umiejetnosc}
</h:column>
<h:column>
<p:selectOneMenu value="#{skillslevel.level}" >
<f:selectItems value="#{editSkills.levels}" var="level" itemLabel="#{level.stopien}" itemValue="#{level.id}" />
</p:selectOneMenu>
</h:column>
</h:dataTable>
<p:commandButton value="#{messages.confirm}" action="#{editSkills.showSkillsAndLevels}" oncomplete="dlg.hide();" /> THIS BUTTON IS NOT FIRED
<p:commandButton value="#{messages.cancel}" onclick="dlg.hide()"/>
</p:dialog>
<p:pickList value="#{editSkills.skills}" var="skill" effect="none"
itemValue="#{skill.id}" itemLabel="#{skill.umiejetnosc}"
showSourceFilter="true" showTargetFilter="true" filterMatchMode="contains"
addLabel="#{messages.add}" removeLabel="#{messages.remove}" removeAllLabel="#{messages.removeAll}" >
<f:facet name="sourceCaption">#{messages.skillsList}</f:facet>
<f:facet name="targetCaption">#{messages.yourSkills}</f:facet>
<p:ajax event="transfer" listener="#{editSkills.onTransfer}" />
<p:column style="width:100%;">
#{skill.umiejetnosc}
</p:column>
</p:pickList>
<p:commandButton value="#{messages.confirm}" action="#{editSkills.afterSubmit}" update="dlg" oncomplete="dlg.show()" /> THIS BUTTON WORKS FINE
<p:commandButton value="#{messages.cancel}" action="profile" immediate="true"/>
</h:form>
</ui:define>
</ui:composition>
</body>
I've marked working button and not working one.
What do I have to do to make it working?
You can try either of the following , I vote number one, it's a cleaner design IMO
Bring the <p:dialog/> outside of the general <h:form/> and put an <h:form/> inside it instead
<p:dialog id="dlg" header="#{messages.chooseSkillLevel}" widgetVar="dlg" modal="true" dynamic="true">
<h:form>
<h:dataTable value="#{editSkills.skillsAndLevels}" var="skillslevel">
<h:column>
#{skillslevel.skill.umiejetnosc}
</h:column>
<h:column>
<p:selectOneMenu value="#{skillslevel.level}" >
<f:selectItems value="#{editSkills.levels}" var="level" itemLabel="#{level.stopien}" itemValue="#{level.id}" />
</p:selectOneMenu>
</h:column>
</h:dataTable>
<p:commandButton value="#{messages.confirm}" action="#{editSkills.showSkillsAndLevels}" oncomplete="dlg.hide();" /> THIS BUTTON IS NOT FIRED
<p:commandButton value="#{messages.cancel}" onclick="dlg.hide()"/>
</h:form>
</p:dialog>
Add appendToBody="false" to the <p:dialog/> to ensure the dialog is rendered within the html form in the DOM instead of being auto-relocated to end of HTML body. But this may cause inconsistent rendering in various browsers.
<p:commandButton value="Cancel" oncomplete="PF('yourDialogWidgedVarName').hide();" process="#this" />
Make sure to use ' when u call the widgetVar name. You can also use immediate="true" or process="#this".

Show/hide JSF2 form using <p:selectBooleanButton>

I need to show and hide component in my JSF 2-PrimeFaces application, please find my code below for the same:
<p:outputLabel for="online_offer" value="Online offer#{msg._question_mark}" styleClass="font-size-1em font-weight-bold input-panel-main" />
<p:panel>
<h:panelGrid columns="1">
<p:selectBooleanButton id="online_offer" value="#{QckPstBen.offer.isExpired}" onLabel="Yes" offLabel="No" onIcon="ui-icon-check" offIcon="ui-icon-close" >
<f:ajax event="click" render="#form" />
</p:selectBooleanButton>
</h:panelGrid>
</p:panel>
<h:outputLabel value=" " />
<h:panelGroup rendered="#{QckPstBen.offer.isExpired}">
<p:outputLabel for="website" value="Website/link to the offer#{msg._colon}" styleClass="font-size-1em font-weight-bold input-panel-main" />
<p:panel>
<h:panelGrid columns="1">
<p:inputText id="website" required="true" size="38" />
<p:watermark for="website" value="www.discountbox.in" />
</h:panelGrid>
</p:panel>
</h:panelGroup>
But it doesnt work, any clue
PrimeFaces components doesn't support <f:ajax>. Use <p:ajax> instead.
<p:selectBooleanButton ...>
<p:ajax update="#form" />
</p:selectBooleanButton>
Note that I omitted the event attribute, it defaults here to click already.
Place rendered on children of <h:panelGroup> instead or place a container of some sort around it, for example p:panel.
This may be OBE by now but...
When referencing the page bean, don't I recall in the #{} context, the convention of using lowercase for class names and method/attributes of the page bean (i.e. not #{QckPstBen.offer.isExpired} but #{qckPstBen.offer.isExpired}?

facesContext.validationFailed is coming back null

For what reason facesContext.validationFailed could be null? (in a postBack where there are errors..)
I had to resort to an ugly if (#{fn:containsIgnoreCase(facesContext.maximumSeverity,'ERROR')}) showSecurePopup('confirm'); because facesContext.validationFailed is coming back null..
the test code is:
<h:form>
<h:messages />
<br></br>
<h:outputText value="Validation failed: #{facesContext.validationFailed}" />
<br></br>
<h:outputLabel for="field1" value="Test Field" />
<br></br>
<h:inputText required="true" />
<h:commandButton action="#{contactBacking.submitComment}" value="Submit"
<f:ajax render="#form" execute="#form" />
</h:commandButton>
</h:form>
EDIT: Edited as per #BalusC's answer.. and took screenshot of result:
The FacesContext#isValidationFailed() returns a boolean which is never null. Just get rid of that nonsensicial nullcheck.
<h:outputText value="Validation failed: #{facesContext.validationFailed}" />

JSF form value change does not work

I have a form with 4 fields (2 dates, 2 selectOne).
My Bean is SessionScoped.
When I change the values in the form once, and click on submit, the applications works fine.
But when I want to change the values in form again, nothing happens. no change nor execution.
My Form looks like:
<ui:define name="sidebar">
<p:panel header="Select Values">
<h:form id="graphform">
<p:growl id="msg" />
<p:panelGrid columns="1">
<h:outputLabel for="servervalue" value="Servervalue: " />
<p:selectOneMenu value="#{graph.servervalue }" id="servervalue">
<f:selectItems value="#{formconst.SERVERVALUES}" />
</p:selectOneMenu>
<h:outputLabel for="startdate" value="Startdate: " />
<p:calendar disabledWeekends="false" size="10" pattern="dd.MM.yyyy"
showOtherMonths="true" maxlength="10"
mindate="#{formconst.MINDATE }" maxdate="#{formconst.MAXDATE}"
showButtonPanel="true" navigator="true" readOnlyInputText="true"
id="startdate" value="#{graph.startdate }" showOn="button"
required="true" />
<h:outputLabel for="enddate" value="Enddate: " />
<p:calendar disabledWeekends="false" size="10" pattern="dd.MM.yyyy"
showOtherMonths="true" maxlength="10"
mindate="#{formconst.MINDATE }" maxdate="#{formconst.MAXDATE }"
showButtonPanel="true" navigator="true" readOnlyInputText="true"
id="enddate" value="#{graph.enddate }" showOn="button"
required="true" />
<h:outputLabel for="filter" value="Filter: " />
<p:selectOneMenu value="#{graph.filter }" id="filter">
<f:selectItems value="#{formconst.GENERALFILTER}" />
</p:selectOneMenu>
</p:panelGrid>
<p:separator />
<p:panelGrid columns="2">
<p:commandButton value="Submit" update="#all"
action="#{ graph.updateChart }" />
<p:commandButton value="Reset" update="#all"
action="#{ graph.resetChart }" />
</p:panelGrid>
</h:form>
</p:panel>
</ui:define>
<ui:define name="content">
<h:form id="linechart">
<p:lineChart value="#{graph.cartesianChartBean.chartmodel }"
enhancedLegend="true" legendPosition="nw" xaxisAngle="50" />
</h:form>
</ui:define>
The same happens when I change SessionScoped to ViewScoped or RequestScoped.
I can change the values only one time.
I use primefaces 3.2 with apache myFaces 2.0.2 on WebSphere Application Server 8.0
Best Regards Veote

Resources