Error reporting in new form.

This commit is contained in:
James Cole
2019-05-24 05:29:04 +02:00
parent 695244c928
commit 8f1928c933
18 changed files with 2151 additions and 814 deletions

2433
public/v1/js/app.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -16,7 +16,9 @@ Vue.component('custom-date', require('./components/transactions/CustomDate.vue')
Vue.component('custom-string', require('./components/transactions/CustomString.vue'));
Vue.component('custom-attachments', require('./components/transactions/CustomAttachments.vue'));
Vue.component('custom-textarea', require('./components/transactions/CustomTextArea.vue'));
Vue.component('standard-date', require('./components/transactions/StandardDate.vue'));
Vue.component('group-description', require('./components/transactions/GroupDescription'));
Vue.component('transaction-description', require('./components/transactions/TransactionDescription'));
Vue.component('custom-transaction-fields', require('./components/transactions/CustomTransactionFields.vue'));
Vue.component('piggy-bank', require('./components/transactions/PiggyBank.vue'));

View File

@@ -18,7 +18,7 @@
- along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
<div class="form-group">
<div class="form-group" v-bind:class="{ 'has-error': hasError()}">
<div class="col-sm-12">
<div class="input-group">
<input
@@ -50,6 +50,9 @@
:target="target"
item-key="name"
></typeahead>
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
@@ -61,6 +64,7 @@
title: String,
index: Number,
transactionType: String,
error: Array,
accountName: {
type: String,
default: ''
@@ -106,6 +110,9 @@
},
methods:
{
hasError: function () {
return this.error.length > 0;
},
triggerTransactionType: function () {
if (null === this.transactionType) {
return;

View File

@@ -19,12 +19,16 @@
-->
<template>
<div class="form-group">
<div class="form-group" v-bind:class="{ 'has-error': hasError()}">
<label class="col-sm-4 control-label" ref="cur"></label>
<div class="col-sm-8">
<input type="number" ref="amount" :value="value" @input="handleInput" step="any" class="form-control"
<input type="number" ref="amount" :value="value" @input="handleInput" step="any"
class="form-control"
name="amount[]"
title="amount" autocomplete="off" placeholder="Amount">
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</template>
@@ -32,7 +36,7 @@
<script>
export default {
name: "Amount",
props: ['source', 'destination', 'transactionType','value'],
props: ['source', 'destination', 'transactionType', 'value', 'error'],
data() {
return {
sourceAccount: this.source,
@@ -44,6 +48,9 @@
handleInput(e) {
this.$emit('input', this.$refs.amount.value);
},
hasError: function () {
return this.error.length > 0;
},
changeData: function () {
if ('' === this.transactionType) {
$(this.$refs.cur).text(this.sourceAccount.currency_name);

View File

@@ -19,11 +19,17 @@
-->
<template>
<div class="form-group" v-if="typeof this.transactionType !== 'undefined' && this.transactionType === 'Withdrawal'">
<div class="form-group"
v-bind:class="{ 'has-error': hasError()}"
v-if="typeof this.transactionType !== 'undefined' && this.transactionType === 'Withdrawal'">
<div class="col-sm-12">
<select name="budget[]" ref="budget" @input="handleInput" class="form-control" v-if="this.budgets.length > 0">
<select name="budget[]" ref="budget" @input="handleInput" class="form-control"
v-if="this.budgets.length > 0">
<option v-for="budget in this.budgets" :label="budget.name" :value="budget.id">{{budget.name}}</option>
</select>
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</template>
@@ -31,7 +37,7 @@
<script>
export default {
name: "Budget",
props: ['transactionType','value'],
props: ['transactionType', 'value', 'error'],
mounted() {
this.loadBudgets();
},
@@ -44,6 +50,9 @@
handleInput(e) {
this.$emit('input', this.$refs.budget.value);
},
hasError: function () {
return this.error.length > 0;
},
loadBudgets: function () {
let URI = document.getElementsByTagName('base')[0].href + "json/budgets";
axios.get(URI, {}).then((res) => {

View File

@@ -19,7 +19,7 @@
-->
<template>
<div class="form-group">
<div class="form-group" v-bind:class="{ 'has-error': hasError()}">
<div class="col-sm-12">
<div class="input-group">
<input
@@ -51,6 +51,9 @@
:target="target"
item-key="name"
></typeahead>
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</template>
@@ -61,6 +64,7 @@
props: {
value: String,
inputName: String,
error: Array,
accountName: {
type: String,
default: ''
@@ -81,6 +85,9 @@
this.categoryAutoCompleteURI = document.getElementsByTagName('base')[0].href + "json/categories?query=";
},
methods: {
hasError: function () {
return this.error.length > 0;
},
handleInput(e) {
if (typeof this.$refs.input.value === 'string') {
this.$emit('input', this.$refs.input.value);

View File

@@ -23,6 +23,16 @@
enctype="multipart/form-data">
<input name="_token" type="hidden" value="xxx">
<div class="row" v-if="invalid_submission !== ''">
<div class="col-lg-12">
<div class="alert alert-danger alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<strong>Error!</strong> {{ invalid_submission }}
</div>
</div>
</div>
<div class="row" v-if="transactions.length > 1">
<div class="col-lg-6">
<div class="box">
@@ -32,18 +42,10 @@
</h3>
</div>
<div class="box-body">
<div class="form-group">
<div class="col-sm-12">
<input type="text" class="form-control" name="group_title"
v-model="group_title"
title="Description of the split transaction" autocomplete="off"
placeholder="Description of the split transaction">
<p class="help-block">
If you create a split transaction, there must be a global description for all splits
of the transaction.
</p>
</div>
</div>
<group-description
:error="group_title_errors"
v-model="group_title"
></group-description>
</div>
</div>
</div>
@@ -75,6 +77,7 @@
:index="index"
v-on:clear:value="clearSource(index)"
v-on:select:account="selectedSourceAccount(index, $event)"
:error="transaction.errors.source_account"
></account-select>
<account-select
inputName="destination[]"
@@ -85,23 +88,20 @@
:index="index"
v-on:clear:value="clearDestination(index)"
v-on:select:account="selectedDestinationAccount(index, $event)"
:error="transaction.errors.destination_account"
></account-select>
<div class="form-group">
<div class="col-sm-12">
<input type="text" class="form-control" name="description[]"
v-model="transaction.description"
title="Description" autocomplete="off" placeholder="Description">
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="date" class="form-control" name="date[]"
title="Date" value="" autocomplete="off"
v-model="transaction.date"
:disabled="index > 0"
placeholder="Date">
</div>
</div>
<transaction-description
v-model="transaction.description"
:index="index"
:error="transaction.errors.description"
>
</transaction-description>
<standard-date
v-model="transaction.date"
:index="index"
:error="transaction.errors.date"
>
</standard-date>
<div v-if="index===0">
<transaction-type
:source="transaction.source_account.type"
@@ -117,6 +117,7 @@
:source="transaction.source_account"
:destination="transaction.destination_account"
v-model="transaction.amount"
:error="transaction.errors.amount"
:transactionType="transactionType"
></amount>
<foreign-amount
@@ -124,26 +125,33 @@
:destination="transaction.destination_account"
v-model="transaction.foreign_amount"
:transactionType="transactionType"
:error="transaction.errors.foreign_amount"
></foreign-amount>
</div>
<div class="col-lg-4">
<budget
:transactionType="transactionType"
v-model="transaction.budget"
:error="transaction.errors.budget_id"
></budget>
<category
:transactionType="transactionType"
v-model="transaction.category"
:error="transaction.errors.category"
></category>
<piggy-bank
:transactionType="transactionType"
v-model="transaction.piggy_bank"
:error="transaction.errors.piggy_bank"
></piggy-bank>
<tags
v-model="transaction.tags"
:error="transaction.errors.tags"
></tags>
<custom-transaction-fields
v-model="transaction.custom_fields"></custom-transaction-fields>
v-model="transaction.custom_fields"
:error="transaction.errors.custom_errors"
></custom-transaction-fields>
</div>
</div>
</div>
@@ -165,9 +173,11 @@
</template>
<script>
import GroupDescription from "./GroupDescription";
export default {
name: "CreateTransaction",
components: {},
components: {GroupDescription},
mounted() {
this.addTransaction();
},
@@ -183,6 +193,10 @@
let transactionType;
let firstSource;
let firstDestination;
let foreignAmount = null;
let foreignCurrency = null;
let currentArray;
if (this.transactions.length > 1) {
data.group_title = this.group_title;
}
@@ -209,7 +223,8 @@
for (let key in this.transactions) {
if (this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
tagList = [];
foreignAmount = null;
foreignCurrency = null;
// loop tags
for (let tagKey in this.transactions[key].tags) {
if (this.transactions[key].tags.hasOwnProperty(tagKey) && /^0$|^[1-9]\d*$/.test(tagKey) && key <= 4294967294) {
@@ -217,8 +232,13 @@
}
}
// set foreign currency info:
if (this.transactions[key].foreign_amount.amount !== '' && parseFloat(this.transactions[key].foreign_amount.amount) !== .00) {
foreignAmount = this.transactions[key].foreign_amount.amount;
foreignCurrency = this.transactions[key].foreign_amount.currency_id;
}
data.transactions.push(
currentArray =
{
type: transactionType,
date: this.transactions[key].date,
@@ -226,9 +246,6 @@
amount: this.transactions[key].amount,
currency_id: this.transactions[key].currency_id,
foreign_amount: this.transactions[key].foreign_amount.amount,
foreign_currency_id: this.transactions[key].foreign_amount.currency_id,
description: this.transactions[key].description,
source_id: this.transactions[key].source_account.id,
@@ -237,10 +254,11 @@
destination_id: this.transactions[key].destination_account.id,
destination_name: this.transactions[key].destination_account.name,
budget_id: this.transactions[key].budget,
category_name: this.transactions[key].category,
piggy_bank_id: this.transactions[key].piggy_bank,
tags: tagList,
//budget_id: this.transactions[key].budget,
//piggy_bank_id: this.transactions[key].piggy_bank,
interest_date: this.transactions[key].custom_fields.interest_date,
book_date: this.transactions[key].custom_fields.book_date,
@@ -250,8 +268,24 @@
invoice_date: this.transactions[key].custom_fields.invoice_date,
internal_reference: this.transactions[key].custom_fields.internal_reference,
notes: this.transactions[key].custom_fields.notes
}
);
};
if (tagList.length > 0) {
currentArray.tags = tagList;
}
if (null !== foreignAmount) {
currentArray.foreign_amount = foreignAmount;
currentArray.foreign_currency_id = foreignCurrency;
}
// set budget id and piggy ID.
if(parseInt(this.transactions[key].budget) > 0) {
currentArray.budget_id = parseInt(this.transactions[key].budget);
}
if(parseInt(this.transactions[key].piggy_bank) > 0) {
currentArray.piggy_bank_id = parseInt(this.transactions[key].piggy_bank);
}
data.transactions.push(currentArray);
}
}
//console.log(data);
@@ -264,21 +298,96 @@
axios.post(uri, data)
.then(response => {
console.log('OK!');
//console.log(response);
window.location.href = 'transactions/show/'+ response.data.data.id + '?message=OK';
}).catch(error => {
// give user errors things back.
console.log('error!');
// give user errors things back.
// something something render errors.
// something something render errors.
console.log(error.response.data);
// something.
console.log(error.response.data);
this.parseErrors(error.response.data);
// something.
});
if (e) {
e.preventDefault();
}
},
setDefaultErrors: function () {
for (const key in this.transactions) {
if (this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
this.transactions[key].errors = {
source_account: [],
destination_account: [],
description: [],
amount: [],
date: [],
budget_id: [],
foreign_amount: [],
category: [],
piggy_bank: [],
tags: [],
// custom fields:
custom_errors: {
interest_date: [],
book_date: [],
process_date: [],
due_date: [],
payment_date: [],
invoice_date: [],
internal_reference: [],
notes: [],
attachments: [],
},
};
}
}
},
parseErrors: function (errors) {
this.setDefaultErrors();
this.invalid_submission = "";
if (errors.message.length > 0) {
this.invalid_submission = "There was something wrong with your submission. Please check out the errors below.";
}
let transactionIndex;
let fieldName;
for (const key in errors.errors) {
if (errors.errors.hasOwnProperty(key)) {
if (key === 'group_title') {
this.group_title_errors = errors.errors[key];
}
if (key !== 'group_title') {
// lol dumbest way to explode "transactions.0.something" ever.
transactionIndex = parseInt(key.split('.')[1]);
fieldName = key.split('.')[2];
// set error in this object thing.
switch (fieldName) {
case 'amount':
case 'date':
case 'budget_id':
case 'description':
case 'tags':
this.transactions[transactionIndex].errors[fieldName] = errors.errors[key];
break;
case 'source_name':
case 'source_id':
this.transactions[transactionIndex].errors.source_account =
this.transactions[transactionIndex].errors.source_account.concat(errors.errors[key]);
break;
case 'destination_name':
case 'destination_id':
this.transactions[transactionIndex].errors.destination_account =
this.transactions[transactionIndex].errors.destination_account.concat(errors.errors[key]);
break;
case 'foreign_amount':
case 'foreign_currency_id':
this.transactions[transactionIndex].errors.foreign_amount =
this.transactions[transactionIndex].errors.foreign_amount.concat(errors.errors[key]);
break;
}
}
}
}
},
addTransaction: function (e) {
this.transactions.push({
description: "",
@@ -286,6 +395,30 @@
amount: "",
category: "",
piggy_bank: 0,
errors: {
source_account: [],
destination_account: [],
description: [],
amount: [],
date: [],
budget_id: [],
foreign_amount: [],
category: [],
piggy_bank: [],
tags: [],
// custom fields:
custom_errors: {
interest_date: [],
book_date: [],
process_date: [],
due_date: [],
payment_date: [],
invoice_date: [],
internal_reference: [],
notes: [],
attachments: [],
},
},
budget: 0,
tags: [],
custom_fields: {
@@ -349,7 +482,6 @@
}
this.transactions.splice(index, 1);
console.log('Going to remove index ' + index);
for (const key in this.transactions) {
if (
@@ -445,7 +577,9 @@
return {
transactionType: null,
group_title: "",
transactions: []
transactions: [],
group_title_errors: [],
invalid_submission: ""
};
},
}

View File

@@ -1,5 +1,7 @@
<template>
<div class="form-group">
<div class="form-group"
v-bind:class="{ 'has-error': hasError()}"
>
<div class="col-sm-12 text-sm">
{{ title }}
</div>
@@ -9,6 +11,9 @@
:placeholder="title"
:title="title"
:name="name" type="file" class="form-control">
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</template>
@@ -18,8 +23,14 @@
name: "CustomAttachments",
props: {
title: String,
name: String
name: String,
error: Array
},
methods: {
hasError: function () {
return this.error.length > 0;
},
}
}
</script>

View File

@@ -1,5 +1,7 @@
<template>
<div class="form-group">
<div class="form-group"
v-bind:class="{ 'has-error': hasError()}"
>
<div class="col-sm-12 text-sm">
{{ title }}
</div>
@@ -9,6 +11,9 @@
ref="date"
:value="value" @input="handleInput"
:placeholder="title">
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</template>
@@ -19,12 +24,16 @@
props: {
value: String,
title: String,
name: String
name: String,
error: Array,
},
methods: {
handleInput(e) {
this.$emit('input', this.$refs.date.value);
}
},
hasError: function () {
return this.error.length > 0;
},
}
}
</script>

View File

@@ -1,5 +1,7 @@
<template>
<div class="form-group">
<div class="form-group"
v-bind:class="{ 'has-error': hasError()}"
>
<div class="col-sm-12 text-sm">
{{ title }}
</div>
@@ -9,6 +11,9 @@
ref="str"
:value="value" @input="handleInput"
:placeholder="title">
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</template>
@@ -19,11 +24,15 @@
props: {
title: String,
name: String,
value: String
value: String,
error: Array
},
methods: {
handleInput(e) {
this.$emit('input', this.$refs.str.value);
},
hasError: function () {
return this.error.length > 0;
}
}
}

View File

@@ -1,14 +1,19 @@
<template>
<div class="form-group">
<div class="form-group"
v-bind:class="{ 'has-error': hasError()}"
>
<div class="col-sm-12 text-sm">
{{ title }}
</div>
<div class="col-sm-12">
<textarea class="form-control" :name="name"
<textarea class="form-control" :name="name"
:title="title" autocomplete="off"
ref="str"
:value="value" @input="handleInput"
:placeholder="title" ></textarea>
:placeholder="title"></textarea>
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</template>
@@ -19,11 +24,15 @@
props: {
title: String,
name: String,
value: String
value: String,
error: Array
},
methods: {
handleInput(e) {
this.$emit('input', this.$refs.str.value);
},
hasError: function () {
return this.error.length > 0;
}
}
}

View File

@@ -20,18 +20,34 @@
<template>
<div>
<component v-model="value.interest_date" v-if="this.fields.interest_date" name="interest_date[]" title="Interest date" v-bind:is="dateComponent"></component>
<component v-model="value.book_date" v-if="this.fields.book_date" name="book_date[]" title="Book date" v-bind:is="dateComponent"></component>
<component v-model="value.process_date" v-if="this.fields.process_date" name="process_date[]" title="Process date" v-bind:is="dateComponent"></component>
<component v-model="value.due_date" v-if="this.fields.due_date" name="due_date[]" title="Due date" v-bind:is="dateComponent"></component>
<component v-model="value.payment_date" v-if="this.fields.payment_date" name="payment_date[]" title="Payment date" v-bind:is="dateComponent"></component>
<component
:error="error.interest_date"
v-model="value.interest_date" v-if="this.fields.interest_date" name="interest_date[]" title="Interest date" v-bind:is="dateComponent"></component>
<component
:error="error.book_date"
v-model="value.book_date" v-if="this.fields.book_date" name="book_date[]" title="Book date" v-bind:is="dateComponent"></component>
<component
:error="error.process_date"
v-model="value.process_date" v-if="this.fields.process_date" name="process_date[]" title="Process date" v-bind:is="dateComponent"></component>
<component
:error="error.due_date"
v-model="value.due_date" v-if="this.fields.due_date" name="due_date[]" title="Due date" v-bind:is="dateComponent"></component>
<component
:error="error.payment_date"
v-model="value.payment_date" v-if="this.fields.payment_date" name="payment_date[]" title="Payment date" v-bind:is="dateComponent"></component>
<component v-model="value.invoice_date" v-if="this.fields.invoice_date" name="invoice_date[]" title="Invoice date" v-bind:is="dateComponent"></component>
<component v-model="value.internal_reference" v-if="this.fields.internal_reference" name="internal_reference[]" title="Internal reference" v-bind:is="stringComponent"></component>
<component
:error="error.internal_reference"
v-model="value.internal_reference" v-if="this.fields.internal_reference" name="internal_reference[]" title="Internal reference" v-bind:is="stringComponent"></component>
<component v-model="value.attachments" v-if="this.fields.attachments" name="attachments[]" title="Attachments" v-bind:is="attachmentComponent"></component>
<component
:error="error.attachments"
v-model="value.attachments" v-if="this.fields.attachments" name="attachments[]" title="Attachments" v-bind:is="attachmentComponent"></component>
<component v-model="value.notes" v-if="this.fields.notes" name="notes[]" title="Notes" v-bind:is="textareaComponent"></component>
<component
:error="error.notes"
v-model="value.notes" v-if="this.fields.notes" name="notes[]" title="Notes" v-bind:is="textareaComponent"></component>
</div>
@@ -40,7 +56,7 @@
<script>
export default {
name: "CustomTransactionFields",
props: ['value'],
props: ['value','error'],
mounted() {
this.getPreference();
},

View File

@@ -19,7 +19,7 @@
-->
<template>
<div class="form-group">
<div class="form-group" v-bind:class="{ 'has-error': hasError()}">
<div class="col-sm-4">
<select class="form-control" ref="currency_select" name="foreign_currency[]"
v-if="this.enabledCurrencies.length > 0" @input="handleInput">
@@ -38,6 +38,10 @@
<input type="number" @input="handleInput" ref="amount" :value="value.amount" step="any" class="form-control"
name="foreign_amount[]" v-if="this.enabledCurrencies.length > 0"
title="Foreign amount" autocomplete="off" placeholder="Foreign amount">
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</template>
@@ -45,7 +49,7 @@
<script>
export default {
name: "ForeignAmountSelect",
props: ['source', 'destination', 'transactionType', 'value'],
props: ['source', 'destination', 'transactionType', 'value','error'],
mounted() {
this.loadCurrencies();
},
@@ -68,6 +72,9 @@
}
},
methods: {
hasError: function () {
return this.error.length > 0;
},
handleInput(e) {
this.$emit('input', {
amount: +this.$refs.amount.value,

View File

@@ -0,0 +1,42 @@
<template>
<div class="form-group" v-bind:class="{ 'has-error': hasError()}">
<div class="col-sm-12">
<input
type="text"
class="form-control"
name="group_title"
title="Description of the split transaction"
ref="descr"
autocomplete="off"
placeholder="Description of the split transaction"
:value="value" @input="handleInput"
>
<p class="help-block" v-if="error.length === 0">
If you create a split transaction, there must be a global description for all splits
of the transaction.
</p>
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</template>
<script>
export default {
props: ['error', 'value', 'index'],
name: "GroupDescription",
methods: {
hasError: function () {
return this.error.length > 0;
},
handleInput(e) {
this.$emit('input', this.$refs.descr.value);
}
}
}
</script>
<style scoped>
</style>

View File

@@ -19,11 +19,16 @@
-->
<template>
<div class="form-group" v-if="typeof this.transactionType !== 'undefined' && this.transactionType === 'Transfer'">
<div class="form-group"
v-bind:class="{ 'has-error': hasError()}"
v-if="typeof this.transactionType !== 'undefined' && this.transactionType === 'Transfer'">
<div class="col-sm-12">
<select name="piggy_bank[]" ref="piggy" @input="handleInput" class="form-control" v-if="this.piggies.length > 0">
<option v-for="piggy in this.piggies" :label="piggy.name" :value="piggy.id">{{piggy.name}}</option>
</select>
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</template>
@@ -31,7 +36,7 @@
<script>
export default {
name: "PiggyBank",
props: ['value','transactionType'],
props: ['value','transactionType','error'],
mounted() {
this.loadPiggies();
},
@@ -44,6 +49,9 @@
handleInput(e) {
this.$emit('input', this.$refs.piggy.value);
},
hasError: function () {
return this.error.length > 0;
},
loadPiggies: function () {
let URI = document.getElementsByTagName('base')[0].href + "json/piggy-banks";
axios.get(URI, {}).then((res) => {

View File

@@ -0,0 +1,39 @@
<template>
<div class="form-group" v-bind:class="{ 'has-error': hasError()}">
<div class="col-sm-12">
<input
type="date"
class="form-control"
name="date[]"
title="Date"
ref="date"
autocomplete="off"
:disabled="index > 0"
placeholder="Date"
:value="value" @input="handleInput"
>
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</template>
<script>
export default {
props: ['error', 'value', 'index'],
name: "StandardDate",
methods: {
hasError: function () {
return this.error.length > 0;
},
handleInput(e) {
this.$emit('input', this.$refs.date.value);
}
}
}
</script>
<style scoped>
</style>

View File

@@ -19,7 +19,9 @@
-->
<template>
<div class="form-group">
<div class="form-group"
v-bind:class="{ 'has-error': hasError()}"
>
<div class="col-sm-12">
<vue-tags-input
v-model="tag"
@@ -30,6 +32,9 @@
@tags-changed="update"
placeholder="Tags"
/>
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</template>
@@ -43,7 +48,7 @@
components: {
VueTagsInput
},
props: ['value'],
props: ['value','error'],
data() {
return {
tag: '',
@@ -61,6 +66,9 @@
this.tags = newTags;
this.$emit('input', this.tags);
},
hasError: function () {
return this.error.length > 0;
},
initItems() {
if (this.tag.length < 2) {
return;

View File

@@ -0,0 +1,38 @@
<template>
<div class="form-group" v-bind:class="{ 'has-error': hasError()}">
<div class="col-sm-12">
<input
type="text"
class="form-control"
name="description[]"
title="Description"
ref="descr"
autocomplete="off"
placeholder="Description"
:value="value" @input="handleInput"
>
<ul class="list-unstyled" v-for="error in this.error">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</template>
<script>
export default {
props: ['error', 'value', 'index'],
name: "TransactionDescription",
methods: {
hasError: function () {
return this.error.length > 0;
},
handleInput(e) {
this.$emit('input', this.$refs.descr.value);
}
}
}
</script>
<style scoped>
</style>