Creating Input masking component using Ember-modifier
If you are an Ember dev you may have come across handlebars element like {{on}}
(which was introduced in Ember Octane). It is nothing but modifiers
. It is very similar to helpers
in handlebars. It is available in two flavorsclass
based and function
based modifiers. In this blog, we are going to create a simple function-based modifier.
What are we going to build? 🤔
We are going to create an input masking component, which will take the input pattern
value from the user (as per the pattern mentioned in the input definition) and render the input as per provided pattern. Refer to the diagram below to get an idea of what we are going to get as a final product.
The component usage would be something like this:
<InputMasking @value={{this.myValue}} @pattern="99999-9999" />
How function based modifier works?
- As per GitHub documentation of
ember-modifier
, Modifiers are a basic primitive for interacting with the DOM in Ember. - It helps you to interact and manipulate DOM.
- This modifier runs the first time when the element the modifier was applied to is inserted into the DOM, and it also tracks the changes while running. It tracks changes including the arguments it receives, and if any of them changes, the function will run again.
- A Function-based modifiers take 3 parameters:
- The element
- An array of positional arguments
- An object of named arguments
- Something like this
export default modifier(function maskInput(element/*, params, hash*/) {
- The first param i.e
element
it is nothing but the DOM element on which you are going to apply some changes.
Example:
- The
on
modifier helps you to applyevent listener
on the element you are applying. - Say, you want to apply
focus
on the input tag. You can addon
something like this<Input {{on 'focus' this.handler}} />
- The
on
modifier applies an event listener like this behind the scene.document.getElementById('yourInput').addEvent('focus', this.handler)
- Similarly, if you want to create your own custom
modifier
,ember-modifier
helps you create one. - Suppose, if you are creating a
modifier
saydo-something
. It can be used something like this<Button {{do-something 'param1 param2'}} > Click </Button>
- In modifier
doSomething(element, params, hash)
, the first parameterelement
is nothing but DOM element on which we are applying this modifier andparams
are nothing but the passed parameters. - We will look into its work in the following
input-masking
example.
Let's create one!!
- First of all, I am assuming you have one running ember application of at least
v3.12
. If not create oneember new my-ember-project
. - Why
v3.12
? Because for making use ofmodifier
we have to install an ember plugin called ember-modifier which has this basic requirement. - So, let's install
ember-modifier
by runningember install ember-modifier
in your terminal. - Now we are going to create a component
input-masking
. For this we will createapp/templates/components/input-masking.hbs
andapp/components/input-masking.js
. - Add some code in the template file of the component.
<Input @value='' />
- As per our requirement user should enter the telephone of the format
4137-4224
in the input. But we don't want the user to specifically add-
in between the numbers for consistency. Our component should be smart enough to add-
after four numbers. - We could write a simple regex in some handler event instead, we are going to use an npm package to make our work easier.
- The npm package we are going to use is called inputmask.
- So, we will install this plugin
npm install inputmask --save
. inputmask
plugin is not an ember plugin, so to use anynpm
package without any configuration there is a plugin called ember-auto-import.- This plugin will help you to directly import
inputmask
. Something like thisimport Inputmask from 'inputmask';
- Now we will create a modifier
mask-input
. Runember g modifier mask-input
. This will generate a file calledmask-input
insidemodifiers
folder with some pre-generated code.import { modifier } from 'ember-modifier'; export default modifier(function maskInput(element, params/*, hash*/) { });
- It's usage will be something like in our
InputMasking
component.<Input {{mask-input}} @value='' />
- As per usage of
Inputmask
plugin. We need to create an instance of it and passed the pattern we want to apply to our element. So, will importInputmask
into our modifier file and create an instance of it.import { modifier } from 'ember-modifier'; import Inputmask from 'inputmask'; export default modifier(function maskInput(element, params/*, hash*/) { const im = Inputmask('9999-9999'); //this is the instance of Inputmask im.mask(element); });
- We will apply the pattern of our choice where we want the input of length 9, with a dash after the fourth number and all should be number. The
9
represent number(Please refer input-mask` documentation for further configurations). - After creating an instance of inputmask, we will pass the element.
- As per the behavior of
modifier
, it will continuously keep track of theinput
we pass. - Everything looks fine except one thing. Right now, we have hard-coded the pattern during the instantiation of
inputmask
. It should be as per the value passed to the component. In our component template file we will pass
@pattern
value. Add the following changes:<Input {{mask-input @pattern}} @value='' />
The passed
pattern
in the modifier will be received as the second parameter in the modifierjs
file. We receive that change and passed to theInputmask
instance.
export default modifier(function maskInput(element, params/*, hash*/) {
const [pattern] = params; // receive pattern
const im = Inputmask({ mask: pattern}); // pass the pattern here.
im.mask(element);
});
Final Usage:
<Form>
<Label> Telephone </Label>
<InputMasking @value={{this.telephone}} @pattern="99999-9999" />
<Label> Credit Card </Label>
<InputMasking @value={{this.creditCard}} @pattern="9999-9999-9999-9999 />
.....
</Form>
I hope you like this blog. If you have any questions then please comment below.
References:
Subscribe to my newsletter
Read articles from AbulAsar S. directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
AbulAsar S.
AbulAsar S.
I am a Software Engineer from Mumbai, India. In love with Functional programming ( precisely Elixir). Love to share the knowledge that I learn while developing things.