HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/netwerkbrabant/netwerkbrabant.nl/resources/assets/js/kms/attributes/password.js
class PasswordController {
    /**
     * Validates password fields.
     * The password fields values wil be imploded with a pipe symbol
     *
     * @param passwordInputSelector The css selector for selecting the password input fields
     * @param wrapperSelector The css selector for the wrapper div / element that wraps the first and second input fields along the validation helper
     * @param passwordDontMatchErrorText string
     * @param saveButtonId The id of a save button that needs to be disabled when the passwords are not valid
     * @param minPasswordLength int
     * @param wrapperHasTitleAttributeAndErrorClass Must be set to true if the wrapper (selected with the wrapper selector) has the ability to have an error class and title attribute for displaying an error
     */
    constructor(passwordInputSelector, wrapperSelector, passwordDontMatchErrorText, saveButtonId, minPasswordLength = 6, wrapperHasTitleAttributeAndErrorClass = false) {
        this.wrapperHasTitleAttributeAndErrorClass = wrapperHasTitleAttributeAndErrorClass;
        this.wrapper = document.querySelector(wrapperSelector);
        this.saveButton = document.querySelector("#"+saveButtonId);

        this.firstPasswordInput = this.wrapper.querySelector('input[name=' + passwordInputSelector + '-1]');
        this.secondPasswordInput = this.wrapper.querySelector('input[name='+passwordInputSelector+ '-2]');
        this.realPasswordInput = this.wrapper.querySelector('input[name='+passwordInputSelector+ ']');

        this.validationMessageWrapperSelector = '.validationHelper';
        this.validationMessageWrapper = this.wrapper.querySelector(this.validationMessageWrapperSelector);

        this.minPasswordLength = minPasswordLength;

        //Used for validation
        this.letter = this.validationMessageWrapper.querySelector(".letter");
        this.capital = this.validationMessageWrapper.querySelector(".capital");
        this.number = this.validationMessageWrapper.querySelector(".number");
        this.length = this.validationMessageWrapper.querySelector(".length");
        this.match = this.validationMessageWrapper.querySelector(".match");
        // this.noPipe = document.querySelector(this.validationMessageWrapperSelector + " .noPipe");

        this.activateListeners(true);
    }

    /**
     * Activates listening for keyup events on the password fields to that the passwordChanged method is triggered
     *
     * @param state
     */
    activateListeners(state) {
        let self = this;
        let validationHelper = this.validationMessageWrapper;

        if (state) {
            this.firstPasswordInput.addEventListener('keyup',
                self.debounce(function () {
                    self.passwordChanged()
                }, 100)
            );

            this.secondPasswordInput.addEventListener('keyup',
                self.debounce(function () {
                    self.passwordChanged()
                }, 100)
            );

            this.firstPasswordInput.addEventListener('focus', function () {
                if (!validationHelper.classList.contains('active')) validationHelper.classList.add('active')
            });
            this.secondPasswordInput.addEventListener('focus', function () {
                if (!validationHelper.classList.contains('active')) validationHelper.classList.add('active')
            });

            this.firstPasswordInput.addEventListener('blur', function () {
                if (validationHelper.classList.contains('active')) validationHelper.classList.remove('active')
            });
            this.secondPasswordInput.addEventListener('blur', function () {
                if (validationHelper.classList.contains('active')) validationHelper.classList.remove('active')
            });
        } else {
            this.firstPasswordInput.removeEventListener('keyup', self.debounce);
            this.secondPasswordInput.removeEventListener('keyup', self.debounce);

            this.firstPasswordInput.removeEventListener('focus');
            this.secondPasswordInput.removeEventListener('focus');

            this.firstPasswordInput.removeEventListener('blur');
            this.secondPasswordInput.removeEventListener('blur');
        }
    }

    /**
     * Triggered when one of the password fields are changed and if the listeners for those fields are active
     */
    passwordChanged() {
        console.log('password changed');

        let value1 = this.firstPasswordInput.value;
        let value2 = this.secondPasswordInput.value;

        let valid = (this.validate(value1, value2));
        console.log(valid);

        if(valid) this.realPasswordInput.value = value2;
        else this.realPasswordInput.value = '';

        this.enableValidMessage(valid);
        this.enableSaveButton(valid);
        this.removeWrapperError();
    }

    enableValidMessage(enable)
    {
        let validationHelper = this.validationMessageWrapper;

        if(enable) {
            if(!validationHelper.classList.contains('valid')) validationHelper.classList.add('valid');
        } else {
            if(validationHelper.classList.contains('valid')) validationHelper.classList.remove('valid');
        }
    }

    enableSaveButton(enable)
    {
        console.log(enable);
        if(enable) {
            if(this.saveButton.classList.contains('disabled')) this.saveButton.classList.remove('disabled');
        } else {
            if(!this.saveButton.classList.contains('disabled')) this.saveButton.classList.add('disabled');
        }
    }

    /**
     * Removes the error that may be set on the wrapper
     */
    removeWrapperError()
    {
        if(!this.wrapperHasTitleAttributeAndErrorClass) return;

        if(this.wrapper.hasAttribute('title')) this.wrapper.setAttribute('title', '');
        if(this.wrapper.classList.contains('error')) this.wrapper.classList.remove('error');
    }

    /**
     * Validate two values and return true or false if respectively valid or not
     *
     * @param value1
     * @param value2
     * @returns {boolean}
     */
    validate(value1, value2)
    {
        let valid = true;

        // Validate lowercase letters
        let lowerCaseLetters = /[a-z]/g;
        if(value1.match(lowerCaseLetters)) {
            this.letter.classList.remove("invalid");
            this.letter.classList.add("valid");
        } else {
            this.letter.classList.remove("valid");
            this.letter.classList.add("invalid");
            valid = false;
        }

        // Validate capital letters
        let upperCaseLetters = /[A-Z]/g;
        if(value1.match(upperCaseLetters)) {
            this.capital.classList.remove("invalid");
            this.capital.classList.add("valid");
        } else {
            this.capital.classList.remove("valid");
            this.capital.classList.add("invalid");
            valid = false;
        }

        // Validate numbers
        let numbers = /[0-9]/g;
        if(value1.match(numbers)) {
            this.number.classList.remove("invalid");
            this.number.classList.add("valid");
        } else {
            this.number.classList.remove("valid");
            this.number.classList.add("invalid");
            valid = false;
        }

        // Validate numbers
        // let pipe = /\|/g;
        // if(value1.match(pipe)) {
        //     this.noPipe.classList.remove("valid");
        //     this.noPipe.classList.add("invalid");
        //     valid = false;
        // } else {
        //     this.noPipe.classList.remove("invalid");
        //     this.noPipe.classList.add("valid");
        // }

        // Validate length
        if(value1.length >= this.minPasswordLength) {
            this.length.classList.remove("invalid");
            this.length.classList.add("valid");
        } else {
            this.length.classList.remove("valid");
            this.length.classList.add("invalid");
            valid = false;
        }

        // Validate password match
        if(value1 === value2 && (value1 !== '' || value2 !== '')) {
            this.match.classList.remove("invalid");
            this.match.classList.add("valid");
        } else {
            this.match.classList.remove("valid");
            this.match.classList.add("invalid");
            valid = false;
        }

        return valid
    }


    /**
     * Triggers the function after the wait time (milliseconds) has expired and only
     * if the function is not triggered again before the wait time expired.
     *
     * @param func
     * @param wait
     * @param immediate
     * @returns {Function}
     */
    debounce(func, wait, immediate) {
        let timeout;

        return function() {
            let context = this, args = arguments;
            let later = function() {
                timeout = null;
                if (!immediate) func.apply(context, args);
            };
            let callNow = immediate && !timeout;
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
            if (callNow) func.apply(context, args);
        };
    };
}