我已经基于JSON以嵌套方式动态创建了一组复选框输入。现在,我想以父子形式将所有选中的复选框作为数组,如下所示:
MASTERDATA
+------------+----------+-------------+------------------------------+------+-------+------------+---------+-----------------+----------------+
| partnumber | partname | description | imageurl | qty | oemid | seriesid | modelid | functiongroupid | assemblynameid |
+------------+----------+-------------+------------------------------+------+-------+------------+---------+-----------------+----------------+
| A32 | Lens | RED | AP3415_________UN01JAN94.gif | 2 | 8 | 256 | 6694 | 12318 | 449980 |
| 14274 | Nut | M10 | TX1061736______UN20JUL09.gif | 1 | 8 | 257 | 8264 | 13996 | 884056 |
| C1115 | HC | NLA ORDER | 0000897883____________A2.gif | 1 | 8 | 258 | 8263 | 13962 | 880092 |
| 03H1626 | BOLT | 1/4 X 1/2 | M5004__________UN02JAN94.gif | 1 | 8 | 259 | 6693 | 17549 | 89782 |
| 1854 | Screw | M10 X 80 | TX1030795______UN25OCT07.gif | 4 | 8 | 260 | 8262 | 14029 | 891643 |
+------------+----------+-------------+------------------------------+------+-------+------------+---------+-----------------+----------------+
let data = {
"personal-information": {
"label": "personal-information",
"children": {
"first_name": {
"type": "string",
"label": "First Name",
"optional": false
},
"last_name": {
"type": "string",
"label": "Last Name",
"optional": false
},
"dob": {
"type": "date",
"label": "Date Of Birth",
"optional": false
},
"gender": {
"type": "string",
"label": "Gender",
"optional": false
},
"height": {
"type": "string",
"label": "Height",
"optional": false
},
"weight": {
"type": "string",
"label": "Weight",
"optional": false
},
"blood-group": {
"type": "string",
"label": "Blood-Group",
"optional": false
},
"addresses": {
"label": "addresses",
"children": {
"address-line-1": {
"type": "string",
"label": "Address",
"optional": false
},
"address-line-2": {
"type": "string",
"label": "Address",
"optional": false
},
"city": {
"type": "string",
"label": "City",
"optional": false
},
"state": {
"type": "string",
"label": "State",
"optional": false
},
"country": {
"type": "string",
"label": "Country",
"optional": false
},
"zipcode": {
"type": "string",
"label": "Zip Code",
"optional": false
}
}
},
"emergency-contact": {
"label": "emergency-contact",
"children": {
"name": {
"type": "string",
"label": "Zip Code",
"optional": false
},
"phone": {
"type": "string",
"label": "Phone",
"optional": false
},
"email": {
"type": "string",
"label": "Email",
"optional": false
}
}
}
}
},
"general-information": {
"label": "general-information",
"children": {
"allergies": {
"type": "String",
"label": "Allergies",
"optional": true
},
"habits": {
"type": "String",
"label": "Habits",
"optional": true
}
}
},
"history": {
"label": "history",
"children": {
"status": {
"type": "Boolean",
"label": "Status",
"optional": false
},
"createdAt": {
"type": "date",
"label": "createdAt",
"optional": false
},
"problem": {
"type": "Text",
"label": "Chief Complaint",
"optional": true
},
"diagnosis": {
"type": "Text",
"label": "Diagnosis",
"optional": true
},
"prescription": {
"type": "Text",
"label": "Prescription",
"optional": true
},
"lab-result": {
"label": "lab-result",
"children": {
"test-name": {
"type": "string",
"label": "Test Name",
"optional": false
},
"loinc": {
"type": "string",
"label": "Loinc",
"optional": false
},
"normal-range": {
"type": "string",
"label": "Normal Range",
"optional": false
},
"unit": {
"type": "string",
"label": "Unit",
"optional": false
},
"value": {
"type": "string",
"label": "Value",
"optional": false
},
"test-result": {
"type": "string",
"label": "Test Name",
"optional": false
},
"createdAt": {
"type": "date-time",
"label": "Time",
"optional": false
},
"status": {
"type": "Boolean",
"label": "Status",
"optional": false
}
}
},
"medication-history": {
"label": "medication-history",
"children": {
"medication-name": {
"type": "string",
"label": "Medication Name",
"optional": false
},
"notes": {
"type": "string",
"label": "Notes",
"optional": false
},
"status": {
"type": "Boolean",
"label": "Status",
"optional": false
},
"qty": {
"type": "string",
"label": "Quantity",
"optional": false
},
"time-to-take": {
"type": "string",
"label": "No. of time to take",
"optional": false
},
"createdAt": {
"type": "date",
"label": "Date",
"optional": false
}
}
}
}
}
};
let nodeLevel = 1;
function addItem(parentUL, branch, parentName) {
for (var key in branch) {
// console.log('Branch', branch[key]);
// console.log('Key: ', key);
var item = branch[key].children;
// console.log('Item: ', item)
let name = '';
if (parentName) {
name = parentName;
}
$item = $('<li>', {
id: key
});
$item.append($('<input>', {
type: "checkbox",
id: key,
name: key,
value: key,
"data-parent": name
}));
// $item.attr('data-parent', name);
$item.append($('<label>', {
for: key,
text: key
}));
parentUL.append($item);
nodeLevel++;
if (branch[key].children) {
var $ul = $('<ul>', {
style: 'display: none'
}).appendTo($item);
addItem($ul, item, branch[key].label);
} else {
nodeLevel = 1;
}
}
}
$(function() {
addItem($('#root'), data);
$(':checkbox').change(function() {
$(this).closest('li').children('ul').slideToggle();
});
// $('label').click(function() {
// $(this).closest('li').find(':checkbox').trigger('click');
// });
});
$(".save").click(function() {
var selected = new Array();
var checkboxes = document.querySelectorAll('input[type=checkbox]:checked')
let arrAll = {};
for (var i = 0; i < checkboxes.length; i++) {
let parent = checkboxes[i].getAttribute('data-parent');
console.log('Checkbox: ', checkboxes[i]);
console.log('Parent: ', parent);
// let inputName = checkboxes[i].getAttribute('name');
// console.log(inputName);
// if(parent) {
// arrAll[parent][inputName] = {};
// } else {
// arrAll[inputName] = {};
// }
/*
if(parent){
selected[parent] = [];
selected[parent].push(checkboxes[i].value);
} else {
selected.push(checkboxes[i].value);
} */
// selected.push(checkboxes[i].value)
}
// console.log('Selected checkbox:', arrAll);
});
所以,如果我选择 1.个人信息->名和姓 2.个人信息->地址->地址行1 3.一般信息->过敏 4.历史记录->状态
我的预期输出是:
ul {
list-style: none;
padding: 0;
margin: 0;
}
ul ul {
margin: 0 0 0 30px;
}
我该如何使用jQuery或Javascript?
答案 0 :(得分:2)
您可以像在创建元素时一样,以递归方式再次遍历data
对象以读取状态。我们从所需的结构开始,而不是从复选框的数组开始。
在此示例中,我使用name
属性将UI元素与原始数据源进行匹配。最好在创建它的某个时候存储对它的引用。这样可以更轻松地找到合适的元素,而不必依赖DOM查询。
还要注意,您当前的HTML在<li>
和<checkbox>
元素上包含重复的ID ...
简而言之:
data
的条目[name=${key}]
元素checked
,则将其key
添加到对象children
对象,请递归。children
,请添加其值const walkCheckedTree = (opts) => Object
.entries(opts)
.reduce((t, [k, v]) => {
const cb = root.querySelector(`[name=${k}]`);
if (cb.checked) {
if (v.children) {
t[k] = { child: walkCheckedTree(v.children) };
} else {
t[k] = k;
}
}
return t;
}, {});
const tree = walkCheckedTree(data);
运行示例:(按保存以记录日志)
let data = {
"personal-information": {
"label": "personal-information",
"children": {
"first_name": {
"type": "string",
"label": "First Name",
"optional": false
},
"last_name": {
"type": "string",
"label": "Last Name",
"optional": false
},
"dob": {
"type": "date",
"label": "Date Of Birth",
"optional": false
},
"gender": {
"type": "string",
"label": "Gender",
"optional": false
},
"height": {
"type": "string",
"label": "Height",
"optional": false
},
"weight": {
"type": "string",
"label": "Weight",
"optional": false
},
"blood-group": {
"type": "string",
"label": "Blood-Group",
"optional": false
},
"addresses": {
"label": "addresses",
"children": {
"address-line-1": {
"type": "string",
"label": "Address",
"optional": false
},
"address-line-2": {
"type": "string",
"label": "Address",
"optional": false
},
"city": {
"type": "string",
"label": "City",
"optional": false
},
"state": {
"type": "string",
"label": "State",
"optional": false
},
"country": {
"type": "string",
"label": "Country",
"optional": false
},
"zipcode": {
"type": "string",
"label": "Zip Code",
"optional": false
}
}
},
"emergency-contact": {
"label": "emergency-contact",
"children": {
"name": {
"type": "string",
"label": "Zip Code",
"optional": false
},
"phone": {
"type": "string",
"label": "Phone",
"optional": false
},
"email": {
"type": "string",
"label": "Email",
"optional": false
}
}
}
}
},
"general-information": {
"label": "general-information",
"children": {
"allergies": {
"type": "String",
"label": "Allergies",
"optional": true
},
"habits": {
"type": "String",
"label": "Habits",
"optional": true
}
}
},
"history": {
"label": "history",
"children": {
"status": {
"type": "Boolean",
"label": "Status",
"optional": false
},
"createdAt": {
"type": "date",
"label": "createdAt",
"optional": false
},
"problem": {
"type": "Text",
"label": "Chief Complaint",
"optional": true
},
"diagnosis": {
"type": "Text",
"label": "Diagnosis",
"optional": true
},
"prescription": {
"type": "Text",
"label": "Prescription",
"optional": true
},
"lab-result": {
"label": "lab-result",
"children": {
"test-name": {
"type": "string",
"label": "Test Name",
"optional": false
},
"loinc": {
"type": "string",
"label": "Loinc",
"optional": false
},
"normal-range": {
"type": "string",
"label": "Normal Range",
"optional": false
},
"unit": {
"type": "string",
"label": "Unit",
"optional": false
},
"value": {
"type": "string",
"label": "Value",
"optional": false
},
"test-result": {
"type": "string",
"label": "Test Name",
"optional": false
},
"createdAt": {
"type": "date-time",
"label": "Time",
"optional": false
},
"status": {
"type": "Boolean",
"label": "Status",
"optional": false
}
}
},
"medication-history": {
"label": "medication-history",
"children": {
"medication-name": {
"type": "string",
"label": "Medication Name",
"optional": false
},
"notes": {
"type": "string",
"label": "Notes",
"optional": false
},
"status": {
"type": "Boolean",
"label": "Status",
"optional": false
},
"qty": {
"type": "string",
"label": "Quantity",
"optional": false
},
"time-to-take": {
"type": "string",
"label": "No. of time to take",
"optional": false
},
"createdAt": {
"type": "date",
"label": "Date",
"optional": false
}
}
}
}
}
};
let nodeLevel = 1;
function addItem(parentUL, branch, parentName) {
for (var key in branch) {
// console.log('Branch', branch[key]);
// console.log('Key: ', key);
var item = branch[key].children;
// console.log('Item: ', item)
let name = '';
if (parentName) {
name = parentName;
}
$item = $('<li>', {
id: key
});
$item.append($('<input>', {
type: "checkbox",
id: key,
name: key,
value: key,
"data-parent": name
}));
// $item.attr('data-parent', name);
$item.append($('<label>', {
for: key,
text: key
}));
parentUL.append($item);
nodeLevel++;
if (branch[key].children) {
var $ul = $('<ul>', {
style: 'display: none'
}).appendTo($item);
addItem($ul, item, branch[key].label);
} else {
nodeLevel = 1;
}
}
}
$(function() {
addItem($('#root'), data);
$(':checkbox').change(function() {
$(this).closest('li').children('ul').slideToggle();
});
// $('label').click(function() {
// $(this).closest('li').find(':checkbox').trigger('click');
// });
});
$(".save").click(function() {
const root = document.getElementById("root");
const walkCheckedTree = (opts) => Object
.entries(opts)
.reduce((t, [k, v]) => {
const cb = root.querySelector(`[name=${k}]`);
if (cb.checked) {
if (v.children) {
t[k] = { child: walkCheckedTree(v.children) };
} else {
t[k] = k;
}
}
return t;
}, {});
const tree = walkCheckedTree(data);
console.log(tree);
});
ul {
list-style: none;
padding: 0;
margin: 0;
}
ul ul {
margin: 0 0 0 30px;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<ul id="root"></ul>
<button class="save">Save</button>