Last active
November 2, 2017 21:30
-
-
Save marsicdev/64d3a98b67cf9ec5183c30f9e27e805f to your computer and use it in GitHub Desktop.
Movie form refactored to ES2015
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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