Created
September 12, 2023 02:09
-
-
Save cferdinandi/992571d97e269c9a2f980f353c01fe5a to your computer and use it in GitHub Desktop.
Two-way data-binding and reactivity. https://gomakethings.com/sotb/
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>Data Binding</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<style type="text/css"> | |
body { | |
margin: 1em auto; | |
max-width: 80em; | |
width: 88%; | |
} | |
/** | |
* Grid Layout | |
*/ | |
.grid { | |
display: grid; | |
grid-template-columns: repeat(2, 1fr); | |
grid-template-rows: 1fr; | |
grid-column-gap: 2em; | |
} | |
#form-1 { | |
grid-area: 1 / 1 / 2 / 2; | |
} | |
#form-2 { | |
grid-area: 1 / 2 / 2 / 3; | |
} | |
/** | |
* Form Styles | |
*/ | |
form { | |
margin-bottom: 2em; | |
} | |
label, | |
input, | |
textarea { | |
display: block; | |
width: 100%; | |
} | |
label { | |
font-weight: bold; | |
} | |
input, | |
textarea { | |
margin-bottom: 1em; | |
} | |
textarea { | |
min-height: 8em; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Two-Way Data-Binding</h1> | |
<div class="grid"> | |
<div id="form-1"> | |
<form data-form-sync> | |
<label for="title-1">Title</label> | |
<input type="text" name="title" id="title-1" value="Go to the beach"> | |
<label for="body-1">Body</label> | |
<textarea id="body-1" name="body">Soak up the sun and swim in the ocean.</textarea> | |
<button>Submit</button> | |
</form> | |
</div> | |
<div id="form-2"> | |
<form data-form-sync> | |
<label for="title-2">Title</label> | |
<input type="text" name="title" id="title-2" value="Go to the beach"> | |
<label for="body">Body</label> | |
<textarea id="body-2" name="body">Soak up the sun and swim in the ocean.</textarea> | |
<button>Submit</button> | |
</form> | |
</div> | |
</div> | |
<script> | |
// Create a Proxy | |
let data = new Proxy({}, { | |
set (obj, key, value) { | |
// Update the property | |
obj[key] = value; | |
// Find the matching fields in the DOM | |
let fields = document.querySelectorAll(`[name="${key}"]`); | |
for (let field of fields) { | |
field.value = value; | |
} | |
return true; | |
} | |
}); | |
// Event listener | |
document.addEventListener('input', function (event) { | |
// Only run on our forms | |
if (!event.target.closest('[data-form-sync]')) return; | |
// Update the data object | |
data[event.target.name] = event.target.value; | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment