I cant make inputmask to work with vanilla JS - javascript

I would like to use inputmask without jquery loaded and directly in the browser with vanilla JS. But it seems to always require jQuery:
var selector = document.getElementById("gg");
Inputmask({mask:"9999"}).mask(selector);
<script src="https://rawgit.com/RobinHerbots/Inputmask/5.x/dist/inputmask.min.js"></script>
<input type="text" id="gg">
(Open console and you will see Uncaught ReferenceError: $ is not defined)
Any ideas?

The version you're using (5.x → 5.0.4) is in beta, so it may be broken (it is). You should use the latest stable release, which is 5.0.3 as of now:
var selector = document.getElementById("gg");
Inputmask({mask:"9999"}).mask(selector);
<script src="https://rawgit.com/RobinHerbots/Inputmask/5.0.3/dist/inputmask.min.js"></script>
<input type="text" id="gg">

After searching for it for a while I decided to code my own and it worked perfectly for what I needed:
// Element constants
const maskedInputs = document.querySelectorAll('input[data-mask]')
// Base configuration for all masked inputs
for (const input of maskedInputs) {
// Get the input's mask
let mask = input.getAttribute('data-mask')
// Get the input's mask reverse boolean
const reverse = input.getAttribute('data-mask-reverse') !== null
// Stores a boolean value to indicate if the mask ends with a numeric character
const maskEndsWithNumber = !isNaN(mask.charAt(mask.length - 1))
// If the data-mask-reverse attribute exists, reverse the mask string
if (reverse) {
mask = [...mask].reverse().join('')
}
// Separate the numeric parts from the mask
const numericParts = mask.split(/[^\d]/g).filter(part => !!part.length)
// Add the regex format to all parts
const regexParts = numericParts.map(m => `([\\d#]\{${m.length}\})`)
// Join the regex parts to create the final regex
const maskRegex = new RegExp(regexParts.join(''))
// Calculates the full length of numeric characters
const fullLength = numericParts.join('').length
// Initiates the group counter
let i = 1
// Creates the group mask string
const maskReplace = mask.replace(/\d{1,}/g, () => `\$${i++}`)
// Set the input's max length to the size of the mask
input.setAttribute('maxlength', mask.length)
// Function to handle the input events
function maskHandler(e) {
// Get the input's current value
let { value } = input
// Removes the last character if the user deleted the last non-numeric character
if (e.type === 'keydown' && e.keyCode == 8 && isNaN(value.charAt(value.length - 1))) {
value = value.replace(/\d[^\d]{1,}$/, '')
e.preventDefault()
}
// Removes all non-numeric characters from it
value = value.replace(/[^\d]/g, '')
// Reverse the string if needed
if (reverse) {
value = [...value].reverse().join('')
}
// Fill the string with '#'
value = value.padEnd(fullLength, '#')
// Apply the mask
value = value.replace(maskRegex, maskReplace)
// Get the end of the numeric part (start of the '#' fill)
const fillIndex = value.indexOf('#')
// Checks if the fill character exists
if (fillIndex !== -1) {
// Remove the '#' fill
value = value.slice(0, fillIndex)
}
// Assures the string ends with a numeric character
if (maskEndsWithNumber) {
value = value.replace(/[^\d]$/, '')
}
// Restore the right order of the string
if (reverse) {
value = [...value].reverse().join('')
}
// Update the input's value
input.value = value
}
// Handles the onkeyup, keydown and change events on the masked input
input.addEventListener('keyup', maskHandler)
input.addEventListener('keydown', maskHandler)
input.addEventListener('change', maskHandler)
}
This makes every input element with the "data-mask" attribute have the specified mask applied to it automatically. Another attributed I included was "data-mask-reverse" which is a boolean attribute for when you need the values to fill the mask in reverse (I used it for monetary values):
<!-- Mask example -->
<input type="text" data-mask="9999/9999">
<!-- Reversed mask example -->
<input type="text" data-mask="999,999,999.99" data-mask-reverse>

Related

Vue3/Javascript - Unable to create an input that only excepts numbers

I have a project with a input that only excepts numbers.
Inside the template I have defined a input with the value set to the variable that is being changed and the input being set to the function that checks if it is a number:
<input
:value="ie"
#input="(evt) => changeIE(evt)"
type="number"
min="0"
/>
Then in the setup function I have declared a ref ie. This contains the actual value that is being set by the input. I also have declared the `changeIE' function. Here I first get the input text from the evt. Then I check if the last entered character is a number. If not I remove the last character from the string. The next step is to parse the string to an Integer. And lastly I set the value of the variable to the new value of the input.
const ie = ref('');
const changeIE = (evt) => {
let value = 0;
let input = evt.target.value;
let isnum = /^\d+$/.test(input[input.length - 1]);
if (!isnum) input = input.slice(0, -1);
if (input !== '') value = parseInt(input);
ie.value = value;
};
The problem is that the input keeps on excepting non numerical numbers even tough I check if they are numbers and if not I remove that character from the string.
Try to use the v-model with number as modifier and set initial value to 0 :
<input
v-model.number="ie"
type="number"
min="0"
/>
and :
const ie=ref(0)
DEMO
try
const ie = ref(null) // instead of ref('')
By default you set it to a string

Number only validation not working in ionic app

<input type="tel" (keydown)="numberOnlyValidation($event)">
// Function not able to read input number values
// On typing into the input field nothing in showing mainly not able to read the keyboard number values
numberOnlyValidation(event: any) {
console.log(event.target.value)
//pattern
const pattern = /[0-9]/;
const inputChar = String.fromCharCode(event.charCode);
if (!pattern.test(inputChar)) {
// invalid character, prevent input
event.preventDefault();
}
}
``
The .charCode property only exists on the keypress event Keyboard Event (developer.mozilla.org)
The specification says to use the KeyboardEvent.key property instead (developer.mozilla.org)
Apart from handling delete, your code should work if you change this line to utilize event.key
const inputChar = String.fromCharCode(event.charCode); // remove
const inputChar = event.key; // add

How can I retain the expected cursor position when auto formatting a number with commas?

I have an input where I want to replace the value of the number on keyup event. Using Intl.NumberFormat().format(num); to accomplish this.
All is fine and it works great until you click inside of the already formatted value and start adding more numbers, the cursor jumps.
I tried to solve this by setting the cursor, but it still behaves badly.
In short, how can I change this snippet so that no matter where you edit the value, the cursor remains in the expected position?
const input = document.getElementById("foo");
input.addEventListener("keyup", handleKeyUp);
function handleKeyUp(e) {
const num = e.target.value.replace(/,/g, "");
const formatted = new Intl.NumberFormat().format(num);
var cursor = e.target.selectionStart;// + 1;
input.value = formatted;
e.target.setSelectionRange(cursor, cursor);
}
// Try the following
// 1) 123456789
// 2) 123
// 3) place cursor between the 1 and 2 and add a number
// If I ++cursor then #1 is resolved
// And #2 initially appears to be resolved unless I keep going with more numbers
<input id="foo" type="text">
Not a very elegant solution, but I moved the cursor based on if a comma was added/removed from the text field (left or right respectively).
See snippet below:
const input = document.getElementById("foo");
input.addEventListener("keyup", handleKeyUp);
let commas = 0;
function handleKeyUp(e) {
const num = e.target.value.replace(/,/g, "");
const formatted = new Intl.NumberFormat().format(num);
// get total commas in number
let totalCommas = (formatted.match(/,/g) || []).length;
var cursor = e.target.selectionStart;
if(commas > totalCommas) {
//shift cursor to the left (a comma was removed)
commas--;
cursor--;
} else if (commas < totalCommas){
// shift cursor to the right (a comma was added)
commas++;
cursor++;
}
input.value = formatted;
e.target.setSelectionRange(cursor, cursor);
}
// Try the following
// 1) 123456789
// 2) 123
// 3) place cursor between the 1 and 2 and add a number
// If I ++cursor then #1 is resolved
// And #2 initially appears to be resolved unless I keep going with more numbers
<input id="foo" type="text">

Filtering ranges of letters in Javascript

I have to create a program that takes the first letter of a prompt, and if that letter is between a and k, then it has to produce a certain output, if it's between l and p another and so on. Is there a way to do this without writing every letter of the alphabet down? (sorry I'm a new coder)
I think you should try to solve the problem, before asking - so you can show what you've already tried.
I think the snippet below points you in the right direction - but it takes any character, not just letters. You need to get everything filtered out that's not a lower case letter.
// UI elements
const input = document.getElementById('input1')
const result = document.getElementById('result')
// input event
// only the first character is taken into account
input.addEventListener('input', function(e) {
// adding the characters of the input value to an array, and
// picking the 0th element (or '', if there's no 0th element)
const a = [...this.value][0] || ''
let ret = ''
if (a !== '') {
// lowercaseing letters, so it's easier to categorize them
ret = categorizeAlphabet(a.toLowerCase().charCodeAt(0))
} else {
ret = 'The input is empty'
}
// displaying the result
result.textContent = ret
})
// you could use this function to filter and categorize
// according to the problem ahead of you - and return the result
// to be displayed.
// In this example this function is rather simple, but
// you can build a more complex return value.
const categorizeAlphabet = (chCode) => {
return `This is the character code: ${chCode}`
}
<label>
First character counts:
<input type="text" id='input1'>
</label>
<h3 id="result">The input is empty</h3>

Validate salary input jQuery

I'm trying to validate input value must be like 1.400,00 and 12.000,00.
If input has the correct value, it should remove the disabled class from the else stays disabled.
I tried like this but did't get success :(
<input id="ex2" class="salary" type="number" placeholder="1.400,00 - 12.000,00" name="salaryRange2"/>
Next Step
$("#ex2").on("keyup", function(){
var valid = /^\d{1,6}(?:\.\d{0,2})?$/.test(this.value),
val = this.value;
if(valid){
console.log("Invalid input!");
this.value = val.substring(0, val.length - 1);
$("#checkSalary1").removeClass("disabled");
}
else{
$("#checkSalary1").addClass("disabled");
}
});
Can anyone help how can achieve this condition?
Thanks in advance
Your regex is way out, something like this gets you a little closer:
^\d{1,2}.\d{3},\d{2}$
Which looks for:
1-2 digits
a literal .
3 digits
a literal ,
2 digits
You may like to enhance this to make the decimal portion optional.
From there, you need to actually parse the string to a number to check it is within the valid numerical range (as, for example 95.000,00 would pass on a regex check, but not in the range check.
The number input value is a ... Number, so you can just use a numeric comparison, no RegExp needed. Furthermore, the keyup event will not trigger if you use a mouse to increment or decrement its value.
Here's a snippet that continuously checks the salary input value, enables or disables the button as applicable and shows a message about the input value validity. To make your live even easier, for a [type=number]-input you can also set a minimum and maximum value by the way (used in the snippets checkValue method).
See also
(() => {
const inputElement = document.querySelector("#ex2");
const report = document.querySelector("#report");
const bttn = document.querySelector("button");
const getAction = cando => cando ? "removeAttribute" : "setAttribute";
const checkVal = val => val
&& val >= +inputElement.getAttribute("min")
&& val <= +inputElement.getAttribute("max");
const messages = {
cando: "Ok to submit",
noValue: "Waiting for input (1.400,00 - 12.000,00)",
invalid: "Value should be from 1.400,00 up to 12.000,00"
};
inputElement.focus();
checkValue();
function checkValue() {
const val = inputElement.value;
const cando = checkVal(val);
report.innerHTML = !val
? messages.noValue
: cando
? messages.cando
: messages.invalid;
bttn[getAction(cando)]("disabled", true);
return setTimeout(checkValue, 200);
}
})();
<input id="ex2"
class="salary"
type="number"
min="1400"
max="12000"
step="0.01"
name="salaryRange2"/>
<button disabled>submit</button> <span id="report"></span>

Categories

Resources