jsf composite component with h:link outcome navigation could not be matched - jsf-2

I want to rewrite part of the code using composite component.
I need to instead this:
<ui:fragment rendered="#{!empty param.vid}">
<h:link outcome="index" value="#{msgs.vendor_tabmenu_profile}"
styleClass="#{(param.pg == 'profile') ? 'selected' : ''}">
<f:param name="pg" value="profile"/>
<f:param name="vid" value="#{param.vid}"/>
</h:link>
<h:link outcome="index" value="#{msgs.vendor_tabmenu_orders}"
styleClass="#{(param.pg == 'orders') ? 'selected' : ''}">
<f:param name="pg" value="orders"/>
<f:param name="vid" value="#{param.vid}"/>
</h:link>
....
somethink like this:
<components:vmtab outPage="index"
value="#{msgs.vendor_tabmenu_search}"
withParam="false"
pg=""
vid=""
selectedClass="#{( (empty param.pg) ||
(param.pg == 'search') ||
(param.pg == 'index') ) ? 'selected' : ''}"
/>
with:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="outPage" required="true"/>
<composite:attribute name="withParam" required="true"/>
<composite:attribute name="pg" required="true"/>
<composite:attribute name="vid" required="true"/>
<composite:attribute name="value" required="true"/>
<composite:attribute name="selectedClass" />
<composite:attribute name="styleClass" />
</composite:interface>
<composite:implementation>
<h:link
outcome="#{composite.attrs.outPage}"
value="#{composite.attrs.value}"
styleClass="#{''.concat((!empty composite.attrs.styleClass ? composite.attrs.styleClass : '')).concat(
(!empty composite.attrs.selectedClass ? composite.attrs.selectedClass : ''))}"
>
<f:param name="pg" value="#{composite.attrs.pg}"
rendered="#{composite.attrs.withParam}"/>
<f:param name="vid" value="#{composite.attrs.vid}"
rendered="#{composite.attrs.withParam}"/>
</h:link>
</composite:implementation>
</html>
But i have a trouble. JSF says me:
This link is disabled because a navigation case could not be matched
Please explain what I'm doing wrong.
UPD:
Thanks for your attention. Sorry. Found the problem. The root of evil, as often happens, inattention. I thought that if I wrote in XML composite namespace I had to use it. But the EL is used object named cc.
PS: I dont know how to close or delete.. or what should I do with this question ?

Related

pass method through ui:include to custom component

I have 3 files:
main.xhtml
<ui:include src="included.xhtml">
<ui:param name="bean" value="#{invoices}" />
<ui:param name="method" value="initExchange" />
</ui:include>
included.xhtml
<s:compositeComponent bean="#{bean}" beanMethod="#{method}"
buttonActionListener="#{bean[method]()}" />
compositeComponent.xhtml
<cc:interface>
<cc:attribute name="bean" />
<cc:attribute name="beanMethod" />
<cc:attribute name="buttonActionListener" method-signature="void f()" />
</cc:interface>
<cc:implementation>
<h:outputText value="#{cc.attrs.bean}" />
<h:outputText value="#{cc.attrs.beanMethod}" />
<p:commandButton actionListener="#{cc.attrs.buttonActionListener}" />
h:outputTexts are OK. But clicking on button gives exception:
Target Unreachable, identifier 'bean' resolved to null
How to pass the method to button's actionListener?
It works when actionListener in composite component is written as bean[method] like in included.xhtml:
<p:commandButton actionListener="#{cc.attrs.bean[cc.attrs.beanMethod]}" />
So generally passing method attributes through multiple stages should always be done by separate bean and method rather then one attribute with 'method-signature'.

JSF: Update and add new request params

I have a page with the following params:
<f:metadata>
<f:event type="preRenderView" listener="#{busquedaBean.init}" />
<f:viewParam name="k" value="#{busquedaBean.keyword}" />
<f:viewParam name="categoryId" value="#{busquedaBean.categoryId}" />
<f:viewParam name="minprice" value="#{busquedaBean.minPrice}" />
<f:viewParam name="maxprice" value="#{busquedaBean.maxPrice}" />
</f:metadata>
All of them are optional. I need to do 2 things, which I wasn't able to do so far:
1) Add new params (keeping the previous params). This is what I tried for adding price params:
<h:outputText value="Precio diario" />
<o:form includeRequestParams="true">
<h:outputText value="min: " />
<p:inputText id="min" value="#{busquedaBean.minPrice}" />
<h:outputText value="max: " />
<p:inputText id="max" value="#{busquedaBean.maxPrice}" />
<p:commandButton icon="ui-icon-search" ajax="false">
<f:param name="minprice" value="#{busquedaBean.minPrice}" />
<f:param name="maxprice" value="#{busquedaBean.maxPrice}" />
</p:commandButton>
</o:form>
This basically works but the problem is that the URL is not updated. if the params in the URL were ?minprice=10&maxprice=200 and I update those values, the url remains the same. if these params were not included in the url, they won't be added and the filter won't work.
2) Updating the value of a param:
When categoryId is not empty, I want to show a button that will clear this param. This is what I tried:
<p:button outcome="/busqueda" includeViewParams="true" >
<f:param name="categoryId=" value="" />
</p:button>
But this button makes a GET to this URL: /busqueda/?categoryId=%3D&categoryId=1
The categoryId param appears twice. How can I just update the existing param?
I'm using MyFaces 2.1.14, Tomcat 7, Primefaces 4.0, Omnifaces
Thanks!
I was looking at this in the wrong way. includeViewParams=true will make the request include all the params declared in f:metadata with the current values. if such value is null, then the parameter is not included.
So.. to add price params:
<h:form >
<h:outputText value="$ " />
<p:inputText id="min" value="#{busquedaBean.minPrice}"/>
<h:outputText value=" a $ " />
<p:inputText id="max" value="#{busquedaBean.maxPrice}"/>
<p:commandButton icon="ui-icon-search" ajax="false" action="/busqueda?faces-redirect=true&includeViewParams=true" />
</h:form>
And to remove a param:
<p:commandButton action="#{busquedaBean.removeCategory}" ajax="false" icon="ui-icon-close" />
In the backing bean:
public String removeCategory() {
categoryId = null;
return "/busqueda?faces-redirect=true&includeViewParams=true";
}

Show dialog when the input data is validated <p:confirmDialog> [duplicate]

This question already has an answer here:
How to display dialog only on complete of a successful form submit
(1 answer)
Closed 6 years ago.
For my school project I have to realize a mini website where I use primefaces framework. In a form I want after pressing the Save button two things:
1 - Validate the data entered. that's why I put
<p:message for="date" /> and <p:message for="zone" />
As the values ​​are not correct, the dialog box should not be displayed.
2 - When all data is correct, and I click Save, I want to display my dialog box.
Now I can not. Can you help me? I use version 4 primefaces.
<h:form>
<p:panel id="panel" header="Create" style="margin-bottom:10px;border-color:blueviolet" >
<p:messages id="messages" />
<h:panelGrid columns="3">
<h:outputLabel for="date" value="Date : *" />
<p:calendar locale="fr" id="date" value="#{newBusinessCtrl.exercice.debut}" required="true" label="date" showButtonPanel="true"/>
<p:message for="date" />
<h:outputLabel for="zone" value="Zone Monétaire: *" />
<p:selectOneMenu id="zone" value="#{newBusinessCtrl.exercice.zoneChoice}" >
<f:selectItem itemLabel="Choice " itemValue="" />
<f:selectItems value="#{newBusinessCtrl.exercice.zones}" var="azone"
itemLabel="#{azone}" itemValue="#{azone}" >
</f:selectItems>
<p:message for="zone" />
</p:selectOneMenu>
<p:message for="zone" />
</h:panelGrid>
</p:panel>
<p:commandButton update="panel" value="Save" icon="ui-icon-check" style="color:blueviolet" onclick="choice.show()"/>
<p:confirmDialog message="Would you like to create accounts automatically ?"
header="Account creation" severity="alert"
widgetVar="choice" appendTo="#(body)">
<p:button outcome="personalizeAccount" value="Personalize" icon="ui-icon-star" />
<p:button outcome="autoAccount" value="Continue" icon="ui-icon-star" />
</p:confirmDialog>
Just show the dialog in Backing Bean like this:
Page:
<p:commandButton update="panel" value="Save"
icon="ui-icon-check"
style="color:blueviolet"
action="#{newBusinessCtrl.showDlg('choice')}"/>
Backing Bean:
public void showDlg(String dlgName){
RequestContext.getCurrentInstance().execute(dlgName+".show()");
}
Once the validation failed, the action won't execute and thus the dialog will not show.
If validation hasn't failed. PrimeFaces puts a global args object in the JavaScript scope which in turn has a boolean validationFailed property. You can check it before showing the dialog So you can use it this way:
<p:commandButton value="save" oncomplete="if (args && !args.validationFailed) saveDialog.show()"/>

Unable to use p:overlaypanel inside composite component

Am trying to create a composite component that will display the values as overlaypanel. But it returns the below error;
Cannot find component 'j_idt58:reviewDataTable:0:overrideCol' in view
overrideVersionDetails.xhtml:(composite component)
<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:cc="http://java.sun.com/jsf/composite"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<cc:interface>
<cc:attribute name="forId" type="java.lang.String" required="true" />
<cc:attribute name="forValue" type="java.lang.Object" />
</cc:interface>
<cc:implementation>
<p:overlayPanel for="#{cc.attrs.forId}" my="left bottom">
#{cc.attrs.forValue}
</p:overlayPanel>
</cc:implementation>
</ui:composition>
Its used in another page:
<h:form>
....
...
<p:dataTable .....>
....
<p:column sortBy="#{dto.isSameCycleOverride}" width="100">
<f:facet name="header">
Override
</f:facet>
<h:commandLink id="overrideCol" binding="#{overrideCol}"
value="#{(dto.isSameCycleOverride) ? 'Yes' : 'No'}" />
<comp:overrideVersionDetails forId="#{overrideCol.clientId}"
forValue="#{dto.message}" />
</p:column>
....
</p:dataTable>
</h:form>
Any help is really appreciated.
I don't work with Primefaces, but with RichFaces I would use :
<comp:overrideVersionDetails forId="#{rich:clientId('overrideCol')}"
forValue="#{dto.message}" />
to do what you want.
With a little Help from SO :
Rich Faces rich:clientId in Primefaces?
it seems you can do this :
...
<h:commandLink id="overrideCol" value="#{(dto.isSameCycleOverride) ? 'Yes' : 'No'}" />
<comp:overrideVersionDetails forId="#{p:component('overrideCol')}"
forValue="#{dto.message}" />
...
Now to see if this works better than the use of binding in a dataTable...

JSF "rendered" - strange behavior

I can't explaine this well - it's need to see:
Video screencast
Please explain me what happens?
next code work and return true or false but when I put this to rendered="" this not work.
#{!empty detailsBean.goods.pictures}
rendered="true" rendered="false" rendered="#{true}" - work
<p:commandButton id="btn_details" value="#{msg.btn_details}" oncomplete="PF('dlg-detailed').show()" update=":dlg-detailed-id">
<f:setPropertyActionListener target="#{detailsBean.goods}" value="#{goods}" />
<f:param name="id" value="#{goods.id}"/>
</p:commandButton>
Dialog - where I try render text with condition.
<p:dialog id="dlg-detailed-id" widgetVar="dlg-detailed" header="#{msg.btn_details}" dynamic="true" modal="true" draggable="false" width="800" height="600">
<h:outputText value="Some Text For Rendering" rendered="#{!empty detailsBean.goods.pictures}" />
</p:dialog>
Mojarra 2.1.7-jbossorg-1
JBoss AS 7.1.1
I apologize for my mistakes in English
in this case, solution is: add < h:form> tag and then rendered="#{!empty detailsBean.goods.pictures}" work
<h:form id="form-detailed" >
<p:dialog id="dlg-detailed-id" widgetVar="dlg-detailed" header="#{msg.btn_details}" dynamic="true" modal="true" draggable="false" width="800" height="600">
<h:outputText value="Some Text For Rendering" rendered="#{!empty detailsBean.goods.pictures}" />
</p:dialog>
</h:form>

Resources