Number only validation not working in ionic app - javascript

<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

Related

how prevent user typing special character in android browsers on keydown event (event.preventDefault not wotking)

the event.preventDefault does not working in android as I know.
so what is the best alternative way to prevent user typing special character in android on keydown event.
note: the replace value solution when input event fired is good but in my situation doesn't solve the problem.
In my case, the problem with replacing value on input event on Android, was with caret, that jumped to wrong position while typing.
I’ve solved it like this:
let input = document.getElementById("input")
function withoutForbiddenChars(str) {
// change to your set of chars
return str.replace(/[^\d]+/g, '')
}
function handleInput(event) {
let charsBeforeCaret = input.value.slice(0, input.selectionStart)
let charsAfterCaret = input.value.slice(input.selectionStart)
charsBeforeCaret = withoutForbiddenChars(charsBeforeCaret)
charsAfterCaret = withoutForbiddenChars(charsAfterCaret)
input.value = charsBeforeCaret + charsAfterCaret
let newCaretPos = charsBeforeCaret.length
input.selectionStart = newCaretPos
input.selectionEnd = newCaretPos
}
input.addEventListener('input', handleInput, false)
Demo: https://codepen.io/udovichenko/pen/vYWWjmR

I cant make inputmask to work with vanilla JS

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>

Prevent invalid formats based on given regex

I have a regex for a set of use cases
Based on that regex I'm trying to prevent the user to type invalid formats.
The regex works and preventing the user adding invalid formats also works.
The part with which I'm struggling now is that if the default value is invalid, the user cannot add additional valid characters.
Here is what I have: http://jsfiddle.net/jgqco7by/2/.
<input id="myInput" type="text" value="co vi1d-" />
var previousValue = document.getElementById('myInput').value;
var pattern = /^[a-zA-Z]+(?:[ -][a-zA-Z]+)*([ ]|[-])?$/g;
function validateInput(event) {
event = event || window.event;
var newValue = event.target.value || '';
if (newValue.match(pattern)) {
// Valid input; update previousValue:
previousValue = newValue;
} else {
// Invalid input; reset field value:
event.target.value = previousValue;
}
}
document.getElementById('myInput').oninput = validateInput;
In this example since I have a default value which contains a number, which is not allowed, everything I type is replaced with previous value because the regex keeps coming back as invalid.
How could I build this so that, if the default value is invalid, the user can still add additional VALID values without having to remove the default invalid values first?
If you want to have the invalid data and a valid one in the same input I'm not seeing how it will happened with your approach.
If you want to have an initial value (that can be either valid or invalid) and then to append something (which is valid) then why are you checking for the initial state.
The third variant is to have both
Empty field and putting a valid chars only
Initial value (valid or invalid) and appending something (valid)
And the result will be to have a valid stuff.
Please place your question / requirement in a more structured manner.
As for the code I would suggest to change your regex. I can give suggestions for modification. :)
For the code:
<input id="myInput" type="text" value="co vi1d-" />
<p id="messageField"></p>
(function() {
const pattern = new RegExp(/^[a-zA-Z]+(?:[ -][a-zA-Z]+)*([ ]|[-])?$/g);
const messageField = document.getElementById('messageField');
function validateInput(event) {
var newValue = event.target.value; // no sense to have a check and to overwrite with window.event , its a different context
messageField.innerText = pattern.test(newValue) ? '' : 'incorrect input'; // its better to use test() method rather than match()
}
document.getElementById('myInput').oninput = validateInput;
}());

How to change user English number to Persian/Arabic instantly after user writes in the input tag?

i'm using Vuejs and I want to prevent input tag from showing user's characters and replace it with my own characters(which is some numbers).
I have already used #onchange and Watch and also getters and setters in computed. the problem is the character instantly appears on input and then changes to what i want.
<input v-model="phonenumber" id="downloadlink" v-
on:keydown="sendDownloadLink" placeholder=""
maxlength="11" autocomplete="off"
>
and in methods:
sendDownloadLink(e){
this.phonenumber = this.toPersianNum(this.phonenumber);
}
Thanks in Advance.
There are a few problems here that are difficult to overcome:
Only the input event is a reliable. Keyboard events won't necessarily fire if the value changes by copy/paste or drag/drop.
The input event fires after the input has been updated, so the characters the user types will be seen, albeit briefly, until the event listener can change them.
If the user changes characters in the middle of the value the position of the text cursor will jump to the end when updating the value to use the new numerals.
One way this could be approached is by using a font that shows the desired numerals for the characters 0 to 9. This would dodge most of the difficulties.
The code below attempts a JavaScript solution instead. It uses the input event as a catch-all. To try to prevent the wrong characters showing temporarily it cancels the keypress event and makes the necessary changes to the value itself. In all cases it tries to preserve the position of the text cursor using setSelectionRange.
This is not a particularly good demonstration of 'correct' Vue usage but I'm not sure the functionality can be achieved without resorting to direct DOM manipulation.
new Vue({
el: '#app',
data() {
return {
phoneNumber: ''
}
},
methods: {
getInputValue() {
const input = this.$refs.input
const value = input.value
const start = input.selectionStart
const end = input.selectionEnd
return [
value.slice(0, start), // before selection
value.slice(start, end), // selection
value.slice(end) // after selection
]
},
onInput() {
this.setInputValue(...this.getInputValue().map(this.toArabicNumerals))
},
onKeyPress(ev) {
ev.preventDefault()
const [before, , after] = this.getInputValue()
const keyValue = this.toArabicNumerals(ev.key)
this.setInputValue(before + keyValue, '', after)
},
setInputValue(before, selection, after) {
const input = this.$refs.input
const start = before.length
const end = start + selection.length
this.phoneNumber = input.value = before + selection + after
input.setSelectionRange(start, end)
},
toArabicNumerals(str) {
return str.split('').map(chr => {
if ('0' <= chr && chr <= '9') {
return String.fromCharCode(+chr + 1632)
}
if ('\u0660' <= chr && chr <= '\u0669') {
return chr
}
return ''
}).join('')
}
}
})
<script src="https://unpkg.com/vue#2.6.10/dist/vue.js"></script>
<div id="app">
<input
ref="input"
:value="phoneNumber"
#input="onInput"
#keypress="onKeyPress"
>
</div>
You may find that you can remove the onKeyPress listener altogether. On the hardware I had available for testing it didn't seem to make any difference but that might not be true for slower machines. The method setInputValue updates the <input> element's value directly and it may be that that is sufficient to get the desired results without the need for onKeyPress.

How to get the -real- last character typed in input with maxlength?

I wanted to know which character the user is typing into an input:
I have an input:
<input maxlength="20"/>
and a script that returns the last typed char:
var eingabe;
$('form').on('keypress', function(event) {
/// if no whitespace:
if (String.fromCharCode(event.keyCode).replace(/\s/g, "").length > 0) {
eingabe = String.fromCharCode(event.keyCode);
$('#eingabe').html("<div>Eingabe : "+ eingabe +"</div>");
}
});
My question is:
because my input has a maxlength attribute, the last typed character on the keyboard is sometimes not the last -real- typed character into the input because the input is "full". How can I get the last character typed into the input?
I haven't tried it, but it must work...
Set onkeypress= or onkeydown= on the Input element and store the key value in a LastChr variable.
I had a similar problem. I wanted to call a function if the user types a specific character into my input field. I solved it with the following:
var input = document.getElementById('myInput');
input.addEventListener('input', function() {
// Get cursor position
var start = this.selectionStart;
// Get last typed character
var lastChar = String.fromCharCode(this.value.charCodeAt(start - 1));
if(lastChar === '[YOURCHARHERE]') {
// do something
}
});
Please keep in mind, that 'input' is only supported down to IE8, but if you don't care about a proprietary browser, you should be fine. I hope this helps.
Inside your function, use the value of the input element to get the last character like $('#input_field').val().substr($('#input_field').val().length - 1) or use your best coding skill to accomplish something similar without accessing the field twice, wink wink.
Use keyup instead:
$('form').on('keyup', function(event) {
var cursorPos = event.target.selectionStart;
var lastTypedChar = elem.target.value[cursorPos - 1];
});

Categories

Resources