There are various classes
Integer numbers positives and negatives or only the positives
Float numbers positives and negatives or only the positives
Float numbers fixing to 2 decimals
demo and free to copy from:
https://www.bc3toexcel.com/compartir/input-format-number-as-keyed.htm
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>FORMAT (PUT THOUSANDS SEPARATOR) INSIDE A FORM NUMERIC INPUT FIELD AS THE VALUE IS KEYED</title>
<style>
input {padding: 20px;margin: 10px;font-size: 18px;}
.label,
.integerPositive,
.integerIndistinct,
.numberPositive,
.numberIndistinct,
.numberPositiveFixed,
.numberIndistinctFixed {text-align: right;}
.positives {color: black;}
.negatives {color: red;}
.oculto{display:none;}
.visible{display:block;}
.table_data_received table,
.table_data_received tr,
.table_data_received th,
.table_data_received td{border: 1px solid black; text-align:right;}
</style>
</head>
<body>
<h2>FORMAT (PUT THOUSANDS SEPARATOR) INSIDE A FORM NUMERIC INPUT FIELD AS THE VALUE IS KEYED</h2>
<!-- ONLY FOR TESTING PURPOSE -->
<div id="data_received" class="oculto">
<h2>DATA RECEIVED FROM FORM</h2>
</div>
<!-- TEST FORM SAMPLE-->
<form id="TheForm" class="oculto" method="get" action="input-format-number-as-keyed.htm" onsubmit="return removeNumberFormat(true);">
<table>
<tr>
<td class="label">Integer(+/-)</td>
<td><input class="integerIndistinct" name="integer1" id="integer1"></td>
</tr>
<tr>
<td class="label">Integer(+)>= 0</td>
<td><input class="integerPositive" name="integer2" id="integer2"></td>
</tr>
<tr>
<td class="label">Float(+/-)</td>
<td><input class="numberIndistinct" name="number1" id="number1"></td>
</tr>
<tr>
<td class="label">Float(+)>= 0</td>
<td><input class="numberPositive" name="number2" id="number2"></td>
</tr>
<tr>
<td class="label">Float Fixed 2 (+/-)</td>
<td><input class="numberIndistinctFixed" name="number3" id="number3"></td>
</tr>
<tr>
<td class="label">Float Fixed 2 (+)>= 0</td>
<td><input class="numberPositiveFixed" name="number4" id="number4"></td>
</tr>
</table>
<input type="submit" value="submit">
</form>
<script>
//================================ ======================================
//============== THIS PART OF THE CODE IS ONLY FOR TESTING ==============
//================================ ======================================
//To test if the form submitted data has been changed removing the thousands
//separators from the numeric values and show the result in dev.tools console.
//Can be eliminated after test is successful
//============================================================================
function reset_form() {
window.location.replace(location.pathname);
}
const getURLParameters = url =>
(
/*
* extract the parameters from the url that has been called
* @param {string} the url that has been called
* @return {array} returns an associative array of the input variables
*/
url.match(/([^?=&]+)(=([^&]*))/g) ||[]).reduce(
(a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a), {}
);
let array_param = getURLParameters(window.location.href);
let array_keys = Object.keys(array_param);
if (array_keys.length!==0) {
let div = document.getElementById("data_received");
let table = document.createElement("table");
table.className = "table_data_received";
let tr = document.createElement("tr");
let len = array_keys.length;
for(let i = 0; i < len; i++) {
let th = document.createElement("th");
th.innerHTML = decodeURIComponent(array_keys[i]);
tr.appendChild(th);
}
table.appendChild(tr);
tr = document.createElement("tr");
for(let j = 0; j < len; j++) {
let td = document.createElement("td");
td.innerHTML = decodeURIComponent(array_param[array_keys[j]]);
tr.appendChild(td);
}
table.appendChild(tr);
div.appendChild(table);
let button = document.createElement("input");
button.setAttribute("style", "cursor:pointer; margin-top:10px;");
button.setAttribute("type", "button");
button.setAttribute("value", "Repeat");
button.setAttribute("onclick", "reset_form();");
div.appendChild(button);
div.className = "visible";
let form = document.getElementById("TheForm");
form.className = "oculto";
}else {
let form = document.getElementById("TheForm");
form.className = "visible";
}
//================================ ======================================
//========================== END OF TESTING =============================
//================================ ======================================
//############################################################################
/**
* @format-numeric-input-as-keyed.js
* @version : 1.0
* @author : Aitor Solozabal Merino (aitorsolozabal@gmail.com)
* @purpose : Format a number (with thousands separator) in an input field
* of a form as it is being entered key by key on the keyboard
* History
* @version : v1.0 – initial
* FUNCTIONS LIST
* ==============
* function integerFormatIndistinct()
* function integerFormatPositive()
* function numberFormatIndistinct()
* function numberFormatPositive()
* function numberFormatIndistinctFixed()
* function numberFormatPositiveFixed()
* There are classes / categories defined to associate with each function and that
* are related when declaring the keyup event for each one of them
* .integerPositive,
* .integerIndistinct,
* .numberPositive,
* .numberIndistinct,
* .numberPositiveFixed,
* .numberIndistinctFixed {text-align: right;}
* .positives {color: black;}
* .negatives {color: red;}
* function numberFormat(strNumber, n, thousands, decimals, minusSigned = true)
* function removeNumberFormat(emptyValues = true) to be call from form submit
*/
//############################################################################
// global variables to define the thousands and decimals separator
// For thousands a comma and a point for decimal (USA)
let DECIMALS = ".";
let THOUSANDS = ",";
// change to "," for decimal comma and point in thousands (SPAIN)
// =============================================== ===========================
function numberFormat(strNumber, n, thousands, decimals, minusSigned = true) {
/**
*This function is called from other functions that are activated when the "keyup"
*event occurs when typing from the keyboard by entering a character within a text
*entry in a form that you want to give a numeric format.
*
*As it is allowed to add characters to the beginning in the middle or at the
*end of the input text of the form, cases of generation of invalid numbers
*can occur due to the concurrence of multiple factors.
*Cases to control of strNumber content with the rule that there can only be
*one minus symbol and it must be at the beginning and a single decimal
*separator that can be anywhere.
*In addition, the following combinations must be processed
* "-" "." "-." "--" ".." "0" "-0" "-0." "0." "00" "0n" ".n" ".n." "-n-"
*
* This function also serves to return a formatted number for printing or display
* on the screen independently of using it in the numeric fields of a form
* ===============================================================================
* @param string strNumber: string with the number to format
* @param integer n: length of decimal (>0)fixed (=0)integer (=-1)float not fixed
* @param string thousands: sections delimiter THOUSANDS USA "," SPAIN "."
* @param string decimals: decimal separator DECIMALS USA "." SPAIN ","
* ===============================================================================
* @VERSION : 1.0
* @DATE : 27 January 2020
* @AUTHOR : Aitor Solozabal Merino (aitorsolozabal@gmail.com)
* sample use:
* integer not minus
* console.log("integer "+"-123456.789"+" 0 decimales = "+numberFormat("-123456.789", 0, ",", ".",false));
* output 123,456
* float indistinct not fixed
* console.log("float "+"-123456.789"+" -1 decimales = "+numberFormat("-123456.789", -1, ",", ".",true));
* output -123,456.789
* float fixed not minus
* console.log("float "+"-123456.789"+" 2 decimales = "+numberFormat("-123456.789", 2, THOUSANDS, DECIMALS,false));
* output 123,456.78
*/
let re = '\\d(?=(\\d{3})+$)';
let resultado = "";
let hasminusSymbol = false;
let hasdecimalsSeparator = false;
let nextCharacter = "";
let initialZero = false;
let numParts =[];
let integerPart = "";
let decimalPart = "";
let firstDecimal = -1;
//filter (minusSigned && n!==0) numbers, minus symbol, decimals separator
let filterNumber1 = new RegExp('[^ 0-9\\-\\'+decimals+']', 'g');
//filter (minusSigned && n===0) numbers, minus symbol not decimals separator
let filterNumber2 = new RegExp('[^ 0-9\\-]', 'g');
//filter (!minusSigned && n!==0) numbers, decimals separator not minus symbol
let filterNumber3 = new RegExp('[^ 0-9\\'+decimals+']', 'g');
//filter (!minusSigned && n===0) only numbers are permitted
let filterNumber4 = new RegExp('[^ 0-9]', 'g');
//Only numbers, decimals separator and minus symbol are allowed, so the
//number is filtered to eliminate those characters that are not valid
//================================================================== F I R S T
//first filtering of invalid characters
//the thousands delimeters are eliminated in this filter process
strNumber = strNumber.replace(filterNumber1, "");
if (strNumber.length>0) {
//============================================================ S E C O N D
//If the minusSigned parameter is false, then this symbol is not allowed
//and only positive values are valid.
//Therefore you have to see if the first character is the minus symbol "-"
//and, if so, it must be removed to be added to the final result of the
//formatting process if the minusSigned parameter is true.
hasminusSymbol = (strNumber.substring(0, 1)==="-");
strNumber = strNumber.replace(filterNumber3, "");
if (strNumber.length>0) {
//========================================================== T H I R D
//if the first character is the decimal separator strNumber must be
//filtered eliminating all ocurrences of the decimalseparator in
//strNumber with a filter and then it is added with the zero character
//previously "." --> "0."
hasdecimalsSeparator = (strNumber.substring(0, 1)===decimals);
strNumber = (hasdecimalsSeparator)? "0.": strNumber;
if (!hasdecimalsSeparator) {
//if there is no decimal separator at the beginning, check if there
//is a decimal separator and check that this is the only one by
//erasing the excess ones
firstDecimal = strNumber.indexOf(decimals);
hasdecimalsSeparator = (firstDecimal>0);
//There is at least one decimal separator in strNumber
//Clean any other occurrence of a decimal separator in strNumber
strNumber = hasdecimalsSeparator?strNumber.substring(0, firstDecimal)+decimals+strNumber.substring(firstDecimal+1, strNumber.length).replace(filterNumber4, ""):strNumber;
}
//======================================================== F O U R T H
//"0"
initialZero = (strNumber.substring(0, 1)==="0");
//the first character can be a 0 or a decimal separator
if (initialZero) {
//if the first character is the number zero then the next character
//must be obtained and find out if it is a number or the decimal
//separator.
//It could be a "0." or a "0n"
nextCharacter = (strNumber.length>1)? strNumber.substring(1, 2): "";
//strNumber is of type "0n"
//"01" "1" / "00" "0"
//In this case the leading zero character is removed
strNumber = ((nextCharacter.length>0) && (nextCharacter!==decimals))?strNumber.substring(1, strNumber.length):strNumber;
}
//========================================================== F I F T H
//strNumber is divided into 2 parts using the defined decimal separator
//character as an element that separates the integer part and the
//decimal part if it exists
numParts = strNumber.split(decimals);
integerPart = numParts[0];
decimalPart = (numParts.length>1)? numParts[1]: "";
//========================================================== S I X T H
// add the thousands separators
resultado = integerPart.replace(new RegExp(re, 'g'), '$&' + (thousands));
//====================================================== S E V E N T H
//join the 2 parts to obtain the result with the established format
if (n!==0) {
if (n>0) {
//fixed decimals
decimalPart = (decimalPart.length>n)? decimalPart.substring(0, n): decimalPart;
}
resultado = (hasdecimalsSeparator)? resultado+decimals+decimalPart: resultado;
}
}
}
//================================================================ E I G H T H
//check if the minus symbol is allowed so that if it exists add it to the final
//result before being returned
resultado = (minusSigned && hasminusSymbol)? "-"+resultado: resultado;
return resultado;
}
function integerFormatIndistinct() {
// Format integers indistinctly both positive and negative
if (this.value.length>0) {
this.value = numberFormat(this.value, 0, THOUSANDS, DECIMALS, true);
this.className = (this.value.substring(0, 1)==="-")? "negatives integerIndistinct": "positives integerIndistinct";
}
}
function integerFormatPositive() {
// Format only positive integers
this.value = this.value.length>0? numberFormat(this.value, 0, THOUSANDS, DECIMALS, false): "";
}
function numberFormatIndistinct() {
// Format decimal numbers indistinctly both positive and negative
if (this.value.length>0) {
this.value = numberFormat(this.value, -1, THOUSANDS, DECIMALS, true);
this.className = (this.value.substring(0, 1)==="-")? "negatives integerIndistinct": "positives integerIndistinct";
}
}
function numberFormatPositive() {
// Format only positive decimal numbers
this.value = this.value.length>0? numberFormat(this.value, -1, THOUSANDS, DECIMALS, false): "";
}
function numberFormatIndistinctFixed() {
// Format decimal numbers indistinctly both positive and negative
// but with 2 decimal places fixed as maximum
if (this.value.length>0) {
this.value = numberFormat(this.value, 2, THOUSANDS, DECIMALS, true);
this.className = (this.value.substring(0, 1)==="-")? "negatives integerIndistinct": "positives integerIndistinct";
}
}
function numberFormatPositiveFixed() {
// Format only positive decimal numbers with 2 decimal places fixed as maximum
this.value = this.value.length>0? numberFormat(this.value, 2, THOUSANDS, DECIMALS, false): "";
}
function removeNumberFormat(emptyValues = true) {
//************************************************************************
//The text input fields that contain the formatted numbers of the form must be
//prepared before they are sent, eliminating the thousands separators and
//placing the decimal separators of the system to transmit the data.
//If the boolean variable emptyValues is true, then all values will be sent
//including those that are empty, otherwise only non-empty values will be sent
//This function is called with the instruction in the <form> tag
//onsubmit = "return removeNumberFormat(emptyValues);"
//************************************************************************
let filterNumber = new RegExp('[^ 0-9\\-' + '\\' + DECIMALS + ']', 'g');
let integer1 = document.getElementById('integer1');
//eliminate thousands separator with the filterNumber
integer1.value = integer1.value.replace(filterNumber, "");
//to remove the field integer1 from submit data if it is empty then:
if (!emptyValues) {
if (integer1.value==="") {integer1.parentNode.removeChild(integer1);}
}
let integer2 = document.getElementById('integer2');
//eliminate thousands separator with the filterNumber
integer2.value = integer2.value.replace(filterNumber, "");
//to remove the field integer2 from submit data if it is empty then:
if (!emptyValues) {
if (integer2.value==="") {integer2.parentNode.removeChild(integer2);}
}
let number1 = document.getElementById('number1');
//eliminate thousands separator with the filterNumber
number1.value = number1.value.replace(filterNumber, "");
number1.value = number1.value.replace(DECIMALS, ".");
//to remove the field number1 from submit data if it is empty then:
if (!emptyValues) {
if(number1.value==="") {number1.parentNode.removeChild(number1);}
}
let number2 = document.getElementById('number2');
//eliminate thousands separator with the filterNumber
number2.value = number2.value.replace(filterNumber, "");
//replace decimals separator in format number with system decimal separator
number2.value = number2.value.replace(DECIMALS, ".");
//to remove the field number2 from submit data if it is empty then:
if (!emptyValues) {
if(number2.value==="") {number2.parentNode.removeChild(number2);}
}
let number3 = document.getElementById('number3');
//eliminate thousands separator with the filterNumber
number3.value = number3.value.replace(filterNumber, "");
//replace decimals separator in format number with system decimal separator
number3.value = number3.value.replace(DECIMALS, ".");
//to remove the field number3 from submit data if it is empty then:
if (!emptyValues) {
if(number3.value==="") {number3.parentNode.removeChild(number3);}
}
let number4 = document.getElementById('number4');
//eliminate thousands separator with the filterNumber
number4.value = number4.value.replace(filterNumber, "");
//replace decimals separator in format number with system decimal separator
number4.value.replace(DECIMALS, ".");
//to remove the field number4 from submit data if it is empty then:
if (!emptyValues) {
if(number4.value==="") {number4.parentNode.removeChild(number4);}
}
return true;
}
//////////////////////////////////////////////////////////////////////////////////
window.onload = function() {
// IT IS EXECUTED AFTER LOADING ALL THE CSS & HTML & JAVASCRIPT CODE
//============================================================================
// Create the keyup event for each defined class and relate it to the appropriate function
//============================================================================
document.querySelectorAll(".integerIndistinct").forEach(el => el.addEventListener("keyup", integerFormatIndistinct));
document.querySelectorAll(".integerPositive").forEach(el => el.addEventListener("keyup", integerFormatPositive));
document.querySelectorAll(".numberIndistinct").forEach(el => el.addEventListener("keyup", numberFormatIndistinct));
document.querySelectorAll(".numberPositive").forEach(el => el.addEventListener("keyup", numberFormatPositive));
document.querySelectorAll(".numberIndistinctFixed").forEach(el => el.addEventListener("keyup", numberFormatIndistinctFixed));
document.querySelectorAll(".numberPositiveFixed").forEach(el => el.addEventListener("keyup", numberFormatPositiveFixed));
};
//////////////////////////////////////////////////////////////////////////////////
</script>
</body>
</html>
Top comments (0)