-
-
Save mnichols08/9d7593c55fd2f468a1e41fbb4e1e3e4f to your computer and use it in GitHub Desktop.
Stage 3/3 of MVC Example
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
// Define a Controller class | |
class Controller { | |
// Initialize the controller | |
init = () => { | |
// Initialize the view | |
app.view.init(); | |
// Add a click event listener to the title that calls the editTitle method | |
app.view.element | |
.querySelector("h1") | |
.addEventListener("click", (e) => app.view.editTitle(e)); | |
// Add a click event listener to the increment button that calls the view's increment method | |
app.view.element | |
.querySelector("button#increment") | |
.addEventListener("click", app.view.increment); | |
// Add a click event listener to the reset button that calls the view's reset method | |
app.view.element | |
.querySelector("button#reset") | |
.addEventListener("click", app.controller.resetState); | |
}; | |
// Save the title and make it non-editable | |
setTitle = (title) => { | |
app.state.title = title; | |
app.view.updateTitle(); | |
}; | |
// Increment the count and update the view | |
incrementCount = () => { | |
app.state.count++; | |
app.view.updateCount(); | |
}; | |
// Reset the state and view | |
resetState = () => { | |
(app.state = { title: "Hello World!", count: 0 }), app.view.resetView(); | |
}; | |
} | |
// Define a View class | |
class View { | |
// Constructor for the View class | |
constructor(tag, innerHTML, parentElement) { | |
// Create a new HTML element with the given tag | |
this.element = document.createElement(tag); | |
// Set the inner HTML of the element to the given HTML | |
this.element.innerHTML = innerHTML; | |
// Append the new element to the given parent element | |
parentElement.append(this.element); | |
} | |
// Initialize the view | |
init = () => { | |
// Create a new View instance | |
new View( | |
"main", | |
` | |
<h1>${app.state.title}</h1> | |
<h2>Welcome to the app.</h2> | |
<p>Click the title to edit it.</p> | |
<p> or </p> | |
<p>Click the button to increase the count.</p> | |
<h3>Count:</h3> | |
<p id="count">${app.state.count}</p> | |
<button id="increment">Click me</button> | |
<button id="reset">Reset</button> | |
`, | |
this.element | |
); | |
}; | |
// Update the title in the view | |
updateTitle = () => | |
(app.view.element.querySelector("h1").innerText = app.state.title); | |
// Reset the view and re-initialize it | |
resetView = () => { | |
app.view.element.innerHTML = ""; | |
app.controller.init(); | |
}; | |
// Increment the count | |
increment = () => app.controller.incrementCount(); | |
// Update the count in the view | |
updateCount = () => | |
(app.view.element.querySelector("#count").innerText = app.state.count); | |
// Make the title editable when it's clicked | |
editTitle = (e) => { | |
const title = e.target; | |
title.contentEditable = true; | |
title.focus(); | |
// Set the title when Enter is pressed | |
title.addEventListener("keypress", (e) => { | |
if (e.key === "Enter") { | |
title.contentEditable = false; | |
app.controller.setTitle(title.innerText); | |
} | |
}); | |
// Set the title when it loses focus | |
title.addEventListener("blur", () => { | |
app.controller.setTitle(title.innerText); | |
title.contentEditable = false; | |
}); | |
}; | |
} | |
// Define a Model class | |
class Model { | |
// Constructor for the Model class | |
constructor() { | |
// Initialize the state with a title and count | |
this.state = { | |
title: "Hello World!", | |
count: 0 | |
}; | |
// Create a new View instance with a div element, no inner HTML, and append it to the body of the document | |
this.view = new View("div", "", document.body); | |
// Create a new Controller instance and pass the view instance to it | |
this.controller = new Controller(this.view); | |
} | |
} | |
// Create a new instance of the Model class and assign it to the constant "app" | |
const app = new Model(); | |
// Call the init method on the controller property of the app instance | |
// This initializes the view and adds event listeners to the HTML elements | |
document.onload = app.controller.init(); |
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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Model View Controller Exercise</title> | |
<link rel="stylesheet" href="./styles.css"> | |
<script src="./app.js" defer></script> | |
</head> | |
<body> | |
<noscript> | |
<h1>Sorry, but JavaScript must be enable to view this application.</h1> | |
</noscript> | |
</body> | |
</html> |
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
body { | |
background: linear-gradient(45deg, #080404, #020606); | |
height: 100%; | |
color: #fff; | |
text-align: center; | |
font-family: monospace; | |
}h1 { | |
font-size: 2.5em; | |
font-weight: bold; | |
color: #FF6347; | |
text-shadow: 2px 2px 4px #000000; | |
} | |
h3 { | |
display: inline-block; | |
} | |
p:nth-of-type(2),p:nth-of-type(4){ | |
display: inline; | |
} | |
p { | |
font-size: 1.2em; | |
line-height: 1.6; | |
color: #ddd; | |
text-align: justify; | |
margin: 0 auto; | |
max-width: 800px; | |
} | |
button { | |
background-color: #4CAF50; | |
border: none; | |
color: white; | |
padding: 15px 32px; | |
text-align: center; | |
text-decoration: none; | |
display: inline-block; | |
font-size: 16px; | |
margin: 4px 2px; | |
transition-duration: 0.4s; | |
cursor: pointer; | |
transition: all .2s; | |
} | |
button:hover { | |
background-color: #473599; | |
color: white; | |
transform: scale(1.1) rotate3d(1, 1, 1, -10deg) translate(10px, 10px); | |
border-radius: 10px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment