Added text-field component to edit database text without it getting bashed by data cleaning

This commit is contained in:
Thaum Rystra
2019-02-06 19:38:27 +02:00
parent de4509ab6a
commit f8e83ebe7e
5 changed files with 93 additions and 15 deletions

View File

@@ -1,10 +1,10 @@
<template lang="html">
<div>
<attribute-edit
v-for="attribute in attributes"
v-for="(attribute, index) in attributes"
:key="attribute._id"
:attribute="attribute"
@change="log"
@change="e => change(index, e)"
/>
</div>
</template>
@@ -35,10 +35,9 @@
],
}},
methods: {
log: console.log,
change(index, e){
for (let i in e){
this.attributes[index][i] = e[i];
this.attributes[index][i] = e[i].trim();
}
},
},

View File

@@ -1,23 +1,23 @@
<template lang="html">
<div>
<v-text-field
<text-field
label="Name"
:value="attribute.name"
/>
<v-text-field
<text-field
label="Variable name"
:value="attribute.variableName"
@change="variableName => $emit('change', {variableName})"
hint="Use this name in formulae to reference this attribute"
/>
<v-text-field
<text-field
label="Base Value"
type="number"
:value="attribute.baseValue"
@change="baseValue => $emit('change', {baseValue})"
hint="This is the value of the attribute before effects are applied"
/>
<v-text-field
<text-field
label="Damage"
type="number"
:value="-attribute.adjustment"
@@ -46,7 +46,7 @@
:menu-props="{auto: true, lazy: true}"
@change="reset => $emit('change', {reset})"
/>
<v-text-field
<text-field
label="Reset Multiplier"
type="number"
:value="attribute.resetMultiplier"

View File

@@ -0,0 +1,75 @@
<template lang="html">
<v-text-field
:error="error"
:value="safeValue"
@input="input"
@focus="focused = true"
@blur="focused = false"
/>
</template>
<script>
/*
* Component to handle text fields that update the database.
* Won't bash the text field while it's focused, even if the database trims
* or otherwise sanitizes the input.
* Emits input events on every input and emits debounced change
* events based on the debounceTime set in its props.
* Losing focus will set the value to the database's current stored value.
*
* Because attributes that aren't properties are passed to the root element,
* this is a drop-in replacement for v-text-field
*
* TODO extract this functionality as a mixin, and share to textarea
*/
import { _ } from 'underscore';
export default {
data(){ return {
safeValue: this.value,
focused: false,
error: false,
errorMessages: null,
}},
props: {
value: [String, Number],
debounceTime: {
type: Number,
default: 250,
},
validator: Function,
},
watch: {
focused(isFocused){
if (!isFocused){
this.safeValue = this.value;
}
},
value(newValue){
if (!this.focused){
this.safeValue = this.value;
}
},
},
methods: {
input(val){
this.$emit('input', val);
this.update(val);
if (this.validator){
try {
this.validator(val);
this.error = false;
this.errorMessages = null;
} catch(e){
this.error = true;
this.errorMessages = e.message;
}
}
},
},
created(){
this.update = _.debounce(val => {
this.$emit('change', val);
}, this.debounceTime);
},
};
</script>

View File

@@ -8,13 +8,17 @@ import router from "/imports/ui/router.js";
import "vuetify/dist/vuetify.min.css";
import theme from '/imports/ui/theme.js';
// Global components
import TextField from '/imports/ui/components/global/TextField.vue';
Vue.component("text-field", TextField);
Vue.use(VueMeteorTracker);
Vue.use(Vuetify, {
theme,
iconfont: "md",
});
// App start
Meteor.startup(() => {
// Start the Vue app

10
app/package-lock.json generated
View File

@@ -104,7 +104,7 @@
},
"block-stream": {
"version": "0.0.9",
"resolved": false,
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
"integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
"requires": {
"inherits": "~2.0.0"
@@ -483,7 +483,7 @@
},
"inherits": {
"version": "2.0.3",
"resolved": false,
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ini": {
@@ -1405,7 +1405,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -1448,7 +1448,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -1835,7 +1835,7 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
"resolved": false,
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
}
}