Vue Local Storage - Newrow
by masade
HTML
<script src="https://unpkg.com/vue"></script>
<section id="gridtable">
<small>click on cells to edit / add</small>
<datagrid :rows="rows" :cols="cols"></datagrid>
<div class="container"><pre>{{ $data }}</pre></div>
</section>
<!-- Data Grid Template -->
<template id="datagrid-template">
<div class="container">
<addrow cellindex="-1,-1"></addrow>
<div v-for="(row,rowIndex) in rows" class="row">
<datacell v-for="(c,colIndex) in cols"
v-model="row[c.m]"
:cellindex="rowIndex+','+colIndex"
:key="rowIndex+','+colIndex"
></datacell>
</div>
</div>
</template>
<!-- Data Cell template -->
<template id="datacell-template">
<div :class="['datacell',{'editing':editing}]">
<div class="datatext" v-text="value?value:'-'" v-show="!editing" @click="editCell" ></div>
<div class="dataedit" v-if="editing">
<input type="text"
:value="value"
v-focus="true"
@keydown.self.stop.enter="doneEdit"
/>
</div>
</div>
</template>
<!-- Data Cell template -->
<template id="addrow-template">
<div class="row addrow">
<div class="datacell">
<div class="datatext" v-text="'+ Add Row'" v-show="!editing" @click="editCell($event)"></div>
<div v-for="(c,colIndex) in $parent.cols" v-if="c.new && editing" class="dataedit">
<input type="text"
:name="c.m"
:placeholder="c.m"
v-model="newrow[c.m]"
v-focus="!colIndex"
@keyup.enter="addRow($event)"
/>
</div>
</div>
</div>
</template>
CSS
body{font-family: sans-serif;}
* {box-sizing: border-box;}
.container{width:100%; margin: auto;clear:both;background: #FFFFFF}
.datacell{width: 49.5%;float:left;border: 1px solid #F5F5F5;height: 40px;}
.datatext{padding:10px;}
.dataedit {height: 100%;}
.datacell input{width: 100%;height:100%;padding:2px 8px;font-size: 1em;background:#CEF;}
.datacell input:focus{border:1px solid #00C;outline: none;}
.row{clear: both;overflow: hidden;}
JavaScript
var STORAGE_KEY = 'grid-vue-local'
var gridStorage = {
fetch: function () {
var rows = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]')
rows.forEach(function (row, index) {
row.id = index
})
gridStorage.uid = rows.length
return rows
},
save: function (rows) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(rows))
}
}
// Data Cell Component
var datacellComponent = Vue.extend({
template : '#datacell-template',
props : ['value','cellindex'],
data : function(){
return {
newrow : {}
}
},
computed : {
editing: function(){
return (this.$parent.editcell == this.cellindex)?true:false;
}
},
methods :{
editCell:function(e){
this.$parent.editcell = this.cellindex;
},
doneEdit: function(e) {
this.$emit('input', e.target.value);
this.$parent.editcell = null;
},
addRow: function (e) {
e.preventDefault();
this.newrow.id = gridStorage.uid++;
var newrow = this.newrow;
this.$parent.cols.map(function(col,index){
if(typeof newrow[col.m] == "undefined")
newrow[col.m] = "";
})
this.$parent.rows.unshift(this.newrow)
this.newrow = {};
},
}
})
var addrowComponent = datacellComponent.extend({
template : '#addrow-template',
})
// Data Grid Component
Vue.component('datagrid', {
template : '#datagrid-template',
props : ['rows','cols'],
components : {
'datacell' : datacellComponent,
'addrow' : addrowComponent,
},
data : function (){
return {
editcell : null,
}
}
});
// v-focus on form element after showing
Vue.directive('focus', function (el,binding) {Vue.nextTick(function() { if(binding.value){ el.focus();}});})
var app = new Vue({
data: {
rows: gridStorage.fetch(),
cols : [{m:'name',new:true},{m:'year',new:false}],
},
watch: {
rows: {
handler: function (rows) {
gridStorage.save(rows)
},
deep: true
}
},
created: function(){
this.rows = this.rows.length? this.rows : [{"name":"Robin Hood","year":1999,"id":0},{"name":"Queen...