创建数组,根据子元素分组
Create array, grouping based on child elements
我有这个html:
<select id="this_id">
<option value="0" class="empty-item">Choose Type</option>
<optgroup label="FirstGrouping"></optgroup>
<option value="2">Thing1</option>
<optgroup label="SecondGrouping"></optgroup>
<option value="8">Thing4</option>
<option value="4">Thing3</option>
<optgroup label="ThirdGrouping"></optgroup>
<option value="7">Thing8</option>
<option value="5">Thing9</option>
</select>
我想做的是创建一个如下所示的数组:
"data": [{
"Label": "FirstGrouping",
"Options": ["Thing1"]
}, {
"Label": "SecondGrouping",
"Options": ["Thing4", "Thing3"]
}, {
"Label": "ThirdGrouping",
"Options": ["Thing8", "Thing9"]
}]
optgroup
和 option
元素没有给定的顺序。所以基本上我需要在 data
数组中的第一个对象中首先对 optgroup
和随后的 options
元素进行分组。其中 "Label"
是 optgroup
,"Options"
是下一个 optgroup
元素之前的所有 option
元素。 data
中的第二个对象有下一个 optgroup
,因为它的 "Label"
和 "Options"
是 optgroup
元素之前的 option
元素。等等。
如果 optgroup
会包装 option
元素,那么我可以这样做:
var yearz = [];
var yearz2 = $('#this_id');
yearz2.each(function() {
var thelabel = $(this).attr('label');
var lengthch = $(this).children().length;
var thisch = $(this).children();
var theobj = [];
var alls = [];
for (var i = 0; i < lengthch; i++) {
alls.push({
"Value": thisch.eq(i).val(),
"Text": thisch.eq(i).text()
});
}
theobj = {
Label: thelabel.trim(),
Options: alls
};
yearz.push(theobj);
});
但是“optgroup”不会包装 option
个元素。
有什么聪明的方法吗?
最好的问候
你可以使用这个 ES5 代码:
var data = [];
var elems = document.getElementById('this_id').children;
for (var i=0; i<elems.length; i++) {
var el = elems[i];
if (el.tagName === 'OPTGROUP') {
data.push({ label: el.getAttribute('label'), options: []});
} else if(el.tagName === 'OPTION' && data.length) {
data[data.length-1].options.push(el.textContent);
}
}
console.log(data);
<select id="this_id">
<optgroup label="FirstGrouping"></optgroup>
<option value="2" style="text-indent: 10px;">Thing1</option>
<optgroup label="SecondGrouping"></optgroup>
<option value="8" style="text-indent: 10px;">Thing4</option>
<option value="4" style="text-indent: 10px;">Thing3</option>
<optgroup label="ThirdGrouping"></optgroup>
<option value="7" style="text-indent: 10px;">Thing8</option>
<option value="5" style="text-indent: 10px;">Thing9</option>
</select>
我有这个html:
<select id="this_id">
<option value="0" class="empty-item">Choose Type</option>
<optgroup label="FirstGrouping"></optgroup>
<option value="2">Thing1</option>
<optgroup label="SecondGrouping"></optgroup>
<option value="8">Thing4</option>
<option value="4">Thing3</option>
<optgroup label="ThirdGrouping"></optgroup>
<option value="7">Thing8</option>
<option value="5">Thing9</option>
</select>
我想做的是创建一个如下所示的数组:
"data": [{
"Label": "FirstGrouping",
"Options": ["Thing1"]
}, {
"Label": "SecondGrouping",
"Options": ["Thing4", "Thing3"]
}, {
"Label": "ThirdGrouping",
"Options": ["Thing8", "Thing9"]
}]
optgroup
和 option
元素没有给定的顺序。所以基本上我需要在 data
数组中的第一个对象中首先对 optgroup
和随后的 options
元素进行分组。其中 "Label"
是 optgroup
,"Options"
是下一个 optgroup
元素之前的所有 option
元素。 data
中的第二个对象有下一个 optgroup
,因为它的 "Label"
和 "Options"
是 optgroup
元素之前的 option
元素。等等。
如果 optgroup
会包装 option
元素,那么我可以这样做:
var yearz = [];
var yearz2 = $('#this_id');
yearz2.each(function() {
var thelabel = $(this).attr('label');
var lengthch = $(this).children().length;
var thisch = $(this).children();
var theobj = [];
var alls = [];
for (var i = 0; i < lengthch; i++) {
alls.push({
"Value": thisch.eq(i).val(),
"Text": thisch.eq(i).text()
});
}
theobj = {
Label: thelabel.trim(),
Options: alls
};
yearz.push(theobj);
});
但是“optgroup”不会包装 option
个元素。
有什么聪明的方法吗?
最好的问候
你可以使用这个 ES5 代码:
var data = [];
var elems = document.getElementById('this_id').children;
for (var i=0; i<elems.length; i++) {
var el = elems[i];
if (el.tagName === 'OPTGROUP') {
data.push({ label: el.getAttribute('label'), options: []});
} else if(el.tagName === 'OPTION' && data.length) {
data[data.length-1].options.push(el.textContent);
}
}
console.log(data);
<select id="this_id">
<optgroup label="FirstGrouping"></optgroup>
<option value="2" style="text-indent: 10px;">Thing1</option>
<optgroup label="SecondGrouping"></optgroup>
<option value="8" style="text-indent: 10px;">Thing4</option>
<option value="4" style="text-indent: 10px;">Thing3</option>
<optgroup label="ThirdGrouping"></optgroup>
<option value="7" style="text-indent: 10px;">Thing8</option>
<option value="5" style="text-indent: 10px;">Thing9</option>
</select>