Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/components/TreeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
@treeNodeClick="(t, e)=>$emit(TreeEvent.Click, t, e)"
@treeNodeDblclick="(t, e)=>$emit(TreeEvent.DoubleClick, t, e)"
@treeNodeCheckboxChange="(t, e)=>$emit(TreeEvent.CheckboxChange, t, e)"
@treeNodeChildCheckboxChange="(t, c, e)=>$emit(TreeEvent.ChildCheckboxChange, t, c, e)"
@treeNodeRadioChange="(t, e)=>$emit(TreeEvent.RadioChange, t, e)"
@treeNodeExpandedChange="(t, e)=>$emit(TreeEvent.ExpandedChange, t, e)"
@treeNodeChildrenLoad="(t, e)=>$emit(TreeEvent.ChildrenLoad, t, e)"
Expand Down Expand Up @@ -121,6 +122,7 @@ const emit = defineEmits([
TreeEvent.Add,
TreeEvent.CheckboxChange,
TreeEvent.ChildrenLoad,
TreeEvent.ChildCheckboxChange,
TreeEvent.Click,
TreeEvent.Delete,
TreeEvent.DoubleClick,
Expand Down Expand Up @@ -220,7 +222,7 @@ function getCheckedRadioButtons() {
* @param matcherFunction {function} A function which takes a node as an argument
* and returns a boolean indicating a match for some condition
* @param maxMatches {integer} The maximum number of matches to return
* @returns {Array<TreeNode>} An array of any nodes matched by the given function
* @returns {Array<TreeViewNode>} An array of any nodes matched by the given function
*/
function getMatching(matcherFunction, maxMatches = 0) {
let matches = [];
Expand Down
18 changes: 17 additions & 1 deletion src/components/TreeViewNode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@
:is-mounted="isMounted"
@treeNodeClick="(t, e)=>$emit(TreeEvent.Click, t, e)"
@treeNodeDblclick="(t, e)=>$emit(TreeEvent.DoubleClick, t, e)"
@treeNodeCheckboxChange="(t, e)=>$emit(TreeEvent.CheckboxChange, t, e)"
@treeNodeCheckboxChange="handleCheckboxChange"
@treeNodeChildCheckboxChange="(t, c, e)=>$emit(TreeEvent.ChildCheckboxChange, t, c, e)"
@treeNodeRadioChange="(t, e)=>$emit(TreeEvent.RadioChange, t, e)"
@treeNodeExpandedChange="(t, e)=>$emit(TreeEvent.ExpandedChange, t, e)"
@treeNodeChildrenLoad="(t, e)=>$emit(TreeEvent.ChildrenLoad, t, e)"
Expand Down Expand Up @@ -277,6 +278,7 @@ const emit = defineEmits([
TreeEvent.Add,
TreeEvent.Click,
TreeEvent.CheckboxChange,
TreeEvent.ChildCheckboxChange,
TreeEvent.ChildrenLoad,
TreeEvent.Delete,
TreeEvent.DoubleClick,
Expand Down Expand Up @@ -530,6 +532,20 @@ function handleChildDeletion(node, event) {
emit(TreeEvent.Delete, node, event);
}

/**
* Emits the treeNodeCheckboxChange event, and if the event is for
* a direct child then it also emits the treeNodeChildCheckboxChange event.
* @param {TreeViewNode} node The node on which the checkbox changed
* @param {Event} event The event that triggered the change
*/
function handleCheckboxChange(node, event) {
emit(TreeEvent.CheckboxChange, node, event);

if (children.value.includes(node)) {
emit(TreeEvent.ChildCheckboxChange, model.value, node, event);
}
}

// CREATION LOGIC

// id and label are required; notify the user. Validation is done here instead
Expand Down
1 change: 1 addition & 0 deletions src/enums/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const events = Object.freeze({
Click: 'treeNodeClick',
DoubleClick: 'treeNodeDblclick',
CheckboxChange: 'treeNodeCheckboxChange',
ChildCheckboxChange: 'treeNodeChildCheckboxChange',
RadioChange: 'treeNodeRadioChange',
ExpandedChange: 'treeNodeExpandedChange',
ChildrenLoad: 'treeNodeChildrenLoad',
Expand Down
25 changes: 13 additions & 12 deletions src/stories/Home.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -273,18 +273,19 @@ If specified, the `modelDefaults` property of the TreeView will be merged with n

## Events

| Event | Description | Handler Parameters |
|:---------------------------|:---------------------------------------------------------------|:-----------------------------------------------------------------------|
| treeNodeAdd | Emitted when a node is added | `target` The model of the target (child) node <br/> `parent` The model of the parent node <br/> `event` The original event |
| treeNodeClick | Emitted when a node is clicked | `target` The model of the target node <br/> `event` The original event |
| treeNodeDblclick | Emitted when a node is double clicked | `target` The model of the target node <br/> `event` The original event |
| treeNodeDelete | Emitted when a node is deleted | `target` The model of the target node <br/> `event` The original event |
| treeNodeCheckboxChange | Emitted when a node's checkbox emits a change event | `target` The model of the target node <br/> `event` The original event |
| treeNodeRadioChange | Emitted when a node's radio button emits a change event | `target` The model of the target node <br/> `event` The original event |
| treeNodeExpandedChange | Emitted when a node is expanded or collapsed | `target` The model of the target node <br/> `event` The original event |
| treeNodeSelectedChange | Emitted when a node is selected or deselected | `target` The model of the target node <br/> `event` The original event |
| treeNodeChildrenLoad | Emitted when a node's children are done loading asynchronously | `target` The model of the target node <br/> `event` The original event |
| treeRootNodesLoad | Emitted when the root nodes are done loading asynchronously | |
| Event | Description | Handler Parameters |
|:----------------------------|:---------------------------------------------------------------|:-----------------------------------------------------------------------|
| treeNodeAdd | Emitted when a node is added | `target` The model of the target (child) node <br/> `parent` The model of the parent node <br/> `event` The original event |
| treeNodeClick | Emitted when a node is clicked | `target` The model of the target node <br/> `event` The original event |
| treeNodeDblclick | Emitted when a node is double clicked | `target` The model of the target node <br/> `event` The original event |
| treeNodeDelete | Emitted when a node is deleted | `target` The model of the target node <br/> `event` The original event |
| treeNodeCheckboxChange | Emitted when a node's checkbox emits a change event | `target` The model of the target node <br/> `event` The original event |
| treeNodeChildCheckboxChange | Emitted when a child node's checkbox emits a change event | `target` The model of the target node (the parent of the changed node) <br/> `child` The model of changed node <br/> `event` The original event |
| treeNodeRadioChange | Emitted when a node's radio button emits a change event | `target` The model of the target node <br/> `event` The original event |
| treeNodeExpandedChange | Emitted when a node is expanded or collapsed | `target` The model of the target node <br/> `event` The original event |
| treeNodeSelectedChange | Emitted when a node is selected or deselected | `target` The model of the target node <br/> `event` The original event |
| treeNodeChildrenLoad | Emitted when a node's children are done loading asynchronously | `target` The model of the target node <br/> `event` The original event |
| treeRootNodesLoad | Emitted when the root nodes are done loading asynchronously | |

## CSS Classes

Expand Down
12 changes: 12 additions & 0 deletions tests/unit/TreeView.eventHandling.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ describe('TreeView.vue (event handling)', () => {
});
});

describe('when a node fires a treeNodeChildCheckboxChange event', () => {

beforeEach(() => {
wrapper = createWrapper({ initialModel: generateNodes(['es']), selectionMode: SelectionMode.Multiple });
wrapper.findComponent(TreeViewNode).vm.$emit('treeNodeChildCheckboxChange');
});

it('should emit a treeNodeChildCheckboxChange event', () => {
expect(wrapper.emitted('treeNodeChildCheckboxChange').length).to.equal(1);
});
});

describe('when a node fires a treeNodeRadioChange event', () => {

beforeEach(() => {
Expand Down
25 changes: 25 additions & 0 deletions tests/unit/TreeViewNode.interactions.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,31 @@ describe('TreeViewNode.vue (interactions)', () => {
});
});

describe('when a child node\'s checkbox is toggled', () => {

let checkbox = null;

beforeEach(() => {
wrapper = createWrapper({
ariaKeyMap: {},
initialModel: generateNodes(['es', ['ces']])[0],
modelDefaults: {},
depth: 0,
treeId: 'tree',
initialRadioGroupValues: {},
isMounted: false
});

const childWrapper = wrapper.find('.grtvn-children').findComponent(TreeViewNode);
checkbox = childWrapper.find('#' + childWrapper.vm.inputId);
});

it('should emit the treeNodeChildCheckboxChange event', () => {
checkbox.setChecked();
expect(wrapper.emitted().treeNodeCheckboxChange.length).to.equal(1);
});
});

describe('when the node\'s radiobutton is toggled', () => {

let radioButton = null;
Expand Down