Replace input value on typing in JS - javascript

I have an input with maxLength of 1. I want that if I type another value (key) the current value (letter) that inside the input will be replaced with the new value (letter of key).
I've tried something like that:
container.addEventListener('keyup', function (e) {
var target = e.srcElement || e.target;
var letter = target.value;
var newLetter = letter.replace(/letter/g, letter);
letter.value = newLetter;
});

You can update the value of the input box using this.value and get the key pressed using e.key. This will, however, enter meta keys if pressed:
const container = document.getElementById('container');
container.addEventListener('keyup', function(e) {
this.value = e.key;
});
<input type="text" id="container" maxlength="1" />
The issue with the meta keys could be fixed by checking whether or not e.key is an alphabetic/digit letter by using a regular expression:
const container = document.getElementById('container');
container.addEventListener('keyup', function({key}) {
if(/^[a-z0-9]$/i.test(key)) {
this.value = key;
}
});
<input type="text" id="container" maxlength="1" />

This works for all single character inputs while excluding the space character:
let container = document.getElementById('container');
container.addEventListener('keyup', function (e) {
let valueLength = this.value.length;
if(this.value == " ") {
this.value = "";
return;
}
if(valueLength == 1) {
if( !e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey
&& e.code != "Space" && e.key.length == 1) {
this.value = e.key;
}
}
});
<input id="container" type="text" value="" maxLength="1" />

Related

set maxlength value dynamically in html

I have input field, with maxlength = 6 and ng-pattern="/^[0-9]{1,6}$/" accepting only numeric values.
On on-blur event I'm formatting the 6 digit code ("123456") to "12-34-56" and browser remembers the formatted value i.e. 12-34-56
next time when I try to auto fill the field using remembered data by browser,
it only fill 4 digits.
How can I fill all the 6 digits. I tried to set the maxlength = 8 when text contains -, but it didn't help.
I prefer solving this kind of issue by rethinking task.
Instead of changing maxLength attribute, change input format. It would be better if user can enter data in "40-15-15" format.
var part1 = document.querySelector("#part1")
var part2 = document.querySelector("#part2")
var part3 = document.querySelector("#part3")
part1.onkeyup = function(el) {
if(isNaN(el.key) && el.key !== "Backspace") {
part1.value = part1.value.slice(0, -1)
}
if (part1.value.length === 2) {
part2.focus()
}
console.log(part1.value + part2.value + part3.value)
}
part2.onkeyup = function(el) {
if(isNaN(el.key) && el.key !== "Backspace") {
part2.value = part2.value.slice(0, -1)
}
if (part2.value.length === 0 && el.key === "Backspace") {
part1.focus()
}
if (part2.value.length === 2) {
part3.focus()
}
console.log(part1.value + part2.value + part3.value)
}
part3.onkeyup = function(el) {
if(isNaN(el.key) && el.key !== "Backspace") {
part3.value = part3.value.slice(0, -1)
}
if (part3.value.length === 0 && el.key === "Backspace") {
part2.focus()
}
console.log(part1.value + part2.value + part3.value)
}
input {
width: 3em;
}
<input type="text" id="part1" maxlength="2" /> -
<input type="text" id="part2" maxlength="2" /> -
<input type="text" id="part3" maxlength="2" />

How can I validate field input against a regex when pasting?

I want to validate an input field with regex (replacing all vowels).
The input should always be matched against that regex, regardles if typed into or pasted into that field.
I know how to deal with the typing part, but I need help for copy - paste.
All vowels should be skipped (e.g.: "abcde" copy --> "bcd" paste)
$('document').ready(function(){
var pattern = /[aeiou]/ig;
$("#input").on("keypress keydown", function (e) {
if (e.key.match(pattern) !== null) {
e.preventDefault();
}
});
$("#input").on("paste", function (e) {
var text = e.originalEvent.clipboardData.getData('Text');
e.preventDefault();
//TODO... replace all vowels
console.log(text);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type='text' id='input'/>
At first i tried to replace them and just set the value with $('#input').val($('#input').val() + copiedValue), but this only works if the cursor is at the end of the input.
A one in all solution subscribes to the input event. In addition to the sanitizing tasks the handler has to take care of reestablishing the input fields exact or most expected cursor/caret position in order to not break the user experience ...
function getSanitizedValue(value) {
return value.replace(/[aeiou]/ig, '');
}
function handleInput(evt) {
evt.preventDefault();
const elmNode = evt.currentTarget;
const currentValue = elmNode.value;
const sanitizedValue = getSanitizedValue(currentValue);
if (currentValue !== sanitizedValue) {
const diff = sanitizedValue.length - currentValue.length;
const { selectionStart, selectionEnd } = elmNode;
elmNode.value = sanitizedValue;
elmNode.selectionStart =
(selectionStart + diff > 0) ? selectionStart + diff : selectionStart;
elmNode.selectionEnd =
(selectionEnd + diff > 0) ? selectionEnd + diff : selectionEnd;
}
}
$('document')
.ready(() => {
$("#input").on("input", handleInput);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type='text' id='input'/>
One method would be to manipulate the value of the text field from the paste event:
$('document').ready(function(){
var pattern = /[aeiou]/ig;
$("#input").on("keypress keydown", function (e) {
if (e.key.length == 1 && !e.ctrlKey && !e.altKey && e.key.match(pattern) !== null) {
e.preventDefault()
}
});
$("#input").on("paste", function (e) {
var text = e.originalEvent.clipboardData.getData('Text').replace(pattern, "");
e.preventDefault();
let input = e.originalEvent.target,
start = input.selectionStart,
end = input.selectionEnd;
input.value = input.value.substr(0, start) + text + input.value.substr(end);
input.selectionStart = start + text.length;
input.selectionEnd = input.selectionStart;
//TODO... replace all vowels
console.log(text, input.value);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type='text' id='input'/>

html Input type number with Thousand Separator

i want to add thousand separator on keyup event in input type number
but this work just in 6 character, if more than 6 character, value on input has reseted
this my short code
<input type="number" id="tanpa-rupiah" step="any">
var dengan_rupiah = document.getElementById('dengan-rupiah');
dengan_rupiah.addEventListener('keyup', function(e)
{
dengan_rupiah.value = formatRupiah(this.value, 'Rp. ');
});
function formatRupiah(bilangan, prefix)
{
var number_string = bilangan.replace(/[^,\d]/g, '').toString(),
split = number_string.split(','),
sisa = split[0].length % 3,
rupiah = split[0].substr(0, sisa),
ribuan = split[0].substr(sisa).match(/\d{1,3}/gi);
if (ribuan) {
separator = sisa ? '.' : '';
rupiah += separator + ribuan.join('.');
}
rupiah = split[1] != undefined ? rupiah + ',' + split[1] : rupiah;
return prefix == undefined ? rupiah : (rupiah ? 'Rp. ' + rupiah : '');
}
this my fiddle https://jsfiddle.net/C2heg/4619/
This might suit you. On keydown prevent the default action if it is not a number key. On keyup, parse the value and update it. Use the data- attributes to store and get the original value.
var elem = document.getElementById("num");
elem.addEventListener("keydown",function(event){
var key = event.which;
if((key<48 || key>57) && key != 8) event.preventDefault();
});
elem.addEventListener("keyup",function(event){
var value = this.value.replace(/,/g,"");
this.dataset.currentValue=parseInt(value);
var caret = value.length-1;
while((caret-3)>-1)
{
caret -= 3;
value = value.split('');
value.splice(caret+1,0,",");
value = value.join('');
}
this.value = value;
});
function showValue()
{
console.log(document.getElementById("num").dataset.currentValue);
}
<input type="text" id="num" maxlength="30">
<button onclick="showValue()">Get Value</button>
Ok I have posted answer below. I have added limit of 20 numbers. You can change it as per your need.
You can use Number.toLocaleString() for this purpose.
Below is working example:
// When ready.
$(function() {
var extra = 0;
var $input = $("#amount");
$input.on("keyup", function(event) {
// When user select text in the document, also abort.
var selection = window.getSelection().toString();
if (selection !== '') {
return;
}
// When the arrow keys are pressed, abort.
if ($.inArray(event.keyCode, [38, 40, 37, 39]) !== -1) {
if (event.keyCode == 38) {
extra = 1000;
} else if (event.keyCode == 40) {
extra = -1000;
} else {
return;
}
}
var $this = $(this);
// Get the value.
var input = $this.val();
var input = input.replace(/[\D\s\._\-]+/g, "");
input = input ? parseInt(input, 10) : 0;
input += extra;
extra = 0;
$this.val(function() {
return (input === 0) ? "" : input.toLocaleString("en-US");
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="amount" name="amount" type="text" maxlength="20" />
change your the input type equal to "text" then its work
<input type="text" id="tanpa-rupiah" step="any">
checkout jsfiddle

jquery- How to automatically insert colon after entering 2 numeric digits

I want a to have a text box which accepts HH:MM(hours/minutes) format. So, when the user enters the value for HH, it should automatically insert a colon after that and let the user enter value for MM.
I do not want to use any plugin for this.
How do i do this?
thanks
HTML:
<input class="time" type="text"/><br/>
<input class="time" type="text"/><br/>
<input class="time" type="text"/>
JS:
var time = document.getElementsByClassName('time'); //Get all elements with class "time"
for (var i = 0; i < time.length; i++) { //Loop trough elements
time[i].addEventListener('keyup', function (e) {; //Add event listener to every element
var reg = /[0-9]/;
if (this.value.length == 2 && reg.test(this.value)) this.value = this.value + ":"; //Add colon if string length > 2 and string is a number
if (this.value.length > 5) this.value = this.value.substr(0, this.value.length - 1); //Delete the last digit if string length > 5
});
};
Fiddle
If you have multiple inputs
<input class="test-input" placeholder="hh:mm" value=""/>
<input class="test-input" placeholder="hh:mm" value=""/>
<input class="test-input" placeholder="hh:mm" value=""/>
<input class="test-input" placeholder="hh:mm" value=""/>
<input class="test-input" placeholder="hh:mm" value=""/>
Jquery Version:
$(document).on('ready',function(){
$('.test-input').on('keyup',keyUpHandler);
});
function keyUpHandler(e){
var element = this;
var key = e.keyCode || e.which;
insertTimingColor(element,key)
}
function insertTimingColor(element,key){
var inputValue = element.value;
if(element.value.trim().length == 2 && key !== 8){
element.value = element.value + ':';
}
}
fiddle - jquery
Vanilla JS version
document.body.addEventListener('keyup',keyUpHandler,false);
function keyUpHandler(e){
var evt = e || window.event;
var target = evt.target || evt.srcElement;
var key = e.keyCode || e.which;
//check if it is our required input with class test input
if(target.className.indexOf('test-input') > -1){
insertTimingColor(target,key)
}
}
function insertTimingColor(element,key){
var inputValue = element.value;
if(element.value.trim().length == 2 && key !== 8){
element.value = element.value + ':';
}
}
fiddle - js
$('id or class or parent id').on('keypress','class or id', function (e){
var key = e.keyCode || e.which;
if(this.value.trim().length == 2 && key !==8 && this.value.search
(':') != -1)
this.value = this.value + ':';
});
$('id or class or parent id').on('keyup click','class or id', function (e){
if(this.value.length >= 3)
this.selectionStart = this.selectionEnd = this.value.length;
});
$('id or class or parent id').on('paste','class or id', function (e){
e.preventDefault();
});
Try it.
jQuery("#textboxId").keypress(function(){
if(jQuery("#textboxId").val().length)==2{
var value=jQuery("#textboxId").val();
jQuery("#textboxId").val(value+":");
}
});
Try the following code:
HTML:
<input type="text" id = "timeInput" maxlength = 14>
Javascript:
$("#timeInput").focusin(function (evt) {
$(this).keypress(function () {
content=$(this).val();
content1 = content.replace(/\:/g, '');
length=content1.length;
if(((length % 2) == 0) && length < 10 && length > 1){
$('#timeInput').val($('#timeInput').val() + ':');
}
});
});
DEMO
$(document).ready(function() {
var global_flag = true;
$("#texboxId").on('keyup', function() {
var cur_val = $(this).val();
var cur_length = cur_val.length;
var flag = true;
if (cur_length > 5) {
cur_val = cur_val.substring(0, 5);
$(this).val(cur_val);
} else {
if (cur_length > 2) {
global_flag = false;
} else if (global_flag == false && cur_length < 2) {
global_flag = true;
}
if (cur_length == 2 && global_flag) {
if (window.event.keyCode != 8) {
$(this).val(cur_val + ":");
}
}
if (cur_length == 5) {
if (cur_val.match(/^(([0-1][0-9]){0,2}|(2[0-3]){0,2}){0,2}:([0-5][0-9]){0,2}$/)) {} else {
$(this).val("");
$(this).attr('placeholder', "HH:MM");
}
}
}
});
});
The code below should do the trick for you. Now all you will need to do is add some validation, like only allowing numeric key press values.
<input id="time-input" placeholder="hh:mm" type="text">
$(document).ready(function(){
$("#time-input").keypress(function(){
$this = $(this);
if($this.val().length == 2){
$this.val($this.val() + ":");
}
});
});
http://jsfiddle.net/g9nahpax/

HTML5 restricting input characters

Is it possible to restrict the input of certain characters in HTML5/JavaScript? For example, could I have an input textbox on the screen and if the user tries to type a letter in it, it wouldn't show up in the box because I've restricted it to only numbers?
I know you can use a pattern which will be checked on submit, but I want the "bad" characters to just never be entered at all.
The input textbox
<input type="text" onKeyDown="myFunction()" value="" />
JavaScript
function myFunction() {
var e = event || window.event; // get event object
var key = e.keyCode || e.which; // get key cross-browser
if (key < 48 || key > 57) { //if it is not a number ascii code
//Prevent default action, which is inserting character
if (e.preventDefault) e.preventDefault(); //normal browsers
e.returnValue = false; //IE
}
}
Use html5 pattern attribute for inputs:
<input type="text" pattern="\d*" title="Only digits" />
OR
Use html5 number type for input :
<input type="number" />
To slightly improve off of jonhopkins excellent answer, I added backspace and delete key acceptance like so:
function inputValidate(){
var e = event || window.event;
var key = e.keyCode || e.which;
if (((key>=48)&&(key<=57))||(key==8)||(key == 46)) { //allow backspace //and delete
if (e.preventDefault) e.preventDefault();
e.returnValue = false;
}
}
For Restricting Characters symbols like '-' and ','
<input type="text" pattern="[^-,]+">
for restricting numbers
<input type="text" pattern="[^0-9]+">
for restricting letters of the alphabet
<input type="text" pattern="[^a-zA-Z]+">
KeyboardEvent.keyCode is deprecated, so here's a solution using the HMLElement.input event. This solution uses a simple regex, and handles copy-paste nicely as well by just removing the offending elements from any input.
My regex: /[^\w\d]/gi
Matches anything not (^) a word character (\w: a-z) or a digit (\d: 0-9).
g modifier makes regex global (don't return after first match)
i modifier makes regex case insensitive
With this regex, special characters and spaces won't be allowed. If you wanted to add more, you'd just have to add allowed characters to the regex list.
function filterField(e) {
let t = e.target;
let badValues = /[^\w\d]/gi;
t.value = t.value.replace(badValues, '');
}
let inputElement = document.getElementById('myInput');
inputElement.addEventListener('input', filterField);
<input id="myInput" type="text" style="width: 90%; padding: .5rem;" placeholder="Type or paste (almost) anything...">
//improved wbt11a function
function numberFieldStrictInput(allowcomma, allownegative) {
var e = event || window.event; // get event object
var key = e.keyCode ||`enter code here` e.which; // get key cross-browser
if(key==8 || key==46 || key == 9 || key==17 || key==91 || key==18 ||
key==116 || key==89 || key==67 || key==88 || key==35 || key==36) //back, delete tab, ctrl, win, alt, f5, paste, copy, cut, home, end
return true;
if(key == 109 && allownegative)
return true;
if(key == 190 && allowcomma)
return true;
if(key>=37 && key<=40) //arrows
return true;
if(key>=48 && key<=57) // top key
return true;
if(key>=96 && key<=105) //num key
return true;
console.log('Not allowed key pressed '+key);
if (e.preventDefault) e.preventDefault(); //normal browsers
e.returnValue = false; //IE
}
//on input put onKeyDown="numberFieldStrictInput(1,0)"
What about this (it supports special keys, like copy, paste, F5 automatically)?
function filterNumericInput() {
var e = event || window.event; // get event object
if (e.defaultPrevented) {
return;
}
const key = e.key || e.code;
if ((e.key.length <= 1) && (!(e.metaKey || e.ctrlKey || e.altKey))) {
if (!((key >= '0' && key <= '9') || (key === '.') || (key === ',') || (key === '-') || (key === ' '))) {
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
}
}
}
Limit input to letters, numbers and '.' (for React users only)
Here is my simple solution, I couldn't find a better solution for React and made my own. 3 steps.
First, create a state.
const [tagInputVal, setTagInputVal] = useState("");
Then, use the state as input value (value={tagInputVal}) and pass the event to the onChange handler.
<input id="tag-input" type="text" placeholder="Add a tag" value={tagInputVal} onChange={(e) => onChangeTagInput(e)}></input>
Then, set the value of the event inside onChange handler.
function onChangeTagInput(e) {
setTagInputVal(e.target.value.replace(/[^a-zA-Z\d.]/ig, ""));
}
var keybNumberAndAlpha = new keybEdit(' 0123456789abcdefghijklmnopqrstuvwxyz');
function keybEdit(strValid, strMsg) {
var reWork = new RegExp('[a-z]','gi'); // Regular expression\
// Properties
if(reWork.test(strValid))
this.valid = strValid.toLowerCase() + strValid.toUpperCase();
else
this.valid = strValid;
if((strMsg == null) || (typeof(strMsg) == 'undefined'))
this.message = '';
else
this.message = strMsg;
// Methods
this.getValid = keybEditGetValid;
this.getMessage = keybEditGetMessage;
function keybEditGetValid() {
return this.valid.toString();
}
function keybEditGetMessage() {
return this.message;
}
}
function editKeyBoard(ev, objForm, objKeyb) {
strWork = objKeyb.getValid();
strMsg = ''; // Error message
blnValidChar = false; // Valid character flag
var BACKSPACE = 8;
var DELETE = 46;
var TAB = 9;
var LEFT = 37 ;
var UP = 38 ;
var RIGHT = 39 ;
var DOWN = 40 ;
var END = 35 ;
var HOME = 35 ;
// Checking backspace and delete
if(ev.keyCode == BACKSPACE || ev.keyCode == DELETE || ev.keyCode == TAB
|| ev.keyCode == LEFT || ev.keyCode == UP || ev.keyCode == RIGHT || ev.keyCode == DOWN) {
blnValidChar = true;
}
if(!blnValidChar) // Part 1: Validate input
for(i=0;i < strWork.length;i++)
if(ev.which == strWork.charCodeAt(i) ) {
blnValidChar = true;
break;
}
// Part 2: Build error message
if(!blnValidChar)
{
//if(objKeyb.getMessage().toString().length != 0)
// alert('Error: ' + objKeyb.getMessage());
ev.returnValue = false; // Clear invalid character
ev.preventDefault();
objForm.focus(); // Set focus
}
}
<input type="text"name="worklistFrmDateFltr" onkeypress="editKeyBoard(event, this, keybNumberAndAlpha)" value="">
I found that onKeyDown captures Shift key, arrows, etc. To avoid having to account for this, I could filter out character input easily by subscribing to onKeyPress instead.
Since many of the answers above didn't satisfy me, I propose my solution which solves the problem of the input event being uncancelable by storing the previous value in a custom attribute, and restoring it in case the pattern is not matched:
const input = document.querySelector('#input-with-pattern')
input.addEventListener('keyup', event => {
const value = event.target.value;
if (!/^[a-zA-Z]+$/.test(value) && value !== '') { // it will allow only alphabetic
event.target.value = event.target.getAttribute('data-value');
} else {
event.target.setAttribute('data-value', value);
}
});
<input id="input-with-pattern">

Categories

Resources