final version
This commit is contained in:
parent
f81ca65798
commit
1191fc0f68
16 changed files with 16555 additions and 207 deletions
11
.babelrc
Normal file
11
.babelrc
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"plugins": ["@babel/syntax-dynamic-import"],
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"modules": false
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
10
.eslintrc.js
Normal file
10
.eslintrc.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
module.exports = {
|
||||
"extends": [
|
||||
"eslint-config-prettier",
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
}
|
||||
}
|
||||
12
.prettierignore
Normal file
12
.prettierignore
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
node_modules/
|
||||
dist/
|
||||
src/style.css
|
||||
src/thumbsup.gif
|
||||
.babelrc
|
||||
.eslintrc.js
|
||||
.prettierignore
|
||||
.prettierrc.json
|
||||
index.html
|
||||
package-lock.json
|
||||
package.json
|
||||
README.md
|
||||
1
.prettierrc.json
Normal file
1
.prettierrc.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
15
README.md
15
README.md
|
|
@ -1,2 +1,15 @@
|
|||
# js-validationform
|
||||
# 🚀 Welcome to your new awesome project!
|
||||
|
||||
This project has been created using **webpack-cli**, you can now run
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
yarn build
|
||||
```
|
||||
|
||||
to bundle your application
|
||||
|
|
|
|||
146
dist/main.js
vendored
Normal file
146
dist/main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -21,7 +21,7 @@
|
|||
<main class="col-sm-6 py-3"></main>
|
||||
</center>
|
||||
</div>
|
||||
<script type="module" src="/src/index.js"></script>
|
||||
<script type="module" src="/dist/main.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.9.2/umd/popper.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.1.0/js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
|
|
|
|||
16134
package-lock.json
generated
16134
package-lock.json
generated
File diff suppressed because it is too large
Load diff
21
package.json
21
package.json
|
|
@ -1,19 +1,30 @@
|
|||
{
|
||||
"name": "js-validationform",
|
||||
"name": "my-webpack-project",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"description": "My webpack project",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "webpack --mode=development",
|
||||
"watch": "webpack --watch"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "ssh://_gitea@git.alexanderk.net:3022/ak/js-validationform.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"author": "ak",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.22.5",
|
||||
"@babel/preset-env": "^7.22.5",
|
||||
"@webpack-cli/generators": "^3.0.7",
|
||||
"babel-loader": "^9.1.2",
|
||||
"css-loader": "^6.7.3",
|
||||
"eslint": "^8.43.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"mini-css-extract-plugin": "^2.7.6",
|
||||
"style-loader": "^3.3.1",
|
||||
"webpack": "^5.88.0",
|
||||
"webpack-cli": "^5.1.4"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
// email field validation
|
||||
export function emailValidation () {
|
||||
// finds "@"" and "." in inputted email address
|
||||
const findAt = new RegExp(/[@]/, 'gi');
|
||||
const findDot = new RegExp(/[\.]/, 'gi');
|
||||
if (findAt.test(this.value) && findDot.test(this.value)) {
|
||||
this.setCustomValidity('');
|
||||
this.reportValidity();
|
||||
return;
|
||||
}
|
||||
// otherwise highlights field and pops up message
|
||||
this.setCustomValidity("Please insert a valid e-mail address");
|
||||
export function emailValidation() {
|
||||
// finds "@"" and "." in inputted email address
|
||||
const findAt = new RegExp(/[@]/, "gi");
|
||||
const findDot = new RegExp(/[\.]/, "gi");
|
||||
if (findAt.test(this.value) && findDot.test(this.value)) {
|
||||
this.setCustomValidity("");
|
||||
this.reportValidity();
|
||||
return;
|
||||
}
|
||||
// otherwise highlights field and pops up message
|
||||
this.setCustomValidity("Please insert a valid e-mail address");
|
||||
this.reportValidity();
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { makeWindow } from "./makeWindow.js";
|
||||
|
||||
const NEWBUTTON = document.getElementById('newButton');
|
||||
const NEWBUTTON = document.getElementById("newButton");
|
||||
|
||||
NEWBUTTON.onclick = () => makeWindow();
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
// input validation for input fields without specific requirements
|
||||
export function inputValidation (originalValue) {
|
||||
// if the user has not entered a value different from the original, highlight and pop up message
|
||||
if (this.value === originalValue || this.value === '') {
|
||||
this.setCustomValidity("Please fill out this field");
|
||||
this.reportValidity();
|
||||
return;
|
||||
}
|
||||
this.setCustomValidity('');
|
||||
export function inputValidation(originalValue) {
|
||||
// if the user has not entered a value different from the original, highlight and pop up message
|
||||
if (this.value === originalValue || this.value === "") {
|
||||
this.setCustomValidity("Please fill out this field");
|
||||
this.reportValidity();
|
||||
return;
|
||||
}
|
||||
this.setCustomValidity("");
|
||||
this.reportValidity();
|
||||
}
|
||||
|
|
@ -1,165 +1,179 @@
|
|||
import { zipValidation } from "./zipValidation.js"
|
||||
import { zipValidation } from "./zipValidation.js";
|
||||
import { emailValidation } from "./emailValidation.js";
|
||||
import { inputValidation } from "./inputValidation.js";
|
||||
import { passwordValidation } from "./passwordValidation.js";
|
||||
import { submissionValid } from "./submissionValidation.js";
|
||||
|
||||
const BODY = document.querySelector('main');
|
||||
const BODY = document.querySelector("main");
|
||||
|
||||
// close button functionality
|
||||
const closeWindow = (headDiv) => {
|
||||
headDiv.parentElement.removeChild(headDiv);
|
||||
}
|
||||
headDiv.parentElement.removeChild(headDiv);
|
||||
};
|
||||
|
||||
// handy way of making new elements
|
||||
const makeElement = (passedClass, passedType = 'div') => {
|
||||
const newElement = document.createElement(passedType);
|
||||
newElement.setAttribute('class', passedClass);
|
||||
return newElement;
|
||||
}
|
||||
const makeElement = (passedClass, passedType = "div") => {
|
||||
const newElement = document.createElement(passedType);
|
||||
newElement.setAttribute("class", passedClass);
|
||||
return newElement;
|
||||
};
|
||||
|
||||
const thumbsUp = () => {
|
||||
// remove input fields
|
||||
for (let i = 0; i < 5; i++) {
|
||||
formWindow.removeChild(document.getElementById(`input-${i + 1}`));
|
||||
}
|
||||
// remove submit button
|
||||
formWindow.removeChild(formWindow.lastChild);
|
||||
// add thumbs up
|
||||
const thumbsUpGIF = document.createElement('img');
|
||||
thumbsUpGIF.src = "/src/thumbsup.gif";
|
||||
formWindow.appendChild(thumbsUpGIF);
|
||||
}
|
||||
// remove input fields
|
||||
for (let i = 0; i < 5; i++) {
|
||||
formWindow.removeChild(document.getElementById(`input-${i + 1}`));
|
||||
}
|
||||
// remove submit button
|
||||
formWindow.removeChild(formWindow.lastChild);
|
||||
// add thumbs up
|
||||
const thumbsUpGIF = document.createElement("img");
|
||||
thumbsUpGIF.src = "/src/thumbsup.gif";
|
||||
formWindow.appendChild(thumbsUpGIF);
|
||||
};
|
||||
|
||||
export const makeWindow = () => {
|
||||
// *make window itself*
|
||||
// 1. window body
|
||||
const formWindow = makeElement('card-body', 'form');
|
||||
formWindow.id = 'formWindow';
|
||||
BODY.appendChild(makeElement('card')).appendChild(formWindow);
|
||||
// *make window itself*
|
||||
// 1. window body
|
||||
const formWindow = makeElement("card-body", "form");
|
||||
formWindow.id = "formWindow";
|
||||
BODY.appendChild(makeElement("card")).appendChild(formWindow);
|
||||
|
||||
// 2. close button div
|
||||
const closeButton = makeElement('mb-3 d-flex');
|
||||
formWindow.appendChild(closeButton);
|
||||
// 2. close button div
|
||||
const closeButton = makeElement("mb-3 d-flex");
|
||||
formWindow.appendChild(closeButton);
|
||||
|
||||
// the close button is SVG
|
||||
// 3. container for SVG - 24x24
|
||||
const closeButtonSVGContainer = document.createElementNS("http://www.w3.org/2000/svg","svg");
|
||||
closeButtonSVGContainer.style = "width: 24px; height: 24px";
|
||||
closeButtonSVGContainer.setAttribute('viewbox', '0 0 24 24');
|
||||
closeButtonSVGContainer.id = 'closeButton';
|
||||
closeButton.appendChild(closeButtonSVGContainer);
|
||||
// the close button is SVG
|
||||
// 3. container for SVG - 24x24
|
||||
const closeButtonSVGContainer = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"svg"
|
||||
);
|
||||
closeButtonSVGContainer.style = "width: 24px; height: 24px";
|
||||
closeButtonSVGContainer.setAttribute("viewbox", "0 0 24 24");
|
||||
closeButtonSVGContainer.id = "closeButton";
|
||||
closeButton.appendChild(closeButtonSVGContainer);
|
||||
|
||||
// 4. the actual SVG path
|
||||
const closeButtonSVGPath = document.createElementNS("http://www.w3.org/2000/svg","path");
|
||||
closeButtonSVGPath.setAttribute('d', "M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z");
|
||||
closeButtonSVGPath.fill = "#6c757d";
|
||||
closeButtonSVGContainer.appendChild(closeButtonSVGPath);
|
||||
// add event listeners to close the window if button is clicked
|
||||
closeButtonSVGContainer.onclick = () => closeWindow(formWindow.parentElement);
|
||||
// 4. the actual SVG path
|
||||
const closeButtonSVGPath = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"path"
|
||||
);
|
||||
closeButtonSVGPath.setAttribute(
|
||||
"d",
|
||||
"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"
|
||||
);
|
||||
closeButtonSVGPath.fill = "#6c757d";
|
||||
closeButtonSVGContainer.appendChild(closeButtonSVGPath);
|
||||
// add event listeners to close the window if button is clicked
|
||||
closeButtonSVGContainer.onclick = () => closeWindow(formWindow.parentElement);
|
||||
|
||||
// *make input fields*
|
||||
// generate container divs
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const inputContainer = makeElement('mb-3');
|
||||
inputContainer.id = `input-${i + 1}`;
|
||||
formWindow.appendChild(inputContainer);
|
||||
}
|
||||
// *make input fields*
|
||||
// generate container divs
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const inputContainer = makeElement("mb-3");
|
||||
inputContainer.id = `input-${i + 1}`;
|
||||
formWindow.appendChild(inputContainer);
|
||||
}
|
||||
|
||||
const originalValues = [];
|
||||
const originalValues = [];
|
||||
|
||||
// 5. email field
|
||||
const userEmail = makeElement('form-control', 'input');
|
||||
userEmail.type = 'text';
|
||||
userEmail.value = 'Email address';
|
||||
originalValues.push(userEmail.value);
|
||||
document.getElementById('input-1').appendChild(userEmail);
|
||||
// 5. email field
|
||||
const userEmail = makeElement("form-control", "input");
|
||||
userEmail.type = "text";
|
||||
userEmail.value = "Email address";
|
||||
originalValues.push(userEmail.value);
|
||||
document.getElementById("input-1").appendChild(userEmail);
|
||||
|
||||
// 6. country field
|
||||
const userCountry = makeElement('form-control', 'input');
|
||||
userCountry.type = 'text';
|
||||
userCountry.value = 'Country';
|
||||
originalValues.push(userCountry.value);
|
||||
document.getElementById('input-2').appendChild(userCountry);
|
||||
// 6. country field
|
||||
const userCountry = makeElement("form-control", "input");
|
||||
userCountry.type = "text";
|
||||
userCountry.value = "Country";
|
||||
originalValues.push(userCountry.value);
|
||||
document.getElementById("input-2").appendChild(userCountry);
|
||||
|
||||
// 7. zip code field
|
||||
const userZip = makeElement('form-control', 'input');
|
||||
userZip.type = 'text';
|
||||
userZip.value = 'Zip code';
|
||||
originalValues.push(userZip.value);
|
||||
document.getElementById('input-3').appendChild(userZip);
|
||||
// only allow numeric input
|
||||
userZip.oninput = (e) => {
|
||||
let numericValue = e.target.value.replace(new RegExp(/[^\d]/,'gi'), "");
|
||||
numericValue = numericValue.substring(0,5);
|
||||
e.target.value = numericValue;
|
||||
}
|
||||
// 7. zip code field
|
||||
const userZip = makeElement("form-control", "input");
|
||||
userZip.type = "text";
|
||||
userZip.value = "Zip code";
|
||||
originalValues.push(userZip.value);
|
||||
document.getElementById("input-3").appendChild(userZip);
|
||||
// only allow numeric input
|
||||
userZip.oninput = (e) => {
|
||||
let numericValue = e.target.value.replace(new RegExp(/[^\d]/, "gi"), "");
|
||||
numericValue = numericValue.substring(0, 5);
|
||||
e.target.value = numericValue;
|
||||
};
|
||||
|
||||
// 8. password field
|
||||
const userPass = makeElement('form-control', 'input');
|
||||
userPass.type = 'text';
|
||||
userPass.value = 'Password';
|
||||
originalValues.push(userPass.value);
|
||||
document.getElementById('input-4').appendChild(userPass);
|
||||
// 8. password field
|
||||
const userPass = makeElement("form-control", "input");
|
||||
userPass.type = "text";
|
||||
userPass.value = "Password";
|
||||
originalValues.push(userPass.value);
|
||||
document.getElementById("input-4").appendChild(userPass);
|
||||
|
||||
// 9. password confirmation field
|
||||
const userPassConfirm = makeElement('form-control', 'input');
|
||||
userPassConfirm.type = 'text';
|
||||
userPassConfirm.value = 'Confirm password';
|
||||
originalValues.push(userPassConfirm.value);
|
||||
document.getElementById('input-5').appendChild(userPassConfirm);
|
||||
// blank out the input fields when focused and change back when not focused
|
||||
document.querySelectorAll('.form-control').forEach(inputField => {
|
||||
// keep original value for validation purposes
|
||||
const originalValue = inputField.value;
|
||||
let oldValue = '';
|
||||
inputField.onfocus = () => {
|
||||
// erases characters from input field when focused
|
||||
oldValue = inputField.value;
|
||||
inputField.value = '';
|
||||
// change password fields to hide password characters
|
||||
if (inputField === userPass || inputField === userPassConfirm) {
|
||||
inputField.type = 'password';
|
||||
}
|
||||
}
|
||||
inputField.onblur = (e) => {
|
||||
// change back input field value to the old value if unmodified
|
||||
if (inputField.value === '') {
|
||||
inputField.value = oldValue;
|
||||
}
|
||||
// email validation
|
||||
if (inputField === userEmail) {
|
||||
emailValidation.call(e.target);
|
||||
return;
|
||||
}
|
||||
// zip validation
|
||||
if (inputField === userZip) {
|
||||
zipValidation.call(e.target);
|
||||
}
|
||||
// general input field validation
|
||||
inputValidation.call(e.target, originalValue);
|
||||
|
||||
// password validation
|
||||
if (inputField === userPassConfirm) {
|
||||
passwordValidation.call(e.target, userPass.value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 10. submit button
|
||||
const submitButton = makeElement('btn btn-primary', 'button');
|
||||
submitButton.type = 'submit';
|
||||
submitButton.textContent = "Submit";
|
||||
formWindow.appendChild(submitButton);
|
||||
// prevent default
|
||||
submitButton.onclick = (event) => {
|
||||
event.preventDefault();
|
||||
if (submissionValid(document.querySelectorAll('.form-control'), originalValues)) {
|
||||
// give em a thumbs up
|
||||
thumbsUp();
|
||||
return;
|
||||
}
|
||||
// or tell them to fix it
|
||||
alert("Please properly fill out all fields");
|
||||
// 9. password confirmation field
|
||||
const userPassConfirm = makeElement("form-control", "input");
|
||||
userPassConfirm.type = "text";
|
||||
userPassConfirm.value = "Confirm password";
|
||||
originalValues.push(userPassConfirm.value);
|
||||
document.getElementById("input-5").appendChild(userPassConfirm);
|
||||
// blank out the input fields when focused and change back when not focused
|
||||
document.querySelectorAll(".form-control").forEach((inputField) => {
|
||||
// keep original value for validation purposes
|
||||
const originalValue = inputField.value;
|
||||
let oldValue = "";
|
||||
inputField.onfocus = () => {
|
||||
// erases characters from input field when focused
|
||||
oldValue = inputField.value;
|
||||
inputField.value = "";
|
||||
// change password fields to hide password characters
|
||||
if (inputField === userPass || inputField === userPassConfirm) {
|
||||
inputField.type = "password";
|
||||
}
|
||||
};
|
||||
}
|
||||
inputField.onblur = (e) => {
|
||||
// change back input field value to the old value if unmodified
|
||||
if (inputField.value === "") {
|
||||
inputField.value = oldValue;
|
||||
}
|
||||
// email validation
|
||||
if (inputField === userEmail) {
|
||||
emailValidation.call(e.target);
|
||||
return;
|
||||
}
|
||||
// zip validation
|
||||
if (inputField === userZip) {
|
||||
zipValidation.call(e.target);
|
||||
}
|
||||
// general input field validation
|
||||
inputValidation.call(e.target, originalValue);
|
||||
|
||||
// password validation
|
||||
if (inputField === userPassConfirm) {
|
||||
passwordValidation.call(e.target, userPass.value);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// 10. submit button
|
||||
const submitButton = makeElement("btn btn-primary", "button");
|
||||
submitButton.type = "submit";
|
||||
submitButton.textContent = "Submit";
|
||||
formWindow.appendChild(submitButton);
|
||||
// prevent default
|
||||
submitButton.onclick = (event) => {
|
||||
event.preventDefault();
|
||||
if (
|
||||
submissionValid(
|
||||
document.querySelectorAll(".form-control"),
|
||||
originalValues
|
||||
)
|
||||
) {
|
||||
// give em a thumbs up
|
||||
thumbsUp();
|
||||
return;
|
||||
}
|
||||
// or tell them to fix it
|
||||
alert("Please properly fill out all fields");
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
// password validation
|
||||
export function passwordValidation (origPassword) {
|
||||
// check if passwords match
|
||||
if (this.value === origPassword) {
|
||||
this.setCustomValidity('');
|
||||
this.reportValidity();
|
||||
return;
|
||||
}
|
||||
// otherwise highlight and pop up message
|
||||
this.setCustomValidity("Please ensure passwords match");
|
||||
export function passwordValidation(origPassword) {
|
||||
// check if passwords match
|
||||
if (this.value === origPassword) {
|
||||
this.setCustomValidity("");
|
||||
this.reportValidity();
|
||||
return;
|
||||
}
|
||||
// otherwise highlight and pop up message
|
||||
this.setCustomValidity("Please ensure passwords match");
|
||||
this.reportValidity();
|
||||
}
|
||||
|
|
@ -1,17 +1,19 @@
|
|||
// submit button validation
|
||||
export const submissionValid = (inputFields, originalValues) => {
|
||||
// checks each field for validity
|
||||
let bool = true;
|
||||
let arrNum = 0;
|
||||
inputFields.forEach(inputField => {
|
||||
// if the field is previously invalid, unchanged or blank declare validity to be false
|
||||
if (!(inputField.validity.valid) ||
|
||||
inputField.value === originalValues[arrNum] ||
|
||||
inputField === '') {
|
||||
bool = false;
|
||||
}
|
||||
arrNum++;
|
||||
});
|
||||
// returns final validity
|
||||
return bool;
|
||||
}
|
||||
// checks each field for validity
|
||||
let bool = true;
|
||||
let arrNum = 0;
|
||||
inputFields.forEach((inputField) => {
|
||||
// if the field is previously invalid, unchanged or blank declare validity to be false
|
||||
if (
|
||||
!inputField.validity.valid ||
|
||||
inputField.value === originalValues[arrNum] ||
|
||||
inputField === ""
|
||||
) {
|
||||
bool = false;
|
||||
}
|
||||
arrNum++;
|
||||
});
|
||||
// returns final validity
|
||||
return bool;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
// zip field validation
|
||||
const LENGTH = 5
|
||||
export function zipValidation () {
|
||||
// if zip code is under 5 digits, highlight field and pop up message
|
||||
if (this.value.length < LENGTH) {
|
||||
this.setCustomValidity("Please enter a valid zip code");
|
||||
this.reportValidity();
|
||||
return;
|
||||
}
|
||||
this.setCustomValidity('');
|
||||
const LENGTH = 5;
|
||||
export function zipValidation() {
|
||||
// if zip code is under 5 digits, highlight field and pop up message
|
||||
if (this.value.length < LENGTH) {
|
||||
this.setCustomValidity("Please enter a valid zip code");
|
||||
this.reportValidity();
|
||||
return;
|
||||
}
|
||||
this.setCustomValidity("");
|
||||
this.reportValidity();
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue