Add validation to forms

Fix values being treated as strings
This commit is contained in:
CheddarCrisp 2020-03-04 20:53:18 -05:00
parent e42f3656a9
commit cea4f35d52
3 changed files with 64 additions and 38 deletions

View file

@ -11,14 +11,16 @@
</div>
{#if showAddDialog}
<div class="dialog">
<div class="dialog-content">
<label>Name<input type="text" bind:value={newCounter.title} use:focus/></label>
<label>Initial Value<input type="text" inputmode="decimal" bind:value={newCounter.initialValue} /></label>
<label>Target<input type="text" inputmode="decimal" bind:value={newCounter.max} /></label>
<form class="dialog-content" novalidate bind:this={ dialogForm }>
<label>Counter Name<input type="text" required bind:value={newCounter.title} use:focus/></label>
<label>Initial Value<input type="text" required pattern="(0|([1-9]\d*))(\.\d+)?" inputmode="decimal" bind:value={newCounter.initialValue} /></label>
<label>Target<input type="text" pattern="(0|([1-9]\d*))(\.\d+)?" inputmode="decimal" bind:value={newCounter.max} /></label>
<label>Save history<input type="checkbox" bind:checked={newCounter.saveHistory} /></label>
<button on:click={ () => { showAddDialog = false; } }>Cancel</button>
<button class="ok" on:click={ add }>OK</button>
</div>
<div class="buttons">
<button class="ok" on:click|preventDefault={ add }>OK</button>
<button on:click|preventDefault={ () => { showAddDialog = false; } }>Cancel</button>
</div>
</form>
</div>
{/if}
{#if showAbout}
@ -32,6 +34,7 @@ import { counters } from './db.js';
let showAddDialog = false;
let showAbout = false;
let newCounter = null;
let dialogForm = null;
function focus(node){
node.focus();
@ -41,6 +44,7 @@ function showAdd(){
newCounter = {
title: '',
initialValue: 0,
max: '',
saveHistory: false,
history: []
}
@ -49,9 +53,15 @@ function showAdd(){
}
function add(){
if(!dialogForm.checkValidity()) {
dialogForm.removeAttribute('novalidate');
return;
}
const counter = {
...newCounter,
value: newCounter.initialValue
max: newCounter.max !== '' ? +newCounter.max : null,
value: +newCounter.initialValue
}
counters.add(counter);
@ -60,10 +70,6 @@ function add(){
}
</script>
<style lang="scss">
.ok {
margin-left: auto;
}
.app {
display: flex;
flex-direction: column;

View file

@ -1,7 +1,7 @@
<div class="counter">
<header>{ counter.title }</header>
<span class="value">{ counter.value }</span>
{#if counter.max}
{#if counter.max !== null}
<MyProgress value={ counter.value } max={ counter.max }></MyProgress>
{/if}
<div class="controls">
@ -16,24 +16,28 @@
</div>
{#if showValueDialog}
<div class="dialog">
<div class="dialog-content">
<form class="dialog-content" novalidate bind:this={ dialogForm }>
<h1>{ showIncrement ? "Add" : "Set" }</h1>
<input class="dialog-value" type="text" inputmode="decimal" bind:value={ dialogValue } use:focus />
<button on:click={ dialogCancel }>Cancel</button>
<button class="ok" on:click={ dialogDone }>OK</button>
</div>
<input class="dialog-value" type="text" required pattern="(0|([1-9]\d*))(\.\d+)?" inputmode="decimal" bind:value={ dialogValue } use:focus />
<div class="buttons">
<button class="ok" on:click|preventDefault={ dialogDone }>OK</button>
<button on:click|preventDefault={ dialogCancel }>Cancel</button>
</div>
</form>
</div>
{/if}
{#if showEditDialog}
<div class="dialog">
<div class="dialog-content">
<label>Name<input type="text" bind:value={editingCounter.title} use:focus/></label>
<label>Initial Value<input type="text" inputmode="decimal" bind:value={editingCounter.initialValue} /></label>
<label>Target<input type="text" inputmode="decimal" bind:value={editingCounter.max} /></label>
<form class="dialog-content" novalidate bind:this={ dialogForm }>
<label>Name<input type="text" required bind:value={editingCounter.title} use:focus/></label>
<label>Initial Value<input type="text" required pattern="(0|([1-9]\d*))(\.\d+)?" inputmode="decimal" bind:value={editingCounter.initialValue} /></label>
<label>Target<input type="text" pattern="(0|([1-9]\d*))(\.\d+)?" inputmode="decimal" bind:value={editingCounter.max} /></label>
<label>Save history<input type="checkbox" bind:checked={editingCounter.saveHistory} /></label>
<button on:click={ () => { showEditDialog = false; } }>Cancel</button>
<button class="ok" on:click={ finishEdit }>OK</button>
</div>
<div class="buttons">
<button class="ok" on:click|preventDefault={ finishEdit }>OK</button>
<button on:click|preventDefault={ () => { showEditDialog = false; } }>Cancel</button>
</div>
</form>
</div>
{/if}
{#if showHistory}
@ -56,6 +60,7 @@ let showSet;
let showEditDialog;
let editingCounter;
let showHistory;
let dialogForm;
$: showValueDialog = showIncrement || showSet;
@ -68,14 +73,23 @@ function update(newCounter){
}
function startEdit(e){
e.stopPropagation();
editingCounter = {...counter};
editingCounter = { ...counter };
showEditDialog = true;
}
function finishEdit(){
update(editingCounter);
if(!dialogForm.checkValidity()) {
dialogForm.removeAttribute('novalidate');
return;
}
const updatedCounter = {
...editingCounter,
max: editingCounter.max !== null && editingCounter.max !== '' ? +editingCounter.max : null,
value: +editingCounter.value
}
update(updatedCounter);
showEditDialog = false;
}
@ -85,12 +99,17 @@ function dialogCancel(){
}
function dialogDone(){
if(!dialogForm.checkValidity()) {
dialogForm.removeAttribute('novalidate');
return;
}
const newCounter = showIncrement ? {
...counter,
value: counter.value + dialogValue
value: +counter.value + +dialogValue
} : {
...counter,
value: dialogValue
value: +dialogValue
}
update(newCounter);
@ -101,12 +120,10 @@ function dialogDone(){
}
function reset(e){
e.stopPropagation();
if(confirm(`Reset ${counter.title}?`)){
const newCounter = {
...counter,
value: counter.initialValue
value: +counter.initialValue
}
update(newCounter);
@ -166,8 +183,4 @@ header {
width: 100%;
margin: 5px 0;
}
.ok {
margin-left: auto;
}
</style>

View file

@ -125,6 +125,13 @@ button:focus, button:hover {
width: auto;
}
.dialog-content .buttons {
display: flex;
flex-direction: row-reverse;
justify-content: space-between;
width: 100%;
}
.dialog-content button:focus, .dialog-content button:hover {
border: 0;
outline: 2px solid var(--button-color);