/*Person Constructor Переделайте задание createPerson на функцию конструктор Person. const a = new Person("Вася", "Пупкин") const b = new Person("Анна", "Иванова") const c = new Person("Елизавета", "Петрова") console.log(a.getFullName()) //Вася Пупкин a.fatherName = 'Иванович' //Вася Иванович Пупкин console.log(b.getFullName()) //Анна Иванова Для этого методы и свойства заносите не в создаваемый объект, а в this внутри конструктора.*/ { const a = new Person("Вася", "Пупкин") const b = new Person("Анна", "Иванова") const c = new Person("Елизавета", "Петрова") console.log(a.getFullName()) //Вася Пупкин a.fatherName = 'Иванович' //Вася Иванович Пупкин console.log(b.getFullName()) //Анна Иванова function Person(name, surname) { this.name = name, this.surname = surname, this.getFullName = () => `${this.name} ${this.fatherName || ""} ${this.surname}` } } /*Person Prototype Переделайте предыдущее задание, вынеся методы в прототип. Для этого вместо присвоения в this занесите их в объект Person.prototype. После этой переделки все должно работать по старому: const a = createPerson("Вася", "Пупкин") const b = createPerson("Анна", "Иванова") const c = createPerson("Елизавета", "Петрова") console.log(a.getFullName()) //Вася Пупкин a.fatherName = 'Иванович' //Вася Иванович Пупкин console.log(b.getFullName()) //Анна Иванова*/ { const a = new Person("Вася", "Пупкин") const b = new Person("Анна", "Иванова") const c = new Person("Елизавета", "Петрова") console.log(a.getFullName()) //Вася Пупкин a.fatherName = 'Иванович' //Вася Иванович Пупкин console.log(a.getFullName()) console.log(b.getFullName()) //Анна Иванова function Person(name, surname) { Person.prototype.getFullName = function () { return `${this.name} ${this.fatherName || ""} ${this.surname}` } this.name = name this.surname = surname } } /*Store (код работает в index.html) Переделайте функцию createStore (та, которая хранилище Redux) на конструктор Store. Прототип не используйте; оставьте переменные state, cbs и reducer замкнутыми. Соответственно методы subscribe, dispatch и getState должны быть объявлены внутри функции-конструктора и не могут быть в прототипе. Проверьте переделанный конструктор на вашем ДЗ по ларьку;*/ { function reducer(state, { type, productName, productQuantity, summ }) { //объект action деструктуризируется на три переменных if (!state) { //начальная уборка в ларьке: return { пиво: { quantity: 100, price: 30, }, чипсы: { quantity: 100, price: 52, }, сиги: { quantity: 100, price: 89, }, касса: 0 } } if (type === 'КУПИТЬ' && productQuantity <= state[productName].quantity && summ >= state[productName].price * productQuantity) { //если тип action - КУПИТЬ, то: return { ...state, //берем все что было из ассортимента [productName]: { quantity: state[productName].quantity - productQuantity, price: state[productName].price }, касса: state.касса + state[productName].price * productQuantity //и уменьшаем то, что покупается на количество } } return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть } /*Store (код работает в index.html) Переделайте функцию createStore (та, которая хранилище Redux) на конструктор Store. Прототип не используйте; оставьте переменные state, cbs и reducer замкнутыми. Соответственно методы subscribe, dispatch и getState должны быть объявлены внутри функции-конструктора и не могут быть в прототипе. Проверьте переделанный конструктор на вашем ДЗ по ларьку;*/ function createStore(reducer) { let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined let cbs = [] //массив подписчиков this.getState = () => state //функция, возвращающая переменную из замыкания + добавление функции getState в результирующий объект this.dispatch = action => { const newState = reducer(state, action) //пробуем запустить редьюсер if (newState !== state) { //проверяем, смог ли редьюсер обработать action state = newState //если смог, то обновляем state for (let cb of cbs) cb() //и запускаем подписчиков } } this.subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве () => cbs = cbs.filter(c => c !== cb)) //добавление subscribe в объект } function actionCreator(type, productName, productQuantity, summ) { return { type, productName, productQuantity, summ } } const store = new createStore(reducer) myState = store.getState() const showcase = document.createElement('section') document.body.append(showcase) showcase.classList.add('showcase') const orderSection = document.createElement('section') document.body.append(orderSection) orderSection.classList.add('orderSection') const orderSelectProd = document.createElement('select') orderSection.append(orderSelectProd) const orderInputQuantity = document.createElement('input') orderInputQuantity.type = 'number' orderInputQuantity.min = '0' orderSection.append(orderInputQuantity) const orderInputQuantityName = document.createElement('div') orderInputQuantity.before(orderInputQuantityName) orderInputQuantityName.innerText = 'количество товара:' const orderSendMoney = document.createElement('input') orderSendMoney.type = 'number' orderSendMoney.min = '0' orderSection.append(orderSendMoney) const orderSendMoneyName = document.createElement('div') orderSendMoney.before(orderSendMoneyName) orderSendMoneyName.innerText = 'сумма:' const orderBuyButton = document.createElement('input') orderBuyButton.type = 'button' orderBuyButton.value = 'КУПИТЬ' orderSection.append(orderBuyButton) orderBuyButton.onclick = () => { store.dispatch(actionCreator(orderBuyButton.value, orderSelectProd.value, +orderInputQuantity.value, +orderSendMoney.value)) } for (const elemProduct in store.getState()) { if (elemProduct === 'касса') continue const productCard = document.createElement('div') const productName = document.createElement('h2') const productPrice = document.createElement('div') const productQuantity = document.createElement('div') productCard.append(productName) productCard.append(productQuantity) productCard.append(productPrice) showcase.append(productCard) productCard.classList.add('productCard') productName.classList.add('productName') productPrice.classList.add('productPrice') productQuantity.classList.add('productQuantity') productName.innerText = elemProduct productPrice.innerText = store.getState()[elemProduct].price + ' грн' productQuantity.innerText = store.getState()[elemProduct].quantity + ' шт\nв наличии' const selectProdOption = document.createElement('option') selectProdOption.value = selectProdOption.innerText = elemProduct orderSelectProd.append(selectProdOption) const productPriceUnsubscribe = store.subscribe(() => { productPrice.innerText = store.getState()[elemProduct].price + ' грн' }) const productQuantityUnsubscribe = store.subscribe(() => { productQuantity.innerText = store.getState()[elemProduct].quantity + ' шт\nв наличии' }) } } /*Password*/ { function Password(parent, open) { const inputPass = document.createElement('input') parent.append(inputPass) const checkboxPass = document.createElement('input') checkboxPass.type = 'checkbox' parent.append(checkboxPass) this.setValue = (value) => { inputPass.value = value if (typeof this.onChange === 'function') this.onChange(this.getValue()) // запускается по событию oninput в поле ввода, передает текст в колбэк } //задает значение this.getValue = () => inputPass.value //читает значение this.setOpen = (open) => { if (open) { checkboxPass.checked = true inputPass.type = "text" } if (!open) { checkboxPass.checked = false inputPass.type = "password" } if (typeof this.onOpenChange === 'function') this.onOpenChange(this.getOpen()) // запускается по изменению состояния открытости пароля } //задает открытость текста в поле ввода this.getOpen = () => checkboxPass.checked //читает открытость текста в поле ввода this.setOpen(open) inputPass.oninput = () => this.setValue(this.getValue()) checkboxPass.oninput = () => this.setOpen(this.getOpen()) } let p = new Password(document.body, true) p.onChange = data => console.log(data) p.onOpenChange = open => console.log(open) p.setValue('qwerty') console.log(p.getValue()) p.setOpen(false) console.log(p.getOpen()) } /* Напишите функцию конструктор Password, которая будет в родительском элементе создавать поле ввода для пароля и кнопку/иконку/чекбокс, который будет переключать режим просмотра пароля в поле ввода. (видимый пароль или нет, input type='text' или же input type='password') Параметры: parent - родительский элемент open - стартовое состояние Методы: setValue/getValue - задают/читают значения setOpen/getOpen - задают/читают открытость текста в поле ввода Колбэки (функции обратного вызова, который возможно, будут заданы снаружи конструктора): onChange - запускается по событию oninput в поле ввода, передает текст в колбэк onOpenChange - запускается по изменению состояния открытости пароля */ /* LoginForm С помощью предыдущего кода Password сделайте форму логина, кнопка в которой будет активна только если и login и пароль не пусты. "С помощью предыдущего кода" значит что в коде формы логина вы используете объект, сконструированный конструктором Password - const password = new Password(........) */ { function Password(parent, open) { const inputPass = document.createElement('input') parent.append(inputPass) const checkboxPass = document.createElement('input') checkboxPass.type = 'checkbox' parent.append(checkboxPass) this.setValue = (value) => { inputPass.value = value if (typeof this.onChange === 'function') this.onChange(this.getValue()) // запускается по событию oninput в поле ввода, передает текст в колбэк } //задает значение this.getValue = () => inputPass.value //читает значение this.setOpen = (open) => { if (open) { checkboxPass.checked = true inputPass.type = "text" } if (!open) { checkboxPass.checked = false inputPass.type = "password" } if (typeof this.onOpenChange === 'function') this.onOpenChange(this.getOpen()) // запускается по изменению состояния открытости пароля } //задает открытость текста в поле ввода this.getOpen = () => checkboxPass.checked //читает открытость текста в поле ввода this.setOpen(open) inputPass.oninput = () => this.setValue(this.getValue()) checkboxPass.oninput = () => this.setOpen(this.getOpen()) } const LoginForm = document.createElement('div') document.body.append(LoginForm) const inputLogin = document.createElement('input') LoginForm.append(inputLogin) let p = new Password(LoginForm, false) const inputButton = document.createElement('input') inputButton.type = 'button' inputButton.value = 'войти' LoginForm.append(inputButton) inputButton.disabled = true p.onChange = () => checkButtonDisabled() inputLogin.oninput = () => checkButtonDisabled() function checkButtonDisabled () { if (p.getValue() && inputLogin.value) inputButton.disabled = false else inputButton.disabled = true } } /*LoginForm Constructor оформите предыдущую задачу как функцию-конструктор. Продумайте и предусмотрите геттеры, сеттеры и колбэки.*/ { function LoginForm(parent, passOpenDefault){ function Password(parent, open) { const inputPass = document.createElement('input') parent.append(inputPass) const checkboxPass = document.createElement('input') checkboxPass.type = 'checkbox' parent.append(checkboxPass) this.setValue = (value) => { inputPass.value = value if (typeof this.onChange === 'function') this.onChange(this.getValue()) // запускается по событию oninput в поле ввода, передает текст в колбэк } //задает значение this.getValue = () => inputPass.value //читает значение this.setOpen = (open) => { if (open) { checkboxPass.checked = true inputPass.type = "text" } if (!open) { checkboxPass.checked = false inputPass.type = "password" } if (typeof this.onOpenChange === 'function') this.onOpenChange(this.getOpen()) // запускается по изменению состояния открытости пароля } //задает открытость текста в поле ввода this.getOpen = () => checkboxPass.checked //читает открытость текста в поле ввода this.setOpen(open) inputPass.oninput = () => this.setValue(this.getValue()) checkboxPass.oninput = () => this.setOpen(this.getOpen()) } const LoginForm = document.createElement('div') parent.append(LoginForm) const inputLogin = document.createElement('input') LoginForm.append(inputLogin) let p = new Password(LoginForm, passOpenDefault) const inputButton = document.createElement('input') inputButton.type = 'button' inputButton.value = 'войти' LoginForm.append(inputButton) inputButton.disabled = true p.onChange = () => checkButtonDisabled() inputLogin.oninput = () => checkButtonDisabled() function checkButtonDisabled () { if (p.getValue() && inputLogin.value) inputButton.disabled = false else inputButton.disabled = true } this.getLogin = () => inputLogin.value this.setLogin = (value) => { inputLogin.value = value checkButtonDisabled() } this.getPass = () => p.getValue() this.setPass = (value) => { p.setValue(value) checkButtonDisabled() } inputButton.onclick = () => { if (typeof this.inputButtonOnclick === 'function') this.inputButtonOnclick() //функция при нажатии на кнопку войти } } const t = new LoginForm (document.body, false) t.setPass("1111") t.setLogin("Абырвалг") t.inputButtonOnclick = () => alert ('заходи - не бойся, выходи - не плачь') } /*Password Verify С помощью Password сделайте пару инпутов, которые проверяют введеный пароль (в двух полях ввода) на совпадение. Подсвечивайте поля красным цветом/бордером когда пароли не совпадают При открытом пароле в первом поле ввода (которое реализуется с помощью объекта класса Password второе поле вводы должно пропадать с экрана Таким образом: Когда Password в скрытом режиме - появляется второй инпут () с паролем в скрытом режиме Когда Password в открытом режиме - второй инпут пропадает*/ { function Password(parent, open) { const inputPass = document.createElement('input') parent.append(inputPass) const checkboxPass = document.createElement('input') checkboxPass.type = 'checkbox' parent.append(checkboxPass) this.setValue = (value) => { inputPass.value = value if (typeof this.onChange === 'function') this.onChange(this.getValue()) // запускается по событию oninput в поле ввода, передает текст в колбэк } //задает значение this.getValue = () => inputPass.value //читает значение this.setOpen = (open) => { if (open) { checkboxPass.checked = true inputPass.type = "text" } if (!open) { checkboxPass.checked = false inputPass.type = "password" } if (typeof this.onOpenChange === 'function') this.onOpenChange(this.getOpen()) // запускается по изменению состояния открытости пароля } //задает открытость текста в поле ввода this.getOpen = () => checkboxPass.checked //читает открытость текста в поле ввода this.getinputPass = () => inputPass this.setOpen(open) inputPass.oninput = () => this.setValue(this.getValue()) checkboxPass.oninput = () => this.setOpen(this.getOpen()) } const pass1 = document.createElement('div') document.body.append(pass1) const pass2 = document.createElement('div') document.body.append(pass2) const p1 = new Password (pass1, false) const p2 = new Password (pass2, false) Password.prototype.onChange = function () { passInputEqalityCheck(p1, p2) } const passInputEqalityCheck = (pass1, pass2) => { if ( pass1.getValue() !== pass2.getValue() ) { pass1.getinputPass().style.borderColor = 'red' pass2.getinputPass().style.borderColor = 'red' } else { pass1.getinputPass().style.borderColor = 'green' pass2.getinputPass().style.borderColor = 'green' } } const pass2Open = (pass1GetOpen) => { if (pass1GetOpen === true) pass2.style.display = 'none' else pass2.style.display = 'block' } p1.onOpenChange = function () { pass2Open (this.getOpen() ) } }