Link to home
Start Free TrialLog in
Avatar of JaimeJegonia
JaimeJegoniaFlag for United States of America

asked on

jquery or javascript equivalent of Net Calculation

Dear Experts,

I have this simple calculation that works but it's annoying because to make it dynamic, I need to trigger each TextChanged event with a postback and it is slow in the detailrows with 35 items.


Net.Text = (Decimal.Parse(Gross.Text)*Decimal.Parse(QtyPerCase.Text) - Decimal.Parse(Lost.Text) - Decimal.Parse(Reject.Text)).ToString();

I need help to have an equivalent calculation in jquery or javascript.

Thanks.
Avatar of Jaime Olivares
Jaime Olivares
Flag of Peru image

that would be pretty simple with jquery:

$("#Net").val( (parseFloat($("#Gross").val()) * parseFloat($("#QtyPerCase").val()) - parseFloat($("#Lost").val()) - parseFloat($("#Reject").val())).toString() );
Avatar of JaimeJegonia

ASKER

Thanks Jaime_Olivares!

Where & how I'm going to implement it on ASPX page?
I think a clean implementation with jquery would be:
for all the involved input textboxes, declare them with a classname, lets say "recalc"

<input type="textbox" class="recalc" .... etc. >

then, on body's onload event, create a change event handler:

<body onload='
$(".recalc").change(function() {
    $("#Net").val( (parseFloat($("#Gross").val()) * parseFloat($("#QtyPerCase").val()) - parseFloat($("#Lost").val()) - parseFloat($("#Reject").val())).toString() );
});' >
Avatar of Rajar Ahmed
You can use document.ready instead of onload which might give some browser compatability issues .

<script >
$(document).ready(function(){
 //jaime_olivares  Code - Starts
$(".recalc").change(function() {
..........
.....
 //jaime_olivares  Code - Ends
});
</script>
<body >

Open in new window


Jquery library should be added .
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>

Open in new window

Okay! I will try again your document.ready suggestion and let you know. The onload did not work. It  picked up the onload values but can't the changed.

Thanks.
We have tested this on a single row and works fine, however it becomes complicated with multiple rows.

The rows are created dynamically upon page load with IDs being iterated. Say we have 3 rows, for Gross Textbox it will have the following IDs:

ctl00_PageContent_tblProductionDetailTableControlRepeater_ctl00_Gross
ctl00_PageContent_tblProductionDetailTableControlRepeater_ctl01_Gross
ctl00_PageContent_tblProductionDetailTableControlRepeater_ctl02_Gross

This also goes for Loss and Reject textboxes and Net label.

Given that these textboxes will have a class 'recalc', we can compute the first row by:

$(".recalc").change(function() {
    $("#ctl00_PageContent_tblProductionDetailTableControlRepeater_ctl00_Net").val( (parseFloat($("#ctl00_PageContent_tblProductionDetailTableControlRepeater_ctl00_Gross").val()) - parseFloat($("#ctl00_PageContent_tblProductionDetailTableControlRepeater_ctl00_Loss").val()) - parseFloat($("#ctl00_PageContent_tblProductionDetailTableControlRepeater_ctl00_Reject").val()));
});

How about the next rows? Also, we don't know how many rows are created at this point of the program.

Any ideas?
Welcome to the client side!  The water is fine here  :)


I would take a radically different approach to your problem.  I would set up web services that deliver and consume JSON data.  And on the client side, I cannot live without Knockout.js.

Here is a working example of your problem using Knockout.  Heavily commented.

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html" />
<meta name="author" content="Evan Cutler" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.1.0.js"></script>
<title>Knockout Sample</title>
    
    <style type="text/css">
        body {font-family:Arial;}
        
    </style>
    <script type="text/javascript">

        //knockout uses a single object to hold all the model elements
        var pageModel = {};


        //this is a "template" that you push all your data through.  It takes the raw values and turns them 
        //in to observables.  This is knockout magic.
        pageModel.rowModel = function (data) {

            //notice that each observable value is a decision:  Either use the value passed in by 
            //the data variable, or set to some default value.  That allows you to push a new value in to
            //your rowData array with a statement like:  pageMode.rowData.push(new pageModel.rowModel())
            this.Gross = ko.observable(data ? data.Gross : 0);
            this.Quantity = ko.observable(data ? data.Quantity : 0);
            this.Lost = ko.observable(data ? data.Lost : 0);
            this.Reject = ko.observable(data ? data.Reject : 0);

            //this is a special type of knockout object called a computed.  You tell it to watch the rest
            //of your model items, and if it sees a change, return a new value
            this.rowTotal = ko.computed(function () {
                var gross = this.Gross();
                var quantity = this.Quantity();
                var lost = this.Lost();
                var reject = this.Reject();

                return (gross * quantity) - lost - reject;
            }, this);
        };

        //this is the data I used for this sample.  Notice it's just a simple array of objects.
        //I've added the step of pushing each item into my rowModel function that wraps each value in an
        //observable.
        pageModel.rowData = ko.observableArray([
            new pageModel.rowModel({ Gross: 10, Quantity: 6, Lost: 0, Reject: 5}),
            new pageModel.rowModel({ Gross: 14, Quantity: 3, Lost: 5, Reject: 5 }),
            new pageModel.rowModel({ Gross: 11, Quantity: 3, Lost: 2, Reject: 5 }),
            new pageModel.rowModel({ Gross: 23, Quantity: 20, Lost: 3, Reject: 5 }),
            new pageModel.rowModel({ Gross: 18, Quantity: 7, Lost: 1, Reject: 5 }),
            new pageModel.rowModel({ Gross: 19, Quantity: 120, Lost: 30, Reject: 5 }),
            new pageModel.rowModel({ Gross: 16, Quantity: 6, Lost: 0, Reject: 5 })
        ]);


        //in the real world I would create a function that fetches this row data using ajax.


        $(document).ready(function () {
            //wait until the page loads and apply the binding.
            ko.applyBindings(pageModel);
        });
        
    </script>
    
</head>

<body>


    <h1>Static Sample</h1>
    <table>
        <thead>
            <tr>
                <th>Gross</th>
                <th>Quantity</th>
                <th>Lost</th>
                <th>Reject</th>
                <th>Total</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: rowData">
            <tr>
                <td data-bind="text:Gross"></td>
                <td data-bind="text:Quantity"></td>
                <td data-bind="text:Lost"></td>
                <td data-bind="text:Reject"></td>
                <td data-bind="text:rowTotal"></td>
            </tr>
        </tbody>
    </table>

    <h1>Dynamic Sample</h1>
    <table>
        <thead>
            <tr>
                <th>Gross</th>
                <th>Quantity</th>
                <th>Lost</th>
                <th>Reject</th>
                <th>Total</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: rowData">
            <tr>
                <td><input type="text" name="gross" data-bind="value: Gross" /></td>
                <td><input type="text" name="quantity" data-bind="value: Quantity" /></td>
                <td><input type="text" name="lost" data-bind="value: Lost" /></td>
                <td><input type="text" name="reject" data-bind="value: Reject" /></td>
                <td data-bind="text:rowTotal"></td>
            </tr>
        </tbody>
    </table>

    <p>As an example of some other functionality - you can add rows like this:  <a href="#" data-bind="click: function(){ pageModel.rowData.push(new pageModel.rowModel()) } ">Add a Row</a></p>
</body>
</html>

Open in new window

Skrile,

I'll try your suggestion and let know if it works.


Thanks.
I've requested that this question be deleted for the following reason:

Not enough information to confirm an answer.
ASKER CERTIFIED SOLUTION
Avatar of Steve Krile
Steve Krile
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial