My input field is cleared automatically after four digits - html

I am trying to convert integers to Indian currency and return them back to the same input tag but it works well for four digits after that when I enter the fifth digit it again starts from the fifth digit. Please help me out. I am new to StackOverflow.
function currency(element) {
let ele = document.getElementById(element.id);
let num = ele.value
let number = (parseInt(num))||0;
console.log(number.toLocaleString('en-IN'));
var int = number.toLocaleString('en-IN');
document.getElementById(element.id).value = int.toString();
}
it gives output 1,234 for 1234
but when I enter 12345 it returns 1 to the input tag

After you type 1234, your function changes the <input>'s value to 1,234. But when you type a 5, your function tries to read an integer from 1,2345. The comma isn't a valid digit in base 10, so parseInt stops parsing at 1 (step 13 in the parseInt algorithm). You'll need to sanitize the <input>'s value before passing it to parseInt:
let num = ele.value.replace(/[^\d]/g, ''); // remove all non-digits from num
let number = (parseInt(num))||0;

Related

How can I automatically insert commas when a user inputs currency value in an Angular 7 reactive form, no [(ngModel)]

I have an input field where the user can input a numeric value. I need to automatically insert commas after every 3rd digit. When the user deletes numbers, the commas need to be in the correct places (after every 3rd digit, starting from the first number) as well as stay in place instead of relocating to the end of the input value. I cannot use ngModel, this is a reactive form.
I have tried this method in my TS file, to mask the user input
maskInputAmount(e) {
const t = e.target.value.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})
(\d{0,3})/);
e.target.value = t[2] ? t[1] + ',' + t[2] + (t[3] ? ',' + t[3] : '') :
t[1];
}
And in my HTML input field
<input (input)="maskInputAmount($event)" maxlength=11
formControlName="businessNetWorth" id="businessNetWorth"
type="text" class="form-control col-3 col-lg-12" data-hint="yes">
I am having commas come after every 3rd number. However, when deleting numbers from the end of the input, the commas at the front of the number should update correctly. For example, I enter '123,456,789'. When I delete the last two numbers I get '123,456,7' when it should be '1,234,567'.
One other issue, when a user deletes one of the first numbers, the comma in the input box automatically repositions itself to the end of the input value, I need it to stay in place. For example: '123,456,789'. I delete '3' and have '124,567,89' and the cursor is now behind the '9' when it should stay in front of the '2'.
How can I change my maskInputAmount(e) method to make this behave correctly?
Following code worked for me. (Assume present currency is in Indian rupees. If you want to have your own currency then you need to mention your country's code in code).
app.component.html
<input type="text" [formControl]="currency" (input)="changeToCurrency(currencyTextRef)" #currencyTextRef>
//sending reference of input element #currencyTextRef to function
{{ currency.value }}
app.component.ts
currency = new FormControl();
temp;
currncyLength=0;
changeToCurrency(currencyTextRef) {
this.currncyLength = this.currency.value.length;
console.log("currency len is "+this.currncyLength);
let index:number;
// if(currencyTextRef.selectionStart || currencyTextRef.selectionStart == '0') {
// console.log("index isss "+currencyTextRef.selectionStart);
index = currencyTextRef.selectionStart; //getting caret(cursor) position
// }
console.log("index is "+index);
// console.log("value is "+this.currency.value);
let a = this.currency.value;
a = a.replace(/,/g,'');
let num:number = + a;
let temp = new Intl.NumberFormat('en-IN').format(num); //inplace of en-IN you can mention your country's code
// console.log("temp is "+temp);
this.currency.setValue(temp.toString());
console.log("pressent len iss "+this.currency.value.length)
if(this.currncyLength<this.currency.value.length) {
console.log("incoming to < ")
index+=1;
currencyTextRef.setSelectionRange(index,index);
}
else if(this.currncyLength >=this.currency.value.length) {
console.log("incoming to > ");
// index-=1;
currencyTextRef.setSelectionRange(index,index);
}
// else {
// currencyTextRef.setSelectionRange(index,index);
// }
}
Following link might help.
Intl number MDN

How to Convert Base 10 to Base 36

I have two columns in my Google Sheets: one column for base 10 and one column for base 36. I have filled out my Base 10 column to go from 1 to 5,000. I would like to create a function in my script that will allow me to take in the value of the Base 10 number and return a value of base 36. (0123456789abcdefghijklmnopqrstuvwxyz) I want to keep the letter lower case so that I won't confuse the number 0 with the letter O.
This is what I have tried so far in my script:
function toBase36(decNumb) {
var base36 = parseInt(decNumb, 36);
return parseInt(base36);
}
The code above produces the following result:
How can I edit my code that that I will add the lower case letters?
It would be much simpler to use the toString() method.
Instead of var base36 = parseInt(decNumb, 36);
use var base36 = decNumb.toString(36);

Casting large numbers as string to number in actionscript

For some values, such as "10152116260776319", casting to number with parseFloat or Number("***") methods increments the original value by 1.
Number("10152116260776319") => 10152116260776320
Number("10202784509328139") => 10202784509328140
Is there any way to fix this? Or do I need to update all of my code to Strings.
Thanks in advance.
The issue is not due to a problem with parseFloat or Number("***"), but a limitation of the Number type. Basically, the Number type can only hold integers properly if they're below 253 (9,007,199,254,740,992), because they're double precision floating point numbers (check out this Wikipedia page for more details: http://en.wikipedia.org/wiki/Double-precision_floating-point_format)
The problem occurs even without casting, for example
var val1:Number = 9007199254740990;
var val2:Number = 9007199254740991;
var val3:Number = 9007199254740992;
var val4:Number = 9007199254740993;
var val5:Number = 9007199254740994;
var val6:Number = 10152116260776319;
trace(val1); // 9007199254740990
trace(val2); // 9007199254740991
trace(val3); // 9007199254740992
trace(val4); // 9007199254740992
trace(val5); // 9007199254740994
trace(val6); // 10152116260776320
If you really need to store integers that large, someone's made a BigInt class that you can use: http://as3asclublib.googlecode.com/svn-history/r29/trunk/data/BigInt.as

ActionScript3 - add thousands separator to negative values

This question relates to an animated map template which we have developed at the UKs Office for National Statistics. It has been applied to many datasets and geographies many uses without problem. For example,
http://www.ons.gov.uk/ons/interactive/vp3-census-map/index.html
http://www.statistica.md/pageview.php?l=ro&idc=390&id=3807
The .fla calls on a supporting .as file (see below) to introduce a thousand separator (in the UK a comma, in Germany a full stop (period) defined elsewhwere.
However, the dataset I am currently mapping has large negative values, and it tutrns out that the ORIGINAL HELPER FUNCTION below does not like negative values with 3, 6, 9 or 12 (etc) digits.
-100 to -999 for instance are rendered NaN,100 to NaN,999.
This is because such values are recognised as being 4 digits long. They are being split, the comma introduced, and the -ve sign is misunderstood.
I reckon the approach must be to use absolute values, add in the comma and then (for the negative values) add the -ve sign back in afterwards. But so far, trials of the ADAPTED HELPER FUNCTION have produced only error. :-(
Can anyone tell me how to put the -ve sign back in , please?
Many thanks.
Bruce Mitchell
==================================================================================
//ORIGINAL HELPER FUNCTION: ACCEPTS A NUMBER AND RETURNS A STRING WITH THOUSANDS SEPARATOR ATTACHED IF NECESSARY
function addThouSep(num) {
/*
a. Acquire the number - 'myTrendValue' or 'myDataValue' - from function calcValues
b. Record it (still as a number) to data precision.
1. Turn dataORtrend into a string
2. See if there is a decimal in it.
3. If there isn't, just run the normal addThouSep.
4. If there is, run addThouSep just on the first bit of the string - then add the decimal back on again at the end.
*/
var myNum:Number = correctFPE(num); // Create number variable myNum and populate it with 'num'
// (myTrendvalue or myData Value from calcValues function) passed thru 'correctPFE'
var strNum:String = myNum+""; // Create string version of the dataORtrend number - so instead of 63, you get '63'
var myArray = strNum.split("."); // Create array representing elements of strNum, split by decimal point.
//trace(myArray.length); // How long is the array?
if (myArray.length==1) { // Integer, no decimal.
if (strNum.length < 4)//999 doesn't need a comma.
return strNum;
return addThouSep(strNum.slice(0, -3))+xmlData.thouSep+strNum.slice(-3);
}
else { // Float, with decimal
if (myArray[0].length < 4)//999 doesn't need a comma
return strNum;
return (addThouSep(myArray[0].slice(0, -3))+xmlData.thouSep+myArray[0].slice(-3)+"."+myArray[1]);
}
}
==================================================================================
//ADAPTED HELPER FUNCTION: ACCEPTS A NUMBER AND RETURNS A STRING WITH THOUSANDS SEPARATOR ATTACHED IF NECESSARY
function addThouSep(num) {
/*
a. Acquire the number - 'myTrendValue' or 'myDataValue' - from function calcValues
b. Record it (still as a number) to data precision.
1. Turn dataORtrend into a string
2. See if there is a decimal in it.
3. If there isn't, just run the normal addThouSep.
4. If there is, run addThouSep just on the first bit of the string - then add the decimal back on again at the end.
*/
var myNum:Number = correctFPE(num); // Create number variable myNum and populate it with 'num'
// (myTrendvalue or myData Value from calcValues function) passed thru 'correctPFE'
var myAbsNum:Number = Math.abs(myNum); // ABSOLUTE value of myNum
var strNum:String = myAbsNum+""; // Create string version of the dataORtrend number - so instead of 63, you get '63'
var myArray = strNum.split("."); // Create array representing elements of strNum, split by decimal point.
//trace(myArray.length); // How long is the array?
if (myNum <0){ // negatives
if (myArray.length==1) { // Integer, no decimal.
if (strNum.length < 4)//999 doesn't need a comma.
return strNum;
return addThouSep(strNum.slice(0, -3))+xmlData.thouSep+strNum.slice(-3);
}
else { // Float, with decimal
if (myArray[0].length < 4)//999 doesn't need a comma
return strNum;
return (addThouSep(myArray[0].slice(0, -3))+xmlData.thouSep+myArray[0].slice(-3)+"."+myArray[1]);
}
}
else // positive
if (myArray.length==1) { // Integer, no decimal.
if (strNum.length < 4)//999 doesn't need a comma.
return strNum;
return addThouSep(strNum.slice(0, -3))+xmlData.thouSep+strNum.slice(-3);
}
else { // Float, with decimal
if (myArray[0].length < 4)//999 doesn't need a comma
return strNum;
return (addThouSep(myArray[0].slice(0, -3))+xmlData.thouSep+myArray[0].slice(-3)+"."+myArray[1]);
}
}
==================================================================================
If you're adding commas often (or need to support numbers with decimals) then you may want a highly optimized utility function and go with straightforward string manipulation:
public static function commaify( input:Number ):String
{
var split:Array = input.toString().split( '.' ),
front:String = split[0],
back:String = ( split.length > 1 ) ? "." + split[1] : null,
pos:int = input < 0 ? 2 : 1,
commas:int = Math.floor( (front.length - pos) / 3 ),
i:int = 1;
for ( ; i <= commas; i++ )
{
pos = front.length - (3 * i + i - 1);
front = front.slice( 0, pos ) + "," + front.slice( pos );
}
if ( back )
return front + back;
else
return front;
}
While less elegant it's stable and performant — you can find a comparison suite at my answer of a similar question https://stackoverflow.com/a/13410560/934195
Why not use something simple like this function I've made?
function numberFormat(input:Number):String
{
var base:String = input.toString();
base = base.split("").reverse().join("");
base = base.replace(/\d{3}(?=\d)/g, "$&,");
return base.split("").reverse().join("");
}
Tests:
trace( numberFormat(-100) ); // -100
trace( numberFormat(5000) ); // 5,000
trace( numberFormat(-85600) ); // -85,600
Explanation:
Convert the input number to a string.
Reverse it.
Use .replace() to find all occurrences of three numbers followed by another number. We use $&, as the replacement, which basically means take all of those occurences and replace it with the value we found, plus a comma.
Reverse the string again and return it.
Did you try using the built in Number formatting options that support localized number values:
Localized Formatting with NumberFormatter

Difficulty splitting array and returning a value from within it; Javascript

I have got an array that consists of strings. I have made a function that searches the array based on the search term parameter. However, when i run the code it only ever outputs the string at index 0 of the array. I want it to return the corresponding url in the array when a search is run.
Any help would be very much appreciated. Thanks in advance.
So you are trying to return URL based on the String after the ~?
Do the line
arrayOfURL[i].toLowerCase().split('~')[i];
seem weird to you? Imagine as i increases, eg. i = 4
arrayOfURL[4].toLowerCase().split('~')[4];
Does that last [4] make sense?
I am guessing the reason it never got past the first element is because the code actually erroring out on that part.
I think what you want is (likewise for the return line, you'll want [0]
arrayOfURL[i].toLowerCase().split('~')[1];
I would also take a look at
if (z >= searchtoLower)
what are you trying to compare there?
The problem may be in the second i param:
var z = arrayOfURL[i].toLowerCase().split('~')[i];
The string will be splitted into 2 parts (index 0, 1). Why did you select part i?
This is a correct version of your program:
var arrayOfURL = [
"http://www.google.co.uk~Google is a search engine.",
"http://www.yahoo.co.uk~Yahoo is another search engine.",
"http://bing.com~Bing is a decision engine."
];
function findURL(arrayOfURL,search)
{
var searchtoLower = search.toLowerCase();
for (var i = 0; i < arrayOfURL.length; i++)
{
var z = arrayOfURL[i].toLowerCase().split('~')[1];
if (z.indexOf(searchtoLower) != -1)
return arrayOfURL[i];
}
return "Nothing Found!";
}
findURL(arrayOfURL,"decision")
I hope it can help you.
I think you should be doing
var terms = arrayOfURL[i].toLowerCase().split('~');
if(0 <= terms[1].indexOf(searchToLower))
// ^ ^
// | |-- 0 <= indexOf method determines
// | if searchToLower is a substring of terms[1]
// |
// |-- term[1] gets the part after the first "~"
and
return terms[0]; //terms[0] is the part before the first "~"
I would also consider returning null or the empty string "" in case of failure (instead of returning the arbritrary "Nothing Found!" message)