Skip to content

Instantly share code, notes, and snippets.

@marsicdev
Last active November 2, 2017 21:30
Show Gist options
  • Save marsicdev/64d3a98b67cf9ec5183c30f9e27e805f to your computer and use it in GitHub Desktop.
Save marsicdev/64d3a98b67cf9ec5183c30f9e27e805f to your computer and use it in GitHub Desktop.
Movie form refactored to ES2015
const dataController = (() => {
const data = {
movies: [],
totalMoviesLength: 0
};
class Movie {
constructor(title, length, genre) {
this.title = title;
this.length = length;
this.genre = genre;
}
getInfo() {
const genreAbbr = getGenreAbbreviation(this.genre);
return `${this.title}, duration: ${this.length}min, genre: ${genreAbbr}`;
}
}
// Private functions used within this module
// Not exposed to the public
function getGenreAbbreviation(genreStr) {
const firstIndex = 0;
const lastIndex = genreStr.length - 1
const output = genreStr.charAt(firstIndex) + genreStr.charAt(lastIndex);
return output.toUpperCase();
}
function calculateTotalLength() {
let total = 0;
// Iterate trough movies and calculate length
data.movies.forEach(currentMovie => {
total += currentMovie.length;
});
// Set our new total to our data object
data.totalMoviesLength = total;
}
// Functions to be exported to public
return {
addMovie({ genre, length, title }) {
const movie = new Movie(title, parseFloat(length), genre);
data.movies.push(movie);
return movie;
},
getTotalLength() {
// calculate total data before returning
calculateTotalLength();
return data.totalMoviesLength;
},
// This is only for TEST
logData() {
console.log(data);
}
};
})();
const UIController = (() => {
const DOMStrings = Object.freeze({
inputTitle: '.movie-title',
inputLength: '.movie-length',
selectGenre: '.genre-select',
containerMovieList: '.movie-list ul',
containerError: '.movie-error',
buttonAddMovie: '.create-movie',
formElement: 'form',
containerTotalLength: '.total-length span'
});
// Methods exposed
return {
getInput() {
const titleElement = document.querySelector(DOMStrings.inputTitle);
const lengthElement = document.querySelector(DOMStrings.inputLength);
const genreSelectElement = document.querySelector(DOMStrings.selectGenre);
const genreOptionElement = genreSelectElement.options[genreSelectElement.selectedIndex];
return {
title: titleElement.value,
length: lengthElement.value,
genre: genreOptionElement.value
};
},
displayListItem(movie) {
const listEl = document.querySelector(DOMStrings.containerMovieList);
const htmlItem = `<li>${movie.getInfo()}</li>`;
listEl.insertAdjacentHTML('beforeend', htmlItem);
},
clearInputs() {
// Reset forma data
document.querySelector(DOMStrings.formElement).reset();
// Reset error if any
document.querySelector(DOMStrings.containerError).textContent = "";
// Set focus to title input
document.querySelector(DOMStrings.inputTitle).focus();
},
displayError({ length, title, genre }) {
let errorMsg = 'Unknown error!';
if (!title) {
errorMsg = "Enter title!"
} else if (!length) {
errorMsg = "Enter length!"
} else if (!genre) {
errorMsg = "Select genre!"
}
document.querySelector(DOMStrings.containerError).textContent = errorMsg;
},
displayTotalLength(tLength = '-') {
document.querySelector(DOMStrings.containerTotalLength).textContent = String(tLength);
},
getDOMStrings() {
return DOMStrings;
}
};
})();
const mainController = ((dataCtrl, UICtrl) => {
const setupEventListeners = () => {
const { buttonAddMovie } = UICtrl.getDOMStrings();
document.querySelector(buttonAddMovie).addEventListener('click', ctrlAddMovieItem);
document.addEventListener('keydown', ({ keyCode }) => {
if (keyCode === 13) {
ctrlAddMovieItem();
}
});
}
const ctrlUpdateTotalLength = () => {
// 1. Get calculated length
const totalLength = dataCtrl.getTotalLength();
// 2. Update the UI with new total length
UICtrl.displayTotalLength(totalLength);
}
const ctrlAddMovieItem = () => {
// 1. get form data (UI)
const { title, length, genre } = UICtrl.getInput();
// 1.1 Validate data validity
if (!title || !length || !genre) {
// throw new Error('Something bad happened');
// alert("Error!")
UICtrl.displayError({ genre, length, title });
return;
}
// 2. Add movie to list
const movie = dataCtrl.addMovie({ title, length, genre });
// 3. Clear form inputs
UICtrl.clearInputs();
// 4. show list on UI
UICtrl.displayListItem(movie);
// 5. Update total length UI
ctrlUpdateTotalLength();
}
return {
init() {
console.log("App has started");
setupEventListeners();
}
}
})(dataController, UIController);
mainController.init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment