Created
April 19, 2018 19:56
-
-
Save oskude/18cb4b4fd18edcaafae5c1eaf20903e3 to your computer and use it in GitHub Desktop.
vue.js tree-list form component experiment
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en" dir="ltr"> | |
<head> | |
<meta charset="utf-8"> | |
<title>vue.js tree-list form component experiment</title> | |
<script src="vue.js"></script> | |
</head> | |
<body> | |
<h2>vue.js tree-list form component experiment</h2> | |
<p>TODO: blah blah...</p> | |
<h3>element attributes/props</h3> | |
<ul> | |
<li><code>name</code> - string for the form input name (ex: <code>cat[]</code> for magic php array)</li> | |
<li><code>depth</code> - number of max tree path depth to descent to</li> | |
<li><code>:tree</code> - array of tree items</li> | |
<li><code>:list</code> - array of item ids that are checked</li> | |
</ul> | |
<h3>tree item</h3> | |
<pre> | |
{ | |
id: 3, // unique id for this item | |
name: "foo-1-1", // name for this item | |
path: [1,2,3] // ids of all parent items, last id is this item | |
} | |
</pre> | |
<h3>example</h3> | |
<p>after submit, check the request post data in devtools</p> | |
<div id="app"> | |
<form method="post"> | |
<tree-list name="cat[]" depth="3" :tree="mytree" :list="mylist"></tree-list> | |
<input type="submit"> | |
</form> | |
</div> | |
</body> | |
<script> | |
Vue.component("tree-list", { | |
props: [ | |
"name", | |
"depth", | |
"tree", | |
"list" | |
], | |
template: ` | |
<div style="display:flex"> | |
<div v-for="d in parseInt(depth)"> <!-- TODO: can vue do parseInt for us? --> | |
<template v-for="item in tree"> | |
<tree-list-entry | |
v-if="item.path.length == d" | |
v-show="item.path.length == 1 || list.includes(item.path.slice(-2)[0])" | |
:name="name" | |
:item="item" | |
:list="list" | |
></tree-list-entry> | |
</template> | |
</div> | |
</div> | |
`.replace(/\n/g, "").replace(/>\s*</g, "><") | |
/* above removes those pesky whitespaces. TODO might break something... */ | |
}); | |
Vue.component("tree-list-entry", { | |
props: [ | |
"name", | |
"item", | |
"list" | |
], | |
methods: { | |
on_change: function (evt) { | |
let id = parseInt(evt.target.value); | |
let list = this.$parent.list; // TODO: yeah, i dont care... | |
if(evt.target.checked) { | |
list.push(id); | |
} else { | |
list.splice(list.indexOf(id), 1); | |
} | |
} | |
}, | |
computed: { | |
element_id: function () { | |
return `${this.name}${this.item.id}`; | |
} | |
}, | |
template: ` | |
<div> | |
<label :for="element_id">{{ item.name }}</label> | |
<input | |
type="checkbox" | |
:id="element_id" | |
:name="name" | |
:value="item.id" | |
:checked="list.includes(item.id)" | |
@change="on_change" | |
/> | |
</div> | |
`.replace(/\n/g, "").replace(/>\s*</g, "><") | |
/* above removes those pesky whitespaces. TODO might break something... */ | |
}); | |
/* ignore me, just an example tree list */ | |
var cats = []; | |
var c = 1; | |
["foo", "bar", "zap"].forEach((name)=>{ | |
let path = [c]; | |
cats.push({ | |
id: c, | |
name: name, | |
path: Array.from(path) | |
}); | |
c++; | |
for (let x = 1; x <= 3; x++) { | |
path.push(c); | |
cats.push({ | |
id: c, | |
name: `${name}-${x}`, | |
path: Array.from(path) | |
}); | |
c++; | |
for (let y = 1; y <= 3; y++) { | |
path.push(c); | |
cats.push({ | |
id: c, | |
name: `${name}-${x}-${y}`, | |
path: Array.from(path) | |
}); | |
path.splice(path.indexOf(c), 1); | |
c++; | |
} | |
path.splice(path.indexOf(c), 1); | |
} | |
}); | |
var app = new Vue({ | |
el: '#app', | |
data: { | |
mylist: [1,2,3], | |
mytree: cats | |
} | |
}); | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment