2

On my website satoshindex.com when I try and type a number with a decimal point into the top input box, it automatically deletes the decimal point. It also doesn't let me highlight the input with Ctrl-A or use the arrow keys to move to a different digit in the number.

I think it has something to do with accounting.js.

Here is the relevant code from my website:

  var SAT = 0.00000001;
  var BIT = 0.000001;
  var MBIT = 0.001;
  var BTC = 1;
  var currentUnit = BTC;

I know it has something to do with these lines in the btcConvert and usdConvert functions because when I delete them the issue goes away but no commas are used to separate the numbers.

var decimals = decimalPlaces(input.value);
input.value = accounting.formatNumber(input.value, decimals)

I think the issue is that btcConvert is called every time you type in the input box and formatNumber is deleting the decimal place, but without formatNumber in btcConvert I can't get it to add commas to the number when it is above 999, same in USD convert.

Darkstar
  • 725
  • 2
  • 8
  • 27
  • please create a js fiddle or plunker – brk Dec 24 '15 at 03:38
  • Everything you need to see is on satoshindex.com, what would the jsfiddle accomplish? – Darkstar Dec 24 '15 at 03:41
  • do you think it is possible to debug from there?Also check demos from accounting.js there it is allowing decimal point.What is the need of both onchange="btcConvert(this);" onkeyup ="btcConvert(this).Arnt they doing the same thing. – brk Dec 24 '15 at 03:46
  • No sorry I guess not. 1 sec – Darkstar Dec 24 '15 at 03:51
  • I tried to recreate it in a jsfiddle but nothing is working the way it should and I cannot recreate the error. – Darkstar Dec 24 '15 at 04:01

1 Answers1

2

You can actually enter a decimal number like 1234.5 if you type the .5 really fast or if you copy-paste it into the input field. With normal typing speed, 1234. always turns into 1234 before you can add the 5. As you suspect, accounting.js is simplifying the 1234. to 1234 because that is what it considers to be the canonical format.

So you want to make it possible for the user to type 1234.0 and have it automatically formatted to 1,234.0 in the input field. I see three possible approaches:

  • Modify the accounting.js code. Edit accounting.formatNumber so that it doesn't discard the decimal point when it's the final character of input.value.

  • Don't use accounting.js to format the input field. Replace the call to accounting.formatNumber with a call to a formatting function that you write yourself.

  • A quick and dirty solution: Don't modify accounting.js and keep the call to accounting.formatNumber, but if input.value had a decimal point at the end and you get back a string without the decimal point, stick it back on.

One way to apply the quick and dirty approach to btcConvert is to replace this line:

input.value = accounting.formatNumber(input.value, decimals)

With this:

var formatted = accounting.formatNumber(input.value, decimals);
if (input.value.indexOf('.') == input.value.length - 1 &&
    input.value.length != 0 &&
    formatted.charAt(formatted.length - 1) != '.') {
  formatted += '.';
}
input.value = formatted;

The check for input.value.length != 0 is necessary because if input.value is the empty string, indexOf will always return -1, which is equal to input.value.length - 1 for empty input.value.

Michael Laszlo
  • 12,009
  • 2
  • 29
  • 47
  • The quick and dirty approach works great for the decimal point, thanks! Any way to fix the arrow key/highlight problem? When you use your arrow keys to move to a different digit, say you mistyped, it automatically moves the blinking line back to the end of the number. Any way to fix this? – Darkstar Dec 24 '15 at 05:03
  • 1
    You can delete `onkeyup ="btcConvert(this);"` from the HTML to prevent `btcConvert` from being called when you're only navigating through the text. However, if you change a digit in the middle of the number, the cursor still gets moved to the end. To fix this properly, you have to [get the cursor position](http://stackoverflow.com/questions/2897155/get-cursor-position-in-characters-within-a-text-input-field) and store it before changing `input.value`, then [restore the cursor to its old position](http://stackoverflow.com/questions/512528/set-cursor-position-in-html-textbox) afterward. – Michael Laszlo Dec 24 '15 at 05:16
  • If I delete onkeyup ="btcConvert(this);" then it waits until I click out of the input box to format the number instead of adding commas as I'm typing. Any way to keep this functionality while also allowing arrow key movement? – Darkstar Dec 24 '15 at 05:36
  • 1
    You can modify `btcConvert` to compare the formatted text against the original input, and only update the input box if the formatted text is different. So you would replace the line `input.value = formatted;` with `if (input.value !== formatted) { input.value = formatted; };`. – Michael Laszlo Dec 24 '15 at 06:17
  • Thanks so much for the help man, I really appreciate it. I've implemented the cursor position thing, but since it is formatting the numbers with commas, when you type, for instance, 123456 in the first input box, it doesn't work. It puts in 123,564 because I think the cursor function is counting the commas. Any way to fix this? accounting.unformat() removes the commas but I'm not sure what values to apply it to in the cursor functions. – Darkstar Dec 24 '15 at 06:53
  • I see what you mean. When a comma gets added, the cursor position is one character behind the digit you just typed. Sorry, my advice was bad. You would actually have to preserve the cursor position independently of the formatting changes that take place to the left and the right of the cursor. This would require a fundamentally different approach to formatting than the one followed by accounting.js. It's an interesting algorithmic challenge, I must say. – Michael Laszlo Dec 24 '15 at 07:17
  • Yea I haven't been able to figure it out. – Darkstar Dec 24 '15 at 15:43
  • accounting.unformat removes all commas and currency signs. Maybe adding this to the getCursorPosition function and then counting the commas added and depending on the cursor position (eg: hundreds place or 10thousands place) add the number of commas applicable to the cursor position? – Darkstar Dec 24 '15 at 15:54
  • Yes, you could do that to correct for the insertion of commas. It doesn't cover other modifications, such as whitespace-trimming and the removal of extraneous decimal points. A general-purpose solution requires a special string-processing method that stores the cursor position as a property of a character or as a character-like object in its own right. It's such an interesting question that I may write a blog post about it this weekend. – Michael Laszlo Dec 24 '15 at 19:45
  • I think I'll just leave it for now. Link me the blog post when you're done! – Darkstar Dec 24 '15 at 19:46
  • Something else weird I noticed: if you type 9876.1 then type a dash or a character other than a number after the 1, it deletes the 1 and the decimal and rounds the ones digit. So if you do .5+character at the end then it will change to 9877. – Darkstar Dec 26 '15 at 00:40
  • Ever write that blog post? – Darkstar Dec 27 '15 at 22:32