我有一个使用 jQuery datepicker 的 JSF (Mojarra) v2.1.11、Primefaces v3.4.2、Java 6 Web 应用程序。我正在使用一个与此类似的选择器:
$('#form1\\:dp').datepicker({showOn: 'button', buttonText: "Choose"});
这使用户能够单击按钮以调用日期选择器。我遇到的问题是用户提交表单后“按钮”消失了。显然,“按钮”仅在页面最初加载时加载一次。我想知道如何(最佳实践是)在提交/回发之间保留 JQuery 日期选择器“按钮”。
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"
});
}