From 444ec62a66029a7e213607ee2c8ccf8fd7329b48 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Tue, 29 Sep 2020 18:37:55 +0200 Subject: [PATCH] Validate expense/reimbursement forms Adds some general helpers and styles for minimalistic form validation. --- app/components/add-expense-item/component.js | 56 +++++++++++++++---- app/components/add-expense-item/template.hbs | 18 ++++-- app/components/add-reimbursement/component.js | 12 ++-- app/components/add-reimbursement/template.hbs | 9 ++- app/styles/_forms.scss | 7 ++- app/utils/is-valid-amount.js | 8 +++ .../add-expense-item/component-test.js | 19 ++----- .../add-reimbursement/component-test.js | 8 +-- tests/unit/utils/is-valid-amount-test.js | 22 ++++++++ 9 files changed, 114 insertions(+), 45 deletions(-) create mode 100644 app/utils/is-valid-amount.js create mode 100644 tests/unit/utils/is-valid-amount-test.js diff --git a/app/components/add-expense-item/component.js b/app/components/add-expense-item/component.js index 30d4824..eb1f3e1 100644 --- a/app/components/add-expense-item/component.js +++ b/app/components/add-expense-item/component.js @@ -2,6 +2,7 @@ import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; import moment from 'moment'; +import isValidAmount from 'kredits-web/utils/is-valid-amount'; export default class AddExpenseItemComponent extends Component { // @tracked newExpense = Expense.create(); @@ -22,6 +23,14 @@ export default class AddExpenseItemComponent extends Component { { code: 'GBP' } ]; + get isValidAmount () { + return isValidAmount(this.amount); + } + + get amountInputClass () { + return this.isValidTotal ? 'valid' : ''; + } + get submitButtonEnabled () { return true; } @@ -30,6 +39,27 @@ export default class AddExpenseItemComponent extends Component { return !this.submitButtonEnabled; } + validateForm () { + const formEl = document.querySelector('form#add-expense-item'); + let validity = true; + + if (!this.isValidAmount) { + document.querySelector('input[name=expense-amount]').classList.add('invalid'); + validity = false; + } + + if (!formEl.checkValidity()) { + document.querySelectorAll('form#add-expense-item input').forEach(i => { + if (!i.validity.valid) { + i.classList.add('invalid'); + validity = false; + } + }) + } + + return validity; + } + @action submit (e) { e.preventDefault(); @@ -38,17 +68,21 @@ export default class AddExpenseItemComponent extends Component { this.date[0] : this.date; const [ date ] = dateInput.toISOString().split('T'); - // TODO validate form - const expense = { - amount: parseFloat(this.amount), - currency: this.currency, - date: date, - title: this.title, - description: this.description, - url: this.url, - tags: this.tags.split(',').map(t => t.trim()) - } + const isValid = this.validateForm(); - this.args.addExpenseItem(expense); + if (isValid) { + const expense = { + amount: parseFloat(this.amount), + currency: this.currency, + date: date, + title: this.title, + description: this.description, + url: this.url, + tags: this.tags.split(',').map(t => t.trim()) + } + this.args.addExpenseItem(expense); + } else { + return false; + } } } diff --git a/app/components/add-expense-item/template.hbs b/app/components/add-expense-item/template.hbs index ddc176c..91f25bd 100644 --- a/app/components/add-expense-item/template.hbs +++ b/app/components/add-expense-item/template.hbs @@ -1,10 +1,15 @@ -
+