JSFiddle - React, Tailwind, and code Playground
by Oski Krawczyk
HTML
<form id="categories">
<fieldset>
<div v-bind:class="'categoryItem accent_' + category.id" v-bind:data-id="category.id" v-for="(category, index) in categories">
<template v-if="category.used">
<input type="text" v-bind:name="'account[categories][' + category.id + ']'" v-bind:value="category.name" placeholder="Category name">
</template>
<template v-else>
<input type="text" v-bind:name="'account[new_categories][' + category.id + ']'" v-bind:value="category.name" placeholder="Category name">
</template>
<a href="#" v-on:click="removeCategory(index, category)">Remove</a>
</div> <!-- /categoryItem -->
<div class="categoryItem" v-show="counter <= 9">
<input type="text" placeholder="Category name" v-model="newCategory">
<a href="#" v-on:click="addCategory">Add</a>
</div> <!-- /categoryItem -->
</fieldset>
<div v-bind:class="'categoryItem accent_' + category.id" v-bind:data-id="category.id" v-for="(category, index) in categories">
<input type="text" v-bind:name="'account[categories][' + category.id + ']'" v-bind:value="category.name" placeholder="Category name">
</div> <!-- /categoryItem -->
</form>
JavaScript
var Categories;
window.Settings = {
categories: [
{
name: "New",
id: 1,
used: true
}, {
name: "Improvements",
id: 2,
used: true
}, {
name: "Fix",
id: 3,
used: true
}, {
name: "Update 1",
id: 4,
used: true
}
]
};
Categories = new Vue({
el: "#categories",
data: {
newCategory: "",
categories: window.Settings.categories,
counter: 0,
availableIds: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
disabled: false
},
mounted: function() {
return this.$nextTick(function() {
var cat, i, index, len, ref;
ref = this.categories;
for (i = 0, len = ref.length; i < len; i++) {
cat = ref[i];
index = this.availableIds.indexOf(cat.id);
this.availableIds.splice(index, 1);
}
return this.counter = this.categories.length;
});
},
methods: {
getId: function() {
return this.availableIds.splice(0, 1);
},
sortIds: function() {
return this.availableIds.sort(function(a, b) {
return a - b;
});
},
returnId: function(index, id) {
this.categories.splice(index, 1);
this.counter = this.counter - 1;
this.availableIds.push(id);
return this.sortIds();
},
addCategory: function(event) {
var text;
event.preventDefault();
event.stopPropagation();
text = this.newCategory.trim();
if (text) {
this.counter = this.counter + 1;
this.categories.push({
name: text,
id: this.getId(),
used: false
});
return this.newCategory = "";
}
},
removeCategory: function(index) {
var categoryId, message;
categoryId = this.categories[index].id;
message = "This category is in use. All changelogs under\nthis category will unassigned from it. Proceed?\"";
if (this.categories[index].used) {
if (confirm(message)) {
return...