jQuery - 日期选择器未填充哈希映射日期字段
jQuery - Datepicker not populating for hashmap date fields
我正在尝试使用 jQuery 日期选择器函数来填充日期字段,这些字段是散列图中对象集的一部分。
我们正在使用 STRUTS 1 来映射我们的表单数据 - 对于我们的大部分数据来说,这就足够了。
我之前已经检查并写出这些字段,以便可以通过手动输入日期来填充它们,现在我想添加 jQuery 日期选择器以允许用户 select弹出式日历中的日期。我正在使用 Chrome。下面的代码片段。
<script>
$(function() {
$( ".datePick").datepicker({
dateFormat: 'mm/dd/yy',
showOn: "button",
buttonImage: "images/calendar.png",
buttonImageOnly: true,
buttonText: "Select date",
onSelect: function(dateText,inst)
{
id=$(this).attr('id');
pos = id.indexOf("(") + 1;
counter = id.slice(pos, -1);
id=id.replace("("+counter+")","");
pieces = dateText.split("/");
$("#"+ id+"MM("+counter+")").val(pieces[0]);
$("#"+ id+"DD("+counter+")").val(pieces[1]);
$("#"+id +"YYYY("+counter+")").val(pieces[2]);
}
});
});
</script>
<!-- "counter" is an integer which keeps track of what iteration of the
hashmap is being accessed, propertyValue is a string that allows me to
dynamically change the property of each form-->
<tr>
<td align="right" colspan="1">
<label for="setOfObjectsStartMMDtH("+counter+")">
<%=label.makeLabel(XXXXForm.FORM_KEY_VALUE)%></label>
</td>
<td align="left" colspan="4">
<% propertyValue="setOfObjectsStartDtHMM("+counter+")";%>
<html:text property="<%=propertyValue%>" styleId="<%=propertyValue%>"
size="2" maxlength="2"/> /
<% propertyValue="setOfObjectsStartDtHDD("+counter+")";%>
<html:text property="<%=propertyValue%>" styleId="<%=propertyValue%>"
size="2" maxlength="2"/> /
<% propertyValue="setOfObjectsStartDtHYYYY("+counter+")";%>
<html:text property="<%=propertyValue%>" styleId="<%=propertyValue%>"
size="4" maxlength="4"/>
<% propertyValue="setOfObjectsStartDtH("+counter+")";%>
<html:hidden styleId="<%=propertyValue%>" property="<%=propertyValue%>"
styleClass="datePick"+counter></html:hidden>
这是我的 getter 和 setter 的样子。
private final HashMap setOfObjects = new HashMap();
/**
* @param startDtH the setOfObjectsStartDtH to set
*/
public void setSetOfObjectsStartDtH(String key, String startDtH) {
setOfObjects obj = getSetOfObjects(key);
obj.setStartDtH(startDtH);
}
/**
* @return the startDtH
*/
public String getSetOfObjectsStartDtH(String key) {
if(setOfObjectss.containsKey(key)){
SetOfObjects obj = getSetOfObjects(key);
return obj.getStartDtH();
}
return "";
}
/**
* @param startDtHDD the startDtHDD to set
*/
public void setSetOfObjectsStartDtHDD(String key, String startDtHDD) {
SetOfObjects obj = getSetOfObjects(key);
obj.setStartDtHDD(startDtHDD);
}
/**
* @return the startDtHDD
*/
public String getSetOfObjectsStartDtHDD(String key) {
if(setOfObjectss.containsKey(key)){
SetOfObjects obj = getSetOfObjects(key);
return obj.getStartDtHDD();
}
return "";
}
/**
* @param startDtHMM the startDtHMM to set
*/
public void setSetOfObjectsStartDtHMM(String key, String startDtHMM) {
SetOfObjects obj = getSetOfObjects(key);
obj.setStartDtHMM(startDtHMM);
}
/**
* @return the startDtHMM
*/
public String getSetOfObjectsStartDtHMM(String key) {
if(setOfObjectss.containsKey(key)){
SetOfObjects obj = getSetOfObjects(key);
return obj.getStartDtHMM();
}
return "";
}
/**
* @param startDtHYYYY the startDtHYYYY to set
*/
public void setSetOfObjectsStartDtHYYYY(String key, String startDtHYYYY) {
SetOfObjects obj = getSetOfObjects(key);
obj.setStartDtHYYYY(startDtHYYYY);
}
/**
* @return the startDtHYYYY
*/
public String getSetOfObjectsStartDtHYYYY(String key) {
if(setOfObjectss.containsKey(key)){
SetOfObjects obj = getSetOfObjects(key);
return obj.getStartDtHYYYY();
}
return "";
}
private SetOfObjects getSetOfObjects(String key){
if(setOfObjects.containsKey(key))
return (SetOfObjects)setOfObjects.get(key);
SetOfObjects set = new SetOfObjects();
set.setId(Integer.parseInt(key));
setOfObjects.put(key, set);
return set;
}
这是 SetOfObjects 的样子:
public class SetOfObjects{
private String startDtH = "";
private String startDtHMM = "";
private String startDtHDD = "";
private String startDtHYYYY = "";
/**
* @param startDtH the startDtH to set
*/
public void setStartDtH(String startDtH) {
startDtH = startDtH;
}
/**
* @return the startDtH
*/
public String getStartDtH() {
return startDtH;
}
/**
* @param startDtHMM the startDtHMM to set
*/
public void setStartDtHMM(String startDtHMM) {
this.startDtHMM = startDtHMM;
}
/**
* @return the startDtHMM
*/
public String getStartDtHMM() {
return startDtHMM;
}
/**
* @param startDtHDD the startDtHDD to set
*/
public void setStartDtHDD(String startDtHDD) {
this.startDtHDD = startDtHDD;
}
/**
* @return the startDtHDD
*/
public String getStartDtHDD() {
return startDtHDD;
}
/**
* @param startDtHYYYY the startDtHYYYY to set
*/
public void setStartDtHYYYY(String startDtHYYYY) {
this.startDtHYYYY = startDtHYYYY;
}
/**
* @return the startDtHYYYY
*/
public String getStartDtHYYYY() {
return startDtHYYYY;
}
}
最后,这是生成的 html。
<script>
$(function() {
$( ".datePick").datepicker({
dateFormat: 'mm/dd/yy',
showOn: "button",
buttonImage: "images/calendar.png",
buttonImageOnly: true,
buttonText: "Select date",
onSelect: function(dateText,inst)
{
id=$(this).attr('id');
pos = id.indexOf("(") + 1;
counter = id.slice(pos, -1);
id=id.replace("("+counter+")","");
pieces = dateText.split("/");
$("#"+ id+"MM("+counter+")").val(pieces[0]);
$("#"+ id+"DD("+counter+")").val(pieces[1]);
$("#"+id +"YYYY("+counter+")").val(pieces[2]);
}
});
});
</script>
<tr>
<td align="right" colspan="1">
<label for="setOfObjectsStartMMDtH("+counter+")"><label class="normal">Set of Objects</label></label>
</td>
<td align="left" colspan="4">
<input type="text" name="setOfObjectsStartDtHMM(0)" maxlength="2" size="2" value="" id="setOfObjectsStartDtHMM(0)"> /
<input type="text" name="setOfObjectsStartDtHDD(0)" maxlength="2" size="2" value="" id="setOfObjectsStartDtHDD(0)"> /
<input type="text" name="setOfObjectsStartDtHYYYY(0)" maxlength="4" size="4" value="" id="setOfObjectsStartDtHYYYY(0)">
<input type="hidden" name="setOfObjectsStartDtH(0)" value="" class="datePick" id="setOfObjectsStartDtH(0)">
((注意:我知道“+counter+”没有创建合适的标签 - 但解决这个问题并没有修复日历功能))
日历本身弹出没有问题,但是当我 select 一个日期时,页面跳到顶部,日期字段没有填充 - 页面上的任何地方都没有出现错误消息,并且日历也不会消失,因为它通常会在 select 约会后消失。
什么会导致 jQuery 日期选择器显示日历,但不允许我分配日历值?
我认为问题出在 id 选择器的连接上。您需要转义括号。
试试这个:
$("#"+ id+"MM\("+counter+"\)").val(pieces[0]);
$("#"+ id+"DD\("+counter+"\)").val(pieces[1]);
$("#"+id +"YYYY\("+counter+"\)").val(pieces[2]);
首先,你混合了两个概念后端代码(Java)和客户端代码(Java脚本)。通常,在 Web 应用程序中,当用户发出请求并访问您的服务器时,服务器会运行后端代码以生成响应并将其发回 - 该响应采用 HTML/JS/CSS 的形式,用于显示内容在浏览器中。进入浏览器后,Java脚本代码可以执行以提供更多功能。
这是针对大多数网络应用程序的基本思想 - Java 可以替换为 PHP 或 C# 或 JavaScript(以 NodeJS 的形式)或许多其他作为后端,但你总是会在不同的时间、环境、甚至机器和地理位置执行。
话虽如此,双方还是可以交流的。不是直接的,例如,你不能从客户端调用MyServerObject.setMyValue()
,但是如果你想从前端转移到后端,基本上有两种方法可以做到:
- 表单提交 - 现在是 "old-school" 的方式。并不是说它 不好 而是不像以前那样使用。本质上,您将在页面上有一个
<form>
,其中包含一组可以操作的 <input>
,当提交表单时,它会将所有值传输到后端。这将根据您希望获取数据的方式而有所不同,但归结为表单上的 the action attribute。这导致页面作为提交的一部分重新加载,并且用户被重定向到其他地方(尽管可能到同一页面)。它被认为是侵入性的而不是用户友好的,因此它的 "old-school"-ness。另一方面,HTML 原生支持它,任何浏览器都知道如何处理表单,因此它有其用途。
- AJAX 请求 - 虽然不是 "new" 以任何方式,这通常是客户端代码与后端通信的首选方式。它涉及在不离开页面的情况下向服务器发送一些数据,而且用户也不一定知道。因此,它提供了更好的用户体验,也更容易从后端处理,因为您可以更好地塑造数据的输入方式(表单只为您提供键值对)。
虽然有很多方法可以实现AJAX,但jQuery .ajax() and its two shorthands .get() and .post()非常方便和容易。您可能会在 onSelect
处理程序调用中执行以下操作:
$.post("some/path/on/my/server", myData)
其中 myData
对象将是您想要的数据,将作为 JSON 发送,而 some/path/on/my/server
是可以接受该数据的服务器的某个部分。一般来说,该路径最终只会调用一些传递数据的服务器端代码 - 在过去,您可能只是点击用 Perl 或其他东西编写的 CGI 脚本,但现在它只是通过 URI 公开的后端。该路径的具体实施方式可能会有所不同,不幸的是,我不熟悉 Struts 如何在那里完成,但我想这一定不难。
无论如何,一旦您的后端收到数据,通常要做的就是以某种方式对其进行处理(检查有效性、清理、决定要做什么),然后将其交给其他部分进行进一步处理的应用程序。在您的情况下,您可能会收到一些数据,然后使用日期创建和填充一些对象,然后......做任何其他需要的事情。但是,如果您需要知道 哪个 用户发出了请求,以及哪个用户正在处理他们的日历,您可能需要包含更多信息。许多服务器端语言都有会话的概念,它只是特定用户的上下文。如果有人修改了一个日历,你可以根据session找出是谁修改的,然后找到对应的日历。会话可能已为您设置好,您可能无需执行任何操作即可使用它们。尽管如此,使用会话的另一种方法是为用户传递令牌——这采用某种信息的形式——用户名、密钥、会话 ID,它们可以作为 AJAX 请求的一部分进行传输,并将识别发出者它。
无论如何,如果你需要将信息传回给客户端,例如"Action succeeded"或"failed",那么后端可以响应AJAX请求更多或少了两种方式。一种方法是仅从最简单的 boolean
发回一些数据以指示 success/failure 传回字符串或整个对象(可能序列化并传输到 JSON)以指示响应。第二种方式是发送一个 response code 来表示发生了什么。实际上,您可能会混合使用两者。在客户端,这将通过使用 jQuery 处理程序
来处理
$.post("some/path/on/my/server", myData)
.done(function() { alert("sending data succeeded") })
.fail(function() { alert("sending data failed") })
.always(function() { alert("finished sending data") })
这是使用 jQuery promises 的另一种方法是将 success/failure 处理程序指定为 $.ajax
调用的一部分。值得注意的是,alert
纯粹是为了说明目的——您可能会以不同的方式通知用户。或者可能根本不,因为只要它有效就可能不相关,所以你可能只在失败时通知他们。
我正在尝试使用 jQuery 日期选择器函数来填充日期字段,这些字段是散列图中对象集的一部分。
我们正在使用 STRUTS 1 来映射我们的表单数据 - 对于我们的大部分数据来说,这就足够了。
我之前已经检查并写出这些字段,以便可以通过手动输入日期来填充它们,现在我想添加 jQuery 日期选择器以允许用户 select弹出式日历中的日期。我正在使用 Chrome。下面的代码片段。
<script>
$(function() {
$( ".datePick").datepicker({
dateFormat: 'mm/dd/yy',
showOn: "button",
buttonImage: "images/calendar.png",
buttonImageOnly: true,
buttonText: "Select date",
onSelect: function(dateText,inst)
{
id=$(this).attr('id');
pos = id.indexOf("(") + 1;
counter = id.slice(pos, -1);
id=id.replace("("+counter+")","");
pieces = dateText.split("/");
$("#"+ id+"MM("+counter+")").val(pieces[0]);
$("#"+ id+"DD("+counter+")").val(pieces[1]);
$("#"+id +"YYYY("+counter+")").val(pieces[2]);
}
});
});
</script>
<!-- "counter" is an integer which keeps track of what iteration of the
hashmap is being accessed, propertyValue is a string that allows me to
dynamically change the property of each form-->
<tr>
<td align="right" colspan="1">
<label for="setOfObjectsStartMMDtH("+counter+")">
<%=label.makeLabel(XXXXForm.FORM_KEY_VALUE)%></label>
</td>
<td align="left" colspan="4">
<% propertyValue="setOfObjectsStartDtHMM("+counter+")";%>
<html:text property="<%=propertyValue%>" styleId="<%=propertyValue%>"
size="2" maxlength="2"/> /
<% propertyValue="setOfObjectsStartDtHDD("+counter+")";%>
<html:text property="<%=propertyValue%>" styleId="<%=propertyValue%>"
size="2" maxlength="2"/> /
<% propertyValue="setOfObjectsStartDtHYYYY("+counter+")";%>
<html:text property="<%=propertyValue%>" styleId="<%=propertyValue%>"
size="4" maxlength="4"/>
<% propertyValue="setOfObjectsStartDtH("+counter+")";%>
<html:hidden styleId="<%=propertyValue%>" property="<%=propertyValue%>"
styleClass="datePick"+counter></html:hidden>
这是我的 getter 和 setter 的样子。
private final HashMap setOfObjects = new HashMap();
/**
* @param startDtH the setOfObjectsStartDtH to set
*/
public void setSetOfObjectsStartDtH(String key, String startDtH) {
setOfObjects obj = getSetOfObjects(key);
obj.setStartDtH(startDtH);
}
/**
* @return the startDtH
*/
public String getSetOfObjectsStartDtH(String key) {
if(setOfObjectss.containsKey(key)){
SetOfObjects obj = getSetOfObjects(key);
return obj.getStartDtH();
}
return "";
}
/**
* @param startDtHDD the startDtHDD to set
*/
public void setSetOfObjectsStartDtHDD(String key, String startDtHDD) {
SetOfObjects obj = getSetOfObjects(key);
obj.setStartDtHDD(startDtHDD);
}
/**
* @return the startDtHDD
*/
public String getSetOfObjectsStartDtHDD(String key) {
if(setOfObjectss.containsKey(key)){
SetOfObjects obj = getSetOfObjects(key);
return obj.getStartDtHDD();
}
return "";
}
/**
* @param startDtHMM the startDtHMM to set
*/
public void setSetOfObjectsStartDtHMM(String key, String startDtHMM) {
SetOfObjects obj = getSetOfObjects(key);
obj.setStartDtHMM(startDtHMM);
}
/**
* @return the startDtHMM
*/
public String getSetOfObjectsStartDtHMM(String key) {
if(setOfObjectss.containsKey(key)){
SetOfObjects obj = getSetOfObjects(key);
return obj.getStartDtHMM();
}
return "";
}
/**
* @param startDtHYYYY the startDtHYYYY to set
*/
public void setSetOfObjectsStartDtHYYYY(String key, String startDtHYYYY) {
SetOfObjects obj = getSetOfObjects(key);
obj.setStartDtHYYYY(startDtHYYYY);
}
/**
* @return the startDtHYYYY
*/
public String getSetOfObjectsStartDtHYYYY(String key) {
if(setOfObjectss.containsKey(key)){
SetOfObjects obj = getSetOfObjects(key);
return obj.getStartDtHYYYY();
}
return "";
}
private SetOfObjects getSetOfObjects(String key){
if(setOfObjects.containsKey(key))
return (SetOfObjects)setOfObjects.get(key);
SetOfObjects set = new SetOfObjects();
set.setId(Integer.parseInt(key));
setOfObjects.put(key, set);
return set;
}
这是 SetOfObjects 的样子:
public class SetOfObjects{
private String startDtH = "";
private String startDtHMM = "";
private String startDtHDD = "";
private String startDtHYYYY = "";
/**
* @param startDtH the startDtH to set
*/
public void setStartDtH(String startDtH) {
startDtH = startDtH;
}
/**
* @return the startDtH
*/
public String getStartDtH() {
return startDtH;
}
/**
* @param startDtHMM the startDtHMM to set
*/
public void setStartDtHMM(String startDtHMM) {
this.startDtHMM = startDtHMM;
}
/**
* @return the startDtHMM
*/
public String getStartDtHMM() {
return startDtHMM;
}
/**
* @param startDtHDD the startDtHDD to set
*/
public void setStartDtHDD(String startDtHDD) {
this.startDtHDD = startDtHDD;
}
/**
* @return the startDtHDD
*/
public String getStartDtHDD() {
return startDtHDD;
}
/**
* @param startDtHYYYY the startDtHYYYY to set
*/
public void setStartDtHYYYY(String startDtHYYYY) {
this.startDtHYYYY = startDtHYYYY;
}
/**
* @return the startDtHYYYY
*/
public String getStartDtHYYYY() {
return startDtHYYYY;
}
}
最后,这是生成的 html。
<script>
$(function() {
$( ".datePick").datepicker({
dateFormat: 'mm/dd/yy',
showOn: "button",
buttonImage: "images/calendar.png",
buttonImageOnly: true,
buttonText: "Select date",
onSelect: function(dateText,inst)
{
id=$(this).attr('id');
pos = id.indexOf("(") + 1;
counter = id.slice(pos, -1);
id=id.replace("("+counter+")","");
pieces = dateText.split("/");
$("#"+ id+"MM("+counter+")").val(pieces[0]);
$("#"+ id+"DD("+counter+")").val(pieces[1]);
$("#"+id +"YYYY("+counter+")").val(pieces[2]);
}
});
});
</script>
<tr>
<td align="right" colspan="1">
<label for="setOfObjectsStartMMDtH("+counter+")"><label class="normal">Set of Objects</label></label>
</td>
<td align="left" colspan="4">
<input type="text" name="setOfObjectsStartDtHMM(0)" maxlength="2" size="2" value="" id="setOfObjectsStartDtHMM(0)"> /
<input type="text" name="setOfObjectsStartDtHDD(0)" maxlength="2" size="2" value="" id="setOfObjectsStartDtHDD(0)"> /
<input type="text" name="setOfObjectsStartDtHYYYY(0)" maxlength="4" size="4" value="" id="setOfObjectsStartDtHYYYY(0)">
<input type="hidden" name="setOfObjectsStartDtH(0)" value="" class="datePick" id="setOfObjectsStartDtH(0)">
((注意:我知道“+counter+”没有创建合适的标签 - 但解决这个问题并没有修复日历功能))
日历本身弹出没有问题,但是当我 select 一个日期时,页面跳到顶部,日期字段没有填充 - 页面上的任何地方都没有出现错误消息,并且日历也不会消失,因为它通常会在 select 约会后消失。
什么会导致 jQuery 日期选择器显示日历,但不允许我分配日历值?
我认为问题出在 id 选择器的连接上。您需要转义括号。
试试这个:
$("#"+ id+"MM\("+counter+"\)").val(pieces[0]);
$("#"+ id+"DD\("+counter+"\)").val(pieces[1]);
$("#"+id +"YYYY\("+counter+"\)").val(pieces[2]);
首先,你混合了两个概念后端代码(Java)和客户端代码(Java脚本)。通常,在 Web 应用程序中,当用户发出请求并访问您的服务器时,服务器会运行后端代码以生成响应并将其发回 - 该响应采用 HTML/JS/CSS 的形式,用于显示内容在浏览器中。进入浏览器后,Java脚本代码可以执行以提供更多功能。
这是针对大多数网络应用程序的基本思想 - Java 可以替换为 PHP 或 C# 或 JavaScript(以 NodeJS 的形式)或许多其他作为后端,但你总是会在不同的时间、环境、甚至机器和地理位置执行。
话虽如此,双方还是可以交流的。不是直接的,例如,你不能从客户端调用MyServerObject.setMyValue()
,但是如果你想从前端转移到后端,基本上有两种方法可以做到:
- 表单提交 - 现在是 "old-school" 的方式。并不是说它 不好 而是不像以前那样使用。本质上,您将在页面上有一个
<form>
,其中包含一组可以操作的<input>
,当提交表单时,它会将所有值传输到后端。这将根据您希望获取数据的方式而有所不同,但归结为表单上的 the action attribute。这导致页面作为提交的一部分重新加载,并且用户被重定向到其他地方(尽管可能到同一页面)。它被认为是侵入性的而不是用户友好的,因此它的 "old-school"-ness。另一方面,HTML 原生支持它,任何浏览器都知道如何处理表单,因此它有其用途。 - AJAX 请求 - 虽然不是 "new" 以任何方式,这通常是客户端代码与后端通信的首选方式。它涉及在不离开页面的情况下向服务器发送一些数据,而且用户也不一定知道。因此,它提供了更好的用户体验,也更容易从后端处理,因为您可以更好地塑造数据的输入方式(表单只为您提供键值对)。
虽然有很多方法可以实现AJAX,但jQuery .ajax() and its two shorthands .get() and .post()非常方便和容易。您可能会在 onSelect
处理程序调用中执行以下操作:
$.post("some/path/on/my/server", myData)
其中 myData
对象将是您想要的数据,将作为 JSON 发送,而 some/path/on/my/server
是可以接受该数据的服务器的某个部分。一般来说,该路径最终只会调用一些传递数据的服务器端代码 - 在过去,您可能只是点击用 Perl 或其他东西编写的 CGI 脚本,但现在它只是通过 URI 公开的后端。该路径的具体实施方式可能会有所不同,不幸的是,我不熟悉 Struts 如何在那里完成,但我想这一定不难。
无论如何,一旦您的后端收到数据,通常要做的就是以某种方式对其进行处理(检查有效性、清理、决定要做什么),然后将其交给其他部分进行进一步处理的应用程序。在您的情况下,您可能会收到一些数据,然后使用日期创建和填充一些对象,然后......做任何其他需要的事情。但是,如果您需要知道 哪个 用户发出了请求,以及哪个用户正在处理他们的日历,您可能需要包含更多信息。许多服务器端语言都有会话的概念,它只是特定用户的上下文。如果有人修改了一个日历,你可以根据session找出是谁修改的,然后找到对应的日历。会话可能已为您设置好,您可能无需执行任何操作即可使用它们。尽管如此,使用会话的另一种方法是为用户传递令牌——这采用某种信息的形式——用户名、密钥、会话 ID,它们可以作为 AJAX 请求的一部分进行传输,并将识别发出者它。
无论如何,如果你需要将信息传回给客户端,例如"Action succeeded"或"failed",那么后端可以响应AJAX请求更多或少了两种方式。一种方法是仅从最简单的 boolean
发回一些数据以指示 success/failure 传回字符串或整个对象(可能序列化并传输到 JSON)以指示响应。第二种方式是发送一个 response code 来表示发生了什么。实际上,您可能会混合使用两者。在客户端,这将通过使用 jQuery 处理程序
$.post("some/path/on/my/server", myData)
.done(function() { alert("sending data succeeded") })
.fail(function() { alert("sending data failed") })
.always(function() { alert("finished sending data") })
这是使用 jQuery promises 的另一种方法是将 success/failure 处理程序指定为 $.ajax
调用的一部分。值得注意的是,alert
纯粹是为了说明目的——您可能会以不同的方式通知用户。或者可能根本不,因为只要它有效就可能不相关,所以你可能只在失败时通知他们。