Calculating GridView total using JavaScript/JQuery

Hello everyone.

One month ago I’ve had very nice conversation with a asp.net forum member asking about issue regarding calculation of GridView textboxes total using JavaScript. The main thing was to allow user to manually write values in the text boxes (placed inside GridView column) and if the value has changed automatically to perform calculation on client side.

At the end of the conversation, we came up to two solutions. The first solution was using plain JavaScript, but since I thought it was not so robust, and in order to make it more robust we would need to write few more functions. Therefore, I have simply proposed another solution using JQuery which came up much better, more robust with less code.

In this blog post I will show both of the solutions and will provide step by step explanation on how we did that.

Note: I’m using VWD.NET 2008, MS SQL 2005 (Northwind database), JQuery library v1.4.2.min.js from the Microsoft AJAX CDN

SOLUTION 1

1. Create simple ASPX page and add GridView.

2. Fill the GridView with data from database using some of the data source controls or programmatically.

3. Lets create custom ItemTemplate inside GridView’s TemplateField and add TextBox control inside.

<asp:TemplateField>
    <ItemTemplate>
     <asp:TextBox ID="TextBox1" onchange="calculate()" runat="server" Text="0"></asp:TextBox>
    </ItemTemplate>
</asp:TemplateField>

This goes as a child node of GridView <Columns> … </Colulmns> nodes.

Here, you can automatically bind data from your data source select command that will be displayed in the TextBox Text property.

For instance:

<asp:TextBox ID="TextBox1" onchange="calculate()" runat="server" Text='<%# Bind("UnitPrice", "{0:N}") %>'></asp:TextBox>

This way the UnitPrice comes from database table which we use to retrieve the data to the GridView using SELECT query of the data source (ex: SqlDataSource).

If you see, the textbox has attribute onchange which is an event. So if value has been changed, the event will fire and the calculate() function will get executed.

4. Once the GridView is ready and the textboxes are there, lets add another textbox which will hold the result of the calculation – the total.

Total :-<asp:TextBox ID="total" runat="server" Text="0"></asp:TextBox>

5. The next is the JavaScript code.

The JavaScript code will do the following:
- loop through all textboxes in the grid view and calculate the sum
- store the result in the total textbox
- format the result as a float with two decimal spaces using math round function

        function calculate() {
            var txtTotal = 0.00; //place where we will keep the total
            var passed = false; //bool val to check whether all textboxes are passed
            var id = 2; //current id

            while (passed == false) {
                var newId = "";
                if (id.toString().length == 1) {
                    //if the length of the id is 1 add '0' at beginning
                    //resultset: '1' => '01', '2'=>'02','3'=>'03'... etc
                    newId = "0" + id.toString();
                }
                else {
                    newId = id.toString(); //else just asign it to newId
                }

                var getElement = document.getElementById("GridView1_ctl" + newId + "_TextBox1");

                id = id + 1; //increment id
                if (getElement == null) {
                    passed = true;
                }
                else {
                    var currentVal = getElement.value.replace(",", ".");
                    txtTotal = MathRound(parseFloat(txtTotal) + parseFloat(currentVal));
                }
            }
            document.getElementById("<%= total.ClientID %>").value = txtTotal.toFixed(2);
        }

and we have MathRound function to make the rounding

        function MathRound(number) {
            return Math.round(number * 100) / 100;
        }
 

Here we have few things to discuss:

THE PROBLEM

The main problem here which made us replace the plain JavaScript  with JQuery is that in different versions of .NET Framework, the textboxes placed inside GridView column get different Client ID, which is very important in order to manipulate the values using JavaScript. Moreover, if you use MasterPage, the Client Id will contain even the ContentPlaceHolder’s ID as well as part of the ID which is automatically generated by the control. So, we have replaced the entire solution with JQuery, which came much shorter and extremely better.

SOLUTION 2

Here is the code, both ASPX and the JQuery code.

The ASPX

    <asp:TemplateField>     
        <ItemTemplate>      
            <asp:TextBox ID="TextBox1" class="calculate" onchange="calculate()" runat="server" Text="0"></asp:TextBox>     
        </ItemTemplate>
    </asp:TemplateField>

The code is similar as previously. Only now we have addedd class=”calculate” to the TextBox in order to perform JQuery manipulation to all the textboxes with class=”calculate” (all textboxes will have class calculate, no matter of the number of textboxes inside the gridview, which will make easier to find and manipulate with them using JQuery).

The JQuery code:

    <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js" type="text/javascript"></script>
    <script language="javascript" type="text/javascript">
        function calculate() {
            var txtTotal = 0.00;
            //var passed = false;
            //var id = 0;

            $(".calculate").each(function (index, value) {
                var val = value.value;
                val = val.replace(",", ".");
                txtTotal = MathRound(parseFloat(txtTotal) + parseFloat(val));
            });

            document.getElementById("<%=total.ClientID %>").value = txtTotal.toFixed(2);            
        }

        function MathRound(number) {
            return Math.round(number * 100) / 100;
        }
    </script>

Using this JQuery each function, we can easily iterate trough all html objects containing the class name calculate, which in our case are the text boxes.

 

That’s it.

I hope this blog post was helpful and informative.

Download the complete source code, including C# code-behind: HERE

Best Regards,
Hajan

P.S. Translation in Macedonian language: http://mkdot.net/blogs/hajan/archive/2010/09/01/gridview-javascript-jquery.aspx

12 Comments

  • looping thru all cells might be not the best approach due to performance issues. to recalculate the total, you only need the difference of the old and the new value in the current input cell, then you add this difference to the current value of the total cell. so, when edit starts (event onfocus) save the content of the current text box, when edit ends get the new value. only in case of a difference, get the value of the total textbox and add this difference.

  • @Ulrich, thank you for your feedback.

    I totally agree with your point. I already thought about such solution where definitely we will achieve better performance. However, in our case we are speaking about GridView data rows not more than, lets say 50. Why? Because otherwise there would be no need for entering the values manually. Because of such reasons, I have proposed this solution in order to avoid more complex coding that might have confused the asp.net forum member that has asked the question. So, trying to keep the simplicity, we've lost bit of performance.

    For example, the first approach using plain JavaScript were getting more complex, which for the forum member that asked the question, the approach was hard to understand completely. Therefor, this second solution was simpler and I didn't want to confuse him with anymore events and functions, knowing the fact that the calculation won't be performed for thousands of rows - on client side.

    Thanks for the very valuable feedback! ;) I'm with you (+1)

  • Thankx,really a good and helpful article

  • gr8 job.. is there any possibility for gridview while paging

  • Great Man...........JQuery Rockz

  • Accessing elements via their class names is costly than accessing using their name. You can also use the following method which is pretty easy:

    $(document).ready(function(){
    var total = 0.00;
    $("#gv1 input[id $= 'TextBox1']").each(function(){
    var value = $(this).val();
    total = parseFloat(total) + Math.round(parseFloat(value));
    });
    $("#txtTotal").val(total);
    });

    But still, for beginners your idea is really good one.

  • @Baaje, I will see what I can do about that. However, I think the best would be to post a question about that on the http://forums.asp.net or more specifically in the suitable forum, here: http://forums.asp.net/24.aspx - You will definitely get an answer sooner than using the commenting page here :). Thanks for your comment.

  • @engineerachu, you are probably right. However, as I've commented previously, sometimes we are trying to search for balance between complexness & performance. Thanks for sharing your idea and the great feedback.

    Thanks for the feedback to the others who sent their valuable feedback.

  • Hello Hajan,

    Nice Article.How did you got that in first page of asp.net site.

    Best Regards,
    Jalpesh

  • @Jalpesh, sincerely, I was not aware of that :). Probably someone has submitted it as an article of the day. In the home page, we see one article per day ;).

  • Calculating gridview total using javascript jquery.. Tiptop :)

  • Good Article..But was wondering what if we want to calculate the total for each column using Jquery, where looping through all textboxes is not necessary? Ofcourse we can do that with javascript, but any Jquery solution??

Comments have been disabled for this content.