HTML input field need to take characters from beginning when full - javascript

I need a text box which when maxlength is reached, need to position cursor to beginning and on key input needs to replace the characters as keys are pressed. My sample code is below. I can get cursor to start of textbox when maxlength is reached, but the characters are not replaced. Please share any ideas on how I can change the default input field behavior.
https://jsfiddle.net/yd62jugk/7/
function myFunction() {
if (document.getElementById("demo").selectionStart ===
parseInt(document.getElementById("demo").getAttribute('maxlength'), 10)) {
document.getElementById("demo").setSelectionRange(0,0);
}
}
<p>Press keys.</p>
<input type="text" id="demo" maxlength=5 onkeyup="myFunction()">

const input = document.querySelector('input');
const maxLength = Number(input.getAttribute('maxlength'));
input.addEventListener('keydown',(e)=>{
let value=input.value;
let start=input.selectionStart;
value[start+1]=e.keyCode;
input.setSelectionRange(start,start+1);
input.value=value;
if (start===maxLength){
input.setSelectionRange(0,1);
}
});
console.log(maxLength);
<!DOCTYPE html>
<html>
<body>
<p>Press a key inside the text field to set a red background color.</p>
<input type="text" id="demo" maxlength="5">
</body>
</html>

const demo = document.getElementById("demo")
demo.addEventListener("keyup", myFunction )
let cursor_position = 1
let can_update = false
function myFunction(e) {
let max = parseInt(demo.getAttribute('maxlength'), 10)
if ( can_update ) {
e.target.value = replaceAt(e.target.value, cursor_position - 1, e.key)
demo.setSelectionRange(cursor_position, cursor_position);
(cursor_position < max ) ? cursor_position++ : cursor_position = 1
} else if (demo.value.length === max) { can_update = true }
}
const replaceAt = (str, index, replacement) => str.substr(0, index) + replacement + str.substr(index + replacement.length)

Related

Consider one input field to 90 percent and display another 10 % automatically

I have two input value, the two value should be equal to 100%, one input contain 90% and the other should contain 10%, the value should be auto calculated based on input change in any field.
function checkValue (type) {
var no = 0;
var percent = 0;
var otherPercent = 0;
if (type === 'ninetyPercent') {
no = document.getElementById('ninetyPercent').value;
percent = parseInt(no) / 90;
otherPercent = (parseFloat(percent.toFixed(2)) - parseInt(no))
document.getElementById('tenPercent').value = otherPercent;
} else {
no = document.getElementById('tenPercent').value;
percent = parseInt(no) / 10;
otherPercent = (parseFloat(percent.toFixed(2)) + parseInt(no));
document.getElementById('ninetyPercent').value = otherPercent;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label>This should consider as 90% for the input</label>
<input type="number" id="ninetyPercent" onInput="checkValue('ninetyPercent')" placeholder="90%">
<br>
<br>
<label>This should consider as 10% for the input</label>
<input type="number" id="tenPercent" onInput="checkValue('tenPercent')" placeholder="10%">
The general Idea is if we insert 90 in first input, the second input should auto fill 10, likewise if we input 10 in second input, the first input should auto fill 90 and so on.
Thanks in advance
This is my approach:
const inputs = document.querySelectorAll('#foo input');
function getOtherInput(changedInput) {
return [...inputs].find(input => input !== changedInput);
}
foo.addEventListener('input', (event) => {
const changedInput = event.target;
const definingValue = Number(changedInput.value);
const definingPercentage = Number(changedInput.dataset.percentage);
const derivedInput = getOtherInput(changedInput);
const derivedPercentage = Number(derivedInput.dataset.percentage);
const derivedValue = definingValue / definingPercentage * derivedPercentage;
derivedInput.value = derivedValue;
});
bar.addEventListener('click', () => {
let firstPercentage = NaN;
while (isNaN(parseInt(firstPercentage))) {
firstPercentage = parseInt(prompt('Enter the percentage for the first input (less than 100, greater than 0, integer):'));
}
inputs[0].dataset.percentage = firstPercentage;
inputs[1].dataset.percentage = 100 - firstPercentage;
})
<div id="foo">
<label>This should consider as 90% for the input
<input type="number" data-percentage="90" placeholder="90%"></label>
<br>
<br>
<label>This should consider as 10% for the input
<input type="number" data-percentage="10" placeholder="10%"></label>
</div>
<button type="button" id="bar">Change ratio</button>
When you click the button labeled "change ratio" it simply changes the data-percentage attributes, and the element behaviour updates automatically (still requires you to cause an input event to trigger in either input to update).

Reverse case (Lowercase/Uppercase) of an input value character by character

By using one input text box and the input type allows only alphabets.The value entered is 'a' and it should be display outside the textbox as 'A'?
If we enter the alphabet small 'a' on input text then it will wanted to display capital 'A' on the outside of the box...
The following is my html code:
<!DOCTYPE html>
<html>
<head>
<!--<script type="text/javascript" href="check.js"></script>-->
</head>
<body>
<input type="text">
<script>
function myFunction()
{
var A = document.getElementById('input').value;
console.log('alphabet'.toUpperCase());
}
</script>
</body>
</html>
To show the input value with case reversed you should:
Call your function in the onkeyup event of your input to update the preview immediately with the inputted string.
And loop through your string and for each character test if it's in
uppercase reverse it to lowercase or make it uppercase if it's
lowercase.
Here's a Snippet DEMO:
function myFunction() {
var A = document.getElementById('input').value;
var output = '';
for (var i = 0, len = A.length; i < len; i++) {
var character = A[i];
if (character == character.toLowerCase()) {
// The character is lowercase
output = output + character.toUpperCase();
} else {
// The character is uppercase
output = output + character.toLowerCase();
}
}
document.getElementById("preview").innerText = output;
}
<input id="input" type="text" pattern="[A-Za-z]" onkeyup="myFunction()" /><span id="preview"></span>
You may use an event for immediatly update the result, while writing.
document.getElementById('input').addEventListener('keyup', function () {
var input = document.getElementById('input').value;
if (!input.match(/^[a-z]*$/i)) {
document.getElementById('output').innerHTML = 'Wrong input';
return;
}
document.getElementById('output').innerHTML = input.split('').map(function (a) {
return a.match(/[a-z]/) ? a.toUpperCase() : a.toLowerCase();
}).join('');
});
<input type="text" id="input">
<div id="output"></div>
function reverseCase(str) {
let newstr = str.split('');
let newarr = [];
//return newstr;
for(i=0; i<newstr.length; i++) {
if(newstr[i] == newstr[i].toLowerCase()){
newarr.push(newstr[i].toUpperCase());
}else
if(newstr[i] == newstr[i].toUpperCase()){
newarr.push(newstr[i].toLowerCase());
}
} return newarr.join('');
}
console.log(reverseCase("Happy Birthday"))

HTML Input type number Thousand separator

I want to have a thousand separator (e.g. 1,000,000) in my Input field. However, it has to be of type number because I need to be able to adjust its value using "step". Code:
<input type="number" id='myNumber' value="40,000" step='100'>
I tried using Javascript to adjust the value but didn't work. Any help would be appreciated. Thanks!
Using autoNumeric plugin you can made a field as numeric input with different separators.
Include plugin:
<script src="~/Scripts/autoNumeric/autoNumeric.min.js" type="text/javascript"></script>
Html:
<input type="text" id="DEMO" data-a-sign="" data-a-dec="," data-a-sep="." class="form-control">
Script:
<script>
jQuery(function($) {
$('#DEMO').autoNumeric('init');
});
</script>
You can type only number, if you input 100000,99 you will see 100.000,99.
More: https://github.com/autoNumeric/autoNumeric
Check this webdesign.tutsplus.com tutorial
Final result is summarized here (look at direct Codepen playground)
$("#formInput".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) {
return;
}
var $this = $(this);
// Get the value.
var input = $this.val();
input = input.replace(/[\D\s\._\-]+/g, "");
input = input?parseInt(input, 10):0;
$this.val(function () {
return (input === 0)?"":input.toLocaleString("en-US");
});
});
Notes:
toLocaleString() javascript function Actually show thousands separator (example and doc)
run below code in your console to get the idea
(30000000).toLocaleString('en-US',{useGrouping:true})
You can fake this functionality by using a pseudo-element to display the comma version.
div[comma-value]{
position:relative;
}
div[comma-value]:before{
content: attr(comma-value);
position:absolute;
left:0;
}
div[comma-value] input{
color:#fff;
}
A wrapping div is required because inputs can't have pseudo elements.
<div>
<input type="number" id='myNumber' value="40000" step='100'>
</div>
And a little bit of JavaScript to insert commas every third character
myNumber.value = commify(myNumber.value)
myNumber.addEventListener("change", function(){
commify(event.target.value)
})
function commify(value){
var chars = value.split("").reverse()
var withCommas = []
for(var i = 1; i <= chars.length; i++ ){
withCommas.push(chars[i-1])
if(i%3==0 && i != chars.length ){
withCommas.push(",")
}
}
var val = withCommas.reverse().join("")
myNumber.parentNode.setAttribute("comma-value",val)
}
Check out the fiddle
Create a mask input displaying the formatted number. This solution avoids changing the type or the value of the input.
$("input.mask").each((i,ele)=>{
let clone=$(ele).clone(false)
clone.attr("type","text")
let ele1=$(ele)
clone.val(Number(ele1.val()).toLocaleString("en"))
$(ele).after(clone)
$(ele).hide()
clone.mouseenter(()=>{
ele1.show()
clone.hide()
})
setInterval(()=>{
let newv=Number(ele1.val()).toLocaleString("en")
if(clone.val()!=newv){
clone.val(newv)
}
},10)
$(ele).mouseleave(()=>{
$(clone).show()
$(ele1).hide()
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="mask" type="number" value="12345.678"/>
csq recommends using the jQuery autoNumeric plugin. I found it to be very easy and intuitive to use.
My only gripe is that it forces <input type="text"> rather than <input type="number">. This means you lose the funcionality of step, but you gain users of your site being able to use commas in fields.
I guess you could use expected values of less than 1,000 as <input type="number"> and values more than 1,000 as <input type="text">
I've managed to pull it off after modifying https://stackoverflow.com/a/70726755/4829915 because:
The code didn't actually add commas due to not using Number().
It deleted the entire field when the initial value was blank.
No demo was provided.
Not saying the original approach was wrong or not, but I chose to use onfocus and onblur directly on the input itself.
Therefore, here's a revised answer:
Start with <input type="text">. You can still add min, max and step properties.
Add onfocus and onblur handlers to the <input> node:
function use_number(node) {
var empty_val = false;
const value = node.value;
if (node.value == '')
empty_val = true;
node.type = 'number';
if (!empty_val)
node.value = Number(value.replace(/,/g, '')); // or equivalent per locale
}
function use_text(node) {
var empty_val = false;
const value = Number(node.value);
if (node.value == '')
empty_val = true;
node.type = 'text';
if (!empty_val)
node.value = value.toLocaleString('en'); // or other formatting
}
<input type="text" min=0 onfocus="use_number(this)" onblur="use_text(this)">
function addCommas(nStr) { ....
In addition of yovanny's answer I create a Vue component which use this function.
Vue.component("in-n", {
template:
`<input #keyup="keyup" #keypress="isNumber($event)" v-model="text" type="text" />`,
props: ["value"],
data() {
return {
text: ""
}
},
methods: {
addCommas(nStr) {
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? ',' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
},
isNumber: function (evt) {
evt = (evt) ? evt : window.event;
var charCode = (evt.which) ? evt.which : evt.keyCode;
if ((charCode > 31 && (charCode < 48 || charCode > 57)) && charCode !== 46) {
evt.preventDefault();;
} else {
return true;
}
},
keyup() {
this.text = this.addCommas(this.text.replace(/,/g, ''));
this.$emit("input", parseInt(this.text.replace(/,/g, '')))
}
}
})
I found a much simpler answer:
Start with <input type="text">. You can still add min, max and step properties.
Add onfocus and onblur handlers to the <input> node:
node.addEventListener('onfocus', () => {
const value = node.value;
node.type = 'number';
node.value = Number(value.replace(/,/g, '')); // or equivalent per locale
});
node.addEventListener('onblur', () => {
const value = node.value;
node.type = 'text';
node.value = value.toLocaleString(); // or other formatting
});
When the user selects the input, it will convert to a regular numeric input with thousands separators removed, but with a normal spinner. When the user blurs the input, it reverts to formatted text.
I add an onkeyup handler that blurs the input when the "enter" key is pressed.
I have updated #CollenZhou answer https://stackoverflow.com/a/67295023/6777672 as on mouse leave, input looses focus which is annoying. I have also added all input type numbers to selector as well as class.
$('input.thousands-separator, input[type="number"]').each((i,ele)=>{
let clone=$(ele).clone(false)
clone.attr('type','text')
let ele1=$(ele)
clone.val(Number(ele1.val()).toLocaleString('en'))
$(ele).after(clone)
$(ele).hide()
clone.mouseenter(()=>{
ele1.show()
clone.hide()
})
setInterval(()=>{
let newv=Number(ele1.val()).toLocaleString('en')
if(clone.val()!=newv){
clone.val(newv)
}
},10)
$(ele).mouseleave((event)=>{
if ($(ele).is(':focus')) {
event.preventDefault();
} else {
$(clone).show()
$(ele1).hide()
}
})
$(ele).focusout(()=>{
$(clone).show()
$(ele1).hide()
})
})
try
function addCommas(nStr)
{
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? ',' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}

how to change the value of input box just for display in html 5 web page

I have a textfield in which i am entering data i want that if user enter 1000 then it show 1,000 in textfield but this same value 1000 is also used in calculations further so how to solve this if user enter 1000 then just for display it show 1,000 and if we use in calcualtion then same var shows 1000 for calculating.
<HTML>
<body>
<input type="text" id="test" value="" />
</body>
<script>
var c=document.getElementById(test);
</script>
</html>
so if c user enter 1000 then it should dispaly 1,000 for dispaly one and if user uses in script
var test=c
then test should show 1000
document.getElementById returns either null or a reference to the unique element, in this case a input element. Input elements have an attribute value which contains their current value (as a string).
So you can use
var test = parseInt(c.value, 10);
to get the current value. This means that if you didn't use any predefined value test will be NaN.
However, this will be evaluated only once. In order to change the value you'll need to add an event listener, which handles changes to the input:
// or c.onkeyup
c.onchange = function(e){
/* ... */
}
Continuing form where Zeta left:
var testValue = parseInt(c.value);
Now let's compose the display as you want it: 1,000
var textDecimal = c.value.substr(c.value.length-3); // last 3 characters returned
var textInteger = c.value.substr(0,c.value.length-3); // characters you want to appear to the right of the coma
var textFinalDisplay = textInteger + ',' + textDecimal
alert(textFinalDisplay);
Now you have the display saved in textFinalDisplay as a string, and the actual value saved as an integer in c.value
<input type="text" id="test" value=""></input>
<button type="button" id="get">Get value</input>
var test = document.getElementById("test"),
button = document.getElementById("get");
function doCommas(evt) {
var n = evt.target.value.replace(/,/g, "");
d = n.indexOf('.'),
e = '',
r = /(\d+)(\d{3})/;
if (d !== -1) {
e = '.' + n.substring(d + 1, n.length);
n = n.substring(0, d);
}
while (r.test(n)) {
n = n.replace(r, '$1' + ',' + '$2');
}
evt.target.value = n + e;
}
function getValue() {
alert("value: " + test.value.replace(/,/g, ""));
}
test.addEventListener("keyup", doCommas, false);
button.addEventListener("click", getValue, false);
on jsfiddle
you can get the actual value from variable x
<html>
<head>
<script type="text/javascript">
function abc(){
var x = document.getElementById('txt').value;
var y = x/1000;
var z = y+","+ x.toString().substring(1);
document.getElementById('txt').value = z;
}
</script>
</head>
<body>
<input type="text" id="txt" value="" onchange = "abc()"/>
</body>
This works with integer numbers on Firefox (Linux). You can access the "non-commaed"-value using the function "intNumValue()":
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
String.prototype.displayIntNum = function()
{
var digits = String(Number(this.intNumValue())).split(""); // strip leading zeros
var displayNum = new Array();
for(var i=0; i<digits.length; i++) {
if(i && !(i%3)) {
displayNum.unshift(",");
}
displayNum.unshift(digits[digits.length-1-i]);
}
return displayNum.join("");
}
String.prototype.intNumValue = function() {
return this.replace(/,/g,"");
}
function inputChanged() {
var e = document.getElementById("numInp");
if(!e.value.intNumValue().replace(/[0-9]/g,"").length) {
e.value = e.value.displayIntNum();
}
return false;
}
function displayValue() {
alert(document.getElementById("numInp").value.intNumValue());
}
</script>
</head>
<body>
<button onclick="displayValue()">Display value</button>
<p>Input integer value:<input id="numInp" type="text" oninput="inputChanged()">
</body>
</html>

Limit number of lines in textarea and Display line count using jQuery

Using jQuery I would like to:
Limit the number of lines a user can enter in a textarea to a set number
Have a line counter appear that updates number of lines as lines are entered
Return key or \n would count as line
$(document).ready(function(){
$('#countMe').keydown(function(event) {
// If number of lines is > X (specified by me) return false
// Count number of lines/update as user enters them turn red if over limit.
});
});
<form class="lineCount">
<textarea id="countMe" cols="30" rows="5"></textarea><br>
<input type="submit" value="Test Me">
</form>
<div class="theCount">Lines used = X (updates as lines entered)<div>
For this example lets say limit the number of lines allowed to 10.
html:
<textarea id="countMe" cols="30" rows="5"></textarea>
<div class="theCount">Lines used: <span id="linesUsed">0</span><div>
js:
$(document).ready(function(){
var lines = 10;
var linesUsed = $('#linesUsed');
$('#countMe').keydown(function(e) {
newLines = $(this).val().split("\n").length;
linesUsed.text(newLines);
if(e.keyCode == 13 && newLines >= lines) {
linesUsed.css('color', 'red');
return false;
}
else {
linesUsed.css('color', '');
}
});
});
fiddle:
http://jsfiddle.net/XNCkH/17/
Here is little improved code. In previous example you could paste text with more lines that you want.
HTML
<textarea data-max="10"></textarea>
<div class="theCount">Lines used: <span id="linesUsed">0</span></div>
JS
jQuery('document').on('keyup change', 'textarea', function(e){
var maxLines = jQuery(this).attr('data-max');
newLines = $(this).val().split("\n").length;
console.log($(this).val().split("\n"));
if(newLines >= maxLines) {
lines = $(this).val().split("\n").slice(0, maxLines);
var newValue = lines.join("\n");
$(this).val(newValue);
$("#linesUsed").html(newLines);
return false;
}
});
For React functional component that sets new value into state and forwards it also to props:
const { onTextChanged, numberOfLines, maxLength } = props;
const textAreaOnChange = useCallback((newValue) => {
let text = newValue;
if (maxLength && text.length > maxLength) return
if (numberOfLines) text = text.split('\n').slice(0, numberOfLines ?? undefined)
setTextAreaValue(text); onTextChanged(text)
}, [numberOfLines, maxLength])
A much ugly , but somehow working example
specify rows of textarea
<textarea rows="3"></textarea>
and then
in js
$("textarea").on('keydown keypress keyup',function(e){
if(e.keyCode == 8 || e.keyCode == 46){
return true;
}
var maxRowCount = $(this).attr("rows") || 2;
var lineCount = $(this).val().split('\n').length;
if(e.keyCode == 13){
if(lineCount == maxRowCount){
return false;
}
}
var jsElement = $(this)[0];
if(jsElement.clientHeight < jsElement.scrollHeight){
var text = $(this).val();
text= text.slice(0, -1);
$(this).val(text);
return false;
}
});
For the React fans out there, and possibly inspiration for a vanilla JS event handler:
onChange={({ target: { value } }) => {
const returnChar = /\n/gi
const a = value.match(returnChar)
const b = title.match(returnChar)
if (value.length > 80 || (a && b && a.length > 1 && b.length === 1)) return
dispatch(setState('title', value))
}}
This example limits a textarea to 2 lines or 80 characters total.
It prevents updating the state with a new value, preventing React from adding that value to the textarea.

Categories

Resources