calling a javascript function everytime a facelets component is loaded - java

I have created a custom facelets component and I need to set some value to the component everytime it loads based on the value it gets from the bean. I used window.onload function in the component and it works correctly when there is only one of this component in the page. But when I use to or more of this component in my page, only the first component gets its value set. I need a nice way to overcome this problem.
My xhtml is like this
<ui:composition>
<f:subview id="#{id}">
<div id="script" style="display: none;">
<script type="text/javascript">
//<![CDATA[
window.onload = function() {
//this function manipulates the value from the bean
};
function processNepCal(){
//this function is for processing the changed values
}
// ]]>
</script>
</div>
<rich:calendar datePattern="yyyy-MM-d" id="gregCal"
rendered="#{backingBean.dataSetParam.userSession.nepDate }"
value="#{value}" inputClass="#{empty styleClass ? '' : styleClass}" />
<h:panelGroup
rendered="#{!backingBean.dataSetParam.userSession.nepDate}">
<h:panelGrid columns="3">
<rich:comboBox id="nepCalYear" styleClass="datecls"
defaultLabel="year" onchange="processNepCal()" width="53px"
readonly="true" directInputSuggestions="true">
<f:selectItem itemLabel="2067" itemValue="2067" />
<f:selectItem itemLabel="2068" itemValue="2068" />
<f:selectItem itemLabel="2069" itemValue="2069" />
<f:selectItem itemLabel="2070" itemValue="2070" />
</rich:comboBox>
<rich:comboBox id="nepCalMonth" styleClass="datecls"
onchange="processNepCal()" width="65px" readonly="true"
defaultLabel="month" directInputSuggestions="true">
<f:selectItem itemLabel="Baisakh" itemValue="Baisakh" />
<f:selectItem itemLabel="Jestha" itemValue="Jestha" />
<f:selectItem itemLabel="Ashad" itemValue="Ashad" />
<f:selectItem itemLabel="Shrawan" itemValue="Shrawan" />
<f:selectItem itemLabel="Bhadra" itemValue="Bhadra" />
<f:selectItem itemLabel="Ahswin" itemValue="Ahswin" />
<f:selectItem itemLabel="Kartik" itemValue="Kartik" />
<f:selectItem itemLabel="Mangsir" itemValue="Mangsir" />
<f:selectItem itemLabel="Paush" itemValue="Paush" />
<f:selectItem itemLabel="Magh" itemValue="Magh" />
<f:selectItem itemLabel="Falgun" itemValue="Falgun" />
<f:selectItem itemLabel="Chaitra" itemValue="Chaitra" />
</rich:comboBox>
<rich:comboBox id="nepCalDay" styleClass="datecls"
onchange="processNepCal()" width="43px" readonly="true"
defaultLabel="day" directInputSuggestions="true">
<f:selectItem itemLabel="01" itemValue="01" />
<f:selectItem itemLabel="02" itemValue="02" />
<f:selectItem itemLabel="03" itemValue="03" />
<f:selectItem itemLabel="04" itemValue="04" />
<f:selectItem itemLabel="05" itemValue="05" />
<f:selectItem itemLabel="06" itemValue="06" />
<f:selectItem itemLabel="07" itemValue="07" />
<f:selectItem itemLabel="08" itemValue="08" />
<f:selectItem itemLabel="09" itemValue="09" />
<f:selectItem itemLabel="10" itemValue="10" />
<f:selectItem itemLabel="11" itemValue="11" />
<f:selectItem itemLabel="12" itemValue="12" />
<f:selectItem itemLabel="13" itemValue="13" />
<f:selectItem itemLabel="14" itemValue="14" />
<f:selectItem itemLabel="15" itemValue="15" />
<f:selectItem itemLabel="16" itemValue="16" />
<f:selectItem itemLabel="17" itemValue="17" />
<f:selectItem itemLabel="18" itemValue="18" />
<f:selectItem itemLabel="19" itemValue="19" />
<f:selectItem itemLabel="20" itemValue="20" />
<f:selectItem itemLabel="21" itemValue="21" />
<f:selectItem itemLabel="22" itemValue="22" />
<f:selectItem itemLabel="23" itemValue="23" />
<f:selectItem itemLabel="24" itemValue="24" />
<f:selectItem itemLabel="25" itemValue="25" />
<f:selectItem itemLabel="26" itemValue="26" />
<f:selectItem itemLabel="27" itemValue="27" />
<f:selectItem itemLabel="28" itemValue="28" />
<f:selectItem itemLabel="29" itemValue="29" />
<f:selectItem itemLabel="30" itemValue="30" />
<f:selectItem itemLabel="31" itemValue="31" />
<f:selectItem itemLabel="32" itemValue="32" />
</rich:comboBox>
</h:panelGrid>
<h:inputText id="nepCalVal" value="#{value}"
styleClass="#{empty styleClass ? '': styleClass}"
style="display:none;">
<f:converter converterId="NepaliDateConverter"></f:converter>
</h:inputText>
</h:panelGroup>
</f:subview>
</ui:composition>

First of all, why don't you just use the component's value attribute for this?
<x:someComponent value="#{bean.value}" />
Do if necessary the manipulation just straight in the bean or with help of a fullworthy Converter.
As to your concrete problem, everytime you declare a window.onload = function() {} the previously declared one will be overridden. The window can has only one onload function. You basically need to put them all in the same onload function.
Better is to use element.addEventListener instead. Here's a crossbrowsercompatible snippet:
function addEvent(element, event, func) {
if (element.addEventListener) {
element.addEventListener(event, func, false); // Real browsers.
return true;
} else if (element.attachEvent) {
return element.attachEvent("on" + event, func); // MSIE<=8.
} else {
return false; // Really ancient browsers.
}
}
So that you can use
addEvent(window, "load", function() {
// Do here your thing.
});

Related

How I pass values from one JSF to another while both are backed by separate Request scoped managed beans

I have gone through a few answers on this topic already, especially from BalusC blogs. But its somehow not working in the implementation below. Am I missing something or doing something completely wrong.
I have a basic form with a few dropdowns, when I submit the form i.e. call submitDetails it returns the following String "phaseTwo?faces-redirect=true" which is backed by bean called PhaseTwoController.java
So on submit from phaseOne.xhtml I want to see phaseTwo.xhtml with values selected on phaseOne.xhtml
Here is the code:
THis is PhaseOne.xhtml backed by PhaseOneController.java
<h:form>
<p:panel header="Select country" style="margin-bottom:10px;">
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel for="country" value="Country: " />
<p:selectOneMenu id="country" value="#{phaseOneController.country}" style="width:150px">
<p:ajax listener="#{phaseOneController.onCountryChange}" update="subCategory" />
<f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{phaseOneController.countries}" />
</p:selectOneMenu>
<p:outputLabel for="province" value="Province: " />
<p:selectOneMenu id="province" value="#{phaseOneController.province}" style="width:150px">
<p:ajax listener="#{phaseOneController.onProvinceChange}" update="city" />
<f:selectItem itemLabel="Select Province" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{phaseOneController.provinces}" />
</p:selectOneMenu>
<p:outputLabel for="city" value="City: " />
<p:selectOneMenu id="city" value="#{phaseOneController.city}" style="width:150px">
<f:selectItem itemLabel="Select City" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{phaseOneController.cities}" />
</p:selectOneMenu>
</h:panelGrid>
<p:separator />
<p:commandButton value="Select" actionListener="#{phaseOneController.submitDetails}" icon="ui-icon-check">
<f:param name="country" value="#{phaseOneController.country}" />
<f:param name="province" value="#{phaseOneController.province}" />
<f:param name="city" value="#{phaseOneController.city}" />
</p:commandButton>
</p:panel>
</h:form>
#ManagedBean
#RequestScoped
public class PhaseTwoController {
#ManagedProperty(value="#{param.country}")
private String country;
#ManagedProperty(value="#{param.province}")
private String province;
public void setCountry(String country) {
this.country = country;
}
public void setProvince(String province) {
this.province = province;
}
public void setCity(String city) {
this.city = city;
}
}
P.S. I havent posted the code for PhaseOneController.java as I am not sure if it is needed. But if someone wants to look at it, I can post it.

p:commandButton not working in p:wizard

The problem that I am facing is that <p:commandButton> with id="emailav" doesn't call the action method emailAvailability. I am using it inside p:wizard and also I have included the following block of code inside h:form.
1) xhtml
<p:tab id="personal" title="Personal">
<p:panel header="Personal Details" style="font-size:small">
<h:panelGrid columns="3" columnClasses="label, value"
styleClass="grid">
<h:outputText value="Username*" />
<p:inputText id="usrname" required="true" label="Username"
value="#{registrationBean.user.userName}"
requiredMessage="Username required" />
<p:message for="usrname"></p:message>
<h:outputText value="Firstname: *" />
<p:inputText id="frstname" required="true" label="Firstname"
value="#{registrationBean.user.firstName}"
requiredMessage="Firstname required" />
<p:message for="frstname"></p:message>
<h:outputText value="Lastname: *" />
<p:inputText id="lstname" required="true" label="Lastname"
value="#{registrationBean.user.lastName}"
requiredMessage="Lastname required" />
<p:message for="lstname"></p:message>
<h:outputText value="Password: *" />
<p:password id="pwd1" value="#{registrationBean.user.password}"
feedback="true" match="pwd2" label="Password" required="true"
requiredMessage="Password required" />
<p:message for="pwd1"></p:message>
<h:outputText value="Confirm Password: *" />
<p:password id="pwd2" value="#{registrationBean.user.password}"
label="Confirm Password" required="true"
requiredMessage="Enter the password again" />
<p:message for="pwd2"></p:message>
<h:outputText value="Date of Birth(dd/MM/yyyy):" />
<p:inputText id="dob" label="Date of Birth"
value="#{registrationBean.user.birthDate}" />
<p:message for="dob"></p:message>
<h:outputText value="Gender: " />
<p:selectOneMenu id="gender" value="#{registrationBean.user.gender}">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItem itemLabel="Male" itemValue="Male" />
<f:selectItem itemLabel="Female" itemValue="Female" />
<f:selectItem itemLabel="Other" itemValue="Other" />
</p:selectOneMenu>
<p:message for="gender"></p:message>
<h:outputText value="Relationship Status: " />
<p:selectOneMenu id="relationship"
value="#{registrationBean.user.relationship}">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItem itemLabel="Single" itemValue="Single" />
<f:selectItem itemLabel="Committed" itemValue="Committed" />
<f:selectItem itemLabel="Open relationship" itemValue="Open relationship" />
<f:selectItem itemLabel="Its comlicated" itemValue="Its complicated" />
</p:selectOneMenu>
<p:message for="relationship"></p:message>
<h:outputText value="Email: *" />
<p:inputText id="email" label="Email"
value="#{registrationBean.user.email}" required="true"
requiredMessage="Email required"/>
<p:message for="email"/>
<p:commandButton id="emailav" value="email availability"
action="#{registrationBean.emailAvailability}" update="emailav" />
<p:message for="emailav"></p:message>
<p:commandButton style="display:none"/>
<h:outputText value="Skip to last: " />
<h:selectBooleanCheckbox value="#{registrationBean.skip}" />
</h:panelGrid>
</p:panel>
</p:tab>
2)Backing bean
public String emailAvailability() {
logger.info("inside emailAvailability");
FacesContext context = FacesContext.getCurrentInstance();
Query query = em.createQuery("SELECT u FROM User u", User.class);
List<User> results = query.getResultList();
Iterator<User> it = results.listIterator();
while (it.hasNext()) {
if (it.next().getEmail().equals(user.getEmail())) {
context.addMessage(null,
new FacesMessage("Email already taken"));
}
}
context.addMessage(null, new FacesMessage("Email not taken"));
return "success";
}
try adding process="#this"
like
<p:commandButton
value="Add Site 1"
update="editor"
title="Remover"
action="#{jobEngine2MB.addSiteType1}"
process="#this" />

How to update JSF SelectManyListBox items from selected item in SelectOneMenu?

I have the following components:
<h:selectOneMenu id="company"
value="#{companyController.selected.companyId}"
onchange="?????????">
<f:selectItems value="#{companyController.itemsAvailableSelectOne}"/>
</h:selectOneMenu>
<h:outputLabel value="some value" for="locations" />
<h:selectManyListbox id="locations" >
<f:selectItems value="#{companyController.selected.locationCollection}"/>
</h:selectManyListbox>
Every time a company is selected in the SelectOneMenu i need to update the items in the SelectManyListBox.
Please Help me
Thank you very much!
You are going to want to use <f:ajax>. Perhaps something like this:
<h:selectOneMenu id="company"
value="#{companyController.selected.companyId}">
<f:ajax event="valueChange" execute="#this" render="#this locations" />
<f:selectItems value="#{companyController.itemsAvailableSelectOne}"/>
</h:selectOneMenu>
<h:outputLabel value="some value" for="locations" />
<h:selectManyListbox id="locations" >
<f:selectItems value="#{companyController.selected.locationCollection}"/>
</h:selectManyListbox>
Then you could modify your selected objects setCompanyId method to update the locationCollection:
public void setCompanyId( long companyId ) {
this.companyId = companyId;
// now update your location collection
this.locationCollection = locationCollectionMap.get( companyId );
}

Static object in viewScoped bean for place holder of fileUpload multiples

I'm using a primefaces fileUpload with multiples and fileUploadListener method. The listener is called each time for each file uploaded, I would like to store each file in a arrayList and after the last is uploaded loop through the list and store them in a database.
My managed bean is viewScoped, would it be alright to have a static arrayList to store the uploads or is there a better way to deal with this?
Facelet
<p:fieldset legend="Info">
<p:selectOneRadio id="newold" value="#{newmailer.selectedCompStatus}">
<f:selectItem itemLabel="Existing Company" itemValue="exist" />
<f:selectItem itemLabel="New Company" itemValue="new" />
<p:ajax listener="#{newmailer.setComp}" event="valueChange" update="main" execute="#all" />
</p:selectOneRadio>
<p:panelGrid columns="2" styleClass="Grid" style="margin-bottom:10px" cellpadding="5" rendered="#{newmailer.exist}">
<h:outputLabel value="Company" id="Company" />
<p:selectOneMenu value="#{newmailer.selectedComp}" id="companies" label="Company">
<f:selectItem itemLabel="Choose Company" itemValue="" />
<f:selectItems value="#{mailerInfo.companies}" var="comp" />
<p:ajax listener="#{demo.getCompanyMailer}" event="valueChange" execute="#all" />
</p:selectOneMenu>
</p:panelGrid>
<p:panelGrid id="newPanel" styleClass="Grid" columns="2" style="margin-bottom:10px" cellpadding="5" rendered="#{!newmailer.exist and newmailer.showInfo}">
<h:outputLabel value="Company" id="Company2" />
<p:inputText id="newCompany" value="#{newmailer.selectedComp}" immediate="true">
<f:ajax event="change"/>
</p:inputText>
</p:panelGrid>
<p:panelGrid styleClass="Grid" columns="2" style="margin-bottom:10px" cellpadding="5" rendered="#{newmailer.showInfo}">
<h:outputLabel value="Mailer Id" />
<p:inputText id="mailerId" value="#{newmailer.mailerId}" immediate="true">
<f:ajax event="change"/>
</p:inputText>
</p:panelGrid>
</p:fieldset>
<p:fieldset legend="Status" rendered="#{newmailer.showInfo}">
<p:selectOneRadio id="status" value="#{newmailer.status}" immediate="true">
<f:selectItem itemLabel="Active" itemValue="A" />
<f:selectItem itemLabel="Inactive" itemValue="I" />
<f:ajax event="change"/>
</p:selectOneRadio>
</p:fieldset>
<p:fieldset legend="Description" rendered="#{newmailer.showInfo}">
<p:inputTextarea rows="5" cols="30" value ="#{newmailer.desc}" counter="counter" maxlength="10"
counterTemplate="{0} characters remaining." autoResize="false" immediate="true">
<f:ajax event="change"/>
</p:inputTextarea>
</p:fieldset>
<p:fieldset legend="Load Image" rendered="#{newmailer.showInfo}">
<p:fileUpload fileUploadListener="#{newmailer.handleFileUpload}"
mode="advanced"
update="messages"
sizeLimit="100000"
allowTypes="/(\.|\/)(gif|jpe?g|png|pdf)$/"
process="#form"
multiple="true"
/>
</p:fieldset>
<p:growl id="messages" showDetail="true"/>
</p:panelGrid>
<!-- <p:commandButton value="Submit" type="sumbit" action="#{newmailer.submit}" ajax="false"/>-->
</h:form>
Bean
#ViewScoped
#ManagedBean(name="newmailer")
public class NewMailerBean implements Serializable{
private String status;
private String compStatus;
private String selectedCompStatus;
private String selectedComp;
private String mailerId;
private String desc;
private boolean exist;
private boolean showInfo;
public static Mailer mail;
public static boolean multi=false;
public ArrayList<byte []> images = new ArrayList<byte []>();
public void handleFileUpload(FileUploadEvent event) {
Mailer mail = new Mailer();
mail.setCompany(selectedComp);
mail.setDesc(desc);
mail.setMailerId(mailerId);
mail.setStatus(status);
mail.setUserId("test");
try{
InputStream inputStream = event.getFile().getInputstream();
ByteArrayOutputStream out=new ByteArrayOutputStream(1024);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
byte[] bytearray = out.toByteArray();
inputStream.close();
out.flush();
out.close();
images.add(bytearray);
mail.setImg(bytearray);
}catch(IOException e) {
e.printStackTrace();
}
A static variable is class-level and thus shared among all instances of the same class and thus behaves like as a global application-wide variable. Every single visitor of your webapp would share the very same variable. Every single uploaded file of every single visitor would end up in the same list which is in turn visible to every single visitor.
Is this what you really want?
I don't think so. Just don't make it a static variable at all. Remove the static modifier and you should be all set with a view scoped bean. A view scoped bean lives as long as you're interacting with the same view by ajax.
See also:
Basic Java tutorial - Understanding instance and class members
How to choose the right bean scope?

h:selectOneMenu change event with p:ajax

I am trying to get the value from on change in h:selectOneMenu using p:ajax.
But I am getting null value always, dont know whats wrong below is the code.
<h:form>
<h:selectOneMenu id="selectMenu" value="#{userHomeController.gymsSelectType}">
<f:selectItem itemLabel="Close to me" itemValue="closest" />
<f:selectItem itemLabel="Visited by me" itemValue="visited" />
<p:ajax process="selectMenu" listener="#{userHomeController.selectMenuListener}" event="change" update=":home-form:panel" />
</h:selectOneMenu>
</h:form>
and the bean class is
public void selectMenuListener() {
System.out.println("-------- >> " + gymsSelectType); // here null coming
if (gymsSelectType.equals("a")) {
//
} else {
//
}
}
this is a viewscoped class.
and below setter for the variable gymsSelectType is also prints null
public void setGymsSelectType(String gymsSelectType) {
System.out.println("------------ >> "+gymsSelectType);
this.gymsSelectType = gymsSelectType;
}
Have your tries this
<p:ajax process="#this" listener="#{userHomeController.selectMenuListener}" event="change" update=":home-form:panel" />
Try this
<p:ajax partialSubmit="true" listener="#{userHomeController.selectMenuListener}" event="change" update=":home-form:panel" />

Categories

Resources