Skip to content

Commit cf5530b

Browse files
committed
Radio buttons, refactoring for future inputs
Also includes documentation and demo updates. Fixes #14
1 parent 06b3370 commit cf5530b

File tree

10 files changed

+488
-130
lines changed

10 files changed

+488
-130
lines changed

README.md

Lines changed: 69 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# vue-tree
22

3-
vue-tree is a Vue component that implements a TreeView control. Its aim is to provide common tree options in a way that is easy to use and easy to customize.
3+
vue-tree is a Vue component that implements a TreeView control. Its aim is to provide common tree options in a way that is easy to use and easy to customize.
44

55
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
66
[![Build status](https://ci.appveyor.com/api/projects/status/j8d19gt0vh16amhh/branch/master?svg=true)](https://ci.appveyor.com/project/Gregg/vue-tree/branch/master)
@@ -12,11 +12,11 @@ Features include:
1212
- A pleasing (or at least generally acceptable) default format in a wide field of browsers
1313
- Expandable nodes
1414
- Checkboxes
15+
- Radio buttons
1516

1617
Planned:
1718

1819
- Node selection ([#5](https://github.com/grapoza/vue-tree/issues/5))
19-
- Radio buttons; possibly other standard input types as well ([#17](https://github.com/grapoza/vue-tree/issues/17))
2020
- Async loading ([#13](https://github.com/grapoza/vue-tree/issues/13))
2121
- Adding/deleting nodes ([#24](https://github.com/grapoza/vue-tree/issues/24), [#16](https://github.com/grapoza/vue-tree/issues/16))
2222
- Setting node enabled state ([#15](https://github.com/grapoza/vue-tree/issues/15))
@@ -58,8 +58,8 @@ export default {
5858
return {
5959
dataModel: [
6060
{id: "numberOrString", label: "Root Node", children: [
61-
{id: 1, label: "Child Node"},
62-
{id: "node2", label: "Second Child"}]
61+
{id: 1, label: "Child Node"},
62+
{id: "node2", label: "Second Child"}]
6363
}]
6464
}
6565
}
@@ -83,8 +83,8 @@ export default {
8383
return {
8484
dataModel: [
8585
{id: "numberOrString", label: "Root Node", children: [
86-
{id: 1, label: "Child Node"},
87-
{id: "node2", label: "Second Child"}]
86+
{id: 1, label: "Child Node"},
87+
{id: "node2", label: "Second Child"}]
8888
}]
8989
}
9090
}
@@ -93,13 +93,14 @@ export default {
9393

9494
## Demos
9595

96-
To see it in action, try out the [Demos](demo/basic.html).
96+
To see it in action, try out the Demos (coming soon; [#32](https://github.com/grapoza/vue-tree/issues/32)).
9797

9898
## Props
9999

100-
| Prop | Type | Description | Default value | Required |
101-
| :--------------- |:--------------|:-------------------------------------------------------|:---------------|:---------|
102-
| model | Array | The data model containing [tree data](#tree-data) | - | Yes |
100+
| Prop | Type | Description | Default value | Required |
101+
|:-----------------|:---------|:-------------------------------------------------------------------------------|:---------------|:---------|
102+
| model | Array | The data model containing [tree data](#tree-data) | - | Yes |
103+
| radioGroupValues | Object | An object, the properties of which correspond to radio button group selections | `{}` | |
103104

104105
## Tree Data
105106

@@ -108,48 +109,79 @@ The data passed to the treeview should be an array of nodes, where each node has
108109
```javascript
109110
{
110111
id: "node0",
111-
label: "My Node!",
112-
checkable: true,
112+
label: "A checkbox node",
113113
expandable: true,
114114
selectable: false,
115+
input: {
116+
type: 'checkbox'
117+
},
118+
state: {
119+
expanded: true,
120+
selected: false,
121+
input: {
122+
value: false
123+
}
124+
},
125+
children: []
126+
},
127+
{
128+
id: "node1",
129+
label: "A radio button node",
130+
expandable: true,
131+
selectable: false,
132+
input: {
133+
type: 'radio',
134+
name: 'rbGroup1', // Used as the name attribute for the radio button
135+
value: 'thisValue' // Used as the value attribute for the radio button
136+
},
115137
state: {
116-
checked: false,
117138
expanded: true,
118139
selected: false
140+
// No input state here; to let complex radio button groupings work, state is bound to a tree-level property
119141
},
120142
children: []
121143
}
122144
```
123145

124-
| Prop | Type | Description | Default value | Required |
125-
| :--------------- |:----------------|:---------------------------------------------------------|:---------------|:---------|
126-
| id | Number/String | An ID that uniquely identifies this node within the tree | - | Yes |
127-
| label | String | The text to show in the treeview | - | Yes |
128-
| checkable | Boolean | True to show a checkbox for the node | `false` | |
129-
| expandable | Boolean | True to show a toggle for expanding nodes' subnode lists | `true` | |
130-
| selectable | Boolean | True to allow the node to be selected* | `false` | |
131-
| state | Object | Contains the current state of the node | - | |
132-
| state.checked | Boolean | True if this node's checkbox is checked | `false` | |
133-
| state.expanded | Boolean | True if this node's subnode list is expanded | `false` | |
134-
| state.selected | Boolean | True if the node is selected* | `false` | |
135-
| children | Array\<Object\> | The child nodes of this node | `[]` | |
146+
| Prop | Type | Description | Default value | Required |
147+
|:------------------|:----------------|:---------------------------------------------------------|:----------------------------------|:---------|
148+
| id | Number/String | An ID that uniquely identifies this node within the tree | - | Yes |
149+
| label | String | The text to show in the treeview | - | Yes |
150+
| expandable | Boolean | True to show a toggle for expanding nodes' subnode lists | `true` | |
151+
| selectable | Boolean | True to allow the node to be selected* | `false` | |
152+
| input | Object | Contains data specific to the node's `input` element | `null` | |
153+
| input.type | String | The type of input; valid values are `checkbox` or `radio`| - | Yes** |
154+
| input.name | String | The name attribute of the input; used with `radio` type | `'unspecifiedRadioName'` | |
155+
| input.value | String | The value attribute of the input; used with `radio` type | `label`'s value*** | |
156+
| state | Object | Contains the current state of the node | - | |
157+
| state.expanded | Boolean | True if this node's subnode list is expanded | `false` | |
158+
| state.selected | Boolean | True if the node is selected* | `false` | |
159+
| state.input | Object | Contains any state related to the input field | `{}` for checkbox, otherwise - | |
160+
| state.input.value | Boolean | Contains the value of the input | `false` for checkbox, otherwise - | |
161+
| children | Array\<Object\> | The child nodes of this node | `[]` | |
136162

137163
\* Selection props are unused; see [#5](https://github.com/grapoza/vue-tree/issues/5).
138164

165+
\*\* If `input.type` is not supplied, `input` is forced to `null`.
166+
167+
\*\*\* For `input.value`, `label`'s value is replaced with `label.replace(/[\s&<>"'\/]/g, '')`
168+
139169
## Methods
140170

141-
| Method | Description | Parameters | Returns |
142-
|-------------|-------------------------------|------------|------------------------------------------------------------------------|
143-
| getChecked | Gets models for checked nodes | | An `Array<Object>` of models for checked nodes (order not guaranteed). |
171+
| Method | Description | Parameters | Returns |
172+
|:-----------------------|:---------------------------------------|:-----------|:------------------------------------------------------------|
173+
| getCheckedCheckboxes | Gets models for checked checkbox nodes | | An `Array<Object>` of models for checked checkbox nodes |
174+
| getCheckedRadioButtons | Gets models for checked radio nodes | | An `Array<Object>` of models for checked radio button nodes |
144175

145176
## Events
146177

147-
| Event | Description | Handler Parameters |
148-
|-----------------------------|----------------------------------------------|------------------------------------------------------------------------|
149-
| treeViewNodeClick | Emitted when a node is clicked | `target` The model of the target node <br/> `event` The original event |
150-
| treeViewNodeDblclick | Emitted when a node is double clicked | `target` The model of the target node <br/> `event` The original event |
151-
| treeViewNodeCheckedChange | Emitted when a node is checked or unchecked | `target` The model of the target node <br/> `event` The original event |
152-
| treeViewNodeExpandedChange | Emitted when a node is expanded or collapsed | `target` The model of the target node <br/> `event` The original event |
178+
| Event | Description | Handler Parameters |
179+
|:----------------------------|:--------------------------------------------------------|:-----------------------------------------------------------------------|
180+
| treeViewNodeClick | Emitted when a node is clicked | `target` The model of the target node <br/> `event` The original event |
181+
| treeViewNodeDblclick | Emitted when a node is double clicked | `target` The model of the target node <br/> `event` The original event |
182+
| treeViewNodeCheckboxChange | Emitted when a node's checkbox emits a change event | `target` The model of the target node <br/> `event` The original event |
183+
| treeViewNodeRadioChange | Emitted when a node's radio button emits a change event | `target` The model of the target node <br/> `event` The original event |
184+
| treeViewNodeExpandedChange | Emitted when a node is expanded or collapsed | `target` The model of the target node <br/> `event` The original event |
153185

154186
## CSS Classes
155187

@@ -165,6 +197,8 @@ The display of the treeview can be customized via CSS using the following classe
165197
| `tree-view-node-self-expanded-indicator` | The `<i>` element containing the expansion indicator |
166198
| `tree-view-node-self-spacer` | An empty spacer to replace fixed-width elements, _e.g._ the expander or checkbox |
167199
| `tree-view-node-self-label` | The label for the checkbox of checkable nodes |
200+
| `tree-view-node-self-input` | Any type of input node within the tree node |
168201
| `tree-view-node-self-checkbox` | The checkbox |
169-
| `tree-view-node-self-text` | The text for an uncheckable node |
202+
| `tree-view-node-self-radio` | The radio button |
203+
| `tree-view-node-self-text` | The text for a non-input node |
170204
| `tree-view-node-children` | The list of child nodes |

demo/basic.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ <h1>Basic Treeview Demo</h1>
3737
},
3838
methods: {
3939
refreshCheckedList() {
40-
this.$set(this, 'checkedNodes', this.$refs.tree.getChecked());
40+
this.$set(this, 'checkedNodes', this.$refs.tree.getCheckedCheckboxes());
4141
}
4242
}
4343
}).$mount('#app')

demo/basic.js

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,43 @@ export default [
33
id: 'node1',
44
label: 'My First Node',
55
expandable: true,
6-
checkable: true,
76
selectable: true,
7+
input: {
8+
type: 'checkbox',
9+
name: 'checkbox1'
10+
},
811
state: {
9-
checked: false,
1012
expanded: false,
11-
selected: false
13+
selected: false,
14+
input: {
15+
value: false
16+
}
1217
},
1318
children: []
1419
},
1520
{
1621
id: 'node2',
1722
label: 'My Second Node',
1823
expandable: true,
19-
checkable: true,
2024
selectable: true,
25+
input: {
26+
type: 'checkbox',
27+
name: 'checkbox2'
28+
},
2129
state: {
22-
checked: false,
2330
expanded: true,
24-
selected: false
31+
selected: false,
32+
input: {
33+
value: false
34+
}
2535
},
2636
children: [
2737
{
2838
id: 'subnode1',
2939
label: 'This is a subnode',
3040
expandable: true,
31-
checkable: false,
3241
selectable: true,
3342
state: {
34-
checked: false,
3543
expanded: false,
3644
selected: false
3745
},
@@ -41,23 +49,26 @@ export default [
4149
id: 'subnode2',
4250
label: 'This is a checkable, checked subnode',
4351
expandable: true,
44-
checkable: true,
4552
selectable: true,
53+
input: {
54+
type: 'checkbox',
55+
name: 'checkbox3'
56+
},
4657
state: {
47-
checked: true,
4858
expanded: false,
49-
selected: false
59+
selected: false,
60+
input: {
61+
value: true
62+
}
5063
},
5164
children: [
5265
{
5366
id: 'subsubnode1',
5467
label: 'An even deeper node',
5568
children: [],
5669
expandable: true,
57-
checkable: false,
5870
selectable: true,
5971
state: {
60-
checked: false,
6172
expanded: false,
6273
selected: false
6374
}

demo/radioBasic.html

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Basic Radio Button Usage</title>
6+
<script src="https://unpkg.com/vue"></script>
7+
<script src="../dist/vue-tree.umd.js"></script>
8+
<link rel="stylesheet" href="demo.css">
9+
<link rel="stylesheet" href="../dist/vue-tree.css">
10+
</head>
11+
<body>
12+
<div class="container">
13+
<h1>Basic Treeview Radiobutton Demo</h1>
14+
<div id="app">
15+
<tree id="customtree" :model="model" :radio-group-values="radioGroupValues" ref="tree"></tree>
16+
<section id="checkedStuff">
17+
<button type="button" @click="refreshCheckedList">What's been checked?</button>
18+
<ul id="checkedList">
19+
<li v-for="checkedNode in checkedNodes">{{ checkedNode.id }}</li>
20+
</ul>
21+
</section>
22+
</div>
23+
</div>
24+
25+
<script type='module'>
26+
import basicRadioData from './radioBasic.js';
27+
28+
new Vue({
29+
components: {
30+
tree: window['vue-tree']
31+
},
32+
data() {
33+
return {
34+
model: basicRadioData,
35+
checkedNodes: [],
36+
radioGroupValues: { 'radio1': 'aValueToSubmit' }
37+
};
38+
},
39+
methods: {
40+
refreshCheckedList() {
41+
let nodes = this.$refs.tree.getCheckedRadioButtons();
42+
this.$set(this, 'checkedNodes', nodes);
43+
}
44+
}
45+
}).$mount('#app')
46+
</script>
47+
</body>
48+
</html>

demo/radioBasic.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
export default [
2+
{
3+
id: 'node1',
4+
label: 'My First Node',
5+
expandable: true,
6+
selectable: true,
7+
input: {
8+
type: 'radio',
9+
name: 'radio1',
10+
value: 'aValueToSubmit'
11+
},
12+
state: {
13+
expanded: false,
14+
selected: false
15+
},
16+
children: []
17+
},
18+
{
19+
id: 'node2',
20+
label: 'My Second Node',
21+
expandable: true,
22+
selectable: true,
23+
input: {
24+
type: 'radio',
25+
name: 'radio1'
26+
},
27+
state: {
28+
expanded: true,
29+
selected: false
30+
},
31+
children: [
32+
{
33+
id: 'subnode1',
34+
label: 'This is a subnode',
35+
expandable: true,
36+
selectable: true,
37+
input: {
38+
type: 'radio',
39+
name: 'radio2'
40+
},
41+
state: {
42+
expanded: false,
43+
selected: false
44+
},
45+
children: []
46+
},
47+
{
48+
id: 'subnode2',
49+
label: 'This is a checkable, checked subnode',
50+
expandable: true,
51+
selectable: true,
52+
input: {
53+
type: 'radio',
54+
name: 'radio2'
55+
},
56+
state: {
57+
expanded: false,
58+
selected: false
59+
},
60+
children: []
61+
}
62+
]
63+
}
64+
];

0 commit comments

Comments
 (0)