Reputation: 706
I've started an Aurelia project and I've opted to use this plugin to enable input masking for phone numbers using an implementation similar to that seen in this post.
It works fine in Chrome and Safari - however, it just plain doesn't work in Firefox. No errors or other useful information. The examples on the above-linked demo page work just fine, however, so I'm sure it must be something with my implementation:
JS:
import {inject, NewInstance} from 'aurelia-dependency-injection';
import {ValidationController, ValidationRules, validateTrigger} from 'aurelia-validation';
import 'igorescobar/jQuery-Mask-Plugin'
@inject(NewInstance.of(ValidationController))
export class MyForm {
async activate(params, routeConfig) {
// do stuff if there are route parameters
}
bind() {
$('#PhoneNumber').mask('(000) 000-0000');
}
constructor(controller) {
this.controller = controller;
this.controller.validateTrigger = validateTrigger.manual;
}
submit() {
this.controller.validate()
.then(errors => {
if (errors.length === 0) {
// do a thing
} else {
// do something else
}
});
}
}
ValidationRules
.ensure('phoneNumber').displayName('Phone number')
.minLength(10).withMessage('Phone number must be at least 10 characters')
.maxLength(14).withMessage('Phone number is too long')
.matches(/[(][0-9]{3}[)] [0-9]{3}-[0-9]{4}/).withMessage('Please provide a valid phone number')
.on(MyForm);
HTML
<input class="form-control" id="PhoneNumber" type="tel" minlength="10" maxlength="14" pattern="[(][0-9]{3}[)] [0-9]{3}-[0-9]{4}" value.bind="phoneNumber & validate" required="required">
I've tried removing the pattern attribute and changing it to regular text input, to no avail. I'm really scratching my head on this one. Any ideas or suggestion would be greatly appreciated.
Upvotes: 1
Views: 527
Reputation: 1036
I work with Jan - we never did get it to work in Firefox the way the original question is coded.
We did end up replacing it with jquery.inputmask because we ran into compatibility issues with jquery.mask('igorescobar/jQuery-Mask-Plugin').
Here is the glue that made it work (based on Two-Way binding in an Aurelia Custom Attribute):
input-mask.js
import {inject, customAttribute, bindable, bindingMode} from 'aurelia-framework';
import 'jquery.inputmask';
import 'jquery.inputmask.numeric';
@customAttribute('input-mask')
@inject(Element)
export class InputMaskCustomAttribute {
@bindable({defaultBindingMode: bindingMode.twoWay}) unmaskedValue;
@bindable maskOptions;
element;
isValidInputElement;
// The maskedinput jquery pluggin does not allow the events that aurelia needs
// for binding to get through. So we will manually put them through.
// This is the list of events we are going to look for. "focusout" allows for the value
// to be correct intime for "onblur".
aureliaBindEvents = 'focusout';
eventTarget = undefined;
constructor(element) {
if (element instanceof HTMLInputElement) {
this.element = element;
this.isValidInputElement = true;
this.eventTarget = $(this.element);
} else {
this.isValidInputElement = false;
}
}
bind() {
this.element.value = this.unmaskedValue;
}
attached() {
this.setupMask();
}
detached() {
this.tearDownMask();
}
maskOptionsChanged(newValue, oldValue) {
this.tearDownMask();
this.setupMask();
}
setupMask(mask) {
if (this.isValidInputElement && this.maskOptions) {
this.eventTarget.inputmask(this.maskOptions);
this.eventTarget.on(this.aureliaBindEvents, (e) => {
this.unmaskedValue = this.eventTarget.inputmask('unmaskedvalue');
this.fireEvent(e.target, 'input');
});
}
}
tearDownMask() {
if (this.isValidInputElement) {
if (this.eventTarget) {
this.eventTarget.off(this.aureliaBindEvents);
this.eventTarget.inputmask('remove');
}
}
}
createEvent(name: string) {
let event = document.createEvent('Event');
event.initEvent(name, true, true);
return event;
}
fireEvent(element: HTMLElement, name: string) {
var event = this.createEvent(name);
element.dispatchEvent(event);
}
}
widget.html
<require from="input-mask"></require>
<input class="form-control" type="text" maxlength="12"
input-mask="mask-options.bind: {alias: 'currency', rightAlign: false, allowMinus:false, allowPlus: false}; unmasked-value.bind: target['monthly-payment'] & validate" />
Upvotes: 2
Reputation: 1067
You can use jquery commands on attached()
event (after html-rendering), not on bind()
. Try that:
attached() {
$('#PhoneNumber').mask('(000) 000-0000');
}
Upvotes: 0