Skip to content

Commit

Permalink
Add validation for client side
Browse files Browse the repository at this point in the history
  • Loading branch information
mjkuranda committed Aug 24, 2022
1 parent e61a967 commit c8eefe9
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 12 deletions.
13 changes: 13 additions & 0 deletions public/css/basic.css
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ button:disabled {
opacity: 0.618;
cursor: not-allowed;
}
button.square {
width: 16px;
height: 16px;
padding: 0;
}

a {
/* cursor: alias; */
Expand Down Expand Up @@ -100,6 +105,14 @@ input[type="checkbox"]:hover {
input[type="checkbox"]:checked {
box-shadow: inset 0 0 0 20px var(--cooper);
}
input:not(:placeholder-shown):required:valid,
textarea:not(:placeholder-shown):required:valid {
background-color: chartreuse;
}
input:not(:placeholder-shown):invalid,
textarea:not(:placeholder-shown):invalid {
background-color: orangered;
}

.center {
width: 1100px;
Expand Down
21 changes: 20 additions & 1 deletion public/css/meals-add.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,25 @@ select {
border-radius: 0.5em;
}

form div[required] > h2::after {
content: "*";
color: red;
font-size: 1em;
}

form input + button,
form textarea + button {
margin-left: 0.5em;
}
form input + button,
form textarea + button,
form :not(:placeholder-shown):valid + button {
opacity: 0;
}
form :not(:placeholder-shown):invalid + button {
opacity: 1;
}

main > div + div {
margin-top: 0.5em;
}
Expand All @@ -53,7 +72,7 @@ main > div + div {
margin-top: 2em;
}

.meals-add-container > form > div > div.flex-center {
.meals-add-container > form div.flex-center {
margin-top: 0.5em;
}

Expand Down
7 changes: 7 additions & 0 deletions src/YummyData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ export const elements = {
},
};

/* Meal Validator */
export const mealValidator = {
author: "^[A-ZĄĆĘŁŃÓŚŹŻa-ząćęłńóśźż\\s]{4,}$",
description: "^[A-ZĄĆĘŁŃÓŚŹŻ][a-ząćęłńóśźż\\s]{15,511}$",
title: "^[A-ZĄĆĘŁŃÓŚŹŻ][a-ząćęłńóśźż\\s]{3,31}$",
};

/* Icons */
export const icons = {
listView: new Icon(
Expand Down
3 changes: 2 additions & 1 deletion src/YummyRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Express, Router, Request, Response, NextFunction } from "express";
import { IDatabase, IQuery } from "../databases/IDatabase";
import MealModel from "../databases/models/MealModel";
import Ingredient from "./classes/Ingredient";
import { elements, icons, ingredients } from "./YummyData";
import { elements, icons, ingredients, mealValidator } from "./YummyData";

import { categorizeIngredients } from "./handlers/searchHandler";
import { Type } from "./classes/Meal";
Expand Down Expand Up @@ -129,6 +129,7 @@ class YummyRouter {
categorized: categorizeIngredients(),
},
mealTypes: mealTypes,
validator: mealValidator,
});
}

Expand Down
54 changes: 44 additions & 10 deletions views/layouts/meals-add.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,52 @@
<a href="/search"><i class="fa fa-chevron-circle-left"></i>Powrót do wyszukiwania</a>
</div>
<div class="meals-add-container">
<form method="post" enctype="multipart/form-data">
<div>
<form method="post" enctype="multipart/form-data" onsubmit="return validate()">
<div required>
<h2>Nazwa posiłku</h2>
<div class="flex-center">
<input
type="text"
name="title"
placeholder="Wprowadź tytuł posiłku"
pattern="{{validator.title}}"
title="Liczba znaków w zakresie od 4 do 32"
required
/>
<button class="square"></button>
</div>
</div>
<div>
<div required>
<h2>Opis posiłku</h2>
<div class="flex-center">
<textarea
cols="32"
rows="10"
name="description"
placeholder="Wprowadź opis dla posiłku"
minlength="16"
maxlength="512"
title="Liczba znaków w zakresie od 16 do 512"
required
></textarea>
<button class="square"></button>
</div>
</div>
<div>
<div required>
<h2>Rodzaj posiłku</h2>
<div class="meal-type-container flex-center">
<select name="type">
<select name="type" required>
{{#each mealTypes as |type|}}
<option value="{{type.k}}">{{type.v}}</option>
{{/each}}
</select>
</div>
</div>
<div>
<div required>
<h2>Imię autora wprowadzającego posiłek</h2>
<div class="flex-center">
<input type="text" name="author" placeholder="Wprowadź swoje imię" />
<input type="text" name="author" placeholder="Wprowadź swoje imię" pattern="{{validator.author}}" title="Co najmniej 4 znaki" required />
<button class="square"></button>
</div>
</div>
<div>
Expand All @@ -48,9 +58,9 @@
<input type="file" name="image" placeholder="Wybierz zdjęcie" id="image" />
</div>
</div>
<div>
<div required>
<h2>Składniki</h2>
<div class="category-container">
<div class="category-container" required>
{{#each filter.categorized as |cat|}}
<div class="category">
<h3>{{cat.category}}</h3>
Expand Down Expand Up @@ -79,4 +89,28 @@
</div>
</form>
</div>
</main>
</main>
<script>
function validate() {
const file = document.querySelector('input[name=image]').files[0];
if (file.size >= 1024 * 512) {
alert('Zdjęcie jest zbyt duże! Maksymalny rozmiar zdjęcia to 512 kB (0.5 MB)');
return false;
}
if (!['image/jpeg', 'image/jpg', 'image/png'].includes(file.type)) {
alert('Wymagany typ pliku to: jpeg | jpg | png');
return false;
}
const ings = document.querySelectorAll('input[type="checkbox"]:checked').length;
if (ings === 0) {
alert('Posiłek powinien zawierać chociaż jeden składnik!');
return false;
}
return true;
}
</script>

0 comments on commit c8eefe9

Please sign in to comment.