Skip to content

Instantly share code, notes, and snippets.

@jdanyow
Last active May 18, 2017 10:34
Show Gist options
  • Save jdanyow/d9d8dd9df7be2dd2f59077bad3bfb399 to your computer and use it in GitHub Desktop.
Save jdanyow/d9d8dd9df7be2dd2f59077bad3bfb399 to your computer and use it in GitHub Desktop.
Aurelia number input
<template>
<require from="./number-input"></require>
<require from="./number-value"></require>
<!-- custom element -->
<number-input value.bind="a"></number-input> a = ${a | debug}<br/>
<number-input value.bind="b"></number-input> b = ${b | debug}<br/>
<number-input value.bind="c"></number-input> c = ${c | debug}<br/>
<!-- custom attribute -->
<input type="text" number-value.bind="a"> a = ${a | debug}<br/>
<input type="text" number-value.bind="b"> b = ${b | debug}<br/>
<input type="text" number-value.bind="c"> c = ${c | debug}<br/>
</template>
export class App {
a = null;
b = 0;
c = 1.56;
}
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
export class DebugValueConverter {
toView(value) {
if (value === undefined) {
return 'undefined';
}
if (value === null) {
return 'null';
}
if (isNumeric(value)) {
return value.toString(10);
}
return `"${value}"`;
}
}
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body aurelia-app>
<h1>Loading...</h1>
<script src="https://jdanyow.github.io/rjs-bundle/node_modules/requirejs/require.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/config.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/aurelia.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/babel.js"></script>
<script>
require(['aurelia-bootstrapper']);
</script>
</body>
</html>
<template>
<input type="text" blur.trigger="blur()">
</template>
import {
bindable,
bindingMode,
DOM,
inject
} from 'aurelia-framework';
function getNumber(value) {
// todo: use numbro
let number = parseFloat(value);
return !isNaN(number) && isFinite(value) ? number : NaN;
}
@inject(DOM.Element)
export class NumberInput {
@bindable({ defaultBindingMode: bindingMode.twoWay }) value;
/*** TODO ***********
* @bindable blankValue; // currently blank input maps to null but this should be customizable.
* @bindable decimalPlaces; // determine number of allowed decimal places.
*******************/
element;
input;
constructor(element) {
this.element = element;
}
created() {
this.input = this.element.firstElementChild;
}
valueChanged() {
// synchronize the input element with the bound value
const number = getNumber(this.value);
if (isNaN(number)) {
this.input.value = '';
} else {
this.input.value = number.toString(10);
}
}
blur() {
// blank input maps to null value
if (this.input.value === '') {
this.value = null;
return;
}
// do we have a number?
const number = getNumber(this.input.value);
if (isNaN(number)) {
// no! reset the input.
this.valueChanged();
} else {
// yes! update the binding.
this.value = number;
}
}
}
import {
customAttribute,
bindingMode,
DOM,
inject
} from 'aurelia-framework';
function getNumber(value) {
// todo: use numbro
let number = parseFloat(value);
return !isNaN(number) && isFinite(value) ? number : NaN;
}
@customAttribute('number-value', bindingMode.twoWay)
@inject(DOM.Element)
export class NumberValue {
constructor(input) {
this.input = input;
}
valueChanged() {
// synchronize the input element with the bound value
const number = getNumber(this.value);
if (isNaN(number)) {
this.input.value = '';
} else {
this.input.value = number.toString(10);
}
}
blur = () => {
// blank input maps to null value
if (this.input.value === '') {
this.value = null;
return;
}
// do we have a number?
const number = getNumber(this.input.value);
if (isNaN(number)) {
// no! reset the input.
this.valueChanged();
} else {
// yes! update the binding.
this.value = number;
}
}
bind() {
this.valueChanged();
this.input.addEventListener('blur', this.blur);
}
unbind() {
this.input.removeEventListener('blur', this.blur);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment