I need to validate a form textfield that's bound to a property of a model using EmberJS. I want the user to only be able to type valid, positive numbers.
I know of jQuery.isNumber(), but I don't know how to wire it to the field. I tried writing explicit getter/setter functions on the model's property using Ember.computed(...), but it didn't work.
Is there something similar to WinForms onChanging() event that I can hook up to?
There are a number of ways to do this sort of thing. Here we can accomplish this using bindings and observers.
First lets create a function that will always return a number.
var onlyNumber = function(input) {
return input.toString().replace(/[^\d.]/g, "");
};
Using that we can do the following
App = Ember.Application.create();
App.person = Ember.Object.create({
age: 42
});
App.NumberField = Ember.TextField.extend({
valueBinding: Ember.Binding.from("App.person.age").transform(onlyNumber),
_cleanValue: function() {
this.set('value', onlyNumber(this.get('value')));
}.observes('value')
});
1) We are creating a Binding to the Person's age, but anything that passes through this binding can only be a number. See Ember.Binding to/from transforms for more details.
2) We are observing the text field's value and setting it to be only a number when it changes. If the user enters '42a' we will immediately set it back to '42'. Note that even though '42a' was in the text input for a brief second it would not have been able to pass through the binding because of our transform.
Here is a fiddle showing this example: http://jsfiddle.net/nDBgC/
You could add a keyDown
event handler on your TextField, see http://jsfiddle.net/pangratz666/SKJfF/:
App.NumberTextField = Ember.TextField.extend({
// implementation of this function, see http://stackoverflow.com/a/995193/65542
keyDown: function(event) {
// Allow: backspace, delete, tab, escape, and enter
if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode == 13 ||
// Allow: Ctrl+A
(event.keyCode == 65 && event.ctrlKey === true) ||
// Allow: home, end, left, right
(event.keyCode >= 35 && event.keyCode <= 39)) {
// let it happen, don't do anything
return;
}
else {
// Ensure that it is a number and stop the keypress
if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
event.preventDefault();
}
}
}
});
Code (handles only numeric input and allows binding of number rather than string, if desired):
App.NumberFieldComponent = Ember.TextField.extend({
tagName: "input",
type: "number",
numericValue: function(key, value) {
if (arguments.length === 1) {
return parseFloat(this.get("value"));
} else {
return this.set("value", (value !== void 0 ? "" + value : ""));
}
}.property("value"),
didInsertElement: function() {
return this.$().keypress(function(key) {
if ((key.charCode !== 46) && (key.charCode !== 45) && (key.charCode < 48 || key.charCode > 57)) {
return false;
}
});
}
});
Template:
{{number-field numericValue=someNumericProperty}}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With