如何将默认 selected 值设置为 multi select
How to set default selected value to multi select
我有以下片段:
function dropdownBis() {
return {
options: [],
selected: [],
show: false,
open() {
this.show = true
},
close() {
this.show = false
},
isOpen() {
return this.show === true
},
selectBis(index, event) {
if (!this.options[index].selected) {
this.options[index].selected = true;
this.options[index].element = event.target;
this.selected.push(index);
} else {
this.selected.splice(this.selected.lastIndexOf(index), 1);
this.options[index].selected = false
}
},
removeBis(index, option) {
this.options[option].selected = false;
this.selected.splice(index, 1);
},
loadOptionsBis() {
const options = document.getElementById('recipe_type').options;
for (let i = 0; i < options.length; i++) {
this.options.push({
value: options[i].value,
text: options[i].innerText,
selected: options[i].getAttribute('selected') != null ? options[i].getAttribute('selected') : false
});
}
},
selectedValuesBis() {
return this.selected.map((option) => {
return this.options[option].value;
})
}
}
}
[x-cloak] {
display: none;
}
.svg-icon {
width: 1em;
height: 1em;
}
.svg-icon path,
.svg-icon polygon,
.svg-icon rect {
fill: #333;
}
.svg-icon circle {
stroke: #4691f6;
stroke-width: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.0.4/tailwind.min.css" integrity="sha512-paVHVRRhdoOu1nOXKnqDC1Vka0nh7FAmU3nsM4n2FKxOQTeF6crMdMfkVvEsuaOXZ6oEAVL5+wLbQcule/Xdag==" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/alpinejs/2.3.0/alpine.js" integrity="sha512-nIwdJlD5/vHj23CbO2iHCXtsqzdTTx3e3uAmpTm4x2Y8xCIFyWu4cSIV8GaGe2UNVq86/1h9EgUZy7tn243qdA==" crossorigin="anonymous"></script>
<div class="w-4/12 pl-4 pr-4">
<label for="recipe_type" class="mb-1 text-xs sm:text-sm tracking-wide text-gray-500">Type</label>
<select x-cloak id="recipe_type" required>
<option class="py-1" value="1">Val1</option>
<option class="py-1" value="2">Val2</option>
<option class="py-1" value="3">Val3</option>
<option class="py-1" value="5">Val5</option>
<option class="py-1" value="7">Val7</option>
<option class="py-1" value="8">Val8</option>
</select>
<div x-data="dropdownBis()" x-init="loadOptionsBis()" class="w-full flex flex-col items-center sh-64 mx-auto">
<input name="recipe_type" id="hidden_in_recipe_type" value="" type="hidden" x-bind:value="selectedValuesBis()">
<div class="inline-block relative w-full">
<div class="flex flex-col items-center relative">
<div x-on:click="open" class="w-full">
<div class="my-2 p-1 flex border border-gray-200 bg-white rounded">
<div class="flex flex-auto flex-wrap">
<template x-for="(option,index) in selected" :key="options[option].value">
<div class="flex justify-center items-center m-1 font-medium py-1 px-1 bg-white rounded bg-gray-100 border">
<div class="text-xs font-normal leading-none max-w-full flex-initial x-model=" options[option] x-text="options[option].text"></div>
<div class="flex flex-auto flex-row-reverse">
<div x-on:click.stop="removeBis(index,option)">
<svg class="fill-current h-4 w-4 " role="button" viewBox="0 0 20 20">
<path d="M14.348,14.849c-0.469,0.469-1.229,0.469-1.697,0L10,11.819l-2.651,3.029c-0.469,0.469-1.229,0.469-1.697,0
c-0.469-0.469-0.469-1.229,0-1.697l2.758-3.15L5.651,6.849c-0.469-0.469-0.469-1.228,0-1.697s1.228-0.469,1.697,0L10,8.183
l2.651-3.031c0.469-0.469,1.228-0.469,1.697,0s0.469,1.229,0,1.697l-2.758,3.152l2.758,3.15
C14.817,13.62,14.817,14.38,14.348,14.849z" />
</svg>
</div>
</div>
</div>
</template>
<div x-show="selected.length == 0" class="flex-1">
<input placeholder="Type de repas" class="bg-transparent p-1 px-2 appearance-none outline-none h-full w-full text-gray-800" x-bind:value="selectedValuesBis()">
</div>
</div>
<div class="text-gray-300 w-8 py-1 pl-2 pr-1 border-l flex items-center border-gray-200 svelte-1l8159u">
<button type="button" x-show="isOpen() === true" x-on:click="open" class="cursor-pointer w-6 h-6 text-gray-600 outline-none focus:outline-none">
<svg version="1.1" class="fill-current h-4 w-4" viewBox="0 0 20 20">
<path d="M17.418,6.109c0.272-0.268,0.709-0.268,0.979,0s0.271,0.701,0,0.969l-7.908,7.83
c-0.27,0.268-0.707,0.268-0.979,0l-7.908-7.83c-0.27-0.268-0.27-0.701,0-0.969c0.271-0.268,0.709-0.268,0.979,0L10,13.25
L17.418,6.109z" />
</svg>
</button>
<button type="button" x-show="isOpen() === false" @click="close" class="cursor-pointer w-6 h-6 text-gray-600 outline-none focus:outline-none">
<svg class="fill-current h-4 w-4" viewBox="0 0 20 20">
<path d="M2.582,13.891c-0.272,0.268-0.709,0.268-0.979,0s-0.271-0.701,0-0.969l7.908-7.83
c0.27-0.268,0.707-0.268,0.979,0l7.908,7.83c0.27,0.268,0.27,0.701,0,0.969c-0.271,0.268-0.709,0.268-0.978,0L10,6.75L2.582,13.891z
" />
</svg>
</button>
</div>
</div>
</div>
<div class="w-full px-4">
<div x-show.transition.origin.top="isOpen()" class="absolute shadow top-100 bg-white z-40 w-full left-0 rounded max-h-select" x-on:click.away="close">
<div class="flex flex-col w-full overflow-y-auto h-full">
<template x-for="(option,index) in options" :key="option" class="overflow-auto">
<div class="cursor-pointer w-full border-gray-100 rounded-t border-b hover:bg-gray-100" @click="selectBis(index,$event)">
<div class="flex w-full items-center p-2 pl-2 border-transparent border-l-2 relative">
<div class="w-full items-center flex justify-between">
<div class="mx-2 leading-6" x-model="option" x-text="option.text"></div>
<div x-show="option.selected">
<svg class="svg-icon" viewBox="0 0 20 20">
<path fill="none" d="M7.197,16.963H7.195c-0.204,0-0.399-0.083-0.544-0.227l-6.039-6.082c-0.3-0.302-0.297-0.788,0.003-1.087
C0.919,9.266,1.404,9.269,1.702,9.57l5.495,5.536L18.221,4.083c0.301-0.301,0.787-0.301,1.087,0c0.301,0.3,0.301,0.787,0,1.087
L7.741,16.738C7.596,16.882,7.401,16.963,7.197,16.963z"></path>
</svg>
</div>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
我想默认选择 val5 和 val7。
我尝试在 <template>
之后添加
<div class="flex justify-center items-center m-1 font-medium py-1 px-1 bg-white rounded bg-gray-100 border">
<div class="text-xs font-normal leading-none max-w-full flex-initial x-model=" options[option]="" x-text="options[option].text">val5</div>
<div class="flex flex-auto flex-row-reverse">
<div x-on:click.stop="removeBis(index,option)">
<svg class="fill-current h-4 w-4 " role="button" viewBox="0 0 20 20">
<path d="M14.348,14.849c-0.469,0.469-1.229,0.469-1.697,0L10,11.819l-2.651,3.029c-0.469,0.469-1.229,0.469-1.697,0
c-0.469-0.469-0.469-1.229,0-1.697l2.758-3.15L5.651,6.849c-0.469-0.469-0.469-1.228,0-1.697s1.228-0.469,1.697,0L10,8.183
l2.651-3.031c0.469-0.469,1.228-0.469,1.697,0s0.469,1.229,0,1.697l-2.758,3.152l2.758,3.15
C14.817,13.62,14.817,14.38,14.348,14.849z"></path>
</svg>
</div>
</div>
</div>
但是我得到了以下错误:
alpine.js:1914 Uncaught ReferenceError: option is not defined
at eval (eval at d.el (alpine.js:144), :3:62)
at d.el (alpine.js:144)
at d (alpine.js:131)
at f (alpine.js:139)
at be.evaluateReturnExpression (alpine.js:1754)
at alpine.js:1721
at Array.forEach ()
at be.resolveBoundAttributes (alpine.js:1703)
at be.initializeElement (alpine.js:1628)
at alpine.js:1612
有没有办法使用 alpine 或 jQuery 来实现它?
问题
Alpine JS 是一个响应式库。因此,逻辑隐藏在 DOM 之外,有点虚拟。你不能直接与它互动。您不能附加到虚拟生成的 DOM 并期望具有相同的功能。
问题 #1
好的,第一个问题是您附加的 DOM 引用的变量仅在模板循环中可用。变量 (index, option)
在模板中声明。您无法在模板之外访问它们。
问题 #2
您不能期望在模板循环之外添加的 DOM 与虚拟 DOM 的其余部分一起工作。您可以手动找到正确的索引并将其粘贴到 DOM 中进行临时修复,但这会随着时间的推移而出现问题。
解决方案
此解决方案在构造函数中获取一组值,并将这些值设置为多select.
的默认值
https://jsfiddle.net/dk2s90cj/
深思
此代码段正在手动更新并从隐藏的多 select 字段中提取数据。为什么不直接使用 AlpineJS 绑定到 multi-select?为什么手动工作?
我有以下片段:
function dropdownBis() {
return {
options: [],
selected: [],
show: false,
open() {
this.show = true
},
close() {
this.show = false
},
isOpen() {
return this.show === true
},
selectBis(index, event) {
if (!this.options[index].selected) {
this.options[index].selected = true;
this.options[index].element = event.target;
this.selected.push(index);
} else {
this.selected.splice(this.selected.lastIndexOf(index), 1);
this.options[index].selected = false
}
},
removeBis(index, option) {
this.options[option].selected = false;
this.selected.splice(index, 1);
},
loadOptionsBis() {
const options = document.getElementById('recipe_type').options;
for (let i = 0; i < options.length; i++) {
this.options.push({
value: options[i].value,
text: options[i].innerText,
selected: options[i].getAttribute('selected') != null ? options[i].getAttribute('selected') : false
});
}
},
selectedValuesBis() {
return this.selected.map((option) => {
return this.options[option].value;
})
}
}
}
[x-cloak] {
display: none;
}
.svg-icon {
width: 1em;
height: 1em;
}
.svg-icon path,
.svg-icon polygon,
.svg-icon rect {
fill: #333;
}
.svg-icon circle {
stroke: #4691f6;
stroke-width: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.0.4/tailwind.min.css" integrity="sha512-paVHVRRhdoOu1nOXKnqDC1Vka0nh7FAmU3nsM4n2FKxOQTeF6crMdMfkVvEsuaOXZ6oEAVL5+wLbQcule/Xdag==" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/alpinejs/2.3.0/alpine.js" integrity="sha512-nIwdJlD5/vHj23CbO2iHCXtsqzdTTx3e3uAmpTm4x2Y8xCIFyWu4cSIV8GaGe2UNVq86/1h9EgUZy7tn243qdA==" crossorigin="anonymous"></script>
<div class="w-4/12 pl-4 pr-4">
<label for="recipe_type" class="mb-1 text-xs sm:text-sm tracking-wide text-gray-500">Type</label>
<select x-cloak id="recipe_type" required>
<option class="py-1" value="1">Val1</option>
<option class="py-1" value="2">Val2</option>
<option class="py-1" value="3">Val3</option>
<option class="py-1" value="5">Val5</option>
<option class="py-1" value="7">Val7</option>
<option class="py-1" value="8">Val8</option>
</select>
<div x-data="dropdownBis()" x-init="loadOptionsBis()" class="w-full flex flex-col items-center sh-64 mx-auto">
<input name="recipe_type" id="hidden_in_recipe_type" value="" type="hidden" x-bind:value="selectedValuesBis()">
<div class="inline-block relative w-full">
<div class="flex flex-col items-center relative">
<div x-on:click="open" class="w-full">
<div class="my-2 p-1 flex border border-gray-200 bg-white rounded">
<div class="flex flex-auto flex-wrap">
<template x-for="(option,index) in selected" :key="options[option].value">
<div class="flex justify-center items-center m-1 font-medium py-1 px-1 bg-white rounded bg-gray-100 border">
<div class="text-xs font-normal leading-none max-w-full flex-initial x-model=" options[option] x-text="options[option].text"></div>
<div class="flex flex-auto flex-row-reverse">
<div x-on:click.stop="removeBis(index,option)">
<svg class="fill-current h-4 w-4 " role="button" viewBox="0 0 20 20">
<path d="M14.348,14.849c-0.469,0.469-1.229,0.469-1.697,0L10,11.819l-2.651,3.029c-0.469,0.469-1.229,0.469-1.697,0
c-0.469-0.469-0.469-1.229,0-1.697l2.758-3.15L5.651,6.849c-0.469-0.469-0.469-1.228,0-1.697s1.228-0.469,1.697,0L10,8.183
l2.651-3.031c0.469-0.469,1.228-0.469,1.697,0s0.469,1.229,0,1.697l-2.758,3.152l2.758,3.15
C14.817,13.62,14.817,14.38,14.348,14.849z" />
</svg>
</div>
</div>
</div>
</template>
<div x-show="selected.length == 0" class="flex-1">
<input placeholder="Type de repas" class="bg-transparent p-1 px-2 appearance-none outline-none h-full w-full text-gray-800" x-bind:value="selectedValuesBis()">
</div>
</div>
<div class="text-gray-300 w-8 py-1 pl-2 pr-1 border-l flex items-center border-gray-200 svelte-1l8159u">
<button type="button" x-show="isOpen() === true" x-on:click="open" class="cursor-pointer w-6 h-6 text-gray-600 outline-none focus:outline-none">
<svg version="1.1" class="fill-current h-4 w-4" viewBox="0 0 20 20">
<path d="M17.418,6.109c0.272-0.268,0.709-0.268,0.979,0s0.271,0.701,0,0.969l-7.908,7.83
c-0.27,0.268-0.707,0.268-0.979,0l-7.908-7.83c-0.27-0.268-0.27-0.701,0-0.969c0.271-0.268,0.709-0.268,0.979,0L10,13.25
L17.418,6.109z" />
</svg>
</button>
<button type="button" x-show="isOpen() === false" @click="close" class="cursor-pointer w-6 h-6 text-gray-600 outline-none focus:outline-none">
<svg class="fill-current h-4 w-4" viewBox="0 0 20 20">
<path d="M2.582,13.891c-0.272,0.268-0.709,0.268-0.979,0s-0.271-0.701,0-0.969l7.908-7.83
c0.27-0.268,0.707-0.268,0.979,0l7.908,7.83c0.27,0.268,0.27,0.701,0,0.969c-0.271,0.268-0.709,0.268-0.978,0L10,6.75L2.582,13.891z
" />
</svg>
</button>
</div>
</div>
</div>
<div class="w-full px-4">
<div x-show.transition.origin.top="isOpen()" class="absolute shadow top-100 bg-white z-40 w-full left-0 rounded max-h-select" x-on:click.away="close">
<div class="flex flex-col w-full overflow-y-auto h-full">
<template x-for="(option,index) in options" :key="option" class="overflow-auto">
<div class="cursor-pointer w-full border-gray-100 rounded-t border-b hover:bg-gray-100" @click="selectBis(index,$event)">
<div class="flex w-full items-center p-2 pl-2 border-transparent border-l-2 relative">
<div class="w-full items-center flex justify-between">
<div class="mx-2 leading-6" x-model="option" x-text="option.text"></div>
<div x-show="option.selected">
<svg class="svg-icon" viewBox="0 0 20 20">
<path fill="none" d="M7.197,16.963H7.195c-0.204,0-0.399-0.083-0.544-0.227l-6.039-6.082c-0.3-0.302-0.297-0.788,0.003-1.087
C0.919,9.266,1.404,9.269,1.702,9.57l5.495,5.536L18.221,4.083c0.301-0.301,0.787-0.301,1.087,0c0.301,0.3,0.301,0.787,0,1.087
L7.741,16.738C7.596,16.882,7.401,16.963,7.197,16.963z"></path>
</svg>
</div>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
我想默认选择 val5 和 val7。
我尝试在 <template>
<div class="flex justify-center items-center m-1 font-medium py-1 px-1 bg-white rounded bg-gray-100 border">
<div class="text-xs font-normal leading-none max-w-full flex-initial x-model=" options[option]="" x-text="options[option].text">val5</div>
<div class="flex flex-auto flex-row-reverse">
<div x-on:click.stop="removeBis(index,option)">
<svg class="fill-current h-4 w-4 " role="button" viewBox="0 0 20 20">
<path d="M14.348,14.849c-0.469,0.469-1.229,0.469-1.697,0L10,11.819l-2.651,3.029c-0.469,0.469-1.229,0.469-1.697,0
c-0.469-0.469-0.469-1.229,0-1.697l2.758-3.15L5.651,6.849c-0.469-0.469-0.469-1.228,0-1.697s1.228-0.469,1.697,0L10,8.183
l2.651-3.031c0.469-0.469,1.228-0.469,1.697,0s0.469,1.229,0,1.697l-2.758,3.152l2.758,3.15
C14.817,13.62,14.817,14.38,14.348,14.849z"></path>
</svg>
</div>
</div>
</div>
但是我得到了以下错误:
alpine.js:1914 Uncaught ReferenceError: option is not defined at eval (eval at d.el (alpine.js:144), :3:62) at d.el (alpine.js:144) at d (alpine.js:131) at f (alpine.js:139) at be.evaluateReturnExpression (alpine.js:1754) at alpine.js:1721 at Array.forEach () at be.resolveBoundAttributes (alpine.js:1703) at be.initializeElement (alpine.js:1628) at alpine.js:1612
有没有办法使用 alpine 或 jQuery 来实现它?
问题
Alpine JS 是一个响应式库。因此,逻辑隐藏在 DOM 之外,有点虚拟。你不能直接与它互动。您不能附加到虚拟生成的 DOM 并期望具有相同的功能。
问题 #1
好的,第一个问题是您附加的 DOM 引用的变量仅在模板循环中可用。变量 (index, option)
在模板中声明。您无法在模板之外访问它们。
问题 #2
您不能期望在模板循环之外添加的 DOM 与虚拟 DOM 的其余部分一起工作。您可以手动找到正确的索引并将其粘贴到 DOM 中进行临时修复,但这会随着时间的推移而出现问题。
解决方案
此解决方案在构造函数中获取一组值,并将这些值设置为多select.
的默认值https://jsfiddle.net/dk2s90cj/
深思
此代码段正在手动更新并从隐藏的多 select 字段中提取数据。为什么不直接使用 AlpineJS 绑定到 multi-select?为什么手动工作?