admin管理员组

文章数量:1327581

I need to create an input in Aurelia that only accepts a phone number. If the user types 1234567890 into this input it should display (123) 456-7890 and the bound variable would be set to 1234567890. The result should be the same if the user types (123) 456-7890 into the input as well. If the user types a letter into the input, the input should not display the letter, nor should the bound javascript variable get updated.

I'm able to partially achieve this using a ValueConverter:

phone.ts

export class PhoneValueConverter {
    private removeNonDigits(input) {
        let digits = '';

        // Remove non-digits. i.e. '(', ')', ' ' and '-'
        for (let i = 0; i < input.length; i++) {
            let char = input.charAt(i);

            if ('0' <= char && char <= '9')
                digits += char;
        }

        return digits;
    }

    toView(value) {
        if (!value)
            return value;

        value = this.removeNonDigits(value);

        let formatted = '(' + value.substring(0, 3);

        if (value.length >= 3)
            formatted += ') ' + value.substring(3, 6);
        if (value.length >= 6) {
            // Don't place an upper limit, otherwise the user would not
            // see the entire value
            formatted += '-' + value.substring(6);
        }

        return formatted;
    }

    fromView(value) {
        let digits = this.removeNonDigits(value);

        // Only accept a 9-digit phone number
        return digits.substring(0, 10);
    }
}

app.html

<template>
  ${PhoneNumber} <br>
  <require from="phone"></require>
  <input value.bind="PhoneNumber | phone">
</template>

This works perfectly in forcing PhoneNumber to always be 0-9 numerical digits. If the user types a letter, or a 10th digit, into the input, it will not be added to PhoneNumber - just as expected. But unfortunately, the value of the input ($('input').value(), not value.bind) will still contain the extra, incorrect character.

Is there an Aurelia convention in controlling what characters get added to the value of the input?

I need to create an input in Aurelia that only accepts a phone number. If the user types 1234567890 into this input it should display (123) 456-7890 and the bound variable would be set to 1234567890. The result should be the same if the user types (123) 456-7890 into the input as well. If the user types a letter into the input, the input should not display the letter, nor should the bound javascript variable get updated.

I'm able to partially achieve this using a ValueConverter:

phone.ts

export class PhoneValueConverter {
    private removeNonDigits(input) {
        let digits = '';

        // Remove non-digits. i.e. '(', ')', ' ' and '-'
        for (let i = 0; i < input.length; i++) {
            let char = input.charAt(i);

            if ('0' <= char && char <= '9')
                digits += char;
        }

        return digits;
    }

    toView(value) {
        if (!value)
            return value;

        value = this.removeNonDigits(value);

        let formatted = '(' + value.substring(0, 3);

        if (value.length >= 3)
            formatted += ') ' + value.substring(3, 6);
        if (value.length >= 6) {
            // Don't place an upper limit, otherwise the user would not
            // see the entire value
            formatted += '-' + value.substring(6);
        }

        return formatted;
    }

    fromView(value) {
        let digits = this.removeNonDigits(value);

        // Only accept a 9-digit phone number
        return digits.substring(0, 10);
    }
}

app.html

<template>
  ${PhoneNumber} <br>
  <require from="phone"></require>
  <input value.bind="PhoneNumber | phone">
</template>

This works perfectly in forcing PhoneNumber to always be 0-9 numerical digits. If the user types a letter, or a 10th digit, into the input, it will not be added to PhoneNumber - just as expected. But unfortunately, the value of the input ($('input').value(), not value.bind) will still contain the extra, incorrect character.

Is there an Aurelia convention in controlling what characters get added to the value of the input?

Share Improve this question edited Oct 12, 2016 at 22:34 Jeremy Danyow 26.4k12 gold badges90 silver badges135 bronze badges asked Apr 8, 2016 at 19:02 Matt JohnsonMatt Johnson 3582 silver badges10 bronze badges 2
  • For what are you using $('input').value()? – kabaehr Commented Apr 8, 2016 at 19:52
  • @kabaehr, sorry for the confusion. I don't actually need to use $('input').value(), I was simply using that as a method of distinguishing between the bound value (the value of PhoneNumber) and the actual text inside the input. – Matt Johnson Commented Apr 8, 2016 at 21:42
Add a ment  | 

1 Answer 1

Reset to default 9

You can subscribe to the input's keydown event and prevent the default action when it's a character you don't want to appear in the input.

Here's an example of using this approach to build a very simple numeric input: https://gist.run?id=3101e8f73cf4da32445505d0e4258f01

app.html

<template>
  <require from="./numeric-input"></require>

  <numeric-input value.bind="value"></numeric-input>

  ${value}
</template>

app.js

export class App {
  value = '';
}

numeric-input.html

<template>
  <input type="text" value.bind="value" placeholder.bind="placeholder">
</template>

numeric-input.js

import {
  inject,
  bindable,
  bindingMode
} from 'aurelia-framework';

// http://stackoverflow./a/995193/725866
function isNavigationOrSelectionKey(e) {
  // Allow: backspace, delete, tab, escape, enter and .
  if ([46, 8, 9, 27, 13, 110, 190].indexOf(e.keyCode) !== -1 ||
    // Allow: Ctrl+A/X/C/V, Command+A/X/C/V
    ([65, 67, 86, 88].indexOf(e.keyCode) !== -1 && (e.ctrlKey === true || e.metaKey === true)) ||
    // Allow: home, end, left, right, down, up
    (e.keyCode >= 35 && e.keyCode <= 40)) {
     // let it happen, don't do anything
     return true;
  }
  return false;
}

// http://stackoverflow./a/995193/725866
function keydown (e) {
  if (isNavigationOrSelectionKey(e)) {
    return;
  }
  // If it's not a number, prevent the keypress...
  if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
    e.preventDefault();
  }
}

@inject(Element)
export class NumericInput {
  @bindable({ defaultBindingMode: bindingMode.twoWay }) value;
  @bindable placeholder = '';

  constructor(element) {
    this.element = element;
  }

  attached() {
    this.element.addEventListener('keydown', keydown);
  }

  detached() {
    this.element.removeEventListener('keydown', keydown);
  }
}

本文标签: javascriptControl value of input in AureliaStack Overflow