Skip to content

Instantly share code, notes, and snippets.

@onefriendaday
Last active February 1, 2019 19:37
Show Gist options
  • Save onefriendaday/6acc58cdaf86ca6c1f62b95065837294 to your computer and use it in GitHub Desktop.
Save onefriendaday/6acc58cdaf86ca6c1f62b95065837294 to your computer and use it in GitHub Desktop.
Storyblok Fieldtype with tree selector
const Fieldtype = {
mixins: [window.Storyblok.plugin],
template: `<div>
<ul class="uk-list">
<li :key="item.id" v-for="item in tree">
<tree :category="item" :sub-categories="allCats" :categories.sync="model.categories"></tree>
</li>
</ul>
</div>`,
components: {
tree: {
data() {
return {
open: false
}
},
name: 'tree',
props: ['category', 'categories', 'subCategories'],
created() {
if (this.subCategories.includes(this.category.item.uuid)) {
this.open = true
}
},
methods: {
addItem() {
if (this.categories.includes(this.category.item.uuid)){
this.categories.splice(this.categories.indexOf(this.category.item.uuid), 1)
} else {
this.categories.push(this.category.item.uuid)
}
}
},
template: `<ul class="uk-list">
<input @input="addItem"
:checked="categories.includes(category.item.uuid)"
:value="category.item.uuid"
type="checkbox"
v-if="category.item.slug.split('/').length > 4" />
<a @click="open = !open"
v-else><i class="uk-icon-plus-square-o"></i></a>
{{category.item.name}}
<ul class="uk-list" v-if="open">
<li :key="item.id" v-for="item in category.children">
<tree :category="item" :sub-categories="subCategories" :categories.sync="categories"></tree>
</li>
</ul>
</ul>
`
}
},
data() {
return {
idUuidMap: {},
links: {},
tree: {},
treeMap: {}
}
},
computed: {
allCats() {
return this.mainCategories.concat(this.subCategories)
},
mainCategories() {
let cats = []
this.subCategories.forEach((uuid) => {
cats.push(this.idUuidMap[this.links[uuid].parent_id])
})
return cats
},
subCategories() {
let cats = []
if (typeof this.model.categories != 'undefined') {
this.model.categories.forEach((uuid) => {
if (typeof this.links[uuid] != 'undefined') {
cats.push(this.idUuidMap[this.links[uuid].parent_id])
}
})
}
return cats
}
},
methods: {
initWith() {
return {
plugin: 'sb-cascanding-selector',
categories: [],
subCategories: [],
mainCategories: []
}
},
pluginCreated() {
this.api
.get('cdn/links', {starts_with: 'shared/category/', version: 'draft'})
.then((res) => {
this.links = res.data.links
this.tree = this.prepareTree(res.data.links)
})
},
prepareTree(cats) {
var tree = {}
for (var uid in cats) {
this.idUuidMap[cats[uid].id] = uid
var parent = cats[uid].parent_id
if (!tree[parent]) {
tree[parent] = []
}
tree[parent].push(cats[uid])
}
this.treeMap = tree
return this.generateTree(497308, tree)
},
generateTree(parent, items) {
var tree = {}
if (items[parent]) {
var result = items[parent]
result.forEach((cat) => {
if (!tree[cat.id]) {
tree[cat.id] = {item: {}, children: []}
}
tree[cat.id].item = cat
tree[cat.id].children = this.generateTree(cat.id, items)
})
}
return tree
}
},
watch: {
'model': {
handler: function (value) {
value.subCategories = this.subCategories
value.mainCategories = this.mainCategories
this.$emit('changed-model', value);
},
deep: true
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment