?
Solved

Text Box Calculations - handling empty fields

Posted on 2013-11-12
9
Medium Priority
?
424 Views
Last Modified: 2013-11-13
Hi Experts,

I have 6 textboxes in a webform to record pricing of order items, they are:
txtQuantity
txtUnitCost
txtNetTotal
txtVATRate
txtVAT
txtTotal
Hopefully their individual prpose is self-explanatory.
I am trying to semi-automate the entry of this information to make it as efficient as possible:
I have been partially successful in this using the following code -  
aspx page:
 <tr>
                                    <td>
                                        Quantity:
                                    </td>
                                    <td>
                                        <asp:TextBox ID="txtQuantity" AutoPostBack="true" OnTextChanged="txtQuantity_TextChanged" runat="server" Width="200px"></asp:TextBox><br />
                                        <br />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        Unit cost:
                                    </td>
                                    <td>
                                        <asp:TextBox ID="txtUnitCost" AutoPostBack="true" Text="0" TextMode="SingleLine" ReadOnly="false" OnTextChanged="txtUnitCost_TextChanged" runat="server" Width="200px"></asp:TextBox><br />
                                        <br />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        Net total:
                                    </td>
                                    <td>
                                        <asp:TextBox ID="txtNetTotal" runat="server" Width="200px"></asp:TextBox><br />
                                        <br />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        VAT Rate:
                                    </td>
                                    <td>
                                        <asp:TextBox ID="txtVATRate" AutoPostBack="true" OnTextChanged="txtVATRate_TextChanged" runat="server"  Text="0.2" TextMode="SingleLine" ReadOnly="false" Width="200px"></asp:TextBox><br />
                                        <br />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        VAT:
                                    </td>
                                    <td>
                                        <asp:TextBox ID="txtVAT" runat="server" Width="200px"></asp:TextBox><br />
                                        <br />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        Total:
                                    </td>
                                    <td>
                                        <asp:TextBox ID="txtTotal" runat="server" Width="200px"></asp:TextBox><br />
                                        <br />
                                    </td>
                                </tr>

Open in new window


Code Behind:
 protected void txtQuantity_TextChanged(object sender, EventArgs e)
    {

        int qty = Convert.ToInt32(txtQuantity.Text);
        decimal uc = Convert.ToDecimal(txtUnitCost.Text);
        decimal rate = Convert.ToDecimal(txtVATRate.Text);

        if (string.IsNullOrEmpty(txtVATRate.Text) || !string.IsNullOrEmpty(txtVATRate.Text) && (string.IsNullOrEmpty(txtUnitCost.Text) || !string.IsNullOrEmpty(txtUnitCost.Text)))
        {
            txtNetTotal.Text = (qty * uc).ToString();
            txtVAT.Text = (rate * (qty * uc)).ToString();
            txtTotal.Text = ((rate * (qty * uc)) + (qty * uc)).ToString();

        }
    }


    protected void txtUnitCost_TextChanged(object sender, EventArgs e)
    {
        int qty = Convert.ToInt32(txtQuantity.Text);
        decimal uc = Convert.ToDecimal(txtUnitCost.Text);
        decimal rate = Convert.ToDecimal(txtVATRate.Text);

        if (string.IsNullOrEmpty(txtVATRate.Text) || !string.IsNullOrEmpty(txtVATRate.Text) && (string.IsNullOrEmpty(txtUnitCost.Text) || !string.IsNullOrEmpty(txtUnitCost.Text)))
        {
            txtNetTotal.Text = (qty * uc).ToString();
            txtVAT.Text = (rate * (qty * uc)).ToString();
            txtTotal.Text = ((rate * (qty * uc)) + (qty * uc)).ToString();

        }
    }


    protected void txtVATRate_TextChanged(object sender, EventArgs e)
    {
        int qty = Convert.ToInt32(txtQuantity.Text);
        decimal uc = Convert.ToDecimal(txtUnitCost.Text);
        decimal rate = Convert.ToDecimal(txtVATRate.Text);

        if (string.IsNullOrEmpty(txtVATRate.Text) || !string.IsNullOrEmpty(txtVATRate.Text))
        {
            txtNetTotal.Text = (qty * uc).ToString();
            txtVAT.Text = (rate * (qty * uc)).ToString();
            txtTotal.Text = ((rate * (qty * uc)) + (qty * uc)).ToString();
        }
    }

Open in new window


I am having two issues that i'm not sure how best to resolve:

1. Because the calculations expect an int and two decimals if any of the boxes are empty at the point of post-back the page errors - to avoid this I have set the text of UnitCost to 0 and instructed the user to edit this as required, similarly for non-taxable items the VATRate has to be set to 0 it cannot be blank. Perhaps this is the best approach but it makes for a rather clunky feel - is there a way to handle this more gracefully?
2. The calculation runs on each post-back and each post-back runs as the user tabs out of an editable textbox, however at this point all text boxes lose focus and so th user is forced to repeatedly click back into the next box they wish to edit, again it makes the thing feel very clunky. I presume this is related to the postback but I don't quite undersatnd what is happening and therefore how to combat it, can anyone advise please?

Many thanks in advance
0
Comment
Question by:forsters
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
9 Comments
 
LVL 75

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 2000 total points
ID: 39642740
You can use TryParse to test if the text box values are both populated and valid:

e.g.

int qty;

int.TryParse(txtQuantity.Text, out qty);

Open in new window


If the value contained within txtQuantity.Text is a valid integer, then qty will hold the converted value; otherwise it will hold the default value for an int, which is zero.


Posting back as each field is tabbed out of is excessive. I would suggest either postponing the validation until a submit button is clicked, or add in some Javascript validation to provide a more user-friendly experience. You should not rely solely on Javascript validation for your inputs, though. Still validate on the server.
0
 

Author Comment

by:forsters
ID: 39644115
Hi kaufmed,

Thank you for your reply, I had been wondering about TryParse, will that work for the decimals too?

Re. the posting back, I agree but I wasn't sure how to handle the user potentially going back to a box to edit, I think I would like the screen to update as they make any edits so they can check figures as they go.
Javascript makes total sense and was my first attempt, unfortunately I don't really know my way around the language well enough to trouble shoot so when it didn't work I retreated to familiar ground. Ha looks like i'm going to have to face my demons and try again.

Thanks for your help I will have another go and report back!
0
 

Author Comment

by:forsters
ID: 39644287
Further to my last I have modified my code behind to include the TryParse as suggested - which solves the problem of empty fields nicely, but obviously leaves me with the postback and focus problem. I have found a promising looking piece of javascript so I will attempt that next :

 protected void txtQuantity_TextChanged(object sender, EventArgs e)
    {
        int qty;
        decimal uc;
        decimal rate;

        int.TryParse(txtQuantity.Text, out qty);
        decimal.TryParse(txtUnitCost.Text, out uc);
        decimal.TryParse(txtVATRate.Text, out rate);
      
            txtNetTotal.Text = (qty * uc).ToString();
            txtVAT.Text = (rate * (qty * uc)).ToString();
            txtTotal.Text = ((rate * (qty * uc)) + (qty * uc)).ToString();
       
    }


    protected void txtUnitCost_TextChanged(object sender, EventArgs e)
    {
        int qty;
        decimal uc;
        decimal rate;

        int.TryParse(txtQuantity.Text, out qty);
        decimal.TryParse(txtUnitCost.Text, out uc);
        decimal.TryParse(txtVATRate.Text, out rate);
       
        txtNetTotal.Text = (qty * uc).ToString();
        txtVAT.Text = (rate * (qty * uc)).ToString();
        txtTotal.Text = ((rate * (qty * uc)) + (qty * uc)).ToString();

    }


    protected void txtVATRate_TextChanged(object sender, EventArgs e)
    {
        int qty;
        decimal uc;
        decimal rate;
        
        int.TryParse(txtQuantity.Text, out qty);
        decimal.TryParse(txtUnitCost.Text, out uc);
        decimal.TryParse(txtVATRate.Text, out rate);
       
        txtNetTotal.Text = (qty * uc).ToString();
        txtVAT.Text = (rate * (qty * uc)).ToString();
        txtTotal.Text = ((rate * (qty * uc)) + (qty * uc)).ToString();
      
    }

Open in new window

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:forsters
ID: 39644576
Bit flummoxed with the Javascript, I realise I am now in the wrong zone for a JavaScript question but can anyone advise?

I am getting the following error:
Cannot assign to a function result

My code is :
<script type="text/javascript" language="javascript">
    function TryParseInt(str, defaultValue)
    {
        var retValue = defaultValue;
        if (str != null)
        {
            if (str.length > 0)
            {
                if (!isNaN(str))
                {
                    retValue = parseInt(str);
                }
            }
        } return retValue;
    }

    function TryParseDecimal(str, defaultValue) {
        var retValue = defaultValue;
        if (str != null) {
            if (str.length > 0) {
                if (!isNaN(str)) {
                    retValue = parseInt(str);
                }
            }
        } return retValue;
    }

function VATcalc()
    {
        var qty = document.getElementById('<%=txtQuantity.ClientID%>');
        var uc = document.getElementById('<%=txtUnitCost.ClientID%>');
        var rate = document.getElementById('<%=txtVATRate.ClientID%>');
        
        document.getElementById('<%=txtNetTotal.ClientID%>') = (TryParseInt(qty.value, 0) * TryParseDecimal(uc.value, 0)) ;
        document.getElementById('<%=txtVAT.ClientID%>') = (TryParseDecimal(rate.value, 0) * (TryParseInt(qty.value, 0) * TryParseDecimal(uc.value, 0)));
        document.getElementById('<%=txtTotal.ClientID%>') = ((TryParseDecimal(rate.value, 0) * (TryParseInt(qty.value, 0) * TryParseDecimal(uc.value, 0))) + (TryParseInt(qty.value, 0) * TryParseDecimal(uc.value, 0)));
    }

</script>

Open in new window


And I am calling the function with :

onchange="VATcalc();" in each of the editable textboxes.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 39644642
In lines 34 - 36, you are trying to assign the DOM element, not its value. Add ".value" to the end of each:

e.g.

document.getElementById('tb4').value = (TryParseInt(qty.value, 0) * TryParseDecimal(uc.value, 0)) ;
document.getElementById('tb5').value = (TryParseDecimal(rate.value, 0) * (TryParseInt(qty.value, 0) * TryParseDecimal(uc.value, 0)));
document.getElementById('tb6').value = ((TryParseDecimal(rate.value, 0) * (TryParseInt(qty.value, 0) * TryParseDecimal(uc.value, 0))) + (TryParseInt(qty.value, 0) * TryParseDecimal(uc.value, 0)));

Open in new window

0
 

Author Comment

by:forsters
ID: 39644674
Ahh yes, thank you.

Ok cool so my textboxes are now auto-calculating except, for some reason it is ignoring the VATRate in all calculations...

I thought it might be because I had set the default value to 0 but having tried removing that and replacing it with 0.2 I'm no further forward.

I had set the txtVATRate textbox Text="0.2" but even if I amend the textbox on screen it doesn't feature in any of the calculations, I must have got something else wrong...can you see my error?

<script type="text/javascript" language="javascript">
    function TryParseInt(str, defaultValue)
    {
        var retValue = defaultValue;
        if (str != null)
        {
            if (str.length > 0)
            {
                if (!isNaN(str))
                {
                    retValue = parseInt(str);
                }
            }
        } return retValue;
    }

    function TryParseDecimal(str, defaultValue) {
        var retValue = defaultValue;
        if (str != null) {
            if (str.length > 0) {
                if (!isNaN(str)) {
                    retValue = parseInt(str);
                }
            }
        } return retValue;
    }

function VATcalc()
    {
        var qty = document.getElementById('<%=txtQuantity.ClientID%>');
        var uc = document.getElementById('<%=txtUnitCost.ClientID%>');
        var rate = document.getElementById('<%=txtVATRate.ClientID%>');
        
        document.getElementById('<%=txtNetTotal.ClientID%>').value = TryParseInt(qty.value, 0) * TryParseDecimal(uc.value, 0);
    document.getElementById('<%=txtVAT.ClientID%>').value = (TryParseDecimal(rate.value, 0.2) * (TryParseInt(qty.value, 0) * TryParseDecimal(uc.value, 0)));
        document.getElementById('<%=txtTotal.ClientID%>').value = ((TryParseDecimal(rate.value, 0.2) * (TryParseInt(qty.value, 0) * TryParseDecimal(uc.value, 0))) + (TryParseInt(qty.value, 0) * TryParseDecimal(uc.value, 0)));
    }

</script>

Open in new window


 <tr>
                                    <td>
                                        Quantity:
                                    </td>
                                    <td>
                                        <asp:TextBox ID="txtQuantity" onchange="VATcalc();" runat="server" Width="200px"></asp:TextBox><br />
                                        <br />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        Unit cost:
                                    </td>
                                    <td>
                                        <asp:TextBox ID="txtUnitCost" onchange="VATcalc();" runat="server" Width="200px"></asp:TextBox><br />
                                        <br />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        Net total:
                                    </td>
                                    <td>
                                        <asp:TextBox ID="txtNetTotal" runat="server" Width="200px"></asp:TextBox><br />
                                        <br />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        VAT Rate:
                                    </td>
                                    <td>
                                        <asp:TextBox ID="txtVATRate" onchange="VATcalc();" runat="server"  Text="0.2" TextMode="SingleLine" ReadOnly="false" Width="200px"></asp:TextBox><br />
                                        <br />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        VAT:
                                    </td>
                                    <td>
                                        <asp:TextBox ID="txtVAT" runat="server" Width="200px"></asp:TextBox><br />
                                        <br />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        Total:
                                    </td>
                                    <td>
                                        <asp:TextBox ID="txtTotal" runat="server" Width="200px"></asp:TextBox><br />
                                        <br />
                                    </td>
                                </tr>

Open in new window

0
 

Author Comment

by:forsters
ID: 39644701
Oh I think this is a rounding thing, if I remove Text="0.2" and set the VATRate to 1 my VAT is populated, if I change it to any figure below 1 then my VAT returns to 0 and my Total is equal to my NET, how can I combat this?
0
 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 2000 total points
ID: 39644826
I noticed earlier that your TryParseDecimal function is using parseInt internally. This doesn't sound right. I would have expected to see parseFloat.
0
 

Author Comment

by:forsters
ID: 39644877
Ahhh yes I copied the TryParseInt probably forgot to change...that has resolved it.

Fantastic thank you for all your help
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Just a quick little trick I learned recently.  Now that I'm using jQuery with abandon in my asp.net applications, I have grown tired of the following syntax:      (CODE) I suppose it just offends my sense of decency to put inline VBScript on a…
Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question