Add controller and optimize view

This commit is contained in:
2023-08-30 16:37:01 +07:00
parent ae070ffc98
commit 7adff5b262
8 changed files with 200 additions and 116 deletions
+15
View File
@@ -0,0 +1,15 @@
import Controller from './controllers/controller';
import Service from './services/service';
import View from './views/view';
import 'regenerator-runtime/runtime';
import 'core-js/stable';
export default class App {
constructor() {
this.controller = new Controller(new Service(), new View());
}
start() {
this.controller.registerController.init();
}
}
@@ -0,0 +1,7 @@
import RegisterController from './registerController';
export default class Controller {
constructor(service, view) {
this.registerController = new RegisterController(service, view);
}
}
@@ -0,0 +1,46 @@
export default class RegisterController {
constructor(service, view) {
this.view = view;
this.service = service;
}
async controlRegister() {
try {
// Load spinner
this.view.registerView.toogleLoaderSpinner();
// Get data from form
const user = this.view.registerView.getDataFromForm();
// Save user
if (user) {
// Check user exist
const userExist = await this.service.userService.checkExistUserByEmail(
user.email,
);
if (userExist) {
throw Error('User is exists! Please try another email!');
} else {
await this.service.userService.saveUser(user);
// Show popup success
this.view.registerView.initRegisterSuccessPopup();
this.view.registerView.tooglePopupForm();
}
}
} catch (error) {
// Show popup error
this.view.registerView.initErrorPopup(error);
this.view.registerView.tooglePopupForm();
}
// Close spinner
this.view.registerView.toogleLoaderSpinner();
}
init() {
if (this.view.registerView.registerForm !== null) {
this.view.registerView.addHandlerForm(this.controlRegister.bind(this));
this.view.registerView.addHandlerInputFormChange();
}
}
}
+7
View File
@@ -0,0 +1,7 @@
import App from './app';
// Sure that scripts called after DOM loaded
document.addEventListener('DOMContentLoaded', () => {
const myApp = new App();
myApp.start();
});
@@ -0,0 +1,117 @@
import CommonView from './commonView';
import * as CONSTANT from '../constants/constant';
import { validatePassword } from '../helpers/helpers';
export default class CommonLoginRegisterView extends CommonView {
constructor() {
super();
this.parentElement = document.querySelector('.form');
this.messageDefault = CONSTANT.MESSAGE.ERROR_MESSAGE_DEFAULT;
this.inputField = document.querySelectorAll('.form__input');
}
/**
* Validate user input data
* @param {Object} account The account object with email, password, passwordConfirm field
* @returns {boolean} Return true if validate success and return false if validate not success
*/
validateForm(account) {
if (account.password === account.passwordConfirm) {
if (validatePassword(account.passwordConfirm)) {
return true;
}
this.showError(CONSTANT.MESSAGE.PASSWORD_NOT_STRONG);
return false;
}
this.showError(CONSTANT.MESSAGE.PASSWORD_NOT_MATCH);
return false;
}
/**
* Add event listener for form input
* @param {Function} handler The function need to be set event
*/
addHandlerForm(handler) {
this.parentElement.addEventListener('submit', (e) => {
e.preventDefault();
this.clearErrorMessage();
handler();
});
}
/**
* Show error style input password
*/
changeToStyleErrorInputPassword() {
// Index = 1 because it should skip email input field
for (let index = 1; index < this.inputField.length; index += 1) {
this.inputField[index].style.background = '#ffc3c3';
this.inputField[index].style.borderColor = '#ce1414';
}
}
/**
* Clear error style input password
*/
clearStyleErrorInputPassword() {
for (let index = 1; index < this.inputField.length; index += 1) {
this.inputField[index].style.background = '#f5f5f5';
this.inputField[index].style.borderColor = '#f5f5f5';
}
}
/**
* Reassign again to check error message element haved on page or not
*/
reassignVariableErrorMessage() {
this.errorMessage = document.querySelector('.form__error-message');
}
/**
* Clear error message at form
*/
clearErrorMessage() {
this.reassignVariableErrorMessage();
// If have error message on page, remove it
if (this.errorMessage) {
this.errorMessage.remove();
this.clearStyleErrorInputPassword();
}
}
/**
* Add event listener for input field at form
*/
addHandlerInputFormChange() {
this.parentElement.addEventListener('input', () => {
this.clearErrorMessage();
});
}
/**
* Show error message with error style input password.
* @param {string} message The error message you want show in form.
*/
showError(message) {
this.renderError(message);
this.changeToStyleErrorInputPassword();
}
/**
* Show error message in form
* @param {*} message The message will show in form
*/
renderError(message) {
const markup = `
<p class="form__error-message">${
!message ? this.messageDefault : message
}</p>
`;
document
.querySelector('.form__title')
.insertAdjacentHTML('afterend', markup);
}
}
@@ -1,21 +1,17 @@
import { validatePassword } from '../helpers/helpers'; import { TYPE_POPUP } from '../constants/constant';
import * as CONSTANT from '../constants/constant'; import CommonLoginRegisterView from './commonLoginRegisterView';
import CommonView from './commonView';
import User from '../models/userModel'; import User from '../models/userModel';
export default class RegisterView extends CommonView { export default class RegisterView extends CommonLoginRegisterView {
constructor() { constructor() {
super(); super();
this.parentElement = document.querySelector('.form'); this.registerForm = document.getElementById('registerForm');
this.inputField = document.querySelectorAll('.form__input');
this.messageDefault = CONSTANT.MESSAGE.ERROR_MESSAGE_DEFAULT;
} }
/** /**
* Get data from user input * Get data from user input
* @returns {Object || null} Return user object or null * @returns {Object || null} Return object or null
*/ */
getDataFromForm() { getDataFromForm() {
const { registerForm } = document.forms; const { registerForm } = document.forms;
@@ -33,99 +29,11 @@ export default class RegisterView extends CommonView {
return null; return null;
} }
/**
* Validate user input data
* @param {Object} account The account object with email, password, passwordConfirm field
* @returns {boolean} Return true if validate success and return false if validate not success
*/
validateForm(account) {
if (account.password === account.passwordConfirm) {
if (validatePassword(account.passwordConfirm)) {
return true;
}
this.showError(CONSTANT.MESSAGE.PASSWORD_NOT_STRONG);
return false;
}
this.showError(CONSTANT.MESSAGE.PASSWORD_NOT_MATCH);
return false;
}
/**
* Add event listener for form input
* @param {Function} handler The function need to be set event
*/
addHandlerForm(handler) {
this.parentElement.addEventListener('submit', (e) => {
e.preventDefault();
this.clearErrorMessage();
handler();
});
}
/**
* Show error style input password
*/
changeToStyleErrorInputPassword() {
// Index = 1 because it should skip email input field
for (let index = 1; index < this.inputField.length; index += 1) {
this.inputField[index].style.background = '#ffc3c3';
this.inputField[index].style.borderColor = '#ce1414';
}
}
/**
* Clear error style input password
*/
clearStyleErrorInputPassword() {
for (let index = 1; index < this.inputField.length; index += 1) {
this.inputField[index].style.background = '#f5f5f5';
this.inputField[index].style.borderColor = '#f5f5f5';
}
}
/**
* Reassign again to check error message element haved on page or not
*/
reassignVariableErrorMessage() {
this.errorMessage = document.querySelector('.form__error-message');
}
/**
* Clear error message at form
*/
clearErrorMessage() {
this.reassignVariableErrorMessage();
// If have error message on page, remove it
if (this.errorMessage) {
this.errorMessage.remove();
this.clearStyleErrorInputPassword();
}
}
/**
* Add event listener for input field at form
*/
addHandlerInputFormChange() {
this.parentElement.addEventListener('input', () => {
this.clearErrorMessage();
});
}
/**
* Show error message with error style input password.
* @param {string} message The error message you want show in form.
*/
showError(message) {
this.renderError(message);
this.changeToStyleErrorInputPassword();
}
/** /**
* Implement register success popup in site * Implement register success popup in site
*/ */
initRegisterSuccessPopup() { initRegisterSuccessPopup() {
const typePopup = CONSTANT.TYPE_POPUP.success; const typePopup = TYPE_POPUP.success;
const title = 'Register Commpleted'; const title = 'Register Commpleted';
const content = 'Please login to continue!'; const content = 'Please login to continue!';
const btnContent = 'OK'; const btnContent = 'OK';
@@ -138,26 +46,10 @@ export default class RegisterView extends CommonView {
* @param {string} content The content will show in error popup * @param {string} content The content will show in error popup
*/ */
initErrorPopup(content) { initErrorPopup(content) {
const typePopup = CONSTANT.TYPE_POPUP.error; const typePopup = TYPE_POPUP.error;
const title = 'Error'; const title = 'Error';
const btnContent = 'Got it!'; const btnContent = 'Got it!';
this.initPopupContent(typePopup, title, content, btnContent); this.initPopupContent(typePopup, title, content, btnContent);
} }
/**
* Show error message in form
* @param {*} message The message will show in form
*/
renderError(message) {
const markup = `
<p class="form__error-message">${
!message ? this.messageDefault : message
}</p>
`;
document
.querySelector('.form__title')
.insertAdjacentHTML('afterend', markup);
}
} }
+1 -1
View File
@@ -55,6 +55,6 @@
<!-- End form --> <!-- End form -->
</div> </div>
</div> </div>
<script type="module" src="../js/controller.js"></script> <script type="module" src="../js/main.js"></script>
</body> </body>
</html> </html>