Richfaces 4 a4j:commandLink action not firing in rich:popupPanel - jsf-2

I seem to be having a problem where I have an a4j:commandLink on a rich:popupPanel but the action is not firing. The xhtml looks as follows:
<rich:popupPanel id="rate-panel" modal="true" height="444" width="780" top="60" show="false" onmaskclick="#{rich:component('rate-panel')}.hide()" styleClass="cs-modal">
/**Some html here**/
<a4j:commandLink immediate="false" action="#{venueScore.up}" render="rate-panel" styleClass="rate love">
<span>Love it</span>
</a4j:commandLink>
/**Some more html here**/
</rich:popupPanel>
And the managed bean looks as follows:
#Named("venueScore")
#ViewScoped
public class VenueScoreManager extends BaseManager implements Serializable {
public void up() {
System.out.println("TEST");
//Do something
}
}
I have made the managed bean #ViewScoped.
I have also tried adding an <h:form> around the commandLink however, this does even less than without it. I actually think that is because the commandLink is inside the <h:form> in which the link that opened the popupPanel sits.
Anyway, can someone please point me in the direction of why the action not fire?

Ok, so I fixed it myself. After screwing around I worked out that I just need to add an <a4j:region> around the content in the <rich:popupPanel>. So now the xhtml looks something like this:
<rich:popupPanel id="rate-panel" modal="true" height="444" width="780" top="60" show="false" onmaskclick="#{rich:component('rate-panel')}.hide()" styleClass="cs-modal">
<a4j:region id="panel-region">
/**Some html here**/
<a4j:commandLink immediate="false" action="#{venueScore.up}" render="panel-region" styleClass="rate love">
<span>Love it</span>
</a4j:commandLink>
/**Some more html here**/
</a4j:region>
</rich:popupPanel>

I had the same problem, a4j:commandLink only worked after first click.... put the poppanel inside a form and add domElementAttachment...
<h:form id="myform">
<rich:popupPanel id="pop" domElementAttachment="form">
...
<a4j:commandLink />
...
</rich:popupPanel>
</h:form>

I know that it's an old question but as I had exactly the same problem, I spent a lot of time before fixing it, maybe it will help someone else.
First, I tried the solution proposed above but it did not worked.
Finally, I found this thread:
Issues closing rich:popupPanel via show condition, RF 4.0
And I added the domElement attribute to my popup:
<rich:popupPanel
id="newMailPopup"
**domElementAttachment="form"**
...>
And now, my a4j:commandLink works perfectly :-)

Related

Redirect using <p:commandButton>

Following line should save a new item and redirect to another page. So far, it saves correctly, but it doesn´t redirect. No errors or warnings.
<p:commandButton id="savebutton" ajax="false" value="#{msg['addCategory.save']}" actionListener="#{addCategoryController.doSave()}" />
Code behind:
public String doSave(){
categoryAddEvent.fire(categoryProducer.getSelectedCategory());
return Pages.LIST_CATEGORIES;
}
As I said, the first line executes correctly, the second one doesn´t seem to do anything. Any ideas what I could be doing wrong?
You can do it in two ways:
Navigation:
Calling an action, with the commandButton component set as ajax false, and the bean method returning a String (as you already have).
xhtml page:
<p:commandButton id="savebutton" ajax="false" value="#{msg['addCategory.save']}" action="#{addCategoryController.doSave()}" />
Redirect:
Calling an actionListener, with the commandButton component set as ajax true, with the bean method not returning value, but instead performing itself the redirection to the desired page.
xhtml page:
<p:commandButton id="savebutton" ajax="true" value="#{msg['addCategory.save']}" actionListener="#{addCategoryController.doSave()}" />
java bean:
public void doSave(){
categoryAddEvent.fire(categoryProducer.getSelectedCategory());
FacesContext.getCurrentInstance().getExternalContext().redirect(Pages.LIST_CATEGORIES);
}

Ajax PrimeFaces not to render the event or disable checkbox

In doc it doesn't have a property render and i did a smoke test by having other components wrapping around p:ajax (Exception: but event attribute is unavailable) am i missing something here?
<p:ajax event="rowSelectCheckbox" listerner="somemethod()" update="someId"/>
Just omit the event totally:
<p:ajax listener="..." update="..."/>
It defaults to event="valueChange" and process="#this", which is often what one want.
If it does'nt work as expected check the Primefaces user guide, find your component and look for "Ajax behavior events" or look for attributes beginning with "on...".
About h:outputLink: its not a Primefaces tag so it should have been f:ajax for this one. However it does'nt work because of this.
Read more in this answer.
rowSelectCheckbox will be use with SelectEvent.
xhtml
<p:ajax event="rowSelectCheckbox" listerner="#{bean.selectCheckbox}" update="someId"/>
managedbean
public void selectCheckbox(SelectEvent event){
}

<p:commandbutton> not working

i am new to JSF and primefaces.. i wrote a small code... i am getting what i want to do with "h:commandbutton" but samething is not working with "p:commandbutton". is there any difference between the functionality of these two things.
<h:commandButton value= "enter" actionListener= "#{newJSFManagedBean.show()}"/><br/>
<p:commandButton value= "enter" actionListener= "#{newJSFManagedBean.show()}"/><br/>
i have tried alot of things, but newjsfmanagedbean.show() havenot been called from p:commandbutton but h:commandbutton is working fine. what is the reason :-( ?
*hey it worked :-) *
thanxmates
<p:commandButton process="#this" value= "enter" ajax="false" actionListener= "#{newJSFManagedBean.show}" /><br/>
You didn't share your show() function but I can guess that it looks like below :
public void show(ActionEvent event) {
// some stuff here
}
Well, just delete your brackets in your EL language if you want to use it with primefaces :
<p:commandButton value= "enter" actionListener= "#{newJSFManagedBean.show}"/>
Otherwise it looks for a show method which does not have any parameters.
You should add process="#this" to p:commandButton to get its action invoked. If you want to process any other components add process="#this,id1,id2" like this.
Hope this helps

Primefaces commandButton inside dialog not firing backing bean's method

I've just started learning JSF and PrimeFaces, and as soon as I solve a problem (with your help), another one arises. I have a datatable showing some data about my application's users; in the last column, a commandButton invokes a dialog allowing the corresponding data to be edited. The dialog actually interacts with the backing bean, since the fields are correctly precompiled with the existing data, but the "Submit changes" commandButton doesn't fire the proper editUser() method!
I've searched everywhere for a solution to my problem, but none of the threads on the PrimeFaces forums nor any question here on Stack Overflow helped me: I tried all combinations of action, actionListener, inner <h:form>, outer <h:form>, even the dreaded nested <h:form>, but the underlying method is still not called.
Thank you all, people!
EDIT: I included some more xhtml. Just to be clear: in the datatable I'm implementing both single and multiple selection mechanisms. The single selection is performed by the editButton in the last column and triggers the editDialog that's giving me pain, while multiple selection is enabled by the checkboxes in the first column and is targeted by a commandButton at the bottom of the table that deletes all selected users; of course they store the selections in different fields in the backing bean (selectedUser and selectedUsers[], respectively).
xhtml file
<h:form id="tableForm">
<p:dataTable id="userList" var="user" value="#{userListBean.userList}"
selection="#{userListBean.selectedUsers}" rowKey="#{user.username}">
<!-- this is a checkbox column I use for multiple selection -->
<p:column selectionMode="multiple" style="width:2%"/>
<!-- other datatable columns -->
<!-- this is the button column that triggers the dialog -->
<p:column style="width:4%">
<p:commandButton id="editButton" update=":tableForm:editUserData"
oncomplete="PF('editDialog').show()" title="Edit" icon="ui-icon-pencil">
<f:setPropertyActionListener target="#{userListBean.selectedUser}"
value="#{user}" />
</p:commandButton>
</p:column>
</p:datatable>
<p:dialog id="editDlg" widgetVar="editDialog" header="Edit User"
showEffect="fade" hideEffect="fade" modal="true" dynamic="true">
<h:panelGrid columns="6" id="editUserData">
<p:outputLabel for="editUsername">Username:</p:outputLabel>
<p:inputText disabled="true" id="editUsername" value="#{userListBean.selectedUser.username}" />
<p:message for="editUsername" />
<!-- and other fields like that -->
</h:panelGrid>
<p:commandButton id="submitChanges" action="#{userListBean.editUser()}"
value="Submit changes" oncomplete="PF('editDialog').hide();" />
</p:dialog>
</h:form>
Backing bean
#ManagedBean(name="userListBean")
#ViewScoped
public class UserListBean {
private UserDTO selectedUser;
public UserListBean() {
}
//some methods...
public String editUser() {
System.out.println("------------------ EDIT TRIGGERED! -------------------");
System.out.println(selectedUser.getUsername());
//this stuff never gets printed, so the method is never called!
}
//getters and setters
}
Actually, the only thing didn't come to my mind turned out to be the one that worked.
I sorted out my issue by using THREE forms (as I mentioned in my question, I had already tried out all possible combinations of one and two forms, even nested ones), like this:
<h:form id="tableForm">
<!-- here lies the p:dataTable -->
</h:form>
<p:dialog>
<h:form id="dialogForm">
<!-- here lies the h:panelGrid with the editable fields -->
</h:form>
<h:form id="buttonForm">
<!-- and HERE goes the commandButton, alone -->
</h:form>
</p:dialog>
It looks like everyone solves this problem in ways that don't work for others :) .

How to save a list/map/set in JSF with h:inputText + managed bean

What I'm trying to achieve is very similar to the one posted in the following link.
How to save an array in JSF with ui:repeat + h:inputText + managed bean?
I'm particularly fascinated with the answer provided by Arjan Tijms in the link above however what I want to achieve is slightly different. Consider the following code snippets.
The bean
import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
#RequestScoped
#Named
public class MyBean {
List<String> choices;
public List<String> getChoices() {
return choices;
}
#PostConstruct
public void initChoices() {
choices= new ArrayList<String>();
}
public String save() {
// should save all the choices into some repository
return "";
}
}
and the facelet page
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:body>
<h:form>
<ui:repeat value="#{myBean.choices}" varStatus="status">
<h:inputText value="#{myBean.choices[status.index]}" />
</ui:repeat>
<h:commandButton value="Save" action="#{myBean.save}" />
</h:form>
</h:body>
</html>
The thing is, this will work if we have some initial data in the list at the beginning. What about situations where the initial list will be empty?
The ideal solution which I'm looking for is to have 1 h:inputText for each choice and when save button is clicked, all choices in each h:inputText is then added to the choices list. I've searched high and low but can't seem to find any hints on how this can be done.
If JSF 2 really doesn't support this, I guess I'll have to use the ugly way with just one h:inputText and use a converter to convert to and from a list but I'm still hoping that an ideal solution can be found.
Hopefully someone from stackoverflow can shed a light in the right direction for me.
Just add an "add" button which adds a new String to the list.
<ui:repeat value="#{myBean.choices}" varStatus="status">
<h:inputText value="#{myBean.choices[status.index]}" />
</ui:repeat>
<h:inputText value="#{myBean.newChoice}" />
<h:commandButton value="Add" action="#{myBean.add}" />
<h:commandButton value="Save" action="#{myBean.save}" />
with
private String newChoice;
public void add() {
choices.add(newChoice);
newChoice = null;
}
// ...
Note that this only works if bean is put in view scope. A request scoped one would be constructed on every request and hereby recreate the list everytime.

Resources