在 Laravel 中用 AJAX 填充 Selectize optgroup 列
Fill Selectize optgroup columns with AJAX in Laravel
我正在尝试使用 Selectize
在客户端为产品分配属性。
在 Laravel
中,针对 Ajax
请求,我从 Controller 返回一个 JSON
对象,如下所示:
$attribs = AttributeClass::find($request->id)->attributes;
$attributes = array();
foreach($attribs as $attrib){
$options = array();
foreach($attrib->options as $opt){
$options[] = array(
'id' => $opt->id,
'name' => $opt->name
);
}
$attributes[] = array(
'id' => $attrib->id,
'name' => $attrib->name,
'options' => $options
);
}
return response()->json([
'attributes' => $attributes
]);
JSON
输出看起来像这样:
"{"attributes":[
{"id":15,
"name":"Color",
"options":[
{"id":63,"name":"Red"},
{"id":64,"name":"Black"},
{"id":65,"name":"White"},
]},
{"id":16,
"name":"Material",
"options":[
{"id":69,"name":"Leather"},
{"id":70,"name":"Rubber"},
{"id":71,"name":"Suede"},
]},
{"id":17,
"name":"Size",
"options":[
{"id":73,"name":"40"},
{"id":74,"name":"41"},
{"id":75,"name":"42"},
{"id":76,"name":"43"},
{"id":77,"name":"44"}
]}
]}"
在 DOM 中,我有一个 ID 为 #attributesContainer
的 div
容器。我正在 div
中创建一个新的 select
元素,并尝试 populate and selectize
在 ajax 响应中提到 select
,如下所示:
$('#attributesContainer').empty().append(
'<label class="col-md-3 control-label">Attributes</label>'+
'<div class="col-md-9">'+
'<select id="inputAttributes" name="inputAttributes" multiple></select>'+
'<span class="help-block">Choose product attributes</span>'+
'</div>'
);
var optGroups = [];
var options = [];
$.each(data.attributes, function(index, attribute) {
var newElement = {};
newElement['id'] = attribute.id;
newElement['name'] = attribute.name;
optGroups.push(newElement);
$.each(attribute.options, function(index, option){
var newElement = {};
newElement['id'] = option.id;
newElement['attribute'] = attribute.name;
newElement['name'] = option.name;
options.push(newElement);
});
});
$('#inputAttributes').selectize({
options: options,
optgroups: optGroups,
labelField: 'name',
valueField: 'id',
optgroupField: 'attribute',
optgroupLabelField: 'name',
optgroupValueField: 'id',
searchField: ['name'],
plugins: ['optgroup_columns', 'remove_button']
});
预期行为是多列,例如 Selectize 文档中的示例:
但我将所有值都放在一列中,如下所示:
我在这里遗漏了什么或做错了什么?请指导。
PS:我还想限制用户 select 每列只能有一个值。 API支持吗?有什么功能可以做到这一点吗?如何在 Selectize.js
中实现此行为?
出于某种原因,向 selectize
提供 optgroups 和选项对我不起作用。通过首先在 DOM 中创建一个 select
元素并用所有 optgroups 和选项填充它来解决它。
我通过替换做到了:
var optGroups = [];
var options = [];
$.each(data.attributes, function(index, attribute) {
var newElement = {};
newElement['id'] = attribute.id;
newElement['name'] = attribute.name;
optGroups.push(newElement);
$.each(attribute.options, function(index, option){
var newElement = {};
newElement['id'] = option.id;
newElement['attribute'] = attribute.name;
newElement['name'] = option.name;
options.push(newElement);
});
});
$('#inputAttributes').selectize({
options: options,
optgroups: optGroups,
labelField: 'name',
valueField: 'id',
optgroupField: 'attribute',
optgroupLabelField: 'name',
optgroupValueField: 'id',
searchField: ['name'],
plugins: ['optgroup_columns', 'remove_button']
});
与:
$.each(data.attributes, function(i, optgroups) {
$.each(optgroups, function(groupName, options) {
var $optgroup = $("<optgroup>", {
label: groupName
});
$optgroup.appendTo('#inputAttributes');
$.each(options, function(j, option) {
var $option = $("<option>", {
text: option.name,
value: option.id
});
$option.appendTo($optgroup);
});
});
});
$('#inputAttributes').selectize({
sortField: 'text',
plugins: ['optgroup_columns', 'remove_button']
});
仍在寻找我的第二个问题,即如何限制用户 select 每个 optgroup 列中只有一个选项?
编辑:
我已经从每个 optgroup 中实现了单个选项 selection,此代码还显示带有 selected 选项的 optgroup 名称,例如Size > Small
或Color > Black
,希望对大家有所帮助。这是完整的代码:
var vals = {};
$.each(data.attributes, function(i, optgroups) {
$.each(optgroups, function(groupName, options) {
var $optgroup = $("<optgroup>", {
label: groupName
});
$optgroup.appendTo('#inputAttributes');
$.each(options, function(j, option) {
var $option = $("<option>", {
text: option.name,
value: option.id,
});
vals[option.id] = groupName;
$option.appendTo($optgroup);
});
});
});
var $select = $('#inputAttributes').selectize({
sortField: 'text',
placeholder: 'Select attributes...',
lockOptgroupOrder: true,
plugins: ['optgroup_columns', 'remove_button']
});
var selectize = $select[0].selectize;
var selections = [];
selectize.on('item_add', function(value, $item){
var group = vals[value];
var v_text = $item.text();
v_text = v_text.substring(v_text.indexOf(">") + 1);
v_text = group+' > '+v_text.substring(0, v_text.length-1);
$item.html(v_text+
'<a href="javascript:void(0)" class="remove" tabindex="-1" title="Remove">×</a>'
);
// $item.text(group+' > '+$item.text());
if(selections.find(x => x.group === group)){
var v_index = selections.findIndex(x => x.group === group);
var v = selections[v_index].value;
selectize.removeItem(v, silent = true);
}
var newSelection = {};
newSelection['group'] = group;
newSelection['value'] = value;
selections.push(newSelection);
});
selectize.on('item_remove', function(value, $item){
var v_index = selections.findIndex(x => x.value === value);
selections.splice(v_index, 1);
});
PS:有更好的解决方法请指导
我正在尝试使用 Selectize
在客户端为产品分配属性。
在 Laravel
中,针对 Ajax
请求,我从 Controller 返回一个 JSON
对象,如下所示:
$attribs = AttributeClass::find($request->id)->attributes;
$attributes = array();
foreach($attribs as $attrib){
$options = array();
foreach($attrib->options as $opt){
$options[] = array(
'id' => $opt->id,
'name' => $opt->name
);
}
$attributes[] = array(
'id' => $attrib->id,
'name' => $attrib->name,
'options' => $options
);
}
return response()->json([
'attributes' => $attributes
]);
JSON
输出看起来像这样:
"{"attributes":[
{"id":15,
"name":"Color",
"options":[
{"id":63,"name":"Red"},
{"id":64,"name":"Black"},
{"id":65,"name":"White"},
]},
{"id":16,
"name":"Material",
"options":[
{"id":69,"name":"Leather"},
{"id":70,"name":"Rubber"},
{"id":71,"name":"Suede"},
]},
{"id":17,
"name":"Size",
"options":[
{"id":73,"name":"40"},
{"id":74,"name":"41"},
{"id":75,"name":"42"},
{"id":76,"name":"43"},
{"id":77,"name":"44"}
]}
]}"
在 DOM 中,我有一个 ID 为 #attributesContainer
的 div
容器。我正在 div
中创建一个新的 select
元素,并尝试 populate and selectize
在 ajax 响应中提到 select
,如下所示:
$('#attributesContainer').empty().append(
'<label class="col-md-3 control-label">Attributes</label>'+
'<div class="col-md-9">'+
'<select id="inputAttributes" name="inputAttributes" multiple></select>'+
'<span class="help-block">Choose product attributes</span>'+
'</div>'
);
var optGroups = [];
var options = [];
$.each(data.attributes, function(index, attribute) {
var newElement = {};
newElement['id'] = attribute.id;
newElement['name'] = attribute.name;
optGroups.push(newElement);
$.each(attribute.options, function(index, option){
var newElement = {};
newElement['id'] = option.id;
newElement['attribute'] = attribute.name;
newElement['name'] = option.name;
options.push(newElement);
});
});
$('#inputAttributes').selectize({
options: options,
optgroups: optGroups,
labelField: 'name',
valueField: 'id',
optgroupField: 'attribute',
optgroupLabelField: 'name',
optgroupValueField: 'id',
searchField: ['name'],
plugins: ['optgroup_columns', 'remove_button']
});
预期行为是多列,例如 Selectize 文档中的示例:
但我将所有值都放在一列中,如下所示:
我在这里遗漏了什么或做错了什么?请指导。
PS:我还想限制用户 select 每列只能有一个值。 API支持吗?有什么功能可以做到这一点吗?如何在 Selectize.js
中实现此行为?
出于某种原因,向 selectize
提供 optgroups 和选项对我不起作用。通过首先在 DOM 中创建一个 select
元素并用所有 optgroups 和选项填充它来解决它。
我通过替换做到了:
var optGroups = [];
var options = [];
$.each(data.attributes, function(index, attribute) {
var newElement = {};
newElement['id'] = attribute.id;
newElement['name'] = attribute.name;
optGroups.push(newElement);
$.each(attribute.options, function(index, option){
var newElement = {};
newElement['id'] = option.id;
newElement['attribute'] = attribute.name;
newElement['name'] = option.name;
options.push(newElement);
});
});
$('#inputAttributes').selectize({
options: options,
optgroups: optGroups,
labelField: 'name',
valueField: 'id',
optgroupField: 'attribute',
optgroupLabelField: 'name',
optgroupValueField: 'id',
searchField: ['name'],
plugins: ['optgroup_columns', 'remove_button']
});
与:
$.each(data.attributes, function(i, optgroups) {
$.each(optgroups, function(groupName, options) {
var $optgroup = $("<optgroup>", {
label: groupName
});
$optgroup.appendTo('#inputAttributes');
$.each(options, function(j, option) {
var $option = $("<option>", {
text: option.name,
value: option.id
});
$option.appendTo($optgroup);
});
});
});
$('#inputAttributes').selectize({
sortField: 'text',
plugins: ['optgroup_columns', 'remove_button']
});
仍在寻找我的第二个问题,即如何限制用户 select 每个 optgroup 列中只有一个选项?
编辑:
我已经从每个 optgroup 中实现了单个选项 selection,此代码还显示带有 selected 选项的 optgroup 名称,例如Size > Small
或Color > Black
,希望对大家有所帮助。这是完整的代码:
var vals = {};
$.each(data.attributes, function(i, optgroups) {
$.each(optgroups, function(groupName, options) {
var $optgroup = $("<optgroup>", {
label: groupName
});
$optgroup.appendTo('#inputAttributes');
$.each(options, function(j, option) {
var $option = $("<option>", {
text: option.name,
value: option.id,
});
vals[option.id] = groupName;
$option.appendTo($optgroup);
});
});
});
var $select = $('#inputAttributes').selectize({
sortField: 'text',
placeholder: 'Select attributes...',
lockOptgroupOrder: true,
plugins: ['optgroup_columns', 'remove_button']
});
var selectize = $select[0].selectize;
var selections = [];
selectize.on('item_add', function(value, $item){
var group = vals[value];
var v_text = $item.text();
v_text = v_text.substring(v_text.indexOf(">") + 1);
v_text = group+' > '+v_text.substring(0, v_text.length-1);
$item.html(v_text+
'<a href="javascript:void(0)" class="remove" tabindex="-1" title="Remove">×</a>'
);
// $item.text(group+' > '+$item.text());
if(selections.find(x => x.group === group)){
var v_index = selections.findIndex(x => x.group === group);
var v = selections[v_index].value;
selectize.removeItem(v, silent = true);
}
var newSelection = {};
newSelection['group'] = group;
newSelection['value'] = value;
selections.push(newSelection);
});
selectize.on('item_remove', function(value, $item){
var v_index = selections.findIndex(x => x.value === value);
selections.splice(v_index, 1);
});
PS:有更好的解决方法请指导