Last active
June 20, 2024 17:00
-
-
Save cferdinandi/088d7f4ca088f7becd911e3e60efeec1 to your computer and use it in GitHub Desktop.
Can you build a modern web app using only vanilla Web Components in 2024? Watch the tutorial on YouTube: https://youtu.be/2S4-42vjZwY
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"> | |
<title>Pick at Random</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<style type="text/css"> | |
body { | |
margin: 1em auto; | |
max-width: 40em; | |
width: 88%; | |
} | |
pick-at-random [role="status"]:not(:empty) { | |
background-color: #f7f7f7; | |
border: 1px solid #e5e5e5; | |
border-radius: 0.25em; | |
padding: 0.5rem 1rem; | |
margin-top: 0.5rem; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Pick at Random</h1> | |
<pick-at-random></pick-at-random> | |
<script> | |
customElements.define('pick-at-random', class extends HTMLElement { | |
/** | |
* Instantiate the component | |
*/ | |
constructor () { | |
// Inherits parent class properties | |
super(); | |
// Create a unique ID for the instance | |
this.uuid = `pick-${crypto.randomUUID()}`; | |
// Render our initial HTML | |
this.innerHTML = | |
`<form> | |
<label for="${this.uuid}">Add an Item</label> | |
<input type="text" id="${this.uuid}"> | |
<button>Add Item</button> | |
</form> | |
<ul></ul> | |
<p><button pick-item>Pick an Item</button></p> | |
<div role="status" pick-result></div>`; | |
// Get our elements | |
this.form = this.querySelector('form'); | |
this.list = this.querySelector('ul'); | |
this.field = this.form.querySelector('input'); | |
this.pickBtn = this.querySelector('[pick-item]'); | |
this.result = this.querySelector('[pick-result]'); | |
// Listen for event | |
this.form.addEventListener('submit', this); | |
this.pickBtn.addEventListener('click', this); | |
} | |
/** | |
* Handle events | |
* @param {Event} event The event object | |
*/ | |
handleEvent (event) { | |
this[`on${event.type}`](event); | |
} | |
/** | |
* Handle submit events | |
* @param {Event} event The event object | |
*/ | |
onsubmit (event) { | |
// Stop the form from reloading the page | |
event.preventDefault(); | |
// Create a list item | |
let li = document.createElement('li'); | |
li.textContent = this.field.value; | |
this.list.append(li); | |
// Show a status message | |
this.showStatus(`"${this.field.value}" has been added to the list.`); | |
// Clear text from field | |
this.field.value = ''; | |
} | |
/** | |
* Handle click event | |
* @param {Event} event The event object | |
*/ | |
onclick (event) { | |
// Get all of the list items | |
let items = Array.from(this.list.querySelectorAll('li')).map(function (item) { | |
return item.textContent; | |
}); | |
// Randomize the items | |
this.shuffle(items); | |
// Show the result | |
this.result.textContent = `You picked ${items[0]}`; | |
} | |
/** | |
* Show a status message in the form | |
* @param {String} msg The message to display | |
*/ | |
showStatus (msg) { | |
// Create a notification | |
let notification = document.createElement('div'); | |
notification.setAttribute('role', 'status'); | |
// Inject it into the DOM | |
this.form.append(notification); | |
// Add text after it's in the UI | |
setTimeout(function () { | |
notification.textContent = msg; | |
}, 1); | |
// Remove it after 4 seconds | |
setTimeout(function () { | |
notification.remove(); | |
}, 4000); | |
} | |
/** | |
* Randomly shuffle an array | |
* https://stackoverflow.com/a/2450976/1293256 | |
* @param {Array} array The array to shuffle | |
* @return {Array} The shuffled array | |
*/ | |
shuffle (array) { | |
let currentIndex = array.length; | |
let temporaryValue, randomIndex; | |
// While there remain elements to shuffle... | |
while (0 !== currentIndex) { | |
// Pick a remaining element... | |
randomIndex = Math.floor(Math.random() * currentIndex); | |
currentIndex -= 1; | |
// And swap it with the current element. | |
temporaryValue = array[currentIndex]; | |
array[currentIndex] = array[randomIndex]; | |
array[randomIndex] = temporaryValue; | |
} | |
return array; | |
} | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment