How to use multiplate onkeyup input? - javascript

I have this input, I want use 2 onkeyup in one input, How use it?
I want sepret my number 3 number with comma and I want my input value of a factor of 10 too.
For example, if the user enters the number 100214, the user will immediately see the number 10021 (No decimal) in span result and see the number 100,214 in input.
function separateNum(value, input) {
var nStr = value + '';
nStr = nStr.replace(/\,/g, "");
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');
}
if (input !== undefined) {
input.value = x1 + x2;
} else {
return x1 + x2;
}
}
function onInputChange(e) {
const span = document.getElementById('result');
span.innerHTML = Math.floor(e.value / 10);
}
<input type="text" onkeyup="onInputChange(this); separateNum(this.value,this);">
<span id='result'>please enter number</span>

function test2(value, input) {
var nStr = value + '';
nStr = nStr.replace(/\,/g, "");
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');
console.log(x1)
}
if (input !== undefined) {
input.value = x1 + x2;
} else {
return x3 + x2;
}
}
function test1(e) {
const span = document.getElementById('result');
e.value = e.value.replace(/,/gi,'')
span.innerHTML = Math.floor(e.value / 10);
}
<input type="text" onkeyup="test1(this); test2(this.value,this);"/>
<div id='result'></div>
change this:
<input type="text" onkeyup="onInputChange(this)" onkeyup="separateNum(this.value,this);">
to:
<input type="text" onkeyup="onInputChange(this); separateNum(this.value,this);">

You should not be using inline HTML event attributes in today's world. Inline event attributes like onXyz where how we "wired" up event handling functions to events before we had standards 25+ years ago. Using this technique today "works", but introduces shortcomings and, in some cases, bigger problems.
Instead, follow modern standards and use .addEventListener() separately in JavaScript, which provides a more robust mechanism for event handling registrations (and de-registrations). In your case, you would just register two handlers for the same event and they will be invoked in the order that you registered them:
// Get a reference to the HTML element
const input = document.querySelector("input");
// Register event handlers
input.addEventListener("keyup", foo1);
input.addEventListener("keyup", foo2);
function foo1(event){
console.log("foo1 detected key up after " + event.key + " was pressed and now the input is: " + this.value);
}
function foo2(event){
console.log("foo2 detected key up after " + event.key + " was pressed and now the input is: " + this.value);
}
<input type="text">

Related

jQuery number format for HTML input number with dynamic decimals

I've seen a lot of similar threads or library but I haven't found one I need.
I have preexisting code with many input[type=number] in the forms. I need to format the number value to local format when form is viewed at first load or when cursor/pointer is out of focus (onblur), and unformat the number to raw input when onfocus or when the form is submitted. The format are dot as separator and comma as decimal. The decimal numbers are dynamic, some don't have decimals, some have 2 or 4, or in other words, the decimal format is only shown when the number has decimal. And when a field doesn't have any value, still displays an empty string ("") not zero (0). A field that has 0 value still displays a 0.
Example:
//Number is 1400.45
//Document ready: 1.400,45
//Onfocus: 1400.45
//Onblur: 1.400,45
//Onsubmit value send by PHP page load: 1400.45
Is there any way to do this or jQuery/javascript library for this?
I don't think there is a library for such a specialized solution you are looking for but you can do it on your own.
That's the idea:
String.prototype.replaceLast = function(find, replace) {
var index = this.lastIndexOf(find);
if (index >= 0) {
return this.substring(0, index) + replace + this.substring(index + find.length);
}
return this.toString();
};
let transformValue = function(value) {
value = parseFloat(value);
value = parseInt(value).toLocaleString() + '.' + parseInt(value.toString().split('.')[1] || '0');
value = value.replace(',', '.');
value = value.replaceLast('.', ',');
return value;
};
let form = document.querySelector('#myForm');
window.addEventListener('load', function() {
let inputs = form.querySelectorAll('input[type="text"]');
for (let i = 0; i < inputs.length; i++) {
let input = inputs[i];
input.value = transformValue(input.value);
input.onfocus = function() {
this.value = this.value.replaceAll('.', '').replace(',', '.');
};
input.onblur = function() {
this.value = transformValue(this.value);
};
}
});
form.onsubmit = function() {
let inputs = form.querySelectorAll('input[type="text"]');
for (let i = 0; i < inputs.length; i++) {
inputs[i].value = inputs[i].value.replaceAll('.', '').replace(',', '.'); }
for (let i = 0; i < inputs.length; i++) {
alert('submitted value ' + inputs[i].value);
}
};
#myForm {
display: flex;
flex-direction: column;
}
#myForm input {
outline: none;
border: 1px solid #000;
border-radius: 3px;
margin: 5px 0;
padding: 3px 7px;
}
<form id="myForm">
<input type="text" value="1400.45">
<input type="text" value="1401.45">
<input type="text" value="1402.45">
<input type="submit">
</form>
The below solution is totally dynamic, as wherever you want to put decimal position.
var num;
$(document).ready(function(){
num=$(".nums").val();
var nstring=num.replace(/\D/g,'');
var total_strings=nstring.length;
totalz=pad("1", (total_strings));
var nums=eval(nstring/totalz);
nums=""+nums+"";
var new_array=nums.split(".");
var val_1=addCommas(new_array[1]);
var narray=new_array[0]+"."+val_1;
$(".nums").val(narray);
});
$(".nums").focus(function(){
var numz=num;
$(".nums").val(numz);
});
$(".nums").blur(function(){
num=$(".nums").val();
var nstring=num.replace(/\D/g,'');
var total_strings=nstring.length;
totalz=pad("1", (total_strings));
var nums=eval(nstring/totalz);
nums=""+nums+"";
var new_array=nums.split(".");
var val_1=addCommas(new_array[1]);
var narray=new_array[0]+"."+val_1;
$(".nums").val(narray);
});
$(".nums").focus(function(){
var numz=num;
$(".nums").val(numz);
});
$(".form1").submit(function(){
var numz2=num;
$(".nums").val(numz2);
$(".form1").submit();
});
function pad (str, max) {
str = str.toString();
return str.length < max ? pad(str+"0", max) : str;
}
function addCommas(nStr) {
nStr += '';
var x = nStr.split('.');
var x1 = x[0];
var x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="form1" action="submit.php" method="post">
<input type="text" name="num" class="nums" value="1.40045">
<input type="submit">
</form>

Display times table up to 12 based on the users input

it seems to think ttinput is a string when I console.log the variable it says "". All else seems to working I just can't figure out how to have ttinput as a number.
document.getElementById("enter").addEventListener("click", ttcalc)
var ttinput = document.getElementById("table").value;
var ttoutput;
function ttcalc(){
var display = "";
for(var i = 1; i <= 12; i++){
ttoutput = ttinput * i;
display += ttinput + "*" + i + "=" + ttoutput + "<br>"
console.log(ttoutput, ttinput, i);
}
document.getElementById("output").innerHTML = display;
}
this is my html
<form>
<h1>Enter what times table you wish to see</h1>
<input type="number" id="table"><br>
</form>
<button id="enter">Show Times Table</button>
</div>
The problem is that the value of
var ttinput = document.getElementById("table").value;
is read on page load (while the input field is empty). If you move that line of code inside your function it will read the value of the input field after the button is clicked.
If you want to be sure the value entered is a number you can use the parseInt() function and then check if the result is a number with the isNaN() function like this:
var ttinput = parseInt(document.getElementById("table").value);
and then use isNaN():
if( !isNaN(ttinput) ) {
// ttinput is a number
} else {
// ttinput is not a number
}
More here: parseInt and isNaN.
Check example below:
document.getElementById("enter").addEventListener("click", ttcalc)
function ttcalc() {
var ttinput = parseInt(document.getElementById("table").value);
var ttoutput;
var display = "";
if( !isNaN(ttinput) ) {
for(var i = 1; i <= 12; i++) {
ttoutput = ttinput * i;
display += ttinput + "*" + i + "=" + ttoutput + "<br>"
console.log(ttoutput, ttinput, i);
}
document.getElementById("output").innerHTML = display;
} else {
console.log("value is not a number");
}
}
<button id="enter">Enter</button>
<input type="text" id="table" value="">
<div id="output"></div>

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;
}

Insert hyphens in JavaScript

What is the easiest way to insert hyphens in JavaScript?
I have a phone number eg. 1234567890
While displaying in the front-end, I have to display it as 123-456-7890 using JavaScript.
What is the simplest way to achieve this?
Quickest way would be with some regex:
Where n is the number
n.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3");
Example: http://jsfiddle.net/jasongennaro/yXD7g/
var n = "1234567899";
console.log(n.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3"));
Given this kind of input, an other way would be:
var phone = "1234567890";
phone = phone.replace(/(\d{3})(\d{3})(\d+)/, '$1-$2-$3');
Of course this does not work if your input changes.
You could use the substr-function to achieve this, assumed that the hyphens are always inserted on the same position:
var hypString = phonestr.substr(0,3) + '-' + phonestr.substr(3, 6) + '-' + phonestr.substr(6);
If you want to mask your input in that way then you can do something like below so that when input is being given by the user it automatically formats it to the required format.
function transform(){
let ele = document.getElementById("phno");
ele.value = ele.value.replace(/^(\d{3})$/g, '$1-')
.replace(/^(\d{3}\-\d{3})$/g, '$1-');
}
<input
type="text"
onkeyup="transform()"
id="phno"
placeholder="123-123-4444"
maxlength="12"
/>
You can create a javascript function to format the phone number. Something like this:
function formatPhoneStr(o)
{
var strPhone = o.value;
if( (strPhone != null) && (strPhone.length > 0) && (strPhone.indexOf('(') == -1))
{
if (strPhone.length == 10)
{
strPhone = '(' + strPhone.substr(0,3) + ') ' + strPhone.substr(3,3) + '-' + strPhone.substr(6,4);
}
else if (strPhone.length > 10)
{
strPhone = '(' + strPhone.substr(0,3) + ') ' + strPhone.substr(3,3) + '-' + strPhone.substr(6,4) + ' x' + strPhone.substr(10);
}
o.value = strPhone;
}
}
Another alternative that I believe is the cleanest one: the slice string method.
formattedPhone = phone.slice(0,3) + '-' + phone.slice(3, 6) + '-' phone.slice(6)
The first parameter is the start position in the string, the second is the end position. As you can see above, no parameters it goes till the end of the string. A nice feature is that, like Python, negative positions count from the end of the string. This can make your code somewhat more robust:
formattedPhone = phone.slice(0,3) + '-' + phone.slice(3, -4) + '-' + phone.slice(-4)
Even if you got a phone with 9 or 11 digits it will look nice.
try this...
<input required type="tel" maxlength="12" onKeypress="addDashesPhone(this)" name="Phone" id="Phone">
function addDashesPhone(f) {
var r = /(\D+)/g,
npa = '',
nxx = '',
last4 = '';
f.value = f.value.replace(r, '');
npa = f.value.substr(0, 3);
nxx = f.value.substr(3, 3);
last4 = f.value.substr(6, 4);
f.value = npa + '-' + nxx + '-' + last4;
}
For react just use a ref like this example:
Here I just replace the value of the element and include hyphens onBlur
Logic part:
const ref = React.useRef(null)
const blurHandle = () => {
ref.current.value = ref.current.value.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3")
};
declarative render part:
<Input
ref={phoneInput}
onFocus={focusHandler}
onBlur={blurHandle}
type="tel"
placeholder="###-###-####"
name="from_phoneNumber"
pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
/>
If your Input is a sepparated styled component using an input JSX element inside remember pass the ref to the children element using a foward ref
const Input = React.forwardRef((props, ref) => (
<input type="tel" ref={ref} ........ />
))
If you're using the ASP.NET client library they have a great String.format method that provides locale formats and all kinds of fancy stuff. The method is called as you'd expect if you're familiar with .NET:
<script type="text/javascript">
var myPhone = String.format("{0}-{1}-{2}", firstThree, secondThree, lastFour);
</script>
If you're not using ASP.NET library, I'm sure you could get the rudimentary formatting done in your own implementation - obviously this would be sans localization and you should throw some error handling/checking in the mix:
function format(str, arr){
for(var i = 0; i < arr.length; i++) {
var r = new RegExp("\\{" + i + "\\}", "g");
str = str.replace(r,arr[i]);
}
return str;
}
alert(format("{0}-{1}-{2}", [123,456,7890]));
here's my solution just in case it helps someone:
validatePhone: function (e) {
var number = this.$el.find('#phoneNumberField').val().replace(/-/g, '');
if(number.length > 10) {
e.preventDefault();
}
if(number.length < 3) {
number = number; // just for legibility
} else if(number.length < 7) {
number = number.substring(0,3) +
'-' +
number.substring(3,6)
} else if(number.length > 6) {
number = number.substring(0,3) +
'-' +
number.substring(3,6) +
'-' +
number.substring(6,10);
}
this.$el.find('#phoneNumberField').val(number);
}

javascript append appearing twice

Here's my problem I have this javascript
if (exchRate != "") {
function roundthecon() {
var value = Math.round(exchRate*Math.pow(10,2)) / Math.pow(10,2);
$('.tablenotes > p > strong ').append(value);
}
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;
}
// When the document is loaded..
$(document).ready(function(){
// Grab an array of the table cells
$('.evenprop table tr td:not(.title)').each(function(){
// Calculate the pound price
var v_euro = $(this).html();
if (v_euro != "N/A") {
var v_euro = v_euro.replace(/,/g,'');
var v_euro = v_euro.replace(/\u20AC/g, '');
var v_euro = v_euro.replace(/£/g, '');
var v_pound = Math.round(v_euro / exchRate);
v_pound = addCommas(v_pound);
// Create a new span element for the pound
// Insert it at the end of the table cell
if (exchRate == <%= Session("xch_dollar") %>) {
$(this).prepend("$");
}
if (exchRate == <%= Session("xch_ntl") %>) {
$(this).prepend("X");
}
if (exchRate == <%= Session("xch_euro") %>) {
$(this).append("€");
}
var o_span = $('<span/>').html(' <span style="font-weight:normal;" id="exchRate">(£' + v_pound + ')</span>');
$(this).append(o_span);
}
});
});
}
And this is my html in the page
<div class="tablenotes">
<p><span class="tariffnote">Weekly price in Euros.</span> £ in brackets are approximate sterling equivalent based on <strong>£1 =
<script type="text/javascript">roundthecon()</script><noscript><%= Session("xch_euro") %></noscript>€</strong> </p>
</div>
And the exchRate = 1.1986 for some reason my code is showing this.
<div class="tablenotes">
<p><span class="tariffnote">Weekly price in Euros.</span> £ in brackets are approximate sterling equivalent based on <strong>£1 =
1.2<noscript>1.1986</noscript>€1.2</strong> </p>
</div>
It is rounding the exchRate as it should but it is placing it in twice
Anyone got any ideas?
Thanks
Jamie
I got around the issue by doing this
$(document).ready(function(){
var value = Math.round(exchRate*Math.pow(10,2)) / Math.pow(10,2);
$('.tablenotes > p > strong ').html("£1 = " + value + "€");
});
It replaces the whole html rather than appending

Categories

Resources