Link to home
Start Free TrialLog in
Avatar of ITsolutionWizard
ITsolutionWizardFlag for United States of America

asked on

Javascript masking

The codes below is working.

But I hope to find out how to use addEventListener based on the input type instead of id like if I have 10+ <input type="tel" id="*">

That is so much easier if it is possible.


I think the route should like.

1. read and loop element inside of the form.

2. if input type is tel, then add eventlistener...


-----------------------------------------------------------

<form>
<input type="tel" id="Phone_Number-11">
</form>
<script>
    document.getElementById('Phone_Number-11').addEventListener('input', function (e) {
        var x = e.target.value.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
        e.target.value = !x[2] ? x[1] : '(' + x[1] + ') ' + x[2] + (x[3] ? '-' + x[3] : '');
    });
</script>

Open in new window

Avatar of Ron Malmstead
Ron Malmstead
Flag of United States of America image

Try this please.

OLD

Open in new window

Avatar of ITsolutionWizard

ASKER

not working...


here is the html i use 

<input id="Phone_Number-11"
                                                           name="Phone_Number-11"
                                                           type="tel"
                                                           class="required"
                                                           pattern="\d*" style="margin-bottom:10px;"
                                                           >
Ok, one more go..
https://jsfiddle.net/tckuej4s/5/
const elems = document.querySelectorAll('input[type="tel"]');

elems.forEach.call(elems, function(el) {
console.log(el.id);

el.addEventListener('keydown', function(){
 
    console.log(el.id + ' is changing');

    
   var x = this.value.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
        this.value = !x[2] ? x[1] : '(' + x[1] + ') ' + x[2] + (x[3] ? '-' + x[3] : '');

    
  })


});

Open in new window

still not working
Thank. But it allows to enter 5 digits at the end like this one.
Can you make it only 4 digits are allowed?

(231) 231-23223
On each input, set maxlength="14"
i have over 10 <input type='tel'> that dynamically generated it. it won't work to add it one by one in my case
Doesn't matter how many you have.

The line ...   const elems = document.querySelectorAll('input[type="tel"]'); 
Gets every <input element, with type='tel', then adds an event handler for 'keydown' event forEach, which then formats/validates the input as it's being typed.
@Ron: this is unnecessary

Array.prototype.forEach.call(elems, function(e) { })

Open in new window

Instead just use this. It is understood by all valid browsers
document.querySelectorAll('input[type="tel"]').forEach(function() { .... })

Open in new window

If you MUST allow IE11, then spread will do it and still be more readable
[...document.querySelectorAll('input[type="tel"]')].forEach(function() { .... })

Open in new window

@Michel Plungjan can you show us the working example?
I would delegate from the nearest container of the form - Here I assume a div with id="formWrapper"

document.getElementById("formWrapper").addEventListener("input", function(e) {
  const tgt = e.target;
  if (!tgt.matches("[type=tel]")) return; // not a telephone - if you have more validations, use an if (tgt.matches("[type=tel]")) { validation here }
  const x = tgt.value.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
  tgt.value = !x[2] ? x[1] : '(' + x[1] + ') ' + x[2] + (x[3] ? '-' + x[3] : '');
})

Open in new window

document.getElementById("formWrapper") ? what it is?
See my updated comment
Michel, you're looking at the first post, which I wrote on the fly...

The subsequent post, works like a charm.
@Ron you still have unnecessary "call" and I saw "Still doesn't work" in the comments
I did try that in the fiddle, but it wasn't working... not sure why.

It's 7 lines of code.
I still prefer delegation, but here is your version without the call

https://jsfiddle.net/mplungjan/uvfbzdny/
It is demonstrated, working, in jsfiddle.net link I posted.


https://jsfiddle.net/tckuej4s/6/#&togetherjs=HbQ8n9wzxv

Cool, thanks, ..That's what I tried, but must have missed a bracket or something.
Either way it works..
Ok, it is working, I just do not like eventListener or each field and  the .call. in your code
We shouldn't assume he has everything under form wrapper div though.  That wasn't part of the question.
According to the question, this is all dynamically generated.
No need to assume. We can recommend and I strongly recommend.

If there is no wrapper and the page is short, then my code will work with

document.addEventListener("input", function(e) {

too
ITsolutionWizard ,   ...can we get an update if this is working for you?
"read and loop element inside of the form."
The question is answered with this line const elems = document.querySelectorAll('input[type="tel"]');  
"how" one chooses to loop through the array is a matter of preference, as there are about 100 ways to do it.  If we really want to shorthand it, we could always go with jQuery and accomplish all of it in one long line of code.
ASKER CERTIFIED SOLUTION
Avatar of lenamtl
lenamtl
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial