2

I have table in which the columns have two input fields. I want to calculate the sum of the first input field of the child rows and add the total corresponding to the first input field of the parent row of the column.

Right now with the code, it does add up correctly but it doesn't set the total in the correct input fields of the parent (that is, in the corresponding input field of the parent row).

Please see jsFiddle.

Updated Fiddle

Code:

HTML:

<table>
    <tr class="parent-realtor percent-text">
        <td>
            <h5>Realtor Percent</h5>
        </td>
        <td>
            <input type="text" class="percent-total" /> //parent
            <input type="text" onfocus="this.blur()" class="percent-data" />
        </td>
        <td>
            <input type="text" class="percent-total" /> //parent
            <input type="text" onfocus="this.blur()" class="percent-data" />
        </td>
        <td>
            <input type="text" class="percent-total" /> //parent
            <input type="text" onfocus="this.blur()" class="percent-data" />
        </td>
        <td>
            <input type="text" class="percent-total" /> //parent
            <input type="text" onfocus="this.blur()" class="percent-data" />
        </td>
    </tr>
    <tr>
        <td>
            <h6>Contract Amount</h6>
        </td>
        <td>
            <input type="text" data-parent="realtor" />
        </td>
        <td>
            <input type="text" data-parent="realtor" />
        </td>
        <td>
            <input type="text" data-parent="realtor" />
        </td>
        <td>
            <input type="text" data-parent="realtor" />
        </td>
    </tr>
    <tr class="percent-text">
        <td>
            <h6>Buyer's Agent</h6>
        </td>
        <td>
            <input type="text" data-parent="realtor" class="percent" /> //child
            <input type="text" data-parent="realtor" class="percent-data r" onfocus="this.blur()" />
        </td>
        <td>
            <input type="text" data-parent="realtor" class="percent" /> //child
            <input type="text" data-parent="realtor" class="percent-data r" onfocus="this.blur()" />
        </td>
        <td>
            <input type="text" data-parent="realtor" class="percent" /> //child
            <input type="text" data-parent="realtor" class="percent-data r" onfocus="this.blur()" />
        </td>
        <td>
            <input type="text" data-parent="realtor" class="percent" /> //child
            <input type="text" data-parent="realtor" class="percent-data r" onfocus="this.blur()" />
        </td>
    </tr>
    <tr class="percent-text">
        <td>
            <h6>Seller's Agent</h6>
        </td>
        <td>
            <input type="text" data-parent="realtor" class="percent" /> //child
            <input type="text" data-parent="realtor" class="percent-data r" onfocus="this.blur()" />
        </td>
        <td>
            <input type="text" data-parent="realtor" class="percent" /> //child
            <input type="text" data-parent="realtor" class="percent-data r" onfocus="this.blur()" />
        </td>
        <td>
            <input type="text" data-parent="realtor" class="percent" /> //child
            <input type="text" data-parent="realtor" class="percent-data r" onfocus="this.blur()" />
        </td>
        <td>
            <input type="text" data-parent="realtor" class="percent" /> //child
            <input type="text" data-parent="realtor" class="percent-data r" onfocus="this.blur()" />
        </td>
    </tr>
</table>

jQuery:

$('.percent').on('keyup', function () {
    //calcRealtor();
    var totals = [0, 0, 0, 0, 0, 0, 0, 0],
        parent_name = $(this).data('parent'),
        find_parent_row = $('tr.parent-realtor');
    find_parent_row.nextUntil('[class="parent-realtor"]').find('input[data-parent="realtor"]').each(function () {
        totals[$(this).parent('td').index() / 1 - 1] += +this.value;
    });
    find_parent_row.find('input').each(function (i) {
        this.value = totals[i];
    });

});
input
  • 7,503
  • 25
  • 93
  • 150
  • I've re-read your question several times and still do not understand which fields are to be summed, and where the totals must be placed. Please refactor your question to increase precision. Please write from perspective of a reader who doesn't understand your industry or what you are doing. – cssyphus Dec 30 '13 at 21:38
  • @gibberish, I have elaborated the question little more in detail. I'm not sure how else to explain. Please see jsFiddle: http://jsfiddle.net/4TnqY/ – input Dec 30 '13 at 22:00
  • Perhaps add an example of input and expected output to help us figure out what you are trying to do. – danasilver Dec 30 '13 at 22:04
  • @dsilver1221, I have updated the fiddle with input and output markings: http://jsfiddle.net/R5Cjw/ – input Dec 30 '13 at 22:09
  • @input are you allowed to alter the HTML ? – Gabriele Petrioli Dec 30 '13 at 22:15
  • @GabyakaG.Petrioli, yes. – input Dec 30 '13 at 22:17

1 Answers1

3

Assumptions

  1. You will have multiple groups like on the example in the same table element
  2. You can add a class contract to the tr that holds the contract inputs

Try

$('table').on('keyup', '.percent', function(){
               // self holds a reference to the input we entered data
    var self = $(this), 
                  // we then find the containing tr element and then find the corresponding `parent-realtor` row and cache it in realtor variable
        realtor = self.closest('tr').prevAll('.parent-realtor').first(),
                // we cache a reference to the all tr rows that interest us
        group = realtor.nextUntil('.parent-realtor'),
                    // we filter the contract inputs
        contracts = group.filter('.contract').find('input'),
                   // and we filter the input elements that will be added to the contracts
        percents = group.filter('.percent-text');

    // for each contract
    contracts.each(function(idx){  // idx holds the index of the contract input
        // gets its value. the + converts it to an number
        var final = +this.value;
        // for each row of elements to add
        percents.each(function(){
            // find the input element that we are interested
            // meaning the one with the same index as our contract input
            // and get its value
            var extra = +$(this).find('input.percent').eq(idx).val();

            // add it to the total of this contracts
            final += extra;
        });

        // find the input that holds the total (based on index again)
        // and assign the total value we just calculated
        realtor.find('input.percent-total').eq(idx).val(final);
    });
});

Demo at http://jsfiddle.net/gaby/R5Cjw/2/


Instead of setting onfocus="this.blur()" you could just set the to readonly and be done.

Also you could name (with some unique value) each of the realtor input fields and give that value to each corresponding input element so you could match them easier.

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • Thank you so much! I would like to understand what is happening. Can you explain the code? I am setting the element to `readonly` using jQuery but I'm using `onfocus="this.blur()"` because it prevents the cursor from showing in the input field. – input Dec 30 '13 at 23:03
  • 1
    @input, added some comments.. let me know if it helps.. The general idea is that i am matching inputs based on their index in the `tr` row. – Gabriele Petrioli Dec 30 '13 at 23:11
  • Great solution Gaby +1 – cssyphus Dec 30 '13 at 23:13
  • Thanks once again for your time and effort @GabyakaG.Petrioli. Appreciated. The only thing is that the contract amount does not have to be added. So I removed this line `var final = +this.value;`. While this doesn't add the contract amount to the total output and works as I want, it also displays the total in all the 4 output columns disregarding the index. Why is this happening? Please see jsFiddle: http://jsfiddle.net/CFLaX/ – input Dec 30 '13 at 23:47
  • 1
    @input see http://jsfiddle.net/gaby/CFLaX/1/ if you want to alter only the *column* in which you edit the input.. – Gabriele Petrioli Dec 31 '13 at 00:01