JSF access html element value in bean class - java

I have a JSF application in which I have a combo box.
<h:selectOneMenu id="collectorType"
value="#{activityDataSource.object.type}"
rendered="#{empty activityDataSource.object.id}"
disabled="#{!sp:hasRight(facesContext, 'ManageApplication')}"
readonly="#{!sp:hasRight(facesContext, 'ManageApplication')}"
onchange="$('editForm:selectTypeButton').click();">
<f:ajax event="change"
execute="#this"
render="dsTransformationRule dsCorrelationRule"
listener="#{activityDataSource.handleCollectorTypeChange}" />
<f:selectItem itemValue="" itemLabel="#{msgs.select_collector_type}"/>
<f:selectItems value="#{activityDataSource.collectorTypes}"/>
</h:selectOneMenu>
And I am getting selected value of that combo box in bean class like:
public void setSelectedTransformationRule(String transformationRule)
throws GeneralException {
String collectorType = (String) getRequestParam().get("editForm:collectorType");
}
And I am successful in doing so. I am calling this method through ajax onchage event of combobox.
But if I try to get same combo box value in a different method i get null value.
public void handleCollectorTypeChange() throws GeneralException {
String collectorType = (String) getRequestParam().get("editForm:collectorType");
}
Any help !

Because Process Events happens before Update Model Values you can retrieve the value from the component, from the UIViewRoot like this:
HtmlSelectOneMenu collectorTypeSelectMenu = (HtmlSelectOneMenu) FacesContext.getCurrentInstance().getViewRoot().findComponent("editForm:collectorType");
String collectorType = (String) collectorTypeSelectMenu.getValue();

try put the attributes process and partialSubmit in your ajax call with the values you need process like this:
<f:ajax event="change"
execute="#this"
render="dsTransformationRule dsCorrelationRule"
process="#this, collectorType"
partialSubmit="true"
listener="#{activityDataSource.handleCollectorTypeChange}" />
In the process atrribute you can put all ids you need to process with the updated values (like you see in the screen.

Related

JSF list depending on selected value returning nullPointer

In my jsf page, in a dialog, I have a list of EntityB which depends on selected EntityA in a datatable.
When I first load the page it's giving me nullPpointer exception because nothing is selected in the first place. Can anyone tell me how to prevent this?
EDIT: I added an actionlistener to the link who open the dialog
and getting this error:
Cannot convert DemandesDocsAdministratif type DemandesDocsAdministratif to class javax.faces.event.ActionEvent
JSF:
<p:commandLink value="#{demande.idDemandeDocAdministratif}"
oncomplete="PF('dlg2').show()" process="#this"
update=":form:pg" actionListener="#{gestionDemandesMB.fillEntityB}">
<f:setPropertyActionListener
target="#{gestionDemandesMB.SelectedEntityA}" value="#{demande}"
/>
</p:commandLink>
<form>
<datatable>
</datatable>
<p:dialog>
<p:selectOneMenu id="Signataires"
value="#{gestionDemandesMB.entityB}">
<f:selectItems value="#{gestionDemandesMB.listEntityB}"
var="sign" itemLabel="#{sign.libRole}"
itemValue="#{sign.idPoste}" />
</p:selectOneMenu>
</p:dialog>
</form>
Bean:
public List<EntityA> getListEntityB() {
if ( selectedentityA != null ){
return entityBService.ListByentityA(selectedEntityA)
; } else {
return Collections.emptyList() ; }
Bean listener that I'm working with now:
public void fillSignataires(ActionEvent event)
{
listB = entityBService.ListByentityA(selectedEntityA)
signaRender = true ;
}
this is the getter of entity B list, I'm looking for a way to either get an empty list or call only when I open dialog.
You could use rendered="#{not empty bean.list}" to prevent the rendering of the selectOnMenu until you have the object filled.
You can also add a f:selectItem with a "Select" label and empty itemValue such as itemValue = " ". By the way, never have a null list, list shouldn't be null but it can be empty. It's the best practice. So you can initialize your listEntityB as an empty list at post construct of your bean.
<p:selectOneMenu id="Signataires"
value="#{gestionDemandesMB.entityB}">
<f:selectItem itemLabel="Select" itemValue="" />
var="sign" itemLabel="#{sign.libRole}"
<f:selectItems value="#{gestionDemandesMB.listEntityB}"
var="sign" itemLabel="#{sign.libRole}"
itemValue="#{sign.idPoste}" />
</p:selectOneMenu>

How to set a f:selectItem in a specific option after a p:commandButton action?

I have a javascript code that clears all the p:inputText (after a p:commandButton action) of the form. The problem is that the p:selectOneMenu still has the f:selectItem selected in the option it was selected. I need to put the values in the first f:selectItem of each p:selectOneMenu.
How to I do that? How can I clear the selected values?
The java script code:
<script type="text/javascript">
function limpiarForm()
{
document.getElementById("formularioAltas").reset();
}
</script>
formularioAltas is the form id.
The code of the p:commandButton:
<p:commandButton value="Guardar" action="#{altasBean.agregarRefaccion()}" oncomplete="limpiarForm()" />
And that code does not reset(I dont want to clear the values, I just want to put the first option selected) the values of the p:selectOneMenu
Here it is:
<h:outputText value="Estado de la refacción" />
<p:selectOneMenu value="#{altasBean.refaccion.estado}">
<f:selectItem itemLabel="..." itemValue="0" />
<f:selectItem itemLabel="Ok" itemValue="Ok" />
<f:selectItem itemLabel="Reparar" itemValue="Reparar" />
<f:selectItem itemLabel="Sospechoso" itemValue="Sospechoso" />
</p:selectOneMenu>
The bean:
private RefaccionBean refaccion = null;
/**
* Get the value of refaccion
*
* #return the value of refaccion
*/
public RefaccionBean getRefaccion() {
return refaccion;
}
/**
* Set the value of refaccion
*
* #param refaccion new value of refaccion
*/
public void setRefaccion(RefaccionBean refaccion) {
this.refaccion = refaccion;
}
public void agregarRefaccion() {
I did a lot of things here...
And after those things i clear the p:inputText with the javascript code
-> After that i want to set the values of the p:selectOneMenu in the fist f:selectItem
}
Josef's answer does lead you in the right direction, but since you shared some code, I will just use it in my answer.
First, make sure that your button calls your bean method and updates the selectOneMenu component after it's done. Although there's some ajax going on here, primefaces abstracts that for you.
<p:commandButton value="Guardar" action="#{altasBean.agregarRefaccion}" update="selectOneMenu" />
The update attribute is important as it will look for the component whose id matches whatever is specified there. So you need to give your selectOneMenu an id. If you need to update more than one component, you can add their ids to the update attribute separated by either space or comma.
<h:outputText value="Estado de la refacción" />
<p:selectOneMenu value="#{altasBean.refaccion.estado}" id="selectOneMenu">
<f:selectItem itemLabel="..." itemValue="0" />
<f:selectItem itemLabel="Ok" itemValue="Ok" />
<f:selectItem itemLabel="Reparar" itemValue="Reparar" />
<f:selectItem itemLabel="Sospechoso" itemValue="Sospechoso" />
</p:selectOneMenu>
Now it's just a matter of cleaning up your values inside your action method:
public void agregarRefaccion() {
//If you have other values to clean, clean them here
this.refaccion.estado="0"; //Matches the value for your first item
}
Now I'm not entirely sure if I follow you, but let me know if this helps you out at all. It's entirely JSF and I threw in some ajax. You can play around with your javascript still.
Front-end:
<p:inputText id="input" value="#{bean.value}" />
<p:commandButton value="button" action="#{bean.action}">
<f:ajax execute="input" render="output" />
</p:commandButton>
<p:selectOneMenu id="output" value="#{bean.placeValue}">
<f:selectItems value="#{bean.values}" />
</p:selectOneMenu>
Bean:
#ManagedBean
#RequestScoped
public class Bean {
private String value;
private List<String> values;
#EJB
private ValueService valueService;
#PostConstruct
public void init() {
values = valueService.list();
}
public void action() {
// ... Action taken
}
public String placeValue() {
// ... Validation and clear desired values
return value;
}
// ... (getters, setters, etc)
}

JSF Converter not called for empty String in selectOneMenu

Following example:
<h:selectOneMenu value="#{bean.value}">
<f:selectItem itemValue="#{null}" itemDisabled="#{true}" noSelectOption="#{true}" itemLabel="choose one" />
<f:selectItem itemValue="FEMALE" itemLabel="female" />
<f:selectItem itemValue="MALE" itemLabel="male" />
<f:converter converterId="myConverter" />
</h:selectOneMenu>
On initial load the value of the bean is null so the please-choose-option is selected. If the user chooses nothing the browser won’t submit a value (the selected option is disabled) and JSF will set the value to an empty String. If the page is rendered again there is no according value, JSF won't render a selected-attribute and most browsers will preselect the first non-disabled-value. Bad.
I thought I could easily change this with a Converter which converts the empty String to null
in getAsObject. But in this case the converter is not called.
Anybody knows why?
I know that I could change this behaviour with javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL
but this leads to other problems with other fields.
I solved my problem by setting the selected-attribute manually:
<f:selectItem itemValue="#{null}" itemDisabled="#{true}" noSelectOption="#{true}" itemLabel="choose one" />
<f:passThroughAttributes value="#{bean.attributes}" />
</f:selectItem>
public Map<String, String> getAttributes() {
Map<String, String> attributes = new HashMap<>();
if (value == null || "".equals(value)) {
attributes.put("selected", "selected");
}
}
return attributes;
}

Java JSF About Custom Validation

i am using this way in custom validation i am little bit confused if this way is correct or not if i assumed that i have this form:
<h:form id="myForm>
<h:outputText value="user name" />
<h:inputText value="#userBean.userName" id="userName" />
<h:outputText value="Password" />
<h:inputText value="#userBean.Password" id="passwd" />
</h:form>
and i have its Managed Bean :
#ManagedBean(name="userBean")
#SessionScoped
public class UserBeanData{
private String userName;
private String password;
// with setters and getters........
//
}
and the custom validator to validate the Managed Bean field and the Implmentation like :
#Override
public validate(FacesContext context, UIComponent component, Object value) throws ValidatorException{
Map<String, String> params = context.getExternalContext().getRequestParametersMap();
String username = params.get("myForm:username");
String pass = params.get("myForm:passwd");
// validate : if fields are not null check if the user exists if the result is empty , throws a validation Message Error
}
My Question is : Retrieving the Managed bean values like this is true or not ????
You're basically looking for the solution in the wrong direction. Validation is only applicable on the individual submitted values, e.g. minimum/maximum length, non-empty/null, regex pattern, etcetera. But you want to invoke a business action based on all submitted values: logging-in an user. This is not exactly input validation.
Just add required="true" to the both input components and perform the job in the action method.
E.g.
<h:form id="myForm>
<h:outputText value="user name" />
<h:inputText value="#{userBean.userName}" id="userName" />
<h:message for="userName" />
<h:outputText value="Password" />
<h:inputSecret value="#{userBean.password}" id="passwd" />
<h:message for="passwd" />
<h:commandButton value="Login" action="#{userBean.login}" />
<h:messages globalOnly="true" />
</h:form>
with
#ManagedBean
#RequestScoped
public class UserBean {
private String userName;
private String password;
#EJB
private UserService service;
public String login() {
User user = service.find(userName, password);
if (user != null) {
FacesContext.getCurrentInstance().getExternalContext().getSessionMap("user", user);
return "home?faces-redirect=true";
} else {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Unknown login"));
return null;
}
}
// ...
}
Pay attention to the validate method's firm. It has an UIComponent parameter that is the component validated by the method. This UIComponent has both the current value (getValue()) and the value that the user submitted (getSubmittedValue()).
You might have to cast that UIComponent to the particular type of component you're validating (int this case, it's an UIInput).
Now, if you're going to validate both username and password prior to a log in, there are several ways to do it. In your case, validating the username field with the password field as an added parameter should suffice. You can achieve that by doing this:
<h:outputText value="user name" />
<h:inputText value="#userBean.userName" id="userName" validator="#{yourBean.validateLogin}">
<f:attribute name="pass" value="#{passwordField}" />
</h:inputText>
<h:outputText value="Password" />
<h:inputText value="#userBean.Password" id="passwd" binding="#{passwordField}"/>
Note that the binding in the password <h:inputText/> is related to the value of the pass of the <f:attribute/> tag nested in your username <h:inputText/>. With this setup, you can perform your validation like this:
public void validateLogin(FacesContext context, UIComponent component, Object value) throws ValidatorException {
//I suppose it's a typo, but your validate method lacks the return type.
String username = (String) value;
UIInput passwordInput = component.getAttributes().containsKey("pass") ?
(UIInput) component.getAttributes().get("pass") : null;
if(passwordInput != null) {
//Just to be sure the input was added as a parameter successfuly
String submittedPassword = passwordInput.getSubmittedValue();
//Now, do your validations based on the strings "username"
//and "password".
}
}
Since all of this is being done in the validation phase, the values aren't set in your managed bean yet, that's why you have to play around a little with the submitted values.

How to display and update a "sub-page" within a condition (using primefaces)

I have a scenario to achieve but I don't know how to do it(I'am using primefaces)
The scenario is:
I have a selectOneMenu that contain options that the user can choose one of them,
when the user choose an option ,a "form" or a "Sub-page" should appear below the selectOneMenu , the user should fill it.
The "Sub-page" change according to the choosen option
eg :option1 ---> Sub-Page1
option2 --->Sub-Page2 etc..
JSF
<h:selectOneMenu style="width:200px" immediate="true" value="#{ToolsKPI.myChoice}" onchange="submit()" valueChangeListener="#{BeanTest.selectChangeHandler}" required="true" >
<f:selectItems value="#{ToolsKPI.getMyListKPI()}" />
</h:selectOneMenu>
<p:panel rendered="#{BeanTest.showPanelBool}" >
<h1>KPI1</h1>
<br></br>
<h:inputText value="test1" />
</p:panel>
<p:panel rendered="#{BeanTest.showPanelBool1}" >
<br></br>
<h1>KPI2</h1>
<h:inputText value="test2" />
<h:inputText value="test3" />
</p:panel>
My Bean
public class BeanTest implements java.io.Serializable {
private String myChoice;
private boolean showPanelBool;
private boolean showPanelBool1;
public BeanTest() {
}
//getters ande setters
public void selectChangeHandler(ValueChangeEvent event){
myChoice = (String) event.getNewValue(); // Must however be the exact page URL. E.g. "contact.jsf".
FacesContext.getCurrentInstance().getExternalContext();
if(myChoice.equals("Number Of Closed issues") ){
this.showPanelBool = true;
} else{
this.showPanelBool = false;
this.showPanelBool1 = true;
}
FacesContext.getCurrentInstance().renderResponse();
}
}
You should really post some semblance of the code: a picture something. What you're probably looking for is a "p:outputPanel" component or something similar.
http://www.primefaces.org/showcase/ui/outputPanel.jsf
You can do something with a ValueChangeListener akin to
public void onSelectItem(ValueChangeEvent evt)
{
if("someValue".equals(evt.getNewValue())
showPageOne = true;//boolean
else
showPageTwo = true;//boolean
}
//JSF
<h:form id="myForm">
<h:selectOneMenu valueChangeListener="#{myBean.onSelectItem}" update="myForm">
<f:selectItems value="items">
</h:selectOneMenu>
<p:outputPanel rendered="#{myBean.showPageOne}">
hi I'm page one
</p:outputPanel>
<p:outputPanel rendered="#{myBean.showPageTwo}">
hi I'm page two
</p:outputPanel>
</h:form>
Sorry for the pseudo code, the examples on Primefaces will really help you here. OutputPanel has saved my bacon often. You'll need to specify an update target, but the example is really clear and easy to run. Play with it.
(Also Primefaces is fantastic you'll likely be very happy with their component suite)

Categories

Resources