unknown 2 lat temu
rodzic
commit
428ac249f1
2 zmienionych plików z 629 dodań i 1 usunięć
  1. 167 0
      html-css/css/style.css
  2. 462 1
      javascript/hw.js

+ 167 - 0
html-css/css/style.css

@@ -7,6 +7,173 @@ html {
 *::after {
   box-sizing: inherit;
 }
+.signInForm{
+  margin: 0 auto;
+  margin-bottom: 20px;
+  width: 600px;
+  display: flex;
+  justify-content: space-between;
+  flex-wrap: wrap;
+  background-color: blueviolet;
+  padding: 5px;
+  border-radius: 10px;
+  border: solid 2px black;
+}
+
+
+.passwordInput , .loginInput ,.confirmPasswordInput{
+  font-size: 18px;
+  color: rgb(94, 91, 91);
+  width: 100%;
+  margin-bottom: 10px;
+}
+
+.hiddenInput {
+  display: none;
+}
+.passwordInput::placeholder{
+  font-size: 18px;
+  background: -webkit-linear-gradient(left, rgb(8, 8, 8) 0%, rgb(2, 2, 2) 65%,red 60%, red 100%);
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+}
+
+.labelCheckBox{
+  font-size: 18px;
+  color: rgb(183, 184, 184);
+  display: flex;
+  align-items: center;
+}
+
+.btnSubmit{
+  width: auto;
+  background-color: black;
+  border-radius: 10px;
+  border: solid 2px rgb(8, 31, 243);
+  font-size: 28px;
+  color: white;
+}
+
+.btnSubmit__disable     {
+  border-radius: 10px;
+  font-size: 28px;
+  width: auto;
+  pointer-events: none;
+  color: #c0c0c0;
+  border: solid 2px rgb(133, 132, 132);
+  background-color: #ffffff;
+  cursor: not-allowed;
+}
+
+.formWrapper{
+  margin: 0 auto;
+  width: 100%;
+  padding: 20px;
+  background-color: rgb(219, 214, 214);
+  border: solid 5px grey;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+}
+
+.placeholderForm{
+  position: relative;
+  width: 340px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-wrap: wrap;
+  padding: 5px;
+  text-transform: uppercase;
+}
+
+.title{
+  display: block;
+  width: 100%;
+  position: relative;
+  margin-bottom: 5px;
+}
+
+.title::before{
+  content: '*';
+  color: red;
+}
+
+.warningSpan{
+  display: inline;
+  width: 340px;
+  text-align: left;
+  padding-left: 5px;
+  font-size: 17px;
+  color: rgb(252, 14, 14);
+  text-transform: none;
+}
+
+.warningSpan--hidden{
+    display: none;
+}
+
+.formInput {
+  height: 40px;
+  width: 340px;
+  color: white;
+  font-size: 18px;
+  background-color: grey;
+  border: solid 2px rgb(240, 236, 236);
+  border-radius: 10px;
+  outline: none;
+  padding-left: 10px;
+  margin-bottom: 5px;
+}
+
+
+.wrongField{
+border: solid 2px red;
+color: red;
+}
+
+.rightInput {
+  color: green;
+  border: solid 2px green;
+}
+
+.placeholderWrong{
+  color: red;
+}
+
+.placeholderRight{
+  color: green;
+}
+
+.btnWrapper{
+  padding: 10px;
+  display: flex;
+  justify-content: center;
+  background-color: grey;
+  margin-bottom: 20px;
+}
+
+.okButton{
+  margin-right: 20px;
+  background-color: green;
+  color: white;
+  border-radius: 5px;
+}
+
+.cancelButton{
+  margin-right: 20px;
+  background-color: rgb(248, 15, 15);
+  color: white;
+  border-radius: 5px;
+}
+.cancelButton , .okButton {
+  font-size: 25px;
+}
+
+
+
+
+
 
 
 

+ 462 - 1
javascript/hw.js

@@ -1,2 +1,463 @@
 'use strict';
-console.log('hello');
+
+function Password(parent, open, onChange, onOpenChange) {
+	const signInForm = document.createElement('form');
+	signInForm.classList.add('signInForm');
+
+	const loginInput = document.createElement('input');
+	loginInput.classList.add('loginInput');
+	loginInput.setAttribute('type', 'text');
+	loginInput.setAttribute('placeholder', 'Write down yor login');
+
+	const handelLoginAndPassword = function () {
+		this.setValue({
+			login: loginInput.value,
+			password: passwordInput.value,
+			confirmPassword: confirmPasswordInput.value,
+		});
+		const { login, password, confirmPassword } = this.getValue();
+		this.onChange({ login, password, confirmPassword });
+		if (login && password && password === confirmPassword) {
+			btnSubmit.classList.replace('btnSubmit__disable', 'btnSubmit');
+		} else if (
+			login &&
+			password &&
+			confirmPasswordInput.classList.contains('hiddenInput')
+		) {
+			btnSubmit.classList.replace('btnSubmit__disable', 'btnSubmit');
+		} else {
+			btnSubmit.classList.replace('btnSubmit', 'btnSubmit__disable');
+		}
+	};
+
+	loginInput.addEventListener('input', handelLoginAndPassword.bind(this));
+
+	const passwordInput = document.createElement('input');
+	passwordInput.classList.add('passwordInput');
+	passwordInput.setAttribute('placeholder', 'Write down yor password *');
+	passwordInput.setAttribute('type', open ? 'password' : 'text');
+
+	passwordInput.addEventListener('input', handelLoginAndPassword.bind(this));
+
+	const confirmPasswordInput = document.createElement('input');
+	confirmPasswordInput.classList.add('confirmPasswordInput');
+	!open && confirmPasswordInput.classList.add('hiddenInput');
+	confirmPasswordInput.setAttribute('placeholder', 'Confirm password');
+	confirmPasswordInput.setAttribute('type', 'password');
+
+	confirmPasswordInput.addEventListener(
+		'input',
+		handelLoginAndPassword.bind(this)
+	);
+
+	const labelCheckBox = document.createElement('label');
+	labelCheckBox.classList.add('labelCheckBox');
+	labelCheckBox.textContent = 'Hide password';
+	const checkBox = document.createElement('input');
+	checkBox.textContent = 'Show password';
+	checkBox.classList.add('checkBox');
+	checkBox.setAttribute('type', 'checkbox');
+
+	const handelTogglePassword = function () {
+		this.setOpen(!this.getOpen());
+		this.onChange(this.getOpen());
+		if (passwordInput.type === 'password') {
+			return confirmPasswordInput.classList.remove('hiddenInput');
+		}
+		confirmPasswordInput.value = '';
+		confirmPasswordInput.classList.add('hiddenInput');
+	};
+
+	checkBox.addEventListener('click', handelTogglePassword.bind(this));
+
+	labelCheckBox.append(checkBox);
+
+	const btnSubmit = document.createElement('button');
+	btnSubmit.textContent = 'Submit';
+	btnSubmit.classList.add('btnSubmit__disable');
+	btnSubmit.setAttribute('type', 'button');
+
+	const handelSubmit = function () {
+		btnSubmit.classList.replace('btnSubmit', 'btnSubmit__disable');
+		loginInput.value = '';
+		passwordInput.value = '';
+		confirmPasswordInput.value = '';
+	};
+
+	btnSubmit.addEventListener('click', handelSubmit.bind(this));
+
+	signInForm.append(
+		loginInput,
+		passwordInput,
+		confirmPasswordInput,
+		labelCheckBox,
+		btnSubmit
+	);
+
+	this.parent = parent.append(signInForm);
+	this.open = open;
+	this.value = { login: '', password: '', confirmPassword: '' };
+	this.onChange = onChange;
+	this.onOpenChange = onOpenChange;
+
+	this.setValue = function (value) {
+		this.value = { ...this.value, ...value };
+	};
+	this.getValue = function () {
+		return this.value;
+	};
+	this.setOpen = function (flag) {
+		passwordInput.setAttribute('type', flag ? 'password' : 'text');
+		this.open = flag;
+	};
+	this.getOpen = function () {
+		return this.open;
+	};
+}
+
+//Password // LoginForm // Password Verify // are done in code above!!!
+
+const passwordFistInstance = new Password(
+	document.body,
+	true,
+	() => {},
+	() => {}
+);
+
+passwordFistInstance.onChange = (value) => console.log(value, 'onChange');
+passwordFistInstance.onOpenChange = (open) => console.log(open, 'onOpenChange');
+
+passwordFistInstance.setValue({ login: 'qwerty' });
+passwordFistInstance.setValue({ password: 'qwerty1231' });
+console.log(passwordFistInstance.getValue());
+passwordFistInstance.setOpen(false);
+console.log(passwordFistInstance.getOpen());
+
+// class Password {
+// 	constructor(parent, open) {
+// 		this.parent = parent;
+// 		this.open = open;
+// 		this.value;
+// 	}
+
+// 	setValue(value) {
+// 		this.value = value;
+// 	}
+// 	get getValue() {
+// 		return this.value;
+// 	}
+// 	setOpen(flag) {
+// 		this.open = flag;
+// 	}
+// 	get getOpen() {
+// 		return this.open;
+// 	}
+// 	onChange(cb) {
+// 		cb(this.value);
+// 	}
+// 	tonOpenChange(cb) {
+// 		cb(this.open);
+// 	}
+// }
+
+// const passwordInClass = new Password(document.body, true);
+// passwordInClass.setValue('Hello Black Belt');
+// console.log(passwordInClass.getValue);
+
+// LoginForm Constructor // are done in code above!!! just for understanding how works classes
+
+//Form
+
+function Form(el, data, okCallback, cancelCallback) {
+	this.okCallback = okCallback;
+	this.cancelCallback = cancelCallback;
+	this.defaultData;
+	this.data = data;
+
+	if (!this.defaultData) this.defaultData = { ...this.data };
+	const inputCreators = {
+		placeholder(key, value, handelInput, type, event) {
+			const placeholder = document.createElement('placeholder');
+			placeholder.classList.add('placeholderForm');
+			const input = document.createElement('input');
+			const title = document.createElement('span');
+			title.textContent = key;
+
+			if (validators[key]) {
+				title.classList.add('title');
+				input.setAttribute('required', '');
+			}
+			input.classList.add('formInput');
+			input.type = type;
+			input.name = key;
+
+			if (type === 'checkbox') {
+				input['checked'] = value;
+			} else if (type === 'datetime-local') {
+				value = new Date(value).toISOString().slice(0, -8);
+			}
+			input.value = value;
+
+			input.addEventListener(event, handelInput.bind(this));
+			const warningSpan = document.createElement('span');
+			warningSpan.classList.add('warningSpan', 'warningSpan--hidden');
+
+			placeholder.append(title, input, warningSpan);
+
+			return placeholder;
+		},
+		string(key, value, handelInput) {
+			if (value === '*') {
+				return inputCreators.placeholder(
+					key,
+					'',
+					handelInput,
+					'password',
+					'input'
+				);
+			} else {
+				return inputCreators.placeholder(
+					key,
+					value,
+					handelInput,
+					'text',
+					'input'
+				);
+			}
+		},
+		boolean(key, value, handelInput) {
+			return inputCreators.placeholder(
+				key,
+				value,
+				handelInput,
+				'checkbox',
+				'input'
+			);
+		},
+		object(key, value, handelInput) {
+			return inputCreators.placeholder(
+				key,
+				value,
+				handelInput,
+				'datetime-local',
+				'input'
+			);
+		},
+	};
+
+	const validators = {
+		validate(adjust, value, key, input, placeholder, err) {
+			const span = placeholder.children[2];
+
+			if (adjust(value)) {
+				span.classList.remove('warningSpan--hidden');
+				span.textContent = err;
+				placeholder.classList.add('placeholderWrong');
+				placeholder.classList.remove('placeholderRight');
+				input.classList.add('wrongField');
+				input.classList.remove('rightInput');
+				data[key] = value;
+				return false;
+			} else {
+				span.classList.add('warningSpan--hidden');
+				placeholder.classList.add('placeholderRight');
+				placeholder.classList.remove('placeholderWrong');
+				input.classList.add('rightInput');
+				input.classList.remove('wrongField');
+				data[key] = value;
+				return true;
+			}
+		},
+
+		name(value, key, input, placeholder) {
+			return validators.validate(
+				(isTrue) => isTrue.length < 6,
+				value,
+				key,
+				input,
+				placeholder,
+				'Name has to be at least 6 characters!'
+			);
+		},
+		surname(value, key, input, placeholder) {
+			return validators.validate(
+				() => false,
+				value,
+				key,
+				input,
+				placeholder,
+				'Name has to be at least 6 characters!'
+			);
+		},
+		married(value, key, input, placeholder) {
+			return validators.validate(
+				(isTrue) => (isTrue === true || isTrue === false ? true : false),
+				value,
+				key,
+				input,
+				placeholder,
+				'Married has to checked!'
+			);
+		},
+		birthday(value, key, input, placeholder) {
+			return validators.validate(
+				() => (value.length === 16 ? false : true),
+				value,
+				key,
+				input,
+				placeholder,
+				'Birthday is required!'
+			);
+		},
+		password(value, key, input, placeholder) {
+			return validators.validate(
+				() => (value.length >= 8 ? false : true),
+				value,
+				key,
+				input,
+				placeholder,
+				'Password length min 8!'
+			);
+		},
+		confirmPassword(value, key, input, placeholder) {
+			return validators.validate(
+				() => (value === data['password'] ? false : true),
+				value,
+				key,
+				input,
+				placeholder,
+				'Password have to be the same *PASSWORD field'
+			);
+		},
+	};
+
+	const form = document.createElement('form');
+	form.classList.add('formWrapper');
+
+	const isCheckedLength = Object.keys(this.data).reduce((acc, key, i) => {
+		if (validators[key]) return acc + 1;
+		return acc;
+	}, 0);
+
+	let isChecked = [];
+
+	Object.entries(this.data).forEach(([key, value], i) => {
+		const handelInput = function () {
+			const input = placeholder.children[1];
+			if (validators[key]) {
+				isChecked[i] = validators[key](input.value, key, input, placeholder);
+			} else {
+				data[key] = input.value;
+			}
+		};
+
+		const placeholder = inputCreators[typeof value](
+			key,
+			value,
+			handelInput.bind(this)
+		);
+
+		form.append(placeholder);
+	});
+
+	const btnWrapper = document.createElement('div');
+	btnWrapper.classList.add('btnWrapper');
+	const okButton = document.createElement('button');
+	okButton.classList.add('okButton');
+	okButton.innerHTML = 'OK';
+
+	const cancelButton = document.createElement('button');
+	cancelButton.classList.add('cancelButton');
+	cancelButton.innerHTML = 'Cancel';
+	btnWrapper.append(okButton, cancelButton);
+
+	el.append(form, btnWrapper);
+
+	okButton.onclick = () => {
+		if (isChecked.includes(false) || isCheckedLength !== isChecked.length) {
+			console.log('Not filed some inputs or do not passed validation');
+		} else {
+			localStorage.setItem('data', JSON.stringify(this.data));
+			okCallback(this.data);
+		}
+	};
+
+	cancelButton.onclick = () => {
+		isChecked = Object.keys(this.data).map(() => false);
+		data = { ...this.defaultData };
+		this.data = { ...data };
+		for (let i = 0; i < form.children.length; i++) {
+			const placeholder = form.children[i];
+			placeholder.classList.remove('placeholderWrong');
+			placeholder.classList.remove('placeholderRight');
+			const [, input, warn] = placeholder.children;
+			warn.classList.add('warningSpan--hidden');
+			input.classList.remove('wrongField');
+			input.classList.remove('rightInput');
+			if (this.data[input.name] === '*') {
+				input.value = '';
+			} else if (input.type === 'datetime-local') {
+				input.value = new Date(this.data[input.name])
+					.toISOString()
+					.slice(0, -8);
+			} else {
+				input.value = this.data[input.name];
+			}
+		}
+		cancelCallback(this.data);
+	};
+}
+
+const cachedFetchStarWars = async () => {
+	const lc = await localStorage.getItem('data');
+	if (lc) return JSON.parse(lc);
+	const data = await fetch('https://swapi.dev/api/people/1/')
+		.then((res) => res.json())
+		.then((data) => {
+			const newData = {};
+			for (const key in data) {
+				if (typeof data[key] === 'string') newData[key] = data[key];
+			}
+			return newData;
+		})
+		.catch((e) => console.log(e));
+	return data;
+};
+
+const data = await cachedFetchStarWars();
+
+const formOne = new Form(
+	document.body,
+	{
+		name: 'Anakin',
+		surname: 'Skywalker',
+		married: true,
+		birthday: new Date(new Date().getTime() - 86400000 * 30 * 365),
+		password: '*',
+		confirmPassword: '*',
+	},
+	(data) => console.log(data, 'ok , it is updated object after fielding form'),
+	(data) =>
+		console.log(
+			data,
+			'ok , it is base  object and form is reset for base settings'
+		)
+);
+
+const formTwo = new Form(
+	document.body,
+	{
+		...data,
+	},
+	(data) => console.log(data, 'ok , it is updated object after fielding form'),
+	(data) =>
+		console.log(
+			data,
+			'ok , it is base  object and form is reset for base settings'
+		),
+	'formTwo'
+);
+
+// localStorage.userName
+// 	? alert(`Your name is ${localStorage.userName}`)
+// 	: (localStorage.userName = prompt('What is your name?'));