validate date input

This commit is contained in:
Chneemann 2024-04-07 13:14:32 +02:00
parent 75b02685ec
commit 450a96d2de
3 changed files with 234 additions and 115 deletions

View file

@ -7,125 +7,158 @@
(ngSubmit)="onSubmit(taskForm)" (ngSubmit)="onSubmit(taskForm)"
#taskForm="ngForm" #taskForm="ngForm"
onsubmit="return false" onsubmit="return false"
class="content"
> >
<div class="left-side"> <div class="content">
<div class="title"> <div class="left-side">
<p>Title<span class="red-dot">*</span></p> <div class="title">
<input <p>Title<span class="red-dot">*</span></p>
type="text" <input
id="title" type="text"
name="title" id="title"
#title="ngModel" name="title"
(input)="saveTaskData()" #title="ngModel"
placeholder="{{ taskData.title }}" (input)="saveTaskData()"
[(ngModel)]="taskData.title" placeholder="{{
autocomplete="off" taskData.title ? taskData.title : 'Enter a title'
required }}"
/> [(ngModel)]="taskData.title"
<div class="error-msg"> autocomplete="off"
@if (!title.valid && title.touched) { required
<p>You must enter a title.</p> />
} <div class="error-msg">
@if (!title.valid && title.touched) {
<p>You must enter a title.</p>
}
</div>
</div>
<div class="description">
<p>Description<span class="red-dot">*</span></p>
<textarea
id="description"
rows="6"
name="description"
#description="ngModel"
minlength="10"
(input)="saveTaskData()"
placeholder="{{
taskData.description
? taskData.description
: 'Enter a description'
}}"
[(ngModel)]="taskData.description"
autocomplete="off"
required
></textarea>
<div class="error-msg">
@if (!description.valid && description.touched) {
<p>You must enter a description. (min. 10 letters)</p>
}
</div>
</div> </div>
</div> </div>
<div class="description"> <div class="middle-spacer"><div class="line"></div></div>
<p>Description<span class="red-dot">*</span></p> <div class="right-side">
<textarea <div class="date">
id="description" <p>Due date<span class="red-dot">*</span></p>
rows="6" <input
name="description" type="date"
#description="ngModel" id="date"
minlength="10" name="date"
(input)="saveTaskData()" #date="ngModel"
placeholder="{{ taskData.description }}" (input)="checkDateInput()"
[(ngModel)]="taskData.description" placeholder="{{ taskData.date }}"
autocomplete="off" [(ngModel)]="taskData.date"
required autocomplete="off"
></textarea> required
<div class="error-msg"> />
@if (!description.valid && description.touched) { <div class="error-msg">
<p>You must enter a description. (min. 10 letters)</p> @if (!date.valid && date.touched) {
} <p>You must enter a date.</p>
} @if (dateInPast && date.valid) {
<p>The date must be in the future</p>
}
</div>
</div>
<div class="priority">
<p>Prio<span class="red-dot">*</span></p>
<div class="btns">
<button
type="button"
class="btn"
[ngClass]="{
'btn-active': taskData.priority == 'urgent'
}"
[ngStyle]="{
'background-color':
taskData.priority == 'urgent' ? 'red' : 'white'
}"
(click)="tooglePriority('urgent')"
>
<div class="btn-text">
<span>Urgent</span>
<img src="./../../../assets/img/urgent.svg" alt="" />
</div>
</button>
<button
type="button"
class="btn"
[ngClass]="{
'btn-active': taskData.priority == 'medium'
}"
[ngStyle]="{
'background-color':
taskData.priority == 'medium' ? 'orange' : 'white'
}"
(click)="tooglePriority('medium')"
>
<div class="btn-text">
<span>Medium</span>
<img src="./../../../assets/img/medium.svg" alt="" />
</div>
</button>
<button
type="button"
class="btn"
[ngClass]="{
'btn-active': taskData.priority == 'low'
}"
[ngStyle]="{
'background-color':
taskData.priority == 'low' ? 'green' : 'white'
}"
(click)="tooglePriority('low')"
>
<div class="btn-text">
<span>Low</span>
<img src="./../../../assets/img/low.svg" alt="" />
</div>
</button>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="middle-spacer"><div class="line"></div></div> <div class="form-buttons">
<div class="right-side"> <input
<div class="date"> class="btn-clear"
<p>Due date<span class="red-dot">*</span></p> type="button"
<input value="Clear"
type="date" (click)="removeTaskData()"
id="date" />
name="date" <input
#date="ngModel" class="btn-submit"
(input)="saveTaskData()" type="submit"
placeholder="{{ taskData.date }}" value="Create Task"
[(ngModel)]="taskData.date" [disabled]="
autocomplete="off" title.invalid ||
required !taskData.title ||
/> description.invalid ||
<div class="error-msg"> !taskData.description ||
@if (!date.valid && date.touched) { date.invalid ||
<p>You must enter a date.</p> !taskData.date ||
} !taskData.priority ||
</div> dateInPast
</div> "
<div class="priority"> />
<p>Prio<span class="red-dot">*</span></p>
<div class="btns">
<button
type="button"
class="btn"
[ngClass]="{
'btn-active': taskData.priority == 'urgent'
}"
[ngStyle]="{
'background-color':
taskData.priority == 'urgent' ? 'red' : 'white'
}"
(click)="tooglePriority('urgent')"
>
<div class="btn-text">
<span>Urgent</span>
<img src="./../../../assets/img/urgent.svg" alt="" />
</div>
</button>
<button
type="button"
class="btn"
[ngClass]="{
'btn-active': taskData.priority == 'medium'
}"
[ngStyle]="{
'background-color':
taskData.priority == 'medium' ? 'orange' : 'white'
}"
(click)="tooglePriority('medium')"
>
<div class="btn-text">
<span>Medium</span>
<img src="./../../../assets/img/medium.svg" alt="" />
</div>
</button>
<button
type="button"
class="btn"
[ngClass]="{
'btn-active': taskData.priority == 'low'
}"
[ngStyle]="{
'background-color': taskData.priority == 'low' ? 'green' : 'white'
}"
(click)="tooglePriority('low')"
>
<div class="btn-text">
<span>Low</span>
<img src="./../../../assets/img/low.svg" alt="" />
</div>
</button>
</div>
</div>
</div> </div>
</form> </form>
</section> </section>

View file

@ -111,3 +111,56 @@ p {
.btn:hover { .btn:hover {
box-shadow: 2px 2px 2px 0px rgba(0, 0, 0, 0.3); box-shadow: 2px 2px 2px 0px rgba(0, 0, 0, 0.3);
} }
/*------------- SUBMIT BUTTON -------------*/
.form-buttons {
display: flex;
justify-content: end;
}
.btn-submit {
width: 183px;
height: 56px;
padding: 12px;
margin: 12px 12px;
border-radius: 10px;
border: 1px solid var(--black) !important;
background-color: var(--light-gray);
font-size: 23px;
font-weight: 400;
transition: 125ms ease-in-out;
&:hover:not(:disabled) {
box-shadow: 2px 2px 2px 0px rgba(0, 0, 0, 0.3);
background-color: var(--light-blue) !important;
border: 1px solid var(--light-blue) !important;
cursor: pointer;
}
&:not(:disabled) {
background-color: var(--very-dark-blue) !important;
color: var(--white);
}
&:hover {
cursor: default;
}
}
.btn-clear {
width: 110px;
height: 56px;
padding: 12px;
margin: 12px 12px;
border-radius: 10px;
color: var(--black);
background-color: var(--white);
border: 1px solid var(--black);
font-size: 23px;
font-weight: 400;
transition: 125ms ease-in-out;
cursor: pointer;
&:hover {
color: var(--light-blue);
border-color: var(--light-bluek);
box-shadow: 2px 2px 2px 0px rgba(0, 0, 0, 0.3);
}
}

View file

@ -1,6 +1,6 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { Component } from '@angular/core'; import { Component, ViewChild } from '@angular/core';
import { FormsModule, NgForm } from '@angular/forms'; import { FormsModule, NgForm, NgModel } from '@angular/forms';
@Component({ @Component({
selector: 'app-add-task', selector: 'app-add-task',
@ -10,7 +10,11 @@ import { FormsModule, NgForm } from '@angular/forms';
styleUrl: './add-task.component.scss', styleUrl: './add-task.component.scss',
}) })
export class AddTaskComponent { export class AddTaskComponent {
@ViewChild('title', { static: true }) titleField!: NgModel;
@ViewChild('description', { static: true }) descriptionField!: NgModel;
currentDate: string = new Date().toISOString().split('T')[0]; currentDate: string = new Date().toISOString().split('T')[0];
dateInPast: boolean = false;
taskData = { taskData = {
title: '', title: '',
@ -26,6 +30,17 @@ export class AddTaskComponent {
} }
} }
checkDateInput() {
const currentDateForm = this.taskData.date.replaceAll('-', '');
const currentDate = new Date()
.toISOString()
.split('T')[0]
.replaceAll('-', '');
currentDateForm < currentDate
? (this.dateInPast = true)
: (this.dateInPast = false);
}
tooglePriority(prio: string) { tooglePriority(prio: string) {
this.taskData.priority !== prio this.taskData.priority !== prio
? (this.taskData.priority = prio) ? (this.taskData.priority = prio)
@ -37,9 +52,27 @@ export class AddTaskComponent {
localStorage.setItem('taskData', JSON.stringify(this.taskData)); localStorage.setItem('taskData', JSON.stringify(this.taskData));
} }
removeTaskData() {
localStorage.removeItem('taskData');
this.untouchedFormFields();
this.clearFormData();
}
untouchedFormFields() {
this.titleField.control.markAsUntouched();
this.descriptionField.control.markAsUntouched();
}
clearFormData() {
this.taskData.title = '';
this.taskData.description = '';
this.taskData.date = this.currentDate;
}
onSubmit(ngForm: NgForm) { onSubmit(ngForm: NgForm) {
if (ngForm.submitted && ngForm.form.valid) { if (ngForm.submitted && ngForm.form.valid) {
console.log('Send completed'); console.log('Send completed');
this.removeTaskData();
} }
} }
} }