I have a form input with a value bound to a reactive data source:
<input type="text" name="first-name" id="first-name" required value="{{currentUser.profile.firstName}}" />
I want to watch 'change' events on the input:
$('#first-name').change(function() { alert('Value changed!'); });
This works fine if I change the value directly in the input. However, if the value changes reactively, the change event doesn't fire.
What's the best way to bind values to form elements so that the 'change' event fires if the reactive data source changes?
The Optimum Solution would be to use manuel:viewmodel
. You keep the state of the UI in a javascript object and bind the UI elements to properties of that object.
Example :
First add the package to the project with meteor add manuel:viewmodel
Then in the Html do the Following :
<template name="loginBox">
First Name: <input type="text" data-bind="value: first"/>
<br/>
Last Name: <input type="text" data-bind="value: last"/>
<div data-bind="text: greeting"></div>
<a data-bind="enabled: canEnter, hover: showError" class="btn-primary">Enter Site</a>
<span data-bind="text: errorText" class="text-error"></span>
</template>
Then in the Javascript file do the Necessary Bindings
Template.loginBox.viewmodel({
first: '',
last: '',
greeting: function() {
return "Hello " + this.first() + " " + this.last();
},
canEnter: function() {
return !!this.first() && !!this.last();
},
showError: false,
errorText: function() {
if (this.canEnter() || !this.showError()) {
return '';
}
return "Please enter your first and last name";
}
});
Here we're binding the value of the input/text element to the property 'first' of the viewmodel.
The result is that the viewmodel object will be kept in sync with the input box. If you change the value in the texbox then the value of the viewmodel's 'first' property will also change and vice versa.
For More information http://viewmodel.meteor.com/
Here's my initial solution, which I'm not particularly thrilled with:
Template.signUpPersonalDetails.rendered = function() {
this.autorun(function() {
if (Meteor.user() && Meteor.user().userAccount) {
var userAccount = Meteor.user().userAccount;
$('#first-name').val(userAccount.firstName).change();
$('#last-name').val(userAccount.lastName).change();
$('#email').val(userAccount.email).change();
$('#phone-number').val(userAccount.phoneNumber).change();
$('#postcode').val(userAccount.shippingPostcode).change();
}
});
};