Skip to content

Commit

Permalink
Fix for recursive drill-down for selecting-all/unselecting-all infini…
Browse files Browse the repository at this point in the history
…te descendants
  • Loading branch information
hujambo-dunia committed May 8, 2024
1 parent 0192501 commit 5b50caa
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 13 deletions.
36 changes: 24 additions & 12 deletions client/src/components/Form/Elements/FormDrilldown/FormDrilldown.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type ComputedRef } from "vue";
import { getAllValues, type Option, type Value } from "./utilities";
import { findDescendants, flattenValues, getAllValues, type Option, type Value } from "./utilities";
import FormDrilldownList from "./FormDrilldownList.vue";
Expand Down Expand Up @@ -53,29 +53,41 @@ const selectAllIndeterminate: ComputedRef<boolean> = computed(() => {
});
// Handle click on individual check/radio element
function handleClick(value: string): void {
function handleClick(clickedElement: string, value: string): void {
if (props.multiple) {
const newValue: string[] = currentValue.value.slice();
const index: number = newValue.indexOf(value);
if (index !== -1) {
newValue.splice(index, 1);
} else {
newValue.push(value);
}
if (newValue.length === 0) {
const clickedElements: string[] = addDescendants(props.options, clickedElement);
const selectedElements: string[] = setElementValues(currentValue.value, clickedElements, value);
if (selectedElements.length === 0) {
emit("input", null);
} else {
emit("input", newValue);
emit("input", selectedElements);
}
} else {
emit("input", value);
emit("input", clickedElement);
}
}
// Handle click on select all checkbox to either select or unselect all values
function onSelectAll(selected: boolean): void {
emit("input", selected ? allValues.value : null);
}
// Returns the descendant values and the selected/parent value (regardless of unselected or selected)
function addDescendants(selectOptions: any[], selectedValue: string): string[] {
const descendants: any[] | null = findDescendants(selectOptions, selectedValue);
const allValues = flattenValues(descendants);
allValues.unshift(selectedValue);
return allValues;
}
function setElementValues(oldArray: string[], newArray: string[], value: string): string[] {
if (value) {
return Array.from(new Set([...oldArray, ...newArray]));
} else {
const newSet = new Set(newArray);
return oldArray.filter((item) => !newSet.has(item));
}
}
</script>

<template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ onMounted(() => {
class="drilldown-option d-inline"
value="true"
:checked="isChecked"
@change="handleClick(option.value)">
@change="handleClick(option.value, $event)">
{{ option.name }}
</component>
<FormDrilldownList
Expand Down
41 changes: 41 additions & 0 deletions client/src/components/Form/Elements/FormDrilldown/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,44 @@ export function getAllValues(headOptions: Array<Option>): string[] {
}
return values;
}

/**
* Returns all types of "decendants" (child, grandchild, and so forth) in nested array (or null).
* @param objects Array of Option objects with all keys intact
* @returns values: string[]
*/
export function findDescendants(objects: Array<Option>, search: string): any[] | null {
const stack: Array<Option> = [...objects];
while (stack.length > 0) {
const current = stack.pop();
if (current === undefined) {
return null;
} else {
if (current.value === search) {
return current.options;
}
if (current.options && Array.isArray(current.options)) {
stack.push(...current.options);
}
}
}

return null;
}

export function flattenValues(objects: any): string[] {
const newArray = [];
const stack = [...objects];

while (stack.length > 0) {
const current = stack.pop();
if (current.value) {
newArray.push(current.value);
}
if (current.options && Array.isArray(current.options)) {
stack.push(...current.options);
}
}

return newArray;
}

0 comments on commit 5b50caa

Please sign in to comment.