Add validation to forms
Fix values being treated as strings
This commit is contained in:
parent
e42f3656a9
commit
cea4f35d52
3 changed files with 64 additions and 38 deletions
|
@ -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 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;
|
||||
|
|
|
@ -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>
|
||||
<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 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 };
|
||||
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>
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue