我有一个下拉菜单(产品类型):
由 Spring MVC 代码生成(Google MDL 已删除)
<form:select path="productType" required="required">
<form:option value="" label="" />
<form:options items="${availableProductTypesForAdd}" />
</form:select>
<label for="productType">Product Type</label>
${availableProductTypesForAdd}
由 Controller 加载到模型中,如下所示:
HashMap<String, String> availableProductTypesForAdd = new HashMap<>();
availableProductTypesForAdd.put("191", "191 - Table");
availableProductTypesForAdd.put("201", "201 - Chair");
availableProductTypesForAdd.put("230", "230 - Desk");
availableProductTypesForAdd.put("232", "232 - Monitor");
model.put("availableProductTypesForAdd", availableProductTypesForAdd);
如果您将 ${availableProductTypesForAdd}
打印到屏幕上,它将如下所示:
{191=191 - table ,201=201 - 椅子,230=230 - table ,232=232 - 显示器}
填写表单的用户知道以下两件事之一:(1) 产品 key (191、201 等)或 (2) 产品名称( table 、椅子等)。
- 有些用户不熟悉按键,因此需要按产品名称进行搜索。
- 一些用户熟悉这些按键,并且更喜欢更快捷的按键方式。
我想让这两个选项都可以通过键盘选择下拉菜单。即,当用户点击此字段时,他们可以在键盘上键入“201”或“椅子”,它将选择列表中的正确项目。
目前,该列表只能通过类型代码(191、201 等)进行搜索,因为显示的字符串以代码开头。
如何实现这一目标?
最佳答案
最简单也可能是最可取的方法是使用标准选择的某种替代品,因为它不太可定制。
您可以尝试'Chosen' jQuery plugin 。这将需要外部 js 和 css。然而,似乎完全满足您的要求,没有痛苦和解决方法。
只需在 jsp 中添加 4 行:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<form:form id="form" method="post" modelAttribute="form" action="/submit2">
<form:select path="productType" required="required" >
<form:option value="" label="" />
<form:options items="${availableProductTypesForAdd}" />
</form:select>
<label for="productType">Product Type</label>
<input type="submit" name="action" value="Submit" />
</form:form>
<script src="https://harvesthq.github.io/chosen/docsupport/jquery-3.2.1.min.js"></script>
<script src="https://harvesthq.github.io/chosen/chosen.jquery.js"></script>
<link rel="stylesheet" href="https://harvesthq.github.io/chosen/chosen.css">
<script>$(function(){ $('select').chosen(); })</script>
你在这里: (它在 OSX 上的或多或少新鲜的 chrome、safari 和 FF 中就像一个魅力)
$(function(){
$('select').chosen();
});
<link href="https://harvesthq.github.io/chosen/chosen.css" rel="stylesheet"/>
<script src="https://harvesthq.github.io/chosen/docsupport/jquery-3.2.1.min.js"></script>
<script src="https://harvesthq.github.io/chosen/chosen.jquery.js"></script>
<form id="form" action="/submit2" method="post">
<select id="productType" name="productType" required="required">
<option value=""></option>
<option value="232">232 - Monitor</option><option value="310">310 - Bad</option><option value="201">201 - Chair</option><option value="555">555 - Sofa</option><option value="191">191 - Table</option><option value="999">999 - Bookcase</option><option value="618">618 - Armchair</option><option value="230">230 - Desk</option>
</select>
<label for="productType">Product Type</label>
<input type="submit" name="action" value="Submit">
</form>
您也可以看看HTML Data List element
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
<form:form id="form" method="post" modelAttribute="form" action="/submit">
<form:input path="productType" list="productTypes" required="required" autocomplete="off" />
<datalist id="productTypes">
<c:forEach items="${availableProductTypesForAdd}" var="productType">
<option value="${productType.key}">${productType.value}</option>
</c:forEach>
</datalist>
<label for="productType">Product Type</label>
<button type="submit">Ok</button>
</form:form>
您甚至可以从选项中删除键,因为它显示并在值和文本中进行搜索
HashMap<String, String> availableProductTypesForAdd = new HashMap<>();
availableProductTypesForAdd.put("191", "Table");
availableProductTypesForAdd.put("201", "Chair");
availableProductTypesForAdd.put("230", "Desk");
availableProductTypesForAdd.put("232", "Monitor");
但是,它不像select那么严格,并且允许输入不受选项限制的任何内容(本质上是建议,这就是为什么自动完成是关闭)
但是,如果您对一些微小的 js 感到满意,您可以添加一些额外的逻辑来弥补这一差距,这是选项之一(如果输入与选项之一不匹配,则清除输入):
<script>
(function() {
function verify() {
var input = document.getElementById("productType");
var o = [].map.call(input.list.options, opt => opt.value);
var opts = o.reduce((result, v) => (result[v.toUpperCase()] = v, result), {});
var value = input.value.toUpperCase();
if (!opts[value]) {
input.value = '';
return false;
}
}
document.getElementById("productType").addEventListener("focusout", verify);
document.getElementById("form").addEventListener("focusout", verify);
})();
</script>
基本上,您可以稍微改进默认值。但前提是你同意这个搜索在菜单打开时不能完全工作(因为该菜单无法从 js 访问,因为它是特定于操作系统的,而且似乎不是 html 的一部分)。
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<form:form id="form" method="post" modelAttribute="form" action="/submit2">
<form:select path="productType" required="required" >
<form:option value="" label="" />
<form:options items="${availableProductTypesForAdd}" />
</form:select>
<label for="productType">Product Type</label>
<input type="submit" name="action" value="Submit" />
</form:form>
<script>
(function() {
var lastKeysForSearchNumber = 7; // tune # of keys entered to keep
var lastKeys = [];
var select = document.querySelector('[name=productType]');
function search(e) {
if (e.key.match(/^\w$/i)) {
lastKeys.push(e.key);
if (lastKeys.length > lastKeysForSearchNumber) {
lastKeys.shift();
}
select.value = bestMatch(select.options, lastKeys.join(''));
e.preventDefault();
}
}
function bestMatch(options, input) {
for (var i = 0; i < input.length; i++) {
for (var j = 0; j < options.length; j++) {
if (options[j].text.match(new RegExp(input.substring(i), 'i'))) { // contains ignore case
return options[j].value;
}
}
}
return '';
}
select.addEventListener("keydown", search);
})();
</script>
这里的想法是存储最后 7 个(或其他)键并检查每个选项是否包含尽可能多的内容。
这可能需要针对特定浏览器(IE?)进行一些调整和/或一些调整 以下是该内容的片段,请尝试一下:
(function() {
var lastKeysSorSearchNumber = 7;
var lastKeys = [];
var select = document.querySelector('[name=productType]');
function search(e) {
if (e.key.match(/^\w$/i)) {
lastKeys.push(e.key);
if (lastKeys.length > lastKeysSorSearchNumber) {
lastKeys.shift();
}
select.value = bestMatch(select.options, lastKeys.join(''));
e.preventDefault();
}
}
function bestMatch(options, input) {
for (var i = 0; i < input.length; i++) {
for (var j = 0; j < options.length; j++) {
if (options[j].text.match(new RegExp(input.substring(i), 'i'))) {
return options[j].value;
}
}
}
return '';
}
select.addEventListener("keydown", search);
})();
<form id="form" action="/submit2" method="post">
<select id="productType" name="productType" required="required">
<option value=""></option>
<option value="310">310 - Bad</option><option value="201">201 - Chair</option><option value="2324">2324 - Monitor</option><option value="555">555 - Sofa</option><option value="191">191 - Table</option><option value="999">999 - Bookcase</option><option value="618">618 - Armchair</option><option value="230">230 - Desk</option>
</select>
<label for="productType">Product Type</label>
<input type="submit" name="action" value="Submit">
</form>
关于javascript - 制作 Spring 形式:select searchable by two parameters,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58607869/