Skip to content

Instantly share code, notes, and snippets.

@smelukov
Last active May 27, 2023 10:58
Show Gist options
  • Save smelukov/abd9b366164461ec5a9f to your computer and use it in GitHub Desktop.
Save smelukov/abd9b366164461ec5a9f to your computer and use it in GitHub Desktop.
Very simple MVVM (dynamic data binding) on JS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>MVVM</h1>
<form role="form">
<div class="checkbox">
<label>
<input type="checkbox" checked id="bindingEnabled"> Динамическое связывание
</label>
</div>
<div class="form-group">
<label for="firstName">Имя</label>
<input type="text" class="form-control" id="firstName" data-bind="firstName">
</div>
<div class="form-group">
<label for="lastName">Фамилия</label>
<input type="text" class="form-control" id="lastName" data-bind="lastName">
</div>
<div class="form-group">
<label for="old">Возраст</label>
<input type="text" class="form-control" id="old" data-bind="old">
</div>
<div class="form-group">
<label for="town">Город</label>
<input type="text" class="form-control" id="town" data-bind="town">
</div>
</form>
<hr>
<div class="jumbotron">
<h1>Привет!</h1>
<p>Меня зовут <span data-bind="firstName"></span> <span data-bind="lastName"></span>.</p>
<p>Мне <span data-bind="old"></span> лет и я живу в городе <span data-bind="town"></span>.</p>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
var bindMap = {},
scope = {},
bindedEls = document.querySelectorAll('*[data-bind]');
for (var i = 0; i < bindedEls.length; i++) {
var el = bindedEls[i],
bindTo = el.dataset.bind;
if (!bindMap[bindTo]) {
bindMap[bindTo] = [];
}
bindMap[bindTo].push(el);
}
function bindValue(bindingName, value) {
scope[bindingName] = value;
}
function syncBindings() {
for (var bindTo in scope) {
var value = scope[bindTo];
bindMap[bindTo].forEach(function(el) {
if (el.tagName === 'INPUT') {
el.value = value;
} else {
el.innerText = value;
}
});
delete scope[bindTo];
}
}
document.addEventListener('keyup', function(e) {
var target = e.target,
bindTo = target.dataset.bind;
if (bindTo && bindMap[bindTo]) {
bindValue(bindTo, target.value);
if (bindingEnabled.checked) {
syncBindings();
}
}
}, true);
bindingEnabled.addEventListener('change', function() {
if (bindingEnabled.checked) {
syncBindings();
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment