simple vue-based column editor

This commit is contained in:
2018-08-04 11:48:35 +02:00
parent 755c65a42d
commit e5a6527d18
22 changed files with 422 additions and 177 deletions
+11 -14
View File
@@ -9,6 +9,9 @@ require('./bootstrap')
let url_slug = require('./url-slug')
$(function () {
// Remove all noscript from forms etc
$('noscript').remove();
$('[data-toggle="tooltip"]').tooltip({
container: 'body'
})
@@ -62,17 +65,11 @@ $(document).on('input keypress paste keyup', 'input[data-autoalias]', function (
}
})
//
// window.Vue = require('vue');
//
// /**
// * Next, we will create a fresh Vue application instance and attach it to
// * the page. Then, you may begin adding components to this application
// * or customize the JavaScript scaffolding to fit your unique needs.
// */
//
// Vue.component('example-component', require('./components/ExampleComponent.vue'));
//
// const app = new Vue({
// el: '#app'
// });
window.Vue = require('vue');
Vue.component('column-editor', require('./components/ColumnEditor.vue'));
Vue.component('v-icon', require('./components/Icon.vue'));
const app = new Vue({
el: '#app'
});
@@ -0,0 +1,89 @@
<template>
<div>
<input type="hidden" :name="name" :value="JSON.stringify(columns)">
<table class="editor-table">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Title</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="(col, i) in columns">
<td>
<input v-model="col.name" class="form-control" type="text" style="width: 140px">
</td>
<td>
<select v-model="col.type" class="form-control custom-select" style="width: 110px">
<option v-for="t in colTypes" :value="t">{{t}}</option>
</select>
</td>
<td>
<input v-model="col.title" class="form-control" type="text" style="width: 170px">
</td>
<td class="text-nowrap">
<a href="" :class="['btn', 'btn-outline-secondary', {disabled: i==0}]" @click.prevent="delCol(i)">
<v-icon class="fa-trash-o" alt="Delete column" />
</a><!--
--><a href="" class="btn btn-outline-secondary" v-if="i === columns.length - 1"
@click.prevent="addCol()">
<v-icon class="fa-plus" alt="Add Column" />
</a>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<style lang="scss" scoped>
@import "base";
table {
border-collapse: collapse;
}
td, th {
@include pr(1);
}
td .btn {
@include py(1);
@include mr(1);
}
</style>
<script>
export default {
props: {
name: String,
initialColumns: Array,
},
data: function() {
return {
columns: this.initialColumns,
colTypes: ['string', 'int', 'float', 'bool'],
}
},
methods: {
delCol(n) {
if (n == 0) return
this.columns.splice(n, 1)
},
addCol() {
let nth = this.columns.length+1
this.columns.push({
name: `column-${nth}`,
type: 'string',
title: `Column ${nth}`,
})
}
}
}
</script>
@@ -1,23 +0,0 @@
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card card-default">
<div class="card-header">Example Component</div>
<div class="card-body">
I'm an example component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
+21
View File
@@ -0,0 +1,21 @@
<template>
<i :title="tooltipText">
<span class="sr-only" v-html=srHtml></span>
</i>
</template>
<script>
export default {
inheritAttrs: false,
props: {
alt: String,
srOnly: Boolean
},
data: function() {
return {
tooltipText: this.srOnly ? null : this.alt.replace(/~/g, ''),
srHtml: this.alt.replace(/~/g, '&nbsp;')
};
}
}
</script>
+1
View File
@@ -0,0 +1 @@
@import "../../sass/bootstrap-base";
+5
View File
@@ -0,0 +1,5 @@
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/mixins";
@import "mixins";
@import "bootstrap-customizations/variables";
+1 -5
View File
@@ -1,8 +1,4 @@
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/mixins";
@import "bootstrap-customizations/variables";
@import "bootstrap-base";
@import "bootstrap-customizations/_helpers-before";
@import "~bootstrap/scss/root";
+55
View File
@@ -0,0 +1,55 @@
@function dist($x) {
@return $spacer*.25*$x;
}
@mixin py($n) {
padding-top: dist($n);
padding-bottom: dist($n);
}
@mixin px($n) {
padding-left: dist($n);
padding-right: dist($n);
}
@mixin my($n) {
margin-top: dist($n);
margin-bottom: dist($n);
}
@mixin mx($n) {
margin-left: dist($n);
margin-right: dist($n);
}
@mixin pl($n) {
padding-left: dist($n);
}
@mixin pr($n) {
padding-right: dist($n);
}
@mixin pt($n) {
padding-top: dist($n);
}
@mixin pb($n) {
padding-bottom: dist($n);
}
@mixin ml($n) {
margin-left: dist($n);
}
@mixin mr($n) {
margin-right: dist($n);
}
@mixin mt($n) {
margin-top: dist($n);
}
@mixin mb($n) {
margin-bottom: dist($n);
}
@@ -1,7 +1,10 @@
$sp0: 0;
$sp1_2: $spacer*.25;
$sp1: $spacer*.5;
$sp1_4: $spacer*.125;
$sp2_4: $sp1_2;
$sp3_4: $spacer*.75;
$sp1: $spacer*.5;
$sp2: $spacer*1;
$sp3: $spacer*1.5;
+2 -2
View File
@@ -29,8 +29,8 @@
@if ($errors->has($w->name))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first($w->name) }}</strong>
</span>
<strong>{{ $errors->first($w->name) }}</strong>
</span>
@endif
</div>
</div>
+29 -2
View File
@@ -30,7 +30,7 @@
->help('If you took the data from some external site, a book, etc., write it here.
URLs in a full format will be clickable.') !!}
{!! Widget::textarea('columns', 'Columns')->value($exampleColumns)->height('8em')
{{--!! Widget::textarea('columns', 'Columns')->value($exampleColumns)->height('8em')
->help('
<div class="text-left">
Column parameters in CSV format:
@@ -39,7 +39,34 @@
<li><b>column data type</b><br>int, string, float, bool
<li><b>column title</b><br>used for display (optional)
</ul>
</div>') !!}
</div>') !!--}}
<div class="row form-group">
<label for="field-columns" class="col-md-3 col-form-label text-md-right">
Columns
</label>
<div class="col-md-8">
<column-editor name="columns" :initial-columns="{{old('columns', toJSON($columns))}}"></column-editor>
<noscript>
You have JavaScript disabled; enter columns as JSON array<br>
<textarea class="form-control" name="columns" rows="10">{{ old('columns', toJSON($columns)) }}</textarea>
</noscript>
@if ($errors->has('columns'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('columns') }}</strong>
</span>
@endif
@if($errors->has('columns'))
<span class="text-danger">
@icon(fa-warning, sr:Validation error:)
{{$errors->first('columns')}}
</span>
@endif
</div>
</div>
{!! Widget::textarea('data', 'Initial data')->value($exampleData)->height('12em')
->help('