Skip to content

Commit 97ea756

Browse files
authored
Adds disabling of inputs, minor bug fixes (#36)
Adds disabling of inputs, minor bug fixes
1 parent cf5530b commit 97ea756

File tree

8 files changed

+109
-42
lines changed

8 files changed

+109
-42
lines changed

README.md

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ The data passed to the treeview should be an array of nodes, where each node has
119119
expanded: true,
120120
selected: false,
121121
input: {
122-
value: false
122+
value: false,
123+
disabled: false
123124
}
124125
},
125126
children: []
@@ -137,28 +138,29 @@ The data passed to the treeview should be an array of nodes, where each node has
137138
state: {
138139
expanded: true,
139140
selected: false
140-
// No input state here; to let complex radio button groupings work, state is bound to a tree-level property
141+
// No input state here; to let complex radio button groupings work, state value is bound to a tree-level property. disabled, however, is valid here for radio buttons.
141142
},
142143
children: []
143144
}
144145
```
145146

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

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

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ deploy_script:
3333
if ($env:APPVEYOR_REPO_TAG -eq "true")
3434
{
3535
# npm_auth_token defined in the appveyor project on the site. https://www.appveyor.com/docs/lang/nodejs-iojs/#authenticating-npm-for-publishing-packages
36-
"//registry.npmjs.org/:_authToken=$env:npm_auth_token`n" | out-file "$env:userprofile\.npmrc" -Encoding ASCII
36+
"//registry.npmjs.org/:_authToken=$env:npm_auth_token`n" | out-file (Join-Path $Home "/.npmrc") -Encoding ASCII
3737
npm publish package/ --access public
3838
}
3939
...

demo/basic.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ export default [
1212
expanded: false,
1313
selected: false,
1414
input: {
15-
value: false
15+
value: false,
16+
disabled: false
1617
}
1718
},
1819
children: []
@@ -30,7 +31,8 @@ export default [
3031
expanded: true,
3132
selected: false,
3233
input: {
33-
value: false
34+
value: false,
35+
disabled: false
3436
}
3537
},
3638
children: [
@@ -58,7 +60,8 @@ export default [
5860
expanded: false,
5961
selected: false,
6062
input: {
61-
value: true
63+
value: true,
64+
disabled: true
6265
}
6366
},
6467
children: [

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "Yet another Vue treeview component.",
44
"author": "Gregg Rapoza <grapoza@gmail.com>",
55
"license": "MIT",
6-
"version": "0.2.0",
6+
"version": "0.3.0",
77
"browser": "vue-tree.umd.min.js",
88
"repository": {
99
"url": "https://github.com/grapoza/vue-tree",

src/components/TreeView.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
radioGroupValues: {
3232
type: Object,
3333
required: false,
34-
default: {}
34+
default: function () { return {}; }
3535
}
3636
},
3737
data() {

src/components/TreeViewNode.vue

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
:id="inputId"
2828
:class="inputClass"
2929
:type="model.input.type"
30+
:disabled="model.state.input.disabled"
3031
v-model="model.state.input.value"
3132
@change="$_treeViewNode_onCheckboxChange" />
3233

@@ -36,6 +37,7 @@
3637
:type="model.input.type"
3738
:name="model.input.name"
3839
:value="model.input.value"
40+
:disabled="model.state.input.disabled"
3941
v-model="radioGroupValues[model.input.name]"
4042
@change="$_treeViewNode_onRadioChange" />
4143

@@ -119,19 +121,22 @@
119121
return this.nodeId ? `${this.nodeId}-input` : null;
120122
},
121123
inputClass() {
122-
if (!this.input || typeof this.input !== 'object') {
124+
if (!this.model.input || typeof this.model.input !== 'object') {
123125
return null;
124126
}
125127
126128
let nodeInputClass = 'tree-view-node-self-input ';
127129
128-
switch (this.input.type) {
130+
switch (this.model.input.type) {
129131
case 'checkbox':
130132
nodeInputClass += 'tree-view-node-self-checkbox';
133+
break;
131134
case 'radio':
132135
nodeInputClass += 'tree-view-node-self-radio';
136+
break;
133137
default:
134138
nodeInputClass = null;
139+
break;
135140
}
136141
137142
return nodeInputClass;
@@ -209,12 +214,20 @@
209214
state.selected = false;
210215
}
211216
212-
if (this.model.input && this.model.input.type === 'checkbox') {
217+
if (this.model.input) {
213218
if (state.input === null || typeof state.input !== 'object') {
214219
state.input = {};
215220
}
216-
if (typeof state.input.value !== 'boolean') {
217-
state.input.value = false;
221+
222+
if (state.input.disabled === null || typeof state.input.disabled !== 'boolean') {
223+
state.input.disabled = false;
224+
}
225+
226+
if (this.model.input.type === 'checkbox') {
227+
228+
if (typeof state.input.value !== 'boolean') {
229+
state.input.value = false;
230+
}
218231
}
219232
}
220233
},
@@ -283,7 +296,10 @@
283296
}
284297
}
285298
286-
.tree-view-node-self-expander, .tree-view-node-self-checkbox, .tree-view-node-self-spacer {
299+
.tree-view-node-self-expander,
300+
.tree-view-node-self-checkbox,
301+
.tree-view-node-self-radio,
302+
.tree-view-node-self-spacer {
287303
min-width: 1rem;
288304
margin: 0;
289305
}

tests/data/node-generator.js

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
* buttons will be added to the radioState parameter.
66
*
77
* The node spec's node string should be in the format:
8-
* [eE]?[sS]?[cCrR]?
8+
* `[eE]?[sS]?[cCrR!?]?`
99
* The presence of e, s or c|r indicate the node is expandable, selectable, and a checkbox or radio buttton
1010
* respectively. If it is capitalized, then the related state should be True. In the case of inputs,
11-
* the capitalization means the input will be selected.
11+
* the capitalization means the input will be selected. The `!` indicates the input will be disabled.
1212
*
1313
* @param {Array<String, Array>} nodeSpec The node specification array.
1414
* @param {Object} radioState An object in which the state of radio button groups is generated. Essentially an "out".
@@ -20,6 +20,7 @@ export function generateNodes(nodeSpec, radioState, baseId = "") {
2020

2121
nodeSpec.forEach(function (item, index) {
2222
if (Array.isArray(item)) {
23+
// Generate child nodes for Arrays
2324
if (prevNode === null) {
2425
return;
2526
}
@@ -46,19 +47,30 @@ export function generateNodes(nodeSpec, radioState, baseId = "") {
4647
children: []
4748
};
4849

49-
if (lowerItem.includes('c')) {
50-
prevNode.state.input = { value: item.includes('C') };
51-
}
50+
// Set up input state if needed
51+
if (prevNode.input) {
52+
53+
// Disable inputs
54+
prevNode.state.input = {
55+
disabled: item.includes('!')
56+
};
5257

53-
if (lowerItem.includes('r')) {
54-
if (!radioState.hasOwnProperty(prevNode.input.name)) {
55-
radioState[prevNode.input.name] = null;
58+
// Set up checkbox state
59+
if (lowerItem.includes('c')) {
60+
prevNode.state.input.value = item.includes('C')
5661
}
5762

58-
// Radio button selectedness can also be specified in the normal way by providing
59-
// the radio button data to the TreeView's radioGroupValues prop.
60-
if (item.includes('R')) {
61-
radioState[prevNode.input.name] = prevNode.input.value;
63+
// Set up the radiobutton state in the radioState
64+
if (lowerItem.includes('r')) {
65+
if (!radioState.hasOwnProperty(prevNode.input.name)) {
66+
radioState[prevNode.input.name] = null;
67+
}
68+
69+
// Radio button selectedness can also be specified in the normal way by providing
70+
// the radio button data to the TreeView's radioGroupValues prop.
71+
if (item.includes('R')) {
72+
radioState[prevNode.input.name] = prevNode.input.value;
73+
}
6274
}
6375
}
6476

tests/unit/TreeViewNode.spec.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,38 @@ describe('TreeViewNode.vue', () => {
240240
expect(wrapper.emitted().treeViewNodeDblclick).to.be.undefined;
241241
});
242242
});
243+
244+
describe('when a node\'s model is disabled', () => {
245+
246+
beforeEach(() => {
247+
let radioState = {};
248+
let model = generateNodes(['ces!'], radioState)[0];
249+
250+
console.debug(model);
251+
252+
wrapper = createWrapper({
253+
model,
254+
depth: 0,
255+
treeId: 'tree',
256+
radioGroupValues: radioState
257+
});
258+
});
259+
260+
it('has a disabled input', () => {
261+
let input = wrapper.find('#' + wrapper.vm.inputId);
262+
expect(input.element.disabled).to.be.true;
263+
});
264+
});
265+
266+
describe('when a node\'s model is not disabled', () => {
267+
268+
beforeEach(() => {
269+
wrapper = createWrapper();
270+
});
271+
272+
it('has an enabled input', () => {
273+
let input = wrapper.find('#' + wrapper.vm.inputId);
274+
expect(input.element.disabled).to.be.false;
275+
});
276+
});
243277
});

0 commit comments

Comments
 (0)