|
function permitDependents(tagTypeId, tagIds) { |
|
tagIds.forEach(tagId => { |
|
const permittedInput = document.getElementById( |
|
`question_tags_tag_types[${tagTypeId}]_${tagId}` |
|
); |
|
if (permittedInput) permittedInput.disabled = false; |
|
}); |
|
} |
|
|
|
function disableDependents(tagTypeId, shouldClear) { |
|
const radioButtons = document.querySelectorAll( |
|
`input[name='question_tags[tag_types[${tagTypeId}]]']` |
|
); |
|
const checkBoxes = document.querySelectorAll( |
|
`input[name='question_tags[tag_types[${tagTypeId}]][]']` |
|
); |
|
const matches = [...radioButtons, ...checkBoxes]; |
|
|
|
let nestedDepenedents = []; |
|
|
|
for (let i = 0; i < matches.length; i++) { |
|
const childInput = matches[i]; |
|
if (["radio", "checkbox"].includes(childInput.type)) { |
|
childInput.disabled = "disabled"; |
|
if (shouldClear) childInput.checked = false; |
|
|
|
const { childTagTypeIds = [] } = parsePropsFromDataset( |
|
childInput.closest(".options").dataset |
|
); |
|
for (const childTagId of childTagTypeIds) { |
|
if (!nestedDepenedents.includes(childTagId)) { |
|
nestedDepenedents.push(childTagId); |
|
} |
|
} |
|
} |
|
} |
|
|
|
nestedDepenedents.forEach(dependent => |
|
disableDependents(dependent, shouldClear) |
|
); |
|
} |
|
|
|
function updateOptions(tagInput, shouldClear) { |
|
const { childTagTypeIds = [] } = parsePropsFromDataset( |
|
tagInput.closest(".options").dataset |
|
); |
|
const { childTagIds = [] } = parsePropsFromDataset(tagInput.dataset); |
|
|
|
childTagTypeIds.forEach(tagTypeId => { |
|
disableDependents(tagTypeId, shouldClear); |
|
permitDependents(tagTypeId, childTagIds); |
|
}); |
|
} |
|
|
|
function parsePropsFromDataset(dataset) { |
|
let stringifyedOptions = { ...dataset }; // convert DOMStringMap into Object |
|
let props = {}; |
|
|
|
for (let key of Object.keys(stringifyedOptions)) { |
|
let rawValue = stringifyedOptions[key]; |
|
|
|
try { |
|
props[key] = JSON.parse(rawValue); |
|
} catch { |
|
props[key] = rawValue; // for { typeAndId: "Student:1232" } |
|
} |
|
} |
|
|
|
return props; |
|
} |
|
|
|
// handle change |
|
document |
|
.querySelectorAll("input[type=radio], input[type=checkbox]") |
|
.forEach(tagInput => { |
|
tagInput.addEventListener("change", event => { |
|
updateOptions(event.target, true); |
|
}); |
|
}); |
|
|
|
// handle mount |
|
document.addEventListener("DOMContentLoaded", () => { |
|
document |
|
.querySelectorAll("input[type=radio]:checked, input[type=checkbox]:checked") |
|
.forEach(selectedInput => { |
|
updateOptions(selectedInput, false); |
|
}); |
|
}); |
|
|