Passing Parameters With Seam, RichFaces & PopupPanel - java

I'm trying to get a little application working using Seam 3, RichFaces 4 and hitting a few troubles with passing some parameters around. I've tried a lot of different things but I keep falling at the final hurdle. I'm carrying through a customerId via a request parameter. But when I hit a RichFaces commandButton on a popupPanel, that customerId is no longer available to me.
I'm setting up an application to manage some data. Basically you select a customer from one screen, that will take you to another screen containing "repositories" where you then can create, edit etc. You can get to this second repositories page via the URL:
http://localhost:8080/media-manager/repositories.xhtml?customer=12
I then have a bean picking this value up:
#Named
#RequestScoped
public class RepositoryBean extends AbstractViewBean<Repository> {
// Various properties etc. here
private Long customerId;
public void init() {
log.info("Customer ID is "+ customerId);
}
}
I then set the customer ID via metadata on the repository page and call init:
<f:metadata>
<f:viewParam name="customer" value="#{repositoryBean.customerId}"/>
<f:event type="preRenderView" listener="#{repositoryBean.init}" />
</f:metadata>
This works well at the start. I can display information I need for the customer with the supplied ID. But when I try to create my popupPanel is goes a bit wrong. Here's a simplified version of the code first:
<rich:popupPanel id="repositoryModalPanel" modal="true" resizeable="true">
<f:facet name="header">Title</f:facet>
<f:facet name="controls">
<h:outputLink value="#" onclick="#{rich:component('repositoryModalPanel')}.hide(); return false;">X</h:outputLink>
</f:facet>
<h:form id="modalForm" class="modalForm">
<fieldset>
<ul class="layout form">
<li>
<label for="name" class="required">Name:</label>
<h:inputText id="name" value="#{repositoryBean.instance.name}" required="true">
<!-- rich:validator event="blur" / -->
</h:inputText>
<rich:message for="name" errorClass="error errormessage" />
</li>
<li class="last">
<a4j:commandButton id="create" value="Create" action="#{repositoryBean.saveRepository}" rendered="#{empty repositoryBean.instance.id}"/>
<a4j:commandButton id="save" value="Save" action="#{repositoryBean.saveRepository}" rendered="#{not empty repositoryBean.instance.id}"/>
<a4j:commandButton id="cancel" value="Cancel" action="#{repositoryBean.clearInstance}" immediate="true" />
</li>
</ul>
</fieldset>
</h:form>
Basically, whenever I hit the save commandButton, the init method is called but the customerId member is never populated. Does anyone have any insight into why?
I've read that viewParam is only for GET requests so maybe that's the problem? But if that's the case - what is the other solution? Lots of things I have seen suggested (e.g. using #ManagedProperty) does not seem to be applicable to Seam 3.

RepositoryBean is RequestScoped, and as such will be newly created on each request, especially if you hit the save button.
The straightforward solution is to promote RepositoryBean to be ConversationScoped, and to make it long running if you enter the page.
#Named
#ConversationScoped
public class RepositoryBean extends AbstractViewBean<Repository> {
// Various properties etc. here
#In
Conversation conversation
private Long customerId;
public void init() {
log.info("Customer ID is "+ customerId);
conversation.begin();
}
}
The easieast way for that is to dump the preRenderView and use seam 3 view-action instead.
<f:metadata>
<f:viewParam name="customer" value="#{repositoryBean.customerId}"/>
<s:viewAction action="#{repositoryBean.init}" if="#{conversation.transient}"/>
</f:metadata>

Related

Input fields not emptying after submit and redirect?

When I want to "delete a plane" from my jsf page, if successful the plane deletes, and I do a redirect to the page and show an alert telling the user the plane was succesfully deleted. However, the values the user entered in the h:inputText are still there, they dont empty.
JSF Page:
<h:form>
<h:panelGrid columns="3" class="table">
<h:outputLabel value="Plane ID" />
<h:inputText value="#{listAirplaneBB.airPlaneId}"/>
<h:commandButton value="Delete"
class="btn btn-primary"
action="#{addAirplaneCtrl.deleteAirplane}" />
</h:panelGrid>
</h:form>
Bean code:
public String deleteAirplane(){
//delete the plane
return private/user?faces-redirect=true;
}
Any ideas on why the fields dont empty after redirect?
Maybe your listAirplaneBB is a #ViewScoped bean (cant tell by your example).
In that case you have to clean any particular fields manually before redirecting as JSF keeps alive that bean while the target page has not changed.

form field in jsp not change java variable

I can't change the data information in my jsp page when I submit the form and call a java function(When the button is pressed).
This is a peace of code used in my .jsp form field:
...
<h:form>
<h:panelGrid columns="3">
<h:outputLabel for="contactName" value="#{msj.contactName}"/>
<h:inputText id="contactName" value="#{CustodiaBean.name}" required="true">
<f:validator validatorId = "TextValidator" />
</h:inputText>
<h:message for="contactName" styleClass="errorMessage" style="color:red"/>
<h:outputLabel for="contactLastName" value="#{msj.contactLastName}"/>
<h:inputText id="contactLastName" value="#{CustodiaBean.last_name}" required="true" >
<f:validator validatorId = "TextValidator" />
</h:inputText>
<h:message for="contactLastName" styleClass="errorMessage" style="color:red"/>
</h:panelGrid>
<div id="button">
<h:commandLink styleClass="hoveringLink3doubleGreen" action="#{CustodiaBean.updateAccount}">
<h:outputText id="save_button" value="#{msj.save_changes}"/>
</h:commandLink>
<h:commandLink styleClass="hoveringLink3double" action="myAccountCustodia">
<h:outputText id="cancel_button" value="#{msj.cancel}"/>
</h:commandLink>
</div>
</h:form>
...
This is the same piece of code used in other pages like login and register user.
The form fields get the current values in "CustodiaBean", but i try to change the value in the form and when I press the button to check the value(call a function in "CustodiaBean"), I always get the previous value (The new form value is not changed in my class "CustodiaBean").
I'm using a tomcat server and eclipse.
Is necesary to force the field to be bloqued and save the changes when the button is pressed??
I don't know why this is happen. Can anyone help me or give me some advice??
Thanks a lot in advance
Does h:inputText etc also has a property name? Try to see what html is generated. It may be possible that your data is not getting submitted properly. Any HTML form directly submit feilds which are non disabled with the name property of each field. IF id is present and not name, it wont be submitted correctly. Try debugging at browser level or via some firefox plugin like tamper data.
Hope it helps

Why this param is being sent as Null in my Bean?

I am Using JSF 2 and EJB 3.1 to create a form.
I am using this part of the page to get me some data, so I can pass it to my bean using the confirmDialog just below
<p:column headerText="#{bundle.edit}" style="width:10px; overflow:visible;">
<p:rowEditor/>
</p:column>
<p:column headerText="#{bundle.delete}" style="width:10px; overflow:visible;">
<p:commandButton update=":form" oncomplete="confirmation.show()"
image="ui-icon ui-icon-close" title="Delete">
<f:param value="#{user}" name="userAction" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:confirmDialog message="Are you sure? user:#{param['userAction']} " width="500"
header="Confirm" severity="alert" widgetVar="confirmation">
<p:commandButton value="Yes sure" update=":form"
actionListener="#{userController.deleteAction(param['userAction'])}"
oncomplete="confirmation.hide()" />
<p:commandButton value="Not yet" onclick="confirmation.hide()" type="button" />
</p:confirmDialog>
</h:form>
And this is the Bean that should get it
#Named(value = "userController")
#Stateful
#RequestScoped
#TransactionManagement(TransactionManagementType.CONTAINER)
public class UserController implements Serializable {
private User current;
#Inject
private br.com.cflex.itm.dataaccess.UserFacade userFacade;
public UserController() {
}
public void deleteAction(User user) {
userFacade.remove(user);
}
But My bean is only receiving null as User, and in the Dialog I am printing the data so I can see there is a User Object selected there.
What is wrong in passing params like that ?
Why am I getting null in my Bean? Because they are getting lost in the communication between client and server-side...
<p:commandButton action="#{userController.deleteAction(param['userAction'])}" />
The EL of action (and actionListener) is evaluated when the form is been submitted, not when the form is been displayed. Request parameters are request scoped and are not there in the subsequent request of the form submit. You need to pass it along:
<p:commandButton action="#{userController.deleteAction(param['userAction'])}">
<f:param name="userAction" value="#{param['userAction']}" />
</p:commandButton>
The EL of <f:param> is evaluated when the form is been displayed. So it will be there in the generated HTML and JavaScript will take care that it is passed along.
Note that request parameters are of String type. Expecting them to be User won't work at all. Basically, it contains the value of User#toString(). You'd need to take String as action argument and convert it to User yourself. Or better, use <f:viewParam> wherein you can explicitly specify a converter.

How to invoke a method with Openfaces/JSF without rendering page?

I am trying to invoke a Save method in a bean with Openfaces 3. While Firefox is not rendering the page, Internet Explorer does.
I'm currently using this code lines:
<o:commandLink value="Save" action="#{beanX.save}">
<h:graphicImage url="/images/save_48.png" />
</o:commandLink>
but I was trying o:ajax as well:
<o:commandLink value="Save" action="#{beanX.save}">
<h:graphicImage url="/images/save_48.png" />
<o:ajax event="click" render="#none" />
</o:commandLink>
Any ideas?
I've found a way to deal with using standard JSF components. Any ideas how to solve this issue with o:commandLink?
You can use <f:ajax> and render attribute in jsf2.0
<h:form>
<h:inputText value="#{managedBean.val1}" >
<f:ajax event="keyup" render="result" listener="#{managedBean.someThingToDoListener}"/>
</h:inputText>
<h:inputText value="#{managedBean.val2}" >
<f:ajax event="keyup" render="result" listener="#{managedBean.someThingToDoListener}"/>
</h:inputText>
<h:outputText id="result" value="#{managedBean.result}"/>
</h:form>
#ManagedBean(name = "managedBean")
public class Bean {
private String val1; // getter and setter
private String val2; // getter and setter
private String res; // getter and setter
...
public void someThingToDoListener(AjaxBehaviorEvent event) {
//res = some processing
}
}
Also See
how-to-update-a-value-displayed-in-the-page-without-refreshing
JSF2: Ajax in JSF – using f:ajax tag
Thank you Jigar Joshi. You've given me the key hint. It works with this code lines:
<h:commandLink value="Save">
<h:graphicImage url="/images/save_48.png" />
<f:ajax event="click" render="#none" listener="#{beanX.save}" />
</h:commandLink>
I've been to this website before, I was not thinking in assuming that o:commandLink might not be able to handle this, might be a bug?
Using h:commandLink instead of o:commandLink and f:ajax with the listener attribute solved my problem.

Two <h:commandButton> in a <h:form>, one work and one doesn't

I'm trying to use one <h:commandButton> with ajax to check some conditions, if it's OK the other <h:commandButton> with no ajax will be display. The one with ajax work well, but the other doesn't although I have specified a return String to another page. I cannot figure out why it failed, the syntaxes are all correct.
<h:form>
<label style="font-weight: bold">Room Code: </label>#{r.code}
<label style="font-weight: bold">Room Type: </label>#{r.roomType}
<label style="font-weight: bold">Price Per Day: </label>#{r.pricePerDay}
<br/>
<h:commandButton value="Check" action="#{bookingController.checkRoom}">
<f:param name="selectedRoomID" value="#{r.id}"/>
<f:ajax execute="#form" render="informer"/>
</h:commandButton>
<h:panelGroup id="informer">
<h:outputText value="#{bookingController.message}" rendered="#{bookingController.checked}"/>
<h:commandButton value="Book now!" action="#{bookingController.doBook}" rendered="#{bookingController.goodToBook}">
<f:param name="selectedRoomID" value="#{r.id}"/>
<f:param name="customerID" value="#{customerLoginController.customerUser.customer.id}"/>
</h:commandButton>
</h:panelGroup>
</h:form>
You've a rendered attribute on the second <h:commandButton>. If it evaluates false during processing of the form submit, then the button's action won't be invoked. This will happen if the bean is request scoped and you don't preserve the same condition for the rendered attribute during the form submit request as it was during displaying the form.
There are several ways to go around this. Since you're using JSF 2.0, best is to put the bean in the view scope instead.
#ManagedBean
#ViewScoped
public class BookingController {
// ...
}
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated

Categories