Last active
November 17, 2017 14:46
-
-
Save andreapavoni/ae2fe61ef946606017c72c0ad420a575 to your computer and use it in GitHub Desktop.
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
<tags-input> | |
<%= hidden_input form, :tags, value: [] , class: "input" %> | |
</tags-input> |
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
<template> | |
<div @click="focusNewTag()" class="vue-input-tag-wrapper"> | |
<span v-for="(tag, index) in tags" class="input-tag"> | |
<span>{{ tag }}</span> | |
<a @click.prevent.stop="remove(index)" class="remove"></a> | |
</span> | |
<input type="text" v-model="newTag" v-on:keydown.delete.stop="removeLastTag()" v-on:keydown.enter.prevent.stop="addNew(newTag)" v-on:keydown.188.prevent.stop="addNew(newTag)" class="new-tag"/> | |
<slot></slot> | |
</div> | |
</template> | |
<script> | |
import Vue from 'vue' | |
const validRegexp = /^(\w|\s|\d)+$/ | |
export default Vue.component('input-tags', { | |
data() { | |
return { | |
newTag: '', | |
tags: [] | |
} | |
}, | |
methods: { | |
focusNewTag() { this.$el.querySelector('.new-tag').focus(); }, | |
addNew(tag) { | |
tag = tag.trim() | |
if (tag && !this.tags.includes(tag) && validRegexp.test(tag)) { | |
this.tags.push(tag) | |
} | |
this.newTag = '' | |
}, | |
remove(index) { this.tags.splice(index, 1) }, | |
removeLastTag() { | |
if (!this.newTag) { this.tags.pop() } | |
} | |
}, | |
mounted() { | |
this.tags = this.$slots.default[0].elm.value.split(",").filter((tag) => { | |
return tag.length !== 0 | |
}) | |
}, | |
watch: { | |
tags() { this.$slots.default[0].elm.value = this.tags } | |
}, | |
}) | |
</script> | |
<style> | |
.vue-input-tag-wrapper { | |
background-color: #fff; | |
border: 1px solid #ccc; | |
overflow: hidden; | |
padding-left: 4px; | |
padding-top: 4px; | |
cursor: text; | |
text-align: left; | |
-webkit-appearance: textfield; | |
} | |
.vue-input-tag-wrapper .input-tag { | |
background-color: #cde69c; | |
border-radius: 2px; | |
border: 1px solid #a5d24a; | |
color: #638421; | |
display: inline-block; | |
font-size: 13px; | |
font-weight: 400; | |
margin-bottom: 4px; | |
margin-right: 4px; | |
padding: 3px; | |
} | |
.vue-input-tag-wrapper .input-tag .remove { | |
cursor: pointer; | |
font-weight: bold; | |
color: #638421; | |
} | |
.vue-input-tag-wrapper .input-tag .remove:hover { | |
text-decoration: none; | |
} | |
.vue-input-tag-wrapper .input-tag .remove::before { | |
content: "\00d7"; | |
} | |
.vue-input-tag-wrapper .new-tag { | |
background: transparent; | |
border: 0; | |
color: #777; | |
font-size: 13px; | |
font-weight: 400; | |
margin-bottom: 6px; | |
margin-top: 1px; | |
outline: none; | |
padding: 4px; | |
padding-left: 0; | |
width: 80px; | |
} | |
.vue-input-tag-wrapper.read-only { | |
cursor: default; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment