用小胡子创建动态下拉菜单
create dynamic dropdown(s) with mustache
我有以下结构:
[
"key 1": [ "val1", "val2", "val3" ],
"key 2": [
"key 3": [ "val4" ],
"key 4": [ "val5" ]
]
]
我想由此生成下拉菜单。 "key 1"...将是可选择的名称,"val1"...是值。
如果所选键上有一个子数组,我想用这些值动态创建另一个下拉列表,直到子数组只有一个值。 (例如 "key 2")
我不知道如何用小胡子继续这个。
我可以使用 Object.keys
将第一级的所有键放入一个平面数组中,但我什至无法生成第一个下拉列表。更不用说我不知道如何处理另一部分了。
最好能得到一个关于如何完成的大体方向。
下面是一些示例代码:
const view = {
files: getFiles(),
"keys": function() {
return Object.keys(this);
}
};
<form>
<select id="selector">
<option>choose...</option>
{{#files}}
{{#keys}}
<option value="">{{.}}</option>
{{/keys}}
{{/files}}
</select>
</form>
这是一个线框图,上面是选择key1
时的第一种情况,下面是选择key2
时的情况。
Mustache 是一种 logic-less
模板语法,因为没有 if 语句、else 子句或 for 循环。相反,只有标签。一些标签被替换为一个值,一些什么都没有,还有一些是一系列值。
因此您无法根据 selected 值 mustache
更新呈现的 HTML。
这里我使用 onchange
事件根据之前的 selected 值动态创建 select 使用普通 Javascript 没有 mustache
模板
var data = {
"key 1": ["val1", "val2", "val3"],
"key 2": {
"key 3": ["val4"],
"key 4": ["val5"]
}
}
function renderSelect(obj) {
var array = Array.isArray(obj) ? obj : Object.keys(obj)
var options = ['Choose', ...array].map(i => "<option>" + i + "</option>").join('')
var select = document.createElement('select')
select.innerHTML = options
if (!Array.isArray(obj)) {
select.onchange = function() {
// remove next siblings
var sib = [], el = this
while (el = el.nextElementSibling) sib.push(el)
sib.forEach(el => el.remove())
// render select based on value
renderSelect(obj[this.value])
}
}
document.querySelector('form').insertAdjacentElement('beforeend', select);
}
renderSelect(data)
<form></form>
<script>
function process() {
var template, data, html;
template = $('#template').val();
eval( $('#data').val() );
html = Mustache.render( template, data );
$('#html').text( html );
$('#result').html( html );
}
</script>
现在附上这个插件
<link rel="stylesheet" href="style.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="mustache.js"></script>
<script type="text/javascript" src="mustache-demos.js"></script>
- 提取#template textarea。
- 使用数据对象调用 eval()。
- 调用 Mustache.render()
- 插入 #html 文本区域。
输出
我有以下结构:
[
"key 1": [ "val1", "val2", "val3" ],
"key 2": [
"key 3": [ "val4" ],
"key 4": [ "val5" ]
]
]
我想由此生成下拉菜单。 "key 1"...将是可选择的名称,"val1"...是值。 如果所选键上有一个子数组,我想用这些值动态创建另一个下拉列表,直到子数组只有一个值。 (例如 "key 2")
我不知道如何用小胡子继续这个。
我可以使用 Object.keys
将第一级的所有键放入一个平面数组中,但我什至无法生成第一个下拉列表。更不用说我不知道如何处理另一部分了。
最好能得到一个关于如何完成的大体方向。
下面是一些示例代码:
const view = {
files: getFiles(),
"keys": function() {
return Object.keys(this);
}
};
<form>
<select id="selector">
<option>choose...</option>
{{#files}}
{{#keys}}
<option value="">{{.}}</option>
{{/keys}}
{{/files}}
</select>
</form>
这是一个线框图,上面是选择key1
时的第一种情况,下面是选择key2
时的情况。
Mustache 是一种 logic-less
模板语法,因为没有 if 语句、else 子句或 for 循环。相反,只有标签。一些标签被替换为一个值,一些什么都没有,还有一些是一系列值。
因此您无法根据 selected 值 mustache
更新呈现的 HTML。
这里我使用 onchange
事件根据之前的 selected 值动态创建 select 使用普通 Javascript 没有 mustache
模板
var data = {
"key 1": ["val1", "val2", "val3"],
"key 2": {
"key 3": ["val4"],
"key 4": ["val5"]
}
}
function renderSelect(obj) {
var array = Array.isArray(obj) ? obj : Object.keys(obj)
var options = ['Choose', ...array].map(i => "<option>" + i + "</option>").join('')
var select = document.createElement('select')
select.innerHTML = options
if (!Array.isArray(obj)) {
select.onchange = function() {
// remove next siblings
var sib = [], el = this
while (el = el.nextElementSibling) sib.push(el)
sib.forEach(el => el.remove())
// render select based on value
renderSelect(obj[this.value])
}
}
document.querySelector('form').insertAdjacentElement('beforeend', select);
}
renderSelect(data)
<form></form>
<script>
function process() {
var template, data, html;
template = $('#template').val();
eval( $('#data').val() );
html = Mustache.render( template, data );
$('#html').text( html );
$('#result').html( html );
}
</script>
现在附上这个插件
<link rel="stylesheet" href="style.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="mustache.js"></script>
<script type="text/javascript" src="mustache-demos.js"></script>
- 提取#template textarea。
- 使用数据对象调用 eval()。
- 调用 Mustache.render()
- 插入 #html 文本区域。
输出