JSF selectOneMenu select a item, inputText's readOnly property changes - jsf

I have a selectOneMenu and a InputText. I want to change readOnly="false" property of InputText when I select other option of selectOneMenu.
These are codes
<h:form>
<h:selectOneMenu id="customerCombo"
value="#{customer.selectedBank}"
required="true"
requiredMessage="Please select one">
<f:selectItem itemLabel="Seçiniz" noSelectionOption="true" />
<f:selectItems value="#{customer.banks}" />
<f:selectItem itemValue="Other" itemLabel="Other"/>
<f:validateRequired/>
</h:selectOneMenu>
<h:message for="customerCombo"/>
<br /><br />
<h:outputText value="other text" />
<h:inputText id="digerText" readonly="true"/>
<br /><br />
<h:commandButton value="submit" action="customerResult" />
</h:form>

Define a variable in your #ViewScoped backing bean that will correspond to the readOnly state
private boolean readOnly;
//getter and setter
Define a method that will toggle the state of the readOnly variable. This method will be called via ajax
public void toggleReadOnly(){
if(selectedBank.equals("Other"){
readOnly = true;
}
}
Bind the value of the readOnly variable to the <h:inputText/>
<h:inputText id="digerText" readonly="#{bean.readOnly}"/>
bean being (hehe) the name of your backing bean
Trigger the toggleReadOnly method from your dropdown menu
<h:selectOneMenu id="customerCombo"
value="#{customer.selectedBank}"
required="true"
requiredMessage="Please select one">
<f:ajax listener="#{bean.toggleReadOnly}" render="digerText"/>
</h:selectOneMenu>

Related

Primefaces slectOneMenu uses itemLabel as itemValue

I have an <p:selectOneMenu> which has an <f:selectItems> and in this <f:selectItems> I have set an itemLabel and an itemValue. The Item Value is an Enum Object which contains only a String and the Label is these String. The value of the <p:selectOneMenu> is an Collection of these Enum Objects. The selectOneMenu has an valueChangeListener and when its called it becomes the label as "new Value" and not the value. Has anyone an idea how I can fix this?
<h:form>
<p:selectOneMenu id="changeSpracheMenu"
value="#{sessionManager.currentUser.sprache}"
label="#{messageManager.getMessage('USER')}"
valueChangeListener="#{sessionManager.updateSpracheForCurrenUser}"
converter="sprachConverter">
<f:selectItem itemLabel="#{messageManager.getMessage('LANGUAGE')}"
noSelectionOption="true" />
<f:selectItems value="#{sprachManager.allSprachen}" var="sprache"
itemLabel="#{messageManager.getMessage('LANGUAGE_'.concat(sprache.name))}"
itemValue="#{sprache}" />
<p:ajax event="change" update="#form" />
</p:selectOneMenu>
</h:form>
Instead of using the Event of valueChangeListener, you can send the value of your selectItem to your bean.
For that, you have to modify
<p:ajax event="change" update="#form" />
To:
<p:ajax event="change" listener="#{yourBean.yourMethod(sprache)}" update="#form" />
Now in your bean:
private yourObject sprache;
//getter/setter
public void yourMethod(yourObject typeSprache){
whatever xyz = typeSprache.getWhatEverYouWant();
}

setting the values of credit/debit textbox in JSF

I have two textbox in jsf
1)creditAmount
2)debit amount
Now if I type in credit textbox, debit textbox should be zero and and viceversa.
How to do it in jsf? I wrote javascript function for it but it's not working. Is there any way to do it in jsf. I am new in jsf?
<p:inputText id="debitAmount" value="#{jvDetailsController.selected.debitAmount}"
title="#{bundle.CreateJvDetailsTitle_debitAmount}" required="true"
requiredMessage="#{bundle.CreateJvDetailsRequiredMessage_debitAmount}">
<f:convertNumber minFractionDigits="2" pattern="#0.000" />
</p:inputText>
You can easily do that with JSF ajax.
<h:inputText id="credit" value="#{bean.credit}">
<f:ajax event="blur" render="devit" listener="#{bean.changeDevit}"/>
</h:inputText>
<h:inputText id="devit" value="#{bean.devit}">
<f:ajax event="blur" render="credit" listener="#{bean.changeCredit}"/>
</h:inputText>
Here is corresponding ManagedBean
#ManagedBean(name="bean")
class Bean{
int devit;
int credit;
public void changeDevit(){
devit=0;
}
public void changeCredit(){
credit=0;
}
//getter & setter
}
You can use primefaces ajax for this like
<h:panelGrid columns="3">
<h:outputText value="Keyup: " />
<p:inputText id="counter">
<p:ajax event="keyup" update="out"
listener="#{counterBean.increment}"/>
</p:inputText>
<h:outputText id="out" value="#{counterBean.count}" />
</h:panelGrid>
Hope it will hep.

How to pass a parameter along with h:commandButton

One of the most common approaches to change locale in JSF+Seam - with <h:selectOneMenu>:
<h:form action="#{localeSelector.select}" rendered="false">
<h:selectOneMenu value="#{localeSelector.language}" onchange="submit()">
<f:selectItem itemLabel="English" itemValue="en" />
<f:selectItem itemLabel="Francais" itemValue="fr" />
</h:selectOneMenu>
</h:form>
I want to implement locale changes with buttons. So, the question is - how to pass the parameter (en, fr, etc.) to update the bean with <h:commandButton>? Maybe <h:inputHidden> would help?
Either pass as method argument (only if your environment supports EL 2.2),
<h:commandButton value="English" action="#{localeSelector.change('en')}" />
<h:commandButton value="Deutsch" action="#{localeSelector.change('de')}" />
<h:commandButton value="Français" action="#{localeSelector.change('fr')}" />
with
public void change(String language) {
locale = new Locale(language);
// ...
}
Or use <f:setPropertyActionListener>
<h:commandButton value="English" action="#{localeSelector.change}">
<f:setPropertyActionListener target="#{localeSelector.language}" value="en" />
</h:commandButton>
<h:commandButton value="Deutsch" action="#{localeSelector.change}">
<f:setPropertyActionListener target="#{localeSelector.language}" value="de" />
</h:commandButton>
<h:commandButton value="Français" action="#{localeSelector.change}">
<f:setPropertyActionListener target="#{localeSelector.language}" value="fr" />
</h:commandButton>
with
private String language;
public void change() {
locale = new Locale(language);
// ...
}
Or use <f:param>
<h:commandButton value="English" action="#{localeSelector.change}">
<f:param name="language" value="en" />
</h:commandButton>
<h:commandButton value="Deutsch" action="#{localeSelector.change}">
<f:param name="language" value="de" />
</h:commandButton>
<h:commandButton value="Français" action="#{localeSelector.change}">
<f:param name="language" value="fr" />
</h:commandButton>
with
public void change() {
locale = new Locale(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("language"));
// ...
}
(you can also let JSF automatically set it by a #ManagedProperty("#{param.language}"), but this requires the bean to be request scoped, or a <f:viewParam>, see also ViewParam vs #ManagedProperty(value = "#{param.id}"))
Enough ways to pass a parameter from view to controller. Take your pick. The <h:inputHidden> serves in JSF context a somewhat different purpose and it can only be manipulated by JavaScript in the onclick which is ugly.

JSF page doesnot work when i add selectOneMenu (prime faces)

i have a managed bean called Lecturer. Lecturer managed bean includes a relation between departments. I want to show all departments stored in the database. when i register a lecturer i need to get its department.
My Lecturer managed bean. i have proper setter and getter methods. i just omit it for clarification.
public class Lecturer
{
private String name;
private String surname;
private String email;
private String username;
private String password;
private List<Department> departments;
private LecturerService lecturerService;
private DepartmentService departmentService;
}
my Licturer.xhtml file:
<h:form>
<f:view>
<p:panelGrid columns="2">
<f:facet name="header">Lecturer Registration Form</f:facet>
<h:outputLabel for="name" value="Name :" />
<p:inputText id="name" value="#{Lecturer.name}" label="Name" required="true" />
<h:outputLabel for="surname" value="Surname :" />
<p:inputText id="surname" value="#{Lecturer.surname}" label="Surname" required="true" />
<h:outputLabel for="department" value="Department :" />
<p:selectOneMenu value="#{Lecturer.departments}" effect="fade" editable="true" var="p" >
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{Lecturer.departments}" var="lec"
itemLabel="#{lec.name}" itemValue="#{lec.name}"/>
</p:selectOneMenu>
<h:outputLabel for="email" value="Email :" />
<p:inputText id="email" value="#{Lecturer.email}" label="Email" required="true" />
<h:outputLabel for="username" value="User Name :" />
<p:inputText id="username" value="#{Lecturer.username}" label="Email" required="true" />
<h:outputLabel for="password" value="Password :" />
<p:inputText id="password" value="#{Lecturer.password}" label="Password" required="true" />
<f:facet name="footer">
<p:commandButton type="submit"
id="lecturer"
action="#{Lecturer.registerLecturer}"
value="Register" icon="ui-icon-disk">
</p:commandButton>
</f:facet>
</p:panelGrid>
</f:view>
</h:form>
my faces-config.xml
<managed-bean>
<managed-bean-name>Lecturer</managed-bean-name>
<managed-bean-class>com.studinfo.controller.Lecturer</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>departmentService</property-name>
<property-class>com.studinfo.services.DepartmentService</property-class>
<value>#{DepartmentService}</value>
</managed-property>
<managed-property>
<property-name>lecturerService</property-name>
<property-class>com.studinfo.services.LecturerService</property-class>
<value>#{LecturerService}</value>
</managed-property>
</managed-bean>
when i remove the selectOneMenu tag. my page works properly.
any idea about the solution?
Do i must add a converter between string and Department class?
The value attribute of p:selectOneMenu should hold the reference to a single department (this is the selected department) and not the whole list. You need to add a field for this in your bean, e.g.:
private Department selectedDepartment
// getter and setter
Then in your facelet change the value attribute of p:selectOneMenu and the f:selectItems:
<p:selectOneMenu value="#{Lecturer.selectedDepartment}" effect="fade"
editable="true" var="p" >
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{Lecturer.departments}" var="lec"
itemLabel="#{lec.name}" itemValue="#{lec}"/>
</p:selectOneMenu>
Furthermore you will need a converter to map selected strings to objects.

valuechangelistener does not populate values in text box

Here is my jsp:
<h:selectOneMenu value="#{member.dependentName}" onchange="this.form.submit()"
immediate="true" valueChangeListener="#{member.getDependentAddress}">
<f:selectItems value="#{member.dependentList}" />
</h:selectOneMenu>
<h:inputText value="#{member.personName}" immediate="true" />
<h:inputText value="#{member.dob}" immediate="true" />
And this, the function valuechangelistener fires.
public void getDependentAddress(ValueChangeEvent e) {
setPersonName((getDependentsList().get(e.getNewValue().toString())
.getDependentName()));
setDob(getDependentsList().get(e.getNewValue().toString()).getBirth());
System.out.println("New dob value : " + dob);
System.out.println("New name value : " + personName);
FacesContext.getCurrentInstance().renderResponse();
}
The two sysouts give the new value in the console but once the page loads, the fields are blank. I have tried all scopes for the bean. No go. What am i missing?
Thanks
You missed nothing. You've just something too much. To get it to work, you should remove immediate="true" from the to-be-changed components.
<h:selectOneMenu value="#{member.dependentName}" onchange="this.form.submit()"
immediate="true" valueChangeListener="#{member.getDependentAddress}">
<f:selectItems value="#{member.dependentList}" />
</h:selectOneMenu>
<h:inputText value="#{member.personName}" />
<h:inputText value="#{member.dob}" />
The immediate="true" on an UIInput component will cause its validations phase to take place in apply request values phase instead. This gives you the opportunity to use FacesContext#responseComplete() inside a valueChangeListener method skip other components which doesn't have immediate="true" set from being processed. As you have now, with immediate="true", they are also processed.
Please note that this is essentially a hack from the old JSF 1.x ages. If you're already using JSF 2.x, you should be using <f:ajax listener> instead.
<h:selectOneMenu value="#{member.dependentName}">
<f:selectItems value="#{member.dependentList}" />
<f:ajax listener="#{member.getDependentAddress}" render="name dob" />
</h:selectOneMenu>
<h:inputText id="name" value="#{member.personName}" />
<h:inputText id="dob" value="#{member.dob}" />
with
public void getDependentAddress() {
Dependent dependent = getDependentsList().get(dependentName); // Isn't that actually a Map instead of List?
personName = dependent.getDependentName();
dob = dependent.getBirth();
}

Resources