Пытаюсь написать контрол, который проверяет пароль. По мере ввода текста под инпутом должны будут отмечаться надписи, для которых условия выполнены. При этом пользователь не может отправить форму, пока пароль не соответствует всем критериям.
Я не могу понять, как реализовать метод isPasswordValid() класса passwordChecker, который должен возвращать true, если все ивены, повещенные на поле с паролем, вернули true при последнем срабатывании. То есть как мне "опросить" эти ивенты или сохранить их результат в контексте инстанса passwordChecker?
Первое, что пришло в голову, это заготовить переменные в конструкторе класса passwordChecker для каждой проверки. Но значения этих переменных я не могу менять из функций проверки, т.к. они вызываются коллбеками в методе stream другого класса.
Смотреть в сторону bind или мой подход в корне не верный?
Весь JS-код:
class passwordControl {
constructor(el) {
this.el = el;
this.toggleContainer = this.el.querySelector('.toggle-password-mask');
this.inputElement = this.el.querySelector('input');
this.closedEye = 'M11.949 2.578L13.527 1A1.041 1.041 0 1115 2.473L2.473 15A1.041 1.041 0 111 13.527l1.409-1.409C.823 10.566 0 8.707 0 8c0-1.302 2.698-6.512 8-6.512 1.536 0 2.853.437 3.949 1.09zm2.573 2.314C15.505 6.167 16 7.442 16 8c0 1.302-2.791 6.512-8 6.512a7.452 7.452 0 01-2.626-.472l2.331-2.331a3.731 3.731 0 004.004-4.004l2.813-2.813zm-4.735-.153A3.688 3.688 0 008 4.279 3.731 3.731 0 004.279 8c0 .647.167 1.256.46 1.787l1.319-1.318A1.931 1.931 0 016 8c0-1.143.857-2 2-2 .163 0 .321.019.471.056l1.316-1.317z';
this.openedEye = 'M8 1.488c-5.302 0-8 5.21-8 6.512 0 1.302 2.791 6.512 8 6.512S16 9.302 16 8c0-1.302-2.698-6.512-8-6.512zm0 10.233A3.731 3.731 0 014.279 8 3.731 3.731 0 018 4.279 3.731 3.731 0 0111.721 8 3.731 3.731 0 018 11.721zM8 6c1.143 0 2 .953 2 2 0 1.143-.952 2-2 2-1.143 0-2-.952-2-2 0-1.142.857-2 2-2z';
this.toggleContainer.addEventListener('click', () => {
this.changeMask();
});
this.isHidden = true;
}
changeMask() {
const svgPath = this.el.querySelector('path');
if (this.isHidden) {
svgPath.setAttribute('d', this.closedEye);
this.inputElement.setAttribute('type', 'text');
this.isHidden = false;
} else {
svgPath.setAttribute('d', this.openedEye);
this.inputElement.setAttribute('type', 'password');
this.isHidden = true;
}
}
stream(cb) {
this.inputElement.addEventListener('input', () => cb(this.inputElement.value));
}
}
class passwordChecker {
constructor(el, passwordControlInstance) {
this.el = el;
this.passwordControlInstance = passwordControlInstance;
function minLengthChecker(value) {
const minLength = 5;
// Здесь нужно менять флаг this.isMinLengthChecked
}
function upperCaseChecker(value) {
// Здесь аналогичная проверка
}
this.passwordControlInstance.stream(minLengthChecker);
this.passwordControlInstance.stream(upperCaseChecker);
}
isPasswordValid() {
// ???
}
}
// Контрол пароля
const userPasswordField = document.querySelector('.js-fieldName_userPassword');
const passwordControlInstance = new passwordControl(userPasswordField);
// Контрол чекинга пароля
const passwordCheckerControl = document.querySelector('.js-passwordChecker');
const passwordCheckerControlInstance = new passwordChecker(passwordCheckerControl, passwordControlInstance);
И HTML формы:
<h1 class="cell-title">Ваш пароль</h1>
<fieldset class="cell-form-step-1 grid-step1">
<div class="cell-step-1-message">
<p>Придумайте надежный пароль для входа в личный кабинет</p>
</div>
<div class="style-textbox cell-user-password js-fieldName_userPassword">
<input type="password" required>
<label>Пароль</label>
<div class="toggle-password-mask">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill-rule="evenodd"
d="M8 1.488c-5.302 0-8 5.21-8 6.512 0 1.302 2.791 6.512 8 6.512S16 9.302 16 8c0-1.302-2.698-6.512-8-6.512zm0 10.233A3.731 3.731 0 014.279 8 3.731 3.731 0 018 4.279 3.731 3.731 0 0111.721 8 3.731 3.731 0 018 11.721zM8 6c1.143 0 2 .953 2 2 0 1.143-.952 2-2 2-1.143 0-2-.952-2-2 0-1.142.857-2 2-2z">
</path>
</svg>
</div>
</div>
<div class="style-password-checker cell-password-checker js-passwordChecker">
<ul>
<li class="js-minLengthChecker">Минимум 8 символов</li>
<li class="js-upperCaseChecker">Хотя бы одна заглавная буква</li>
<li class="js-digitChecker">Хотя бы одно число</li>
<li class="js-specialCharChecker">Любой спец-символ</li>
</ul>
</div>
<button class="cell-btn-send js-btnSend" onclick="return false;" disabled>Создать аккаунт</button>
</fieldset>
<fieldset class="cell-form-step-fin grid-form-step-fin" hidden>
<div class="cell-fin-message">
Пароль установлен! Теперь вы можете использовать его для входа в личный кабинет.
</div>
<a href="/" class="cell-btn-link-to-auth">Перейти в почту</a>
</fieldset>
<fieldset class="cell-form-step-err grid-form-step-err" hidden>
<div class="cell-err-message"></div>
</fieldset>