I am building a multi-select checkdown group item list. The goal is to have only ONE active group at a time. So the user can select parents - but if they select a child item, that child group becomes the focus and the selected parents become unchecked.
<div class="checkboxhandler">
<input
type="checkbox"
checked=
onclick=
>
<label> -- checked: </label>
<CheckboxGroup @item= @onClick= />
</div>
I've got as far with the checkboxes with recursive helper checks.
This is the helper tree - where the logic to deselect takes place. This application also needs to hold the array for selectedItems - but needs to clear those array's as well as the checkboxes.
const toggle = value => !value;
const disable = () => false;
// the roots / siblings are contained by arrays
export function check(tree, id, transform = toggle) {
if (tree === undefined) return undefined;
if (Array.isArray(tree)) {
return tree.map(t => check(t, id, transform));
}
if (tree.id === id || id === 'all') {
return checkNode(tree, id, transform);
}
if (tree.children) {
return checkChildren(tree, id, transform);
}
return tree;
}
function selectOnlySubtree(tree, id, transform) {
return tree.map(subTree => {
const newTree = check(subTree, id, transform);
if (!newTree.children || (transform !== disable && didChange(newTree, subTree))) {
return newTree;
}
return disableTree(subTree);
});
}
function isTargetAtThisLevel(tree, id) {
return tree.map(t => t.id).includes(id);
}
function checkNode(tree, id, transform) {
return {
...tree,
checked: transform(tree.checked),
children: disableTree(tree.children)
};
}
function disableTree(tree) {
return check(tree, 'all', disable);
}
function checkChildren(tree, id, transform) {
const newChildren = check(tree.children, id, transform);
const changed = didChange(tree.children, newChildren);
const checked = changed ? false : (
id === 'all' ? transform(tree.checked) : tree.checked
);
return {
...tree,
checked: checked,
children: check(tree.children, id, transform)
};
}
export function didChange(treeA, treeB) {
const rootsChanged = treeA.checked !== treeB.checked;
if (rootsChanged) return true;
if (Array.isArray(treeA) && Array.isArray(treeB)) {
return didChangeList(treeA, treeB);
}
if (treeA.children && treeB.children) {
return didChangeList(treeA.children, treeB.children);
}
return false;
}
function didChangeList(a, b) {
const compares = a.map((childA, index) => {
return didChange(childA, b[index]);
});
const nothingChanged = compares.every(v => v === false);
return !nothingChanged;
}
//latest ember fiddle https://canary.ember-twiddle.com/468a737efbbf447966dd83ac734f62ad?openFiles=tests.unit.utils.tree-helper-test.js%2C
so these are valid conditions -- just parents selected
but the current bugs are occuring
- currently - I can select chilli - then burger - and no decheck of chilli occurs - so that's a bug
- currently - I can select coffee maker - then pickle - and no decheck of coffee maker occurs - so that's a bug
- currently - I can select filter - then chilli - and no decheck of filter occurs - so that's a bug
//illustration of error 1 - so only burger should remain selected in this instance
//illustration of error 2 - so only pickle should remain selected in this instance
//illustration of problem 3 - so only chilli should remain selected in this instance
Aucun commentaire:
Enregistrer un commentaire