navigation by action for p:menuitem doesn't work - jsf

I am currently using PrimeFaces 5.
I have this method in a bean called home:
public String panelSearch() {
pnlsearch = true;
return "home";
}
pnlsearch is a property that makes a panel visible
home.xhtml contains:
<p:menubar>
<p:menuitem id="mnusearch"
value="Search"
ajax="true"
action="#{home.panelSearch}"
icon="ui-icon-search" />
<p:menuitem value="Search" >
<p:commandLink ajax="false"
action="#{home.panelSearch}"
value="Search" />
</p:menuitem>
</p:menubar>
<h:panelGrid rendered="#{home.pnlsearch}">...</h:panelGrid>
panelSearch is called with action in both p:menuitem and in p:commandLink
but panelSearch is visible only with p:commandLink
Why panelSearch is not made visible with a click on p:menuitem alone as well?
note: p:commandLink is called no matter the navigation-rule in faces-config.xml

Related

p:steps example not functioning

I'm trying use the STEPS component - Primefaces. But in the documentation the tutorial is very poor.
Can someone write an example using steps with property rendered or something like that, how Can I show and hide a panel using STEPS component.
I tried like this but does not work
My xhtml
<p:steps id="testSteps">
<p:menuitem value="Personal" update="testSteps" actionListener="#{BeanTest.shown2()}"/>
<p:menuitem value="Seat Selection" update="testSteps"/>
</p:steps>
<form id="formShowField1" >
<p:panel rendered="#{BeanTest.showfield1}">
<p:outputLabel value="FORM 1"/>
</p:panel>
</form>
<form id="formShowField2">
<p:panel rendered="#{BeanTest.showfield2}">
<p:outputLabel value="FORM 2" />
</p:panel>
</form>
My bean
public void shown1(){
showfield1 = true;
updateEntirePage("formShowField1");
}
public void shown2(){
showfield1 = false;
updateEntirePage("formShowField1");
showfield2 = true;
updateEntirePage("formShowField2");
}
As stated by comments, there are multiple issues with your XHTML code.
1) Use <h:form> instead of <form>
2) The p:steps component is readonly by default. Set readonly="false" in order to have interactive menu items. In this mode, it needs to be placed somwhere inside a h:form to - I get a javax.faces.FacesException: MenuItem must be inside a form element else.
3) Your menuItems update the p:steps component only. Your other panels won't ever show up this way as they are not updated. You should update an element containing them too. Don't know what updateEntirePage is though, especially when invoked twice.
4) Bean names like Java variables typically start with lower case character.
Try it like this:
<h:form>
<p:steps id="testSteps" readonly="false">
<p:menuitem value="Personal" update="#form" actionListener="#{beanTest.shown2()}"/>
<p:menuitem value="Seat Selection" update="#form"/>
</p:steps>
<p:panel rendered="#{neanTest.showfield1}">
<p:outputLabel value="FORM 1"/>
</p:panel>
<p:panel rendered="#{beanTest.showfield2}">
<p:outputLabel value="FORM 2" />
</p:panel>
</h:form>
And in your bean:
public void shown2(){
showfield1 = false;
showfield2 = true;
}

Button in dialog inside p:dialog is not calling controller method

I've got a problem as described in the title.
Small description of the problem is as following:
I have button which is used to open dialog. Then, inside that dialog, there is button which opens another dialog on top of the first one. After clicking second button I want method from controller to be called but nothing happens. Value in h:outputText is read properly, so I guess it is not a problem with connection controller->view.
I'm using:
Spring web 3.1.2.RELEASE
JSF 2.2.10
Primefaces 5.1
Code:
beans.xml
<bean id="testController" class="test.TestController" />
TestController.java
public class TestController implements Serializable
{
private static final long serialVersionUID = 7028608421091861830L;
private String test;
public TestController()
{
test = "abc";
}
public void testMethod()
{
test = "cba";
}
public String getTest()
{
return test;
}
}
test.xhtml
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg1').show();" />
</h:panelGrid>
<p:dialog widgetVar="dlg1">
<h:outputText value="Resistance to PrimeFaces is futile!" />
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg2').show();" />
</h:panelGrid>
<p:dialog widgetVar="dlg2">
<h:outputText value="#{testController.test}" />
<p:commandButton value="Call method" type="button" actionListener="#{testController.testMethod}" />
</p:dialog>
</p:dialog>
What I tried:
adding appendToBody="true" to each p:dialog
changing from p:commandButton to p:button
changing from actionListener to action
but nothing helps.
I would be grateful for any help or advice of what can be the reason of not calling given method.
There are 3 problems.
You're nesting <p:dialog> components. This doesn't make sense. Separate them.
A <p:dialog> must have its own <h:form>, particularly when you explicitly use appendToBody="true" or appendTo="#(body)", otherwise nothing can be submitted because JavaScript would relocate the dialog out of its position in the HTML DOM tree to the end of body, causing it to not be sitting in a form anymore.
A <p:commandButton type="button"> acts as a "click" button, not as a submit button. Remove that attribute from submit buttons.
All in all, this is how it should look like:
<h:form>
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg1').show();" />
</h:panelGrid>
</h:form>
<p:dialog widgetVar="dlg1">
<h:form>
<h:outputText value="Resistance to PrimeFaces is futile!" />
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg2').show();" />
</h:panelGrid>
</h:form>
</p:dialog>
<p:dialog widgetVar="dlg2">
<h:form>
<h:outputText value="#{testController.test}" />
<p:commandButton value="Call method" actionListener="#{testController.testMethod}" />
</h:form>
</p:dialog>
OK. I guess I found a way to fix this problem.
It seems that the problem was:
type="button"
I deleted it from the list of attributes of each button and now it works even without h:form. Thanks for help.

How to make work a actionListener in a breadCrumb menuitem?

I have the following code in an XHTML page :
<h:form id="myform">
<p:breadCrumb>
<p:menuitem value="Home" ajax="false" actionListener="#{menu.actionButton}"/>
<p:menuitem value="Page 1" actionListener="#{menu.actionButton()}" ajax="false"/>
<p:menuitem value="Page 2" url="#" />
</p:breadCrumb>
</h:form>
In my bean menu the method :
public void actionButton() {
System.out.println("OKKKKKKKKKKKKK");
}
If I call the method with a command button, it works fine but in menuitem the method is not call.
Can someone please help ?

Updating a dataTable using f:ajax needs button pressed twice or enter pressed twice

<h:form id="searchForm">
Keyword: <p:inputText id="search"
value="#{employeeSearch.searchString}" />
<p:commandButton value="Search"
action="#{employeeSearch.searchByString}">
<f:ajax execute="#all" render="output" />
</p:commandButton> (Enter keywords separated by spaces)
<p:dataTable id="output" var="employee"
value="#{employeeSearch.employees}">
... etc...
I know that the database is being hit after the first button click, it's just the view is not being updated with Ajax
if I add ajax="false" to the commandButton <p:commandButton value="Search" ajax="false"
The datatable is updated as expected after a single click of the button or hitting enter just once but the whole page is refreshed.
here is my bean
#ViewScoped
#ManagedBean
public class EmployeeSearch {
public String searchByString() {
this.employees = employeeRepository.searchBySingleString2(searchString);
return null;
}
If u want update only dataTable component try do something like this :
<p:commandButton value=" action="#{employeeSearch.searchByString}" update="output">
or just add in commandButton
<f:ajax update=":searchForm:output" />

How to Hide/show <p:toolbar> onclick of a <p:menuitem>

I am working with JSF 2.0 and primefaces 3.3. I want to hide/show a toolbar onclick of a menuitem.
Here is the more info.
<p:menubar autoSubmenuDisplay="true" style="width:99%">
<p:submenu label="Projects">
<p:menuitem id="m11" value="Select Product" actionListener="#{menuBean.renderTool}" update="t1" />
<p:menuitem id="m12" value="Select Project" />
<p:menuitem id="m13" value="Select Contract" />
</p:submenu>
<p:menuitem id="m2" value="Global" />
<p:menuitem id="m7" value="Exit" />
</p:menubar>
<p:toolbar id="t1" rendered="#{menuBean.renderToolbar}">
<p:toolbarGroup align="left" style="height:20px;">
<h:outputText value="Projects " />
<h:outputText value=" - select Product" />
</p:toolbarGroup>
</p:toolbar>
ManagedBean
private boolean renderToolbar = false;
//getters and setters
public void renderTool(ActionEvent actionEvent){
System.out.println("inside renderTool method...");
renderToolbar = true;
}
The actionListener method is executing But, it's not updating or rendering the toolbar.
add some boolean variable to your bean
boolean someBoolean; //+ getter/setter
and inside your renderToolbar method add
someBoolean = !someBoolean; // toggle the disaplay on and off
in xhtml change
<p:toolbar id="t1" rendered="#{menuBean.renderToolbar}">
into
<h:panelGroup id="t1">
<p:toolbar rendered="#{menuBean.someBoolean}">
.
.
.
</h:panelGroup>
Not much info that you provided.
However, one way to do it is using Javascript with the onclick event handler.
Like this (untested code):
<p:toolbar id="toolbarID" />
<p:menu>
<p:menuitem onclick="$('#toolbarID').toggle();" />
</p:menu>
I think primefaces already includes jquery so you should be able to use jquery selectors out of the box.
The solution Daniel provided works using a backing bean. However if showing/displaying some element isn't dependent on data but is more a client-side thing or a simple user controlled element I would advice against using a backing bean. Using a backing bean for client-side stuff causes delays or as a regular user would put it: "It's slow".
In stead use client side things like JavaScript as Jens suggested. Since you're using PrimeFaces you can make use of jQuery. A simple example to demonstrate jQuery's toggle(), show() and hide() functions:
<h:form>
<p:menubar>
<p:menuitem value="Toggle" onclick="$("[id='t1']").toggle()" />
<p:menuitem value="Show" onclick="$("[id='t1']").show()" />
<p:menuitem value="Hide" onclick="$("[id='t1']").hide()" />
</p:menubar>
</h:form>
<p:toolbar id="t1" />
Note that if your p:toolbar lives in a container like a form or such the client-side ID is prefixed with the form's ID.

Resources