I have a JSF (Mojarra) v2.1.11, Primefaces v3.4.2, Java 6 web application using jQuery datepicker. I am using a selector that looks similar to this:
$('#form1\\:dp').datepicker({showOn: 'button', buttonText: "Choose"});
This enables the user to click the button in order to invoke the datepicker. The issue I'm having is that the "button" disappears after the user submits the form. Apparently, the "button" loads only once when the page is initially loaded. I'd like to know how (what the best practice is) to persist the JQuery datepicker "button" between submits/postbacks.
index.xhtml
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:p="http://primefaces.org/ui"> <f:view contentType="text/html"> <h:head> <title>testcal - index.xhtml</title> <meta charset="utf-8" /> </h:head> <h:body> <h:form id="queryForm"> <f:event type="postValidate" listener="#{testBean.validate}" /> <p:panel id="queryPanel" header="Test p:calendar, datepicker, validation, etc..." style="width:100%;"> <p:focus context="queryPanel"/> <h:panelGroup id="msgs"> <p:message id="lastName_msg" for="lastName" style="display:none;"/> <p:message id="birthDate_msg" for="birthDate" style="display:none;"/> <p:message id="startDate_msg" for="startDate" style="display:none;"/> <p:message id="endDate_msg" for="endDate" style="display:none;"/> <p:message id="drpdwn_msg" for="drpdwn" style="display:none;"/> </h:panelGroup> <br/> <br/> <h:panelGroup id="querypanelgroup" style="display:inline-block;"> <p:focus context="querypanelgroup"/> <h:panelGroup> <h:panelGroup style="text-align:right;vertical-align:middle;display:inline-block;width:150px"> <p:outputLabel style="margin-right: 5px;" value="Last Name:" for="lastName"/> </h:panelGroup> <h:panelGroup style="margin-left: 4px; vertical-align:middle;display:inline-block;width:250px;"> <p:inputText id="lastName" value="#{testBean.parmMap['lastName']}" requiredMessage="last name required" size="95" maxlength="95" onfocus="$('#queryForm\\:msgs > div').hide();$('#queryForm\\:msgs > div').eq(0).show();return false;" > </p:inputText> </h:panelGroup> </h:panelGroup> <br/> <br/> <h:panelGroup> <h:panelGroup style="text-align:right;vertical-align:middle;display:inline-block;width:150px"> <p:outputLabel style="margin-right: 5px;" value="Birth Date:" for="birthDate"/> </h:panelGroup> <h:panelGroup style="margin-left: 4px; vertical-align:middle;display:inline-block;width:250px;"> <p:inputText id="birthDate" value="#{testBean.parmMap['birthDate']}" requiredMessage="birth date required" converter="dpConverter" styleClass="datePicker" onfocus="$('#queryForm\\:msgs > div').hide();$('#queryForm\\:msgs > div').eq(1).show();$(this).mask('99/99/9999');return false;"> <p:ajax event="change" process="@this" update="@this"/> </p:inputText> </h:panelGroup> </h:panelGroup> <br/> <br/> <h:panelGroup> <h:panelGroup style="text-align:right;vertical-align:middle;display:inline-block;width:150px"> <p:outputLabel style="margin-right: 5px;" value="Start Date:" for="startDate"/> </h:panelGroup> <h:panelGroup style="margin-left: 4px; vertical-align:middle;display:inline-block;width:250px;"> <p:inputText id="startDate" value="#{testBean.parmMap['startDate']}" requiredMessage="start date required" converter="dpConverter" styleClass="datePicker" onfocus="$('#queryForm\\:msgs > div').hide();$('#queryForm\\:msgs > div').eq(2).show();$(this).mask('99/99/9999');return false;"> <!-- optional to populate another field with same value... onchange="$('...hashSymbolHere...queryForm\\:endDate').val($(this).val());"> --> <p:ajax event="change" process="@this" update="@this"/> </p:inputText> </h:panelGroup> </h:panelGroup> <br/> <br/> <h:panelGroup> <h:panelGroup style="text-align:right;vertical-align:middle;display:inline-block;width:150px"> <p:outputLabel for="endDate" value="Enter a date:"/> </h:panelGroup> <h:panelGroup style="margin-left: 4px; vertical-align:middle;display:inline-block;width:250px;"> <p:inputText id="endDate" value="#{testBean.parmMap['endDate']}" requiredMessage="endDate required" converter="dpConverter" styleClass="datePicker" onfocus="$('#queryForm\\:msgs > div').hide();$('#queryForm\\:msgs > div').eq(3).show();$(this).mask('99/99/9999');return false;"> <p:ajax event="change" process="@this" update="@this"/> </p:inputText> </h:panelGroup> </h:panelGroup> <br/> <br/> <h:panelGroup> <h:panelGroup style="text-align:right;vertical-align:middle;display:inline-block;width:150px"> <p:outputLabel for="drpdwn" value="Choose from drop down selction:"> <h:panelGroup rendered="false" style="margin-left: 2px;" id="drpdwnRequired" styleClass="requiredInd">*</h:panelGroup> </p:outputLabel> </h:panelGroup> <h:panelGroup style="margin-left: 4px; vertical-align:middle;display:inline-block;width:250px;"> <p:autoComplete id="drpdwn" style="overflow: hidden" maxResults="200" scrollHeight="150" dropdown="false" value="#{testBean.parmMap['drpdwn']}" completeMethod="#{testBean.drpdwnListComplete}" var="entry" itemLabel="#{entry.split(':')[1]}" itemValue="#{entry.split(':')[0]}" minQueryLength="1" forceSelection="true" onfocus="$('#queryForm\\:msgs > div').hide();$('#queryForm\\:msgs > div').eq(4).show();" > </p:autoComplete> </h:panelGroup> </h:panelGroup> <br/> <br/> <p:commandButton id="submit" value="Submit" oncomplete="applyDatePicker();" type="submit" update="@form" process="@form" action="#{testBean.submitQuery}" style="width:150px;" styleClass="button"/> <p:commandButton value="Reset" update="@form" onclick="location.reload();return true;" process="@this" actionListener="#{testBean.reset}" immediate="true" ajax="false"/> </h:panelGroup> </p:panel> </h:form> <h:outputStylesheet library="styles" name="query.css" /> <h:outputScript library="primefaces" name="/jquery/jquery.js" /> <h:outputScript library="primefaces" name="/jquery/plugins/ui/jquery-ui.custom.js" /> <h:outputScript library="primefaces" name="/jquery/plugins/inputmask/maskedinput.js" /> <h:outputScript library="js" name="testcal2.js" target="head" /> </h:body> </f:view> </html>
TestBean.java
package aaa.bbb.ccc.war; import java.io.IOException; import java.io.Serializable; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import javax.faces.application.FacesMessage; import javax.faces.component.UIForm; import javax.faces.component.UIInput; import javax.faces.component.UIPanel; import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; import javax.faces.event.ComponentSystemEvent; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component("testBean") @Scope("view") public class TestBean implements Serializable { private static final List<String> drpdwnListOrig; private static final String[] prfx = {"aaa","bbb","ccc", "ddd", "eee", "fff","ggg","hhh","iii","jjj","kkk","lll","mmm","nnn","ooo","ppp","qqq","rrr","sss","ttt","uuu","vvv","www","xxx","yyy","zzz"}; //////////////////////////// [static initializer] /////////////////////////////// //////////////////////////// [static initializer] /////////////////////////////// //////////////////////////// [static initializer] /////////////////////////////// static { //drpdwnListOrig... List<String> l = getListOfStrings(); drpdwnListOrig = Collections.unmodifiableList(null == l ? new ArrayList<String>() : l); FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("drpdwnListOrig", drpdwnListOrig); List<String> testList = (List<String>) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("drpdwnListOrig"); } public TestBean() { parmMap = this.getParmMap(); FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("parmMap", parmMap); } public void reset(ActionEvent event) { LinkedHashMap<String, Object> m = new LinkedHashMap<String, Object>(); FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("parmMap"); setParmMap(m); } public String submitQuery() { FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("hitlistData"); if (this.getParmMap().isEmpty()) { return ""; } return "/page2.xhtml?faces-redirect=true"; } private static LinkedHashMap<String, Object> parmMap; public LinkedHashMap<String, Object> getParmMap() { LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("parmMap"); if (null == map) { map = new LinkedHashMap<String, Object>(); } return map; } public void setParmMap(LinkedHashMap<String, Object> map) { parmMap = map; FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("parmMap", parmMap); } private static SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy"); public void validate(ComponentSystemEvent e) throws ParseException { LinkedHashMap parmMap = this.getParmMap(); UIForm queryForm = (UIForm) e.getComponent(); UIInput lastName_c = (UIInput) queryForm.findComponent("lastName"); String lastName = (String) (lastName_c.getValue()); UIInput birthDate_c = (UIInput) queryForm.findComponent("birthDate"); birthDate_c.setValid(true); String birthDate = (String) birthDate_c.getValue(); FacesContext fc = FacesContext.getCurrentInstance(); if (null != lastName && lastName.trim().length() > 0) { birthDate_c.setRequired(true); if (null == birthDate || birthDate.length() < 1) { birthDate_c.setValid(false); fc.addMessage(birthDate_c.getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "birth date is required", "birth date is required")); fc.renderResponse(); } else { birthDate_c.setValid(true); } } else { birthDate_c.setValid(true); birthDate_c.setRequired(false); } } //////////////////////////// autocomplete /////////////////////////////// //////////////////////////// autocomplete /////////////////////////////// //////////////////////////// autocomplete /////////////////////////////// private static List<String> drpdwnList; public static List<String> getDrpdwnList() { if (null == drpdwnList) { drpdwnList = (null == drpdwnList ? (List<String>) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("drpdwnListOrig") : drpdwnListOrig); } return drpdwnList; } public void setDrpdwnList(List<String> data) throws IOException { drpdwnList = data; } public static List<String> drpdwnListComplete(String s) //autocomplete "completeMethod"... { List<String> list = getDrpdwnList(); List<String> drpdwnSuggestions = new ArrayList<String>(); for (String ss : list) { if (ss.toLowerCase().contains(s.toLowerCase())) { drpdwnSuggestions.add(ss); } } FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("drpdwnSuggestions", drpdwnSuggestions); return drpdwnSuggestions; } //////////////////////////// get listbox values /////////////////////////////// //////////////////////////// get listbox values /////////////////////////////// //////////////////////////// get listbox values /////////////////////////////// public static List<String> getListOfStrings() //(String sql) { List<String> list = new ArrayList<String>(); int ii=0; String key=null; String val=null; for (int i=0;i< 3500; i++) { if (ii > 25) { ii=0; } key = (i + "").trim(); val = (i + prfx[ii]).trim(); list.add(key + ":" + val); ii++; } return list; } }
testcal2.js
$(document).ready(function() { applyDatePicker(); }); function applyDatePicker(){ $('.datePicker').datepicker( { showOn: 'button', buttonText: "Choose", showButtonPanel: true, showOptions: {direction: 'up'}, changeYear: true, changeMonth: true, yearRange: "c-120:c+0" }); }