Well, managed to find a way to do simple data binding via shadow dom solution. It's not the perfect solution but it will do for now.
Data binding to Mustache templates? (preferably clean and simple)
-
02-09-2022 - |
Question
What I am after is a piece of code that could provide me a clean and simple one-way solution to bind the changes from DOM to the object that is used to render it.
Example: And object
{name: 'Joe'}
is used to render the Mustache template
<div><input val="{{name}}" /></div>
How can I match the change event in the inputfield to the correct property?
What about iterations?
{{#users}}
<div><input val="{{name}}" /></div>
{{/users}}
Is there a such thing?
Edit: And yes, I am aware of Backbone, Angular, Ember, younameit. However, what I need is a specific case to Mustache/Handlebars.
Solution 5
OTHER TIPS
Ractive is exactly this. Mustache with data binding. https://ractive.js.org
What you are asking for called Angular.js
There is little bit different approach in other similar frameworks like knockout.js, batman.js etc.
Check sample todo application to see how different framework do it.
UPDATE:
On the other hand, if all your "bindings" are going to be simple and you do not care much about syntax there are two approaches that you can use with just jquery in order to minimize ammount of code working with input fields:
- one input field per model field and just one model
var model = {
a: 1,
b: 2,
c: 3
}
$('#myForm').on('blur', 'input', function(e) {
var $this = $(this),
field = $this.data('model')
model[field] = $this.val()
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id='myForm'>
<input type='text' data-model='a' />
<input type='text' data-model='b' />
<input type='text' data-model='c' />
</form>
- kinda extension of first one you can grouping elements together if you have multiple models and multiple fields per model. Good example is table editor, when each row bound to element in array and has several fields bound to cells in a row
js
var models = { modelA : {...}, modelB: {...}}
$('#myForm').on('blur', 'input', function(e) {
var $this = $(this), field = $this.data('field')
, model = $this.data('model')
// last line can be smth like $this.closest('div.group').data('model')
models[model][field] = $this.val()
})
So to sum up your example:
{{#users}}
<div><input data-model='users' data-index='{{ $index }}' val="{{name}}" /></div>
{{/users}}
$('#myForm').on('blur', 'input', function(e) {
var $this = $(this), index = $this.data('index')
, model = $this.data('model')
window.data[model][index][field] = $this.val()
})
Check jtmpl, it should exactly fit your need—render a Mustache template and keep DOM synchronized with model at all times.
Collections and node attributes are supported and your example syntax should work as is (just correct "val" -> "value").
I suggest you look at vue.js
- it's now a widely adopted framework and is much lighter than Angular (600kb vs 60kb minified and 20kb if gzipped) and uses mustache-similar syntax.