Added text-field component to edit database text without it getting bashed by data cleaning
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
<template lang="html">
|
<template lang="html">
|
||||||
<div>
|
<div>
|
||||||
<attribute-edit
|
<attribute-edit
|
||||||
v-for="attribute in attributes"
|
v-for="(attribute, index) in attributes"
|
||||||
:key="attribute._id"
|
:key="attribute._id"
|
||||||
:attribute="attribute"
|
:attribute="attribute"
|
||||||
@change="log"
|
@change="e => change(index, e)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -35,10 +35,9 @@
|
|||||||
],
|
],
|
||||||
}},
|
}},
|
||||||
methods: {
|
methods: {
|
||||||
log: console.log,
|
|
||||||
change(index, e){
|
change(index, e){
|
||||||
for (let i in e){
|
for (let i in e){
|
||||||
this.attributes[index][i] = e[i];
|
this.attributes[index][i] = e[i].trim();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
<template lang="html">
|
<template lang="html">
|
||||||
<div>
|
<div>
|
||||||
<v-text-field
|
<text-field
|
||||||
label="Name"
|
label="Name"
|
||||||
:value="attribute.name"
|
:value="attribute.name"
|
||||||
/>
|
/>
|
||||||
<v-text-field
|
<text-field
|
||||||
label="Variable name"
|
label="Variable name"
|
||||||
:value="attribute.variableName"
|
:value="attribute.variableName"
|
||||||
@change="variableName => $emit('change', {variableName})"
|
@change="variableName => $emit('change', {variableName})"
|
||||||
hint="Use this name in formulae to reference this attribute"
|
hint="Use this name in formulae to reference this attribute"
|
||||||
/>
|
/>
|
||||||
<v-text-field
|
<text-field
|
||||||
label="Base Value"
|
label="Base Value"
|
||||||
type="number"
|
type="number"
|
||||||
:value="attribute.baseValue"
|
:value="attribute.baseValue"
|
||||||
@change="baseValue => $emit('change', {baseValue})"
|
@change="baseValue => $emit('change', {baseValue})"
|
||||||
hint="This is the value of the attribute before effects are applied"
|
hint="This is the value of the attribute before effects are applied"
|
||||||
/>
|
/>
|
||||||
<v-text-field
|
<text-field
|
||||||
label="Damage"
|
label="Damage"
|
||||||
type="number"
|
type="number"
|
||||||
:value="-attribute.adjustment"
|
:value="-attribute.adjustment"
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
:menu-props="{auto: true, lazy: true}"
|
:menu-props="{auto: true, lazy: true}"
|
||||||
@change="reset => $emit('change', {reset})"
|
@change="reset => $emit('change', {reset})"
|
||||||
/>
|
/>
|
||||||
<v-text-field
|
<text-field
|
||||||
label="Reset Multiplier"
|
label="Reset Multiplier"
|
||||||
type="number"
|
type="number"
|
||||||
:value="attribute.resetMultiplier"
|
:value="attribute.resetMultiplier"
|
||||||
|
|||||||
75
app/imports/ui/components/global/TextField.vue
Normal file
75
app/imports/ui/components/global/TextField.vue
Normal 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>
|
||||||
@@ -8,13 +8,17 @@ import router from "/imports/ui/router.js";
|
|||||||
import "vuetify/dist/vuetify.min.css";
|
import "vuetify/dist/vuetify.min.css";
|
||||||
import theme from '/imports/ui/theme.js';
|
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(VueMeteorTracker);
|
||||||
Vue.use(Vuetify, {
|
Vue.use(Vuetify, {
|
||||||
theme,
|
theme,
|
||||||
iconfont: "md",
|
iconfont: "md",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// App start
|
// App start
|
||||||
Meteor.startup(() => {
|
Meteor.startup(() => {
|
||||||
// Start the Vue app
|
// Start the Vue app
|
||||||
|
|||||||
10
app/package-lock.json
generated
10
app/package-lock.json
generated
@@ -104,7 +104,7 @@
|
|||||||
},
|
},
|
||||||
"block-stream": {
|
"block-stream": {
|
||||||
"version": "0.0.9",
|
"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=",
|
"integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
|
||||||
"requires": {
|
"requires": {
|
||||||
"inherits": "~2.0.0"
|
"inherits": "~2.0.0"
|
||||||
@@ -483,7 +483,7 @@
|
|||||||
},
|
},
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": false,
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||||
},
|
},
|
||||||
"ini": {
|
"ini": {
|
||||||
@@ -1405,7 +1405,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"readable-stream": {
|
"readable-stream": {
|
||||||
"version": "2.3.6",
|
"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==",
|
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"core-util-is": "~1.0.0",
|
"core-util-is": "~1.0.0",
|
||||||
@@ -1448,7 +1448,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"readable-stream": {
|
"readable-stream": {
|
||||||
"version": "2.3.6",
|
"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==",
|
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"core-util-is": "~1.0.0",
|
"core-util-is": "~1.0.0",
|
||||||
@@ -1835,7 +1835,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": false,
|
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user