'use strict'; 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(true); 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 }; this.validators = { validate(adjust, value, key, input, placeholder, err) { const title = placeholder.children[0]; const span = placeholder.children[2]; if (!input.required) { title.classList.add('title'); input.setAttribute('required', ''); } 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; } }, married(value, key, input, placeholder) { return this.validate( (isTrue) => (isTrue === true || isTrue === false ? true : false), value, key, input, placeholder, 'Married has to checked!' ); }, birthday(value, key, input, placeholder) { return this.validate( () => (value.length === 16 ? false : true), value, key, input, placeholder, 'Birthday is required!' ); }, password(value, key, input, placeholder) { return this.validate( () => (value.length >= 8 ? false : true), value, key, input, placeholder, 'Password length min 8!' ); }, confirmPassword(value, key, input, placeholder) { return this.validate( () => (value === data['password'] ? false : true), value, key, input, placeholder, 'Password have to be the same *PASSWORD field' ); }, }; const inputCreators = { placeholder(key, value, handelInput, type, event, validators) { 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, validators) { const dataTime = new Date(value); if (dataTime.getDate()) return inputCreators.object(key, value, handelInput, validators); if (value === '*') { return inputCreators.placeholder( key, '', handelInput, 'password', 'input', validators ); } else { return inputCreators.placeholder( key, value, handelInput, 'text', 'input', validators ); } }, boolean(key, value, handelInput, validators) { return inputCreators.placeholder( key, value, handelInput, 'checkbox', 'input', validators ); }, object(key, value, handelInput, validators) { return inputCreators.placeholder( key, value, handelInput, 'datetime-local', 'input', validators ); }, }; const form = document.createElement('form'); form.classList.add('formWrapper'); let isChecked = []; Object.entries(this.data).forEach(([key, value], i) => { const handelInput = function () { const input = placeholder.children[1]; if (this.validators[key]) { isChecked[i] = this.validators[key]( input.value, key, input, placeholder ); } else { data[key] = input.value; } }; const placeholder = inputCreators[typeof value]( key, value, handelInput.bind(this), this.validators ); 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 = () => { const isCheckedLength = Object.keys(this.data).reduce((acc, key, i) => { if (this.validators[key]) return acc + 1; return acc; }, 0); if (isChecked.includes(false) || isCheckedLength !== isChecked.length) { console.log('Not filed some inputs or do not passed validation'); } else { this.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]; } } this.cancelCallback(this.data); }; } const cachedFetchStarWars = async () => { const lc = await localStorage.getItem('data'); if (lc) return JSON.parse(lc); const data = await fetch('https://swapi.py4e.com/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' ) ); formOne.okCallback = function (data) { localStorage.setItem('data', JSON.stringify(data)); }; formOne.cancelCallback = function (data) { localStorage.setItem('data', JSON.stringify(data)); }; formOne.validators.name = function (value, key, input, placeholder) { return this.validate( (isTrue) => isTrue.length < 6, value, key, input, placeholder, 'Name has to be at least 6 characters!' ); }; formOne.validators.surname = function (value, key, input, placeholder) { return this.validate( (isTrue) => isTrue.length < 8, value, key, input, placeholder, 'Name has to be at least 8 characters!' ); }; 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' ); formTwo.okCallback = function (data) { localStorage.setItem('data', JSON.stringify(data)); }; formTwo.cancelCallback = function (data) { localStorage.setItem('data', JSON.stringify(data)); }; formTwo.validators.name = function (value, key, input, placeholder) { return this.validate( (isTrue) => isTrue.length < 8, value, key, input, placeholder, 'Name has to be at least 8 characters!' ); }; formTwo.validators.height = function (value, key, input, placeholder) { return this.validate( (isTrue) => isTrue.length < 10, value, key, input, placeholder, 'Name has to be at least 10 characters!' ); }; // localStorage.userName // ? alert(`Your name is ${localStorage.userName}`) // : (localStorage.userName = prompt('What is your name?'));