Primefaces dataTable with embedded commandLink - java

I'm trying to embed a Primefaces commandLink and call an action listener from a link inside a column of a Primefaces dataTable. Is this not possible? The "Test" onclick alert gets fired but it never makes it to my bean's method.
<p:dataTable var="location" value="#{adminBean.locations}">
<p:column headerText="Options">
<p:commandLink value="delete" actionListener="#{admin.deleteLocation}" onclick="alert('test')"/>
</p:column>
</p:dataTable>
bean code:
public void deleteLocation(ActionEvent e){
//delete logic here...
}

This is possible. Your actionListener should be called. Keep in mind that the p:commandButton uses ajax by default. So you should use the update attribute in order to define the components to be updated.
However, I don't know if this affects the actionListener. Did you try it with action instead of actionListener?
Here is an example how I got it working:
<p:commandLink action="#{spc.selectPatient(item)}"
ajax="false"
value="Open"/>
The bean method looks as follows:
public String selectPatient(Patient p) {
// do something
// return some outcome
}

Related

Ajax call in p:selectManyCheckbox

Hi guys is there a way to fire an ajax call in a p:selectManyCheckbox of primefaces once I check one of them? something like this:
<p:selectManyCheckbox label="Elements" value="#{crearVacacionMB.elementSelected}" layout="grid" columns="1">
<f:selectItems value="#{MB.elements}" />
<p:ajax event="check" listener="#{MB.function}"/>
</p:selectManyCheckbox>
And my MB:
public void function(AjaxBehaviorEvent event){
System.out.println("I was fired");
}
The code you posted produces a JSF error, at least with Mojarra 2.2, and I am surprised you haven't mentioned it:
<p:ajax> Event:check is not supported.
Remove the event attribute from <p:ajax>: the ajax behaviour will default to the default event valueChange:
<p:ajax listener="#{MB.function}"/>
Links:
When to use valueChangeListener or f:ajax listener?

JSF 1.2 Life Cycle understanding: Executing the ValueChangeListener method in InvokeApplication phase

I am using a <h:selectBooleanCheckbox> in the facet header of a DataTable. All the rows content for that <h:column> DataTable are <h:selectBooleanCheckbox>. The rows are getting selected perfectly the way I wanted. Below is the code I used:
<h:form>
<h:dataTable
value="#{employeeService.employeeList }"
var="empl"
binding="#{employeeService.dataTablebinding }">
......
......
......
<h:column>
<f:facet name="header">
<h:selectBooleanCheckbox id="chkBoxAll" value="#{employeeService.checkedHdr }" valueChangeListener="#{employeeService.checkAll }" onclick="submit()"></h:selectBooleanCheckbox>
</f:facet>
<h:selectBooleanCheckbox id="tableChkBox" value="#{empl.checked }" valueChangeListener="#{employeeService.getCheckChanged }" onclick="submit()"></h:selectBooleanCheckbox>
</h:column>
</h:dataTable>
This is the code for the ValueChangeListener:
public void checkAll(ValueChangeEvent event){
if(isInvokeApplicationPhase(event)){
Iterator<Employee> empl = employeeList.iterator();
while(empl.hasNext()){
Employee emp = empl.next();
emp.setChecked(checkedHdr);
}
}
}
This is the isInvokeApplicationPhase utility I added up for making this code work (referred the solution suggested by BalusC in this link: JSF 1.2: valueChangeListener event not returning newly selected value ):
public boolean isInvokeApplicationPhase(FacesEvent event){
if(event.getPhaseId() != PhaseId.INVOKE_APPLICATION){
event.setPhaseId(PhaseId.INVOKE_APPLICATION);
event.queue();
return false;
}
return true;
}
Now my Question:
What is the use of that isInvokeApplicationPhase check in the ValueChangeListener method? If I comment out this check then it does not work - WHY? I thought I have understood the JSF life cycle properly but this behavior proves that I have not :(
Kindly let me know the explanation based on the JSF life cycle phases.
The value change listener runs during validations phase and is intented to hook on the value change event. I.e. the newly submitted value is different from the original model value.
The validations phase runs before update model values phase, wherein JSF set all submitted, converted and validated values in the model (the backing bean's properties). So when you attempt to change the model value of a different field in the value change listener, then it would be overridden during the update model values phase.
This particular trick re-queues the value change event to the invoke application phase, which runs after update model values phase. So when you attempt to change the model value of a different field, then it won't be overriden.
In a nutshell: the validations phase is simply the wrong moment to manually manipulate the model values and the invoke application phase is the right moment to manually manipulate the model values.
Actually, the value change event is being abused here. You should rather be using an action event here, but this was not available for inputs in JSF 1.x. This was only available in JSF 2.x in flavor of <f:ajax listener>.
See also:
When to use valueChangeListener or f:ajax listener?
Setter not called for input text

how can I send a value from my view to my bean using primefaces?

I am sending values to my view from my bean and from my view to my bean, everything is fine if I work with event such as "acitonListener" but now I want to send the user to other page (with a navigation rule, it works perfect) when I click on a button, but before of that I want to set in my bean one value, how can I do this?
I am doing something like this
<p:commandButton value="Send" id="sendButton" action="#{myBean.myMethod}"
update=":form:growTop" >
</p:commandButton>
Before of that there is only a table with <h:outputText/> with values from my bean, any way to do this?
Thanks
action="#{myBean.myMethod(myParameter)}
The above method expression will send myParameter to the myMethod function in your backing bean:
public void myMethod(String myParameter) {
// ...
}
You can also send the user to the next page by returning a valid navigation outcome from your action method:
public String myMethod(String myParameter) {
// ...
return "myPage?faces-redirect=true";
}
In your concrete case if there is a backing bean value which is printed out:
<h:outputText value=#{myBean.myParameter}/>
the following action
<p:commandButton value="Send" id="sendButton" action="#{myBean.myMethod(myParameter)}
update=":form:growTop" >
</p:commandButton>
will pass myParameter to your action method.
In order to get the expected behavior with primefaces datatable use at least #ViewScoped backing bean behind your table values.

Primefaces TabView by a model - remove model associated with tab on close

I'm using Primefaces (version 3.0.1) p:tabView component, which displays dynamic number of tabs backed by a list in a model. Tabs inside TabView are closable. I'd like to remove list element associated with a tab by close event.
Here is my view:
<p:tabView id="tabView" var="iterator" value="#{bean.list}">
<p:ajax event="tabClose"
listener="#{bean.removeElement(iterator)}" process="#this" />
<p:tab id="tab" closable="true">
<h:outputText value="#{iterator.text}" />
</p:tab>
</p:tabView>
My bean handler:
public void removeElement(Element e) {
this.list.remove(e);
}
Element e is null in this case
I've also tried to use p:collector inside p:ajax element. There is example at primefaces.org showcase. According to it my event handler should look like
public void removeElement(TabCloseEvent event) {
// ...
}
But I don't know how can I get associated with tab list element.
All answers will be appreciated. Thanks in advance
public void removeElement(TabCloseEvent event) should be used, imo.
According to TabCloseEvent it has a method getData(). This should give you access to your model class. Disclaimer: I haven't used TabView the way you do yet, but it works this way for Primeface's Tree component (i.e. selection of a node). Could you post back your findings?

JSF GAE: Value Update Problem in managed bean method

I have the following piece of code with a simple h:outputText pointing to a int and a p:commandLink to set a value:
<h:form id="f1">
<h:outputText id="text" value="#{testBean.index}"/>
<p:commandLink actionListener="#{testBean.test}" update="text">
<f:setPropertyActionListener target="#{testBean.index}" value="5" />
<h:graphicImage url="/images.png"/>
</p:commandLink>
</h:form>
The managed bean looks like this:
#javax.faces.bean.ManagedBean #ViewScoped
public class TestBean implements Serializable{
private int index; // getter/setter
#PostConstruct public void init() {
index = 0;log.log(Level.WARNING, "#PostConstruct");}
public void test(ActionEvent ae){
log.log(Level.WARNING, "Index: "+index);}
}
The bean is constructed correctly, and after the first click on the image the h:ouputText is updated to 5. But in my log message I only see Index: 0 during the first click on the image.
It's something similar like Jsf updates model value with old value, but I have the JSF #ManagedBean annotation.
Action listeners are invoked in the order they're definied in the view. You want to use action instead of actionListener. Even more, the action should in first place have been used to invoke a business action.
<p:commandLink action="#{testBean.test}" update="text">
<f:setPropertyActionListener target="#{testBean.index}" value="5" />
<h:graphicImage url="/images.png"/>
</p:commandLink>
See also:
Differences between action and actionListener
What is happening is that the test ActionEvent is getting fired before the request values have been applied.
To get a better understanding of the JSF phase lifecycle and when lifecycle events and ActionEvents fire, implement the Debug PhaseListener as specified in the following blog article.
http://balusc.blogspot.com/2006/09/debug-jsf-lifecycle.html
This should help you understand when request values are being applied, and when events are being fired.

Categories

Resources