dev*_*ven 40 jsp servlets cascading drop-down-menu
假设我有三个名为的下拉列表控件dd1
,dd2
和dd3
.每个下拉列表的值来自数据库.dd3
价值取决于价值dd2
和dd2
价值取决于价值dd1
.任何人都可以告诉我如何调用servlet来解决这个问题?
Bal*_*usC 49
基本上有三种方法可以达到这个目的:
在第一个下拉列表的onchange事件期间将表单提交给servlet(您可以使用Javascript),让servlet获取第一个下拉列表的选定项作为请求参数,让它从数据库中获取第二个下拉列表的关联值作为a Map<String, String>
,让它将它们存储在请求范围内.最后让JSP/JSTL在第二个下拉列表中显示值.您可以使用JSTL(刚落,JSTL-1.2.jar中/WEB-INF/lib
)c:forEach
标签此.您可以在与JSP页面关联的doGet()
方法中预填充第一个列表Servlet
.
<select name="dd1" onchange="submit()">
<c:forEach items="${dd1options}" var="option">
<option value="${option.key}" ${param.dd1 == option.key ? 'selected' : ''}>${option.value}</option>
</c:forEach>
</select>
<select name="dd2" onchange="submit()">
<c:if test="${empty dd2options}">
<option>Please select parent</option>
</c:if>
<c:forEach items="${dd2options}" var="option">
<option value="${option.key}" ${param.dd2 == option.key ? 'selected' : ''}>${option.value}</option>
</c:forEach>
</select>
<select name="dd3">
<c:if test="${empty dd3options}">
<option>Please select parent</option>
</c:if>
<c:forEach items="${dd3options}" var="option">
<option value="${option.key}" ${param.dd3 == option.key ? 'selected' : ''}>${option.value}</option>
</c:forEach>
</select>
Run Code Online (Sandbox Code Playgroud)
然而,一旦提出警告,这将提交整个表单并导致"内容闪现",这可能对用户体验不利.您还需要根据请求参数以相同的形式保留其他字段.您还需要在servlet中确定请求是更新下拉列表(子下拉列表值为空)还是提交实际表单.
将第二个和第三个下拉列表的所有可能值作为Javascript对象打印出来,并使用Javascript函数根据第一个下拉列表的onchange事件中第一个下拉列表的选定项填充第二个下拉列表.没有表单提交,这里不需要服务器周期.
<script>
var dd2options = ${dd2optionsAsJSObject};
var dd3options = ${dd3optionsAsJSObject};
function dd1change(dd1) {
// Fill dd2 options based on selected dd1 value.
var selected = dd1.options[dd1.selectedIndex].value;
...
}
function dd2change(dd2) {
// Fill dd3 options based on selected dd2 value.
var selected = dd2.options[dd2.selectedIndex].value;
...
}
</script>
<select name="dd1" onchange="dd1change(this)">
<c:forEach items="${dd1options}" var="option">
<option value="${option.key}" ${param.dd1 == option.key ? 'selected' : ''}>${option.value}</option>
</c:forEach>
</select>
<select name="dd2" onchange="dd2change(this)">
<option>Please select parent</option>
</select>
<select name="dd3">
<option>Please select parent</option>
</select>
Run Code Online (Sandbox Code Playgroud)
但有一点需要注意的是,当你有很多物品时,这可能会变得不必要地冗长和昂贵.想象一下,每100个可能的项目中有3个步骤,这意味着JS对象中有100*100*100 = 1,000,000个项目.HTML页面的长度将超过1MB.
在第一个下拉列表的onchange事件期间,使用Javascript中的XMLHttpRequest向servlet发出异步请求,让servlet获取第一个下拉列表的选定项作为请求参数,让它从第二个下拉列表中获取相关值.数据库,以XML或JSON字符串形式返回.最后让Javascript通过HTML DOM树显示第二个下拉列表中的值(Ajax方式,如前所述).最好的方法是使用jQuery.
<%@ page pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html lang="en">
<head>
<title>SO question 2263996</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
$('#dd1').change(function() { fillOptions('dd2', this); });
$('#dd2').change(function() { fillOptions('dd3', this); });
});
function fillOptions(ddId, callingElement) {
var dd = $('#' + ddId);
$.getJSON('json/options?dd=' + ddId + '&val=' + $(callingElement).val(), function(opts) {
$('>option', dd).remove(); // Clean old options first.
if (opts) {
$.each(opts, function(key, value) {
dd.append($('<option/>').val(key).text(value));
});
} else {
dd.append($('<option/>').text("Please select parent"));
}
});
}
</script>
</head>
<body>
<form>
<select id="dd1" name="dd1">
<c:forEach items="${dd1}" var="option">
<option value="${option.key}" ${param.dd1 == option.key ? 'selected' : ''}>${option.value}</option>
</c:forEach>
</select>
<select id="dd2" name="dd2">
<option>Please select parent</option>
</select>
<select id="dd3" name="dd3">
<option>Please select parent</option>
</select>
</form>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
.. Servlet
后面的地方/json/options
看起来像这样:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String dd = request.getParameter("dd"); // ID of child DD to fill options for.
String val = request.getParameter("val"); // Value of parent DD to find associated child DD options for.
Map<String, String> options = optionDAO.find(dd, val);
String json = new Gson().toJson(options);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
}
Run Code Online (Sandbox Code Playgroud)
这里,Gson
是谷歌GSON从而简化了转换fullworthy Java对象到JSON,反之亦然.另请参见如何使用Servlet和Ajax?
归档时间: |
|
查看次数: |
62218 次 |
最近记录: |