This problem is driving me nuts. I've lost at least a week because of it and I've no idea what's causing it. I started using jQuery Number Format last week but found it extremely buggy for what I wanted to do - basically, a user enters a number in one box and two other boxes are changed depending on the input. I then started looking at toFixed()
and managed to hack something together. However, I couldn't get the numbers to format with thousand comma separators. I then spent all day today trying toLocale()
, then the answer from this stackoverflow question, then finally accounting.js, but I'm having the exact same issue. I'm now thinking that NumberFormat wasn't buggy at all and it's my code that's causing the issue. Can anyone help?
The bug is as follows:-
I enter a number in a 'weekly' textbox (
id="weekly_credit"
) and my javascript converts it to both a 'monthly' and 'annual' equivalent and outputs them in two other textboxes (id="monthly_credit"
&id="tax_credit"
)When I then click into the monthly or annual textbox and click back out again, the numbers are changing by themselves - it usually hacks a number of 000s off the end.
I've linked to two videos below. One shows it working fine but without comma formatted numbers. The second one shows the bug. I can't for the life of me figure out what I'm doing wrong. I'm reasonably new to rails and haven't used much javascript or jQuery but know enough to get by. Thanks for reading. I can post more code if necessary.
1. Working code but without comma formatted numbers
Here's a short video of this working as it's supposed to, but without comma formatted numbers. Below is the code extract that implements it:
views/employees/_form.html.erb
<script>
// Highlight the text when the user clicks on a textbox
var getFocus = function(){
$(this).select();
};
// Function to re-calculate weekly/monthly/annual when move away from the text input
var loseFocus = function(){
var amount = parseFloat(this.value).toFixed(2);
if (($(this).is('#weekly_credit'))||($(this).is('#weekly_cutoff'))){
var monthly = calculateEquivalent(amount, "weekly", "monthly").toFixed(2);
var annual = calculateEquivalent(amount, "weekly", "annual").toFixed(2);
if ($(this).is('#weekly_credit')){
$("#monthly_credit").val(monthly);
$("#tax_credit").val(annual);
}
else{
$("#monthly_cutoff").val(monthly);
$("#tax_cutoff").val(annual);
}
}
else if (($(this).is('#monthly_credit'))||($(this).is('#monthly_cutoff'))){
var weekly = calculateEquivalent(amount, "monthly", "weekly").toFixed(2);
var annual = calculateEquivalent(amount, "monthly", "annual").toFixed(2);
if ($(this).is('#monthly_credit')){
$("#weekly_credit").val(weekly);
$("#tax_credit").val(annual);
}
else{
$("#weekly_cutoff").val(weekly);
$("#tax_cutoff").val(annual);
}
}
else if (($(this).is('#tax_credit'))||($(this).is('#tax_cutoff'))){
var weekly = calculateEquivalent(amount, "annual", "weekly").toFixed(2);
var monthly = calculateEquivalent(amount, "annual", "monthly").toFixed(2);
if ($(this).is('#tax_credit')){
$("#weekly_credit").val(weekly);
$("#monthly_credit").val(monthly);
}
else{
$("#weekly_cutoff").val(weekly);
$("#monthly_cutoff").val(monthly);
}
}
else{
document.write("Something is very wrong");
}
// alert("The value of amount is: " + amount);
$(this).val(amount);
};
// Everything inside this function gets called on the page load
$(function() {
// Implement the jQuery UI tab structure for employee form
$( "#tabs-1" ).tabs({
active:1});
// Bind getFocus function to textbox focus
$("#weekly_credit, #monthly_credit, #tax_credit, #weekly_cutoff, #monthly_cutoff, #tax_cutoff").focus(getFocus);
// Bind loseFocus function to textbox blur
$("#weekly_credit, #monthly_credit, #tax_credit, #weekly_cutoff, #monthly_cutoff, #tax_cutoff").blur(loseFocus);
});
</script>
<div class="col-md-5">
<div class="form_label"><strong>Tax Credit</strong></div>
<div class="form_spacer"></div>
<input type="text" id="weekly_credit" value=<%= number_to_currency("#{@weekly_credit}") %>>
<div class="form_spacer"></div>
<input type="text" id="monthly_credit" value=<%= number_to_currency("#{@monthly_credit}") %>>
<div class="form_spacer"></div>
<%= f.text_field :tax_credit, id: "tax_credit", value: number_to_currency(f.object.tax_credit) %>
</div>
2. Bug is occurring
It's easiest to see the bug by watching this short video. The code below is pretty much the same as above, except I've added accounting.formatNumber()
when changing the values of the other textboxes.
views/employees/_form.html.erb (extract)
<script>
// Highlight the text when the user clicks on a textbox
var getFocus = function(){
$(this).select();
};
// Function to re-calculate weekly/monthly/annual when move away from the text input
var loseFocus = function(){
var amount = parseFloat(this.value).toFixed(2);
if (($(this).is('#weekly_credit'))||($(this).is('#weekly_cutoff'))){
var monthly = calculateEquivalent(amount, "weekly", "monthly").toFixed(2);
var annual = calculateEquivalent(amount, "weekly", "annual").toFixed(2);
if ($(this).is('#weekly_credit')){
$("#monthly_credit").val(accounting.formatNumber(monthly, 2));
$("#tax_credit").val(accounting.formatNumber(annual, 2));
}
else{
$("#monthly_cutoff").val(accounting.formatNumber(monthly, 2));
$("#tax_cutoff").val(accounting.formatNumber(annual, 2));
}
}
else if (($(this).is('#monthly_credit'))||($(this).is('#monthly_cutoff'))){
var weekly = calculateEquivalent(amount, "monthly", "weekly").toFixed(2);
var annual = calculateEquivalent(amount, "monthly", "annual").toFixed(2);
if ($(this).is('#monthly_credit')){
$("#weekly_credit").val(accounting.formatNumber(weekly, 2));
$("#tax_credit").val(accounting.formatNumber(annual, 2));
}
else{
$("#weekly_cutoff").val(accounting.formatNumber(weekly, 2));
$("#tax_cutoff").val(accounting.formatNumber(annual, 2));
}
}
else if (($(this).is('#tax_credit'))||($(this).is('#tax_cutoff'))){
var weekly = calculateEquivalent(amount, "annual", "weekly").toFixed(2);
var monthly = calculateEquivalent(amount, "annual", "monthly").toFixed(2);
if ($(this).is('#tax_credit')){
$("#weekly_credit").val(accounting.formatNumber(weekly, 2));
$("#monthly_credit").val(accounting.formatNumber(monthly, 2));
}
else{
$("#weekly_cutoff").val(accounting.formatNumber(weekly, 2));
$("#monthly_cutoff").val(accounting.formatNumber(monthly, 2));
}
}
else{
document.write("Something is very wrong");
}
// alert("The value of amount is: " + amount);
$(this).val(amount);
};
// Everything inside this function gets called on the page load
$(function() {
// Implement the jQuery UI tab structure for employee form
$( "#tabs-1" ).tabs({
active:1});
// Bind getFocus function to textbox focus
$("#weekly_credit, #monthly_credit, #tax_credit, #weekly_cutoff, #monthly_cutoff, #tax_cutoff").focus(getFocus);
// Bind loseFocus function to textbox blur
$("#weekly_credit, #monthly_credit, #tax_credit, #weekly_cutoff, #monthly_cutoff, #tax_cutoff").blur(loseFocus);
});
</script>
<div class="col-md-5">
<div class="form_label"><strong>Tax Credit</strong></div>
<div class="form_spacer"></div>
<input type="text" id="weekly_credit" value=<%= number_to_currency("#{@weekly_credit}") %>>
<div class="form_spacer"></div>
<input type="text" id="monthly_credit" value=<%= number_to_currency("#{@monthly_credit}") %>>
<div class="form_spacer"></div>
<%= f.text_field :tax_credit, id: "tax_credit", value: number_to_currency(f.object.tax_credit) %>
</div>