Skip to content

Instantly share code, notes, and snippets.

@ryasmi
Last active November 8, 2017 14:53
Show Gist options
  • Save ryasmi/2e62b1d79024ed317d31d734e58b730d to your computer and use it in GitHub Desktop.
Save ryasmi/2e62b1d79024ed317d31d734e58b730d to your computer and use it in GitHub Desktop.
Toggles items in a tree. Toggling on selects all children and all parents (but not siblings). Toggling off deselects all children (but not parents or siblings).
item4 = {id: 4, children: []};
item3 = {id: 3, children: [], parent: 2};
item2 = {id: 2, children: [item3], parent: 1};
item1 = {id: 1, children: [item2]};
items = [item1, item4];
flatten = (items) => {
return items.reduce((flatItems, item) => {
const children = _.get(item, 'children', []);
const flatChildren = children.length === 0 ? [] : flatten(children);
return [...flatItems, item, ...flatChildren];
}, []);
};
getParents = (flatItems, item) => {
if (item.parent === undefined) {
return [];
}
const parent = _.find(flatItems, (flatItem) => {
return item.parent === flatItem.id;
});
return [parent, ...getParents(flatItems, parent)];
};
select = (selectedItems, item) => {
const flatItems = flatten(items);
const selectedParents = getParents(flatItems, item).map((item) => item.id);
const selectedChildren = flatten(item.children).map((item) => item.id);
return _.union(selectedItems, [item.id, ...selectedParents, ...selectedChildren]);
};
deselect = (selectedItems, item) => {
const flatItems = flatten(items);
const children = flatten(item.children).map((item) => item.id);
return _.difference(selectedItems, [item.id, ...children]);
};
toggle = (selectedItems, item) => {
if (_.includes(selectedItems, item.id)) {
return deselect(selectedItems, item);
}
return select(selectedItems, item);
};
// Example.
selectedItems = [];
selectedItems = toggle(selectedItems, item3); // [3, 2, 1]
selectedItems = toggle(selectedItems, item3); // [2, 1]
item4 = {id: 4, children: []};
item3 = {id: 3, children: [], parent: 2};
item2 = {id: 2, children: [item3], parent: 1};
item1 = {id: 1, children: [item2]};
items = [item1, item4];
flatten = (items) => {
return items.reduce((flatItems, item) => {
const children = _.get(item, 'children', []);
const flatChildren = children.length === 0 ? [] : flatten(children);
return _.concat(flatItems, [item], flatChildren);
}, []);
};
getParents = (flatItems, item) => {
if (item.parent === undefined) {
return [];
}
const parent = _.find(flatItems, (flatItem) => {
return item.parent === flatItem.id;
});
return _.concat([parent], getParents(flatItems, parent));
};
select = (selectedItems, item) => {
const flatItems = flatten(items);
const selectedParents = getParents(flatItems, item).map((item) => item.id);
const selectedChildren = flatten(item.children).map((item) => item.id);
return _.union(selectedItems, _.concat([item.id], selectedParents, selectedChildren));
};
deselect = (selectedItems, item) => {
const flatItems = flatten(items);
const children = flatten(item.children).map((item) => item.id);
return _.difference(selectedItems, _.concat([item.id], children));
};
toggle = (selectedItems, item) => {
if (_.includes(selectedItems, item.id)) {
return deselect(selectedItems, item);
}
return select(selectedItems, item);
};
// Example.
selectedItems = [];
selectedItems = toggle(selectedItems, item3); // [3, 2, 1]
selectedItems = toggle(selectedItems, item3); // [2, 1]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment