Question

I have a script to do some calculations however the target fields are in a repeater.

How can I make my script target the class in the same row?

I have been trying jquery .closest() but with little success.

REPEATER OUTPUT

<table>
    <tr>
        <td>
            <input class="Time1" value="10:00" />
        </td>
        <td>
            <input class="Time2" value="12:00" />
        </td>
        <td>
            <input class="Hours" value="0" />
        </td>
    </tr>
</table>

<table>
    <tr>
        <td>
            <input class="Time1" value="10:00" />
        </td>
        <td>
            <input class="Time2" value="12:00" />
        </td>
        <td>
            <input class="Hours" value="0" />
        </td>
    </tr>
</table>

SCRIPT

$(function () {
  function calculate() {
    var time1, time2, hours1, hours2, mins1, mins2, hours, mins;
    time1 = $(".Time1").val().split(':'),
    time2 = $(".Time2").val().split(':'),
    hours1 = parseInt(time1[0], 10),
    hours2 = parseInt(time2[0], 10),
    mins1 = parseInt(time1[1], 10),
    mins2 = parseInt(time2[1], 10),
    hours = hours2 - hours1,
    mins = 0;
    if (hours < 0) hours = 24 + hours;
    if (mins2 >= mins1) {
      mins = mins2 - mins1;
    }
    else {
      mins = (mins2 + 60) - mins1;
      hours--;
    }
    mins = mins / 60; // take percentage in 60
    hours += mins;
    hours = hours.toFixed(2);
    $(".Hours").val(hours);
  }
  $(".Time1,.Time2").change(calculate);
  calculate();
});

JSFIDDLE

In this example when you update a time in row one the last column in both rows will update. However when you update row two nothing.

http://jsfiddle.net/JZ7Ad/

Était-ce utile?

La solution

The general concept you probably want to use is to find the corresponding .Time1, .Time2 and .Hours that are all in the same row and make your function operate on only them together. Your current script is not paying any attention to what row an item is in.

The general idea for finding things that are all in a common parent is to start with one particular item and then find the common parent using .closest() and then use .find() from the common parent to find the other items under that same parent.

.closest("tr") works by going up the parent chain from your starting point and finding the closest parent that matches the selector. Once you have that, you can then use .find() to find the other elements you want in that same row. In that way, you can find the three objects in the same row and operate on them as a unit without regard for all the other elements in other rows.

For example, this script would iterate through each .Time1 element and find the other corresponding two elements in it's same row.

// for each .Time1
$(".Time1").each(function() {
    var time1Obj = $(this);
    // find the row
    var row = time1Obj.closest("tr");
    // find the .Time2 in that row
    var time2Obj = row.find(".Time2");
    // find the .Hours in that row
    var hoursObj = row.find(".Hours");

    // now you have all three elements that you can make your script operate on
});

Putting that logic into your calculate function, you could do this:

$(function () {
  function calculate() {
    // for each .Time1
    $(".Time1").each(function() {
        var time1Obj = $(this);
        // find the row
        var row = time1Obj.closest("tr");
        // find the .Time2
        var time2Obj = row.find(".Time2");
        // find the .Hours
        var hoursObj = row.find(".Hours");

        // now you have all three elements that you can make your script operate on

        var time1, time2, hours1, hours2, mins1, mins2, hours, mins;
        time1 = time1Obj.val().split(':'),
        time2 = time2Obj.val().split(':'),
        hours1 = parseInt(time1[0], 10),
        hours2 = parseInt(time2[0], 10),
        mins1 = parseInt(time1[1], 10),
        mins2 = parseInt(time2[1], 10),
        hours = hours2 - hours1,
        mins = 0;
        if (hours < 0) hours = 24 + hours;
        if (mins2 >= mins1) {
          mins = mins2 - mins1;
        }
        else {
          mins = (mins2 + 60) - mins1;
          hours--;
        }
        mins = mins / 60; // take percentage in 60
        hours += mins;
        hours = hours.toFixed(2);
        hoursObj.val(hours);
    });

  }
  $(".Time1,.Time2").change(calculate);
  calculate();
});

Autres conseils

here: http://jsfiddle.net/JZ7Ad/17/

$(function () {
$(".Time1").change(function(){
  var time1, time2, hours1, hours2, mins1, mins2, hours, mins;
    time1 = $(this).val().split(':');
    time2 = $(this).parent().next().find('.Time2').val().split(':');
    hours1 = parseInt(time1[0], 10),
    hours2 = parseInt(time2[0], 10),
    mins1 = parseInt(time1[1], 10),
    mins2 = parseInt(time2[1], 10),
    hours = hours2 - hours1,
    mins = 0;
    if (hours < 0) hours = 24 + hours;
    if (mins2 >= mins1) {
        mins = mins2 - mins1;
    } else {
        mins = (mins2 + 60) - mins1;
        hours--;
    }
    mins = mins / 60; // take percentage in 60
    hours += mins;
    hours = hours.toFixed(2);

    $(this).parent().next().next().find(".Hours").val(hours);
});

$(".Time2").change(function(){
  var time1, time2, hours1, hours2, mins1, mins2, hours, mins;
    time1 = $(this).parent().prev().find('.Time1').val().split(':');
    time2 = $(this).val().split(':');
    hours1 = parseInt(time1[0], 10),
    hours2 = parseInt(time2[0], 10),
    mins1 = parseInt(time1[1], 10),
    mins2 = parseInt(time2[1], 10),
    hours = hours2 - hours1,
    mins = 0;
    if (hours < 0) hours = 24 + hours;
    if (mins2 >= mins1) {
        mins = mins2 - mins1;
    } else {
        mins = (mins2 + 60) - mins1;
        hours--;
    }
    mins = mins / 60; // take percentage in 60
    hours += mins;
    hours = hours.toFixed(2);

    $(this).parent().next().find(".Hours").val(hours);
})

});

You should extraxt it for method for a better code. But works

that should work for you:

http://jsfiddle.net/JZ7Ad/22/

$(function () {
        function calculate() {
            $('table tr').each(function (index) {
                var time1, time2, hours1, hours2, mins1, mins2, hours, mins;
                time1 = $(this).find(".Time1").val().split(':'),
                time2 = $(this).find(".Time2").val().split(':'),
                hours1 = parseInt(time1[0], 10),
                hours2 = parseInt(time2[0], 10),
                mins1 = parseInt(time1[1], 10),
                mins2 = parseInt(time2[1], 10),
                hours = hours2 - hours1,
                mins = 0;
                if (hours < 0) hours = 24 + hours;
                if (mins2 >= mins1) {
                    mins = mins2 - mins1;
                } else {
                    mins = (mins2 + 60) - mins1;
                    hours--;
                }
                mins = mins / 60; // take percentage in 60
                hours += mins;
                hours = hours.toFixed(2);
                $(this).find(".Hours").val(hours);

            });
        }

        $(".Time1,.Time2").change(calculate);
        calculate();
    });

The related inputs are in the same tr we can select other elements from the same tr.

(".Time1,.Time2").change(function(){
   var parentRow = $(this).parents('tr');
   var myTime1 = parentRow.find('.Time1');
   var myTime2 = parentRow.find('.Time2');
   var myHours = parentRow.find('.Hours');


});

jQuery: selecting grandparents

How to get the children of the $(this) selector?

Oops, while debugged everybody already answered ))) Here is tested solution: Add a "tcont" class to table elements and ...

$(function () {
    function calculate() {
        var containers = $('.tcont');
        containers.each(function(index, el) {
            var time1, time2, hours1, hours2, mins1, mins2, hours, mins;
            time1 = $(".Time1", el).val().split(':'),
            time2 = $(".Time2", el).val().split(':'),

            hours1 = parseInt(time1[0], 10),
            hours2 = parseInt(time2[0], 10),
            mins1 = parseInt(time1[1], 10),
            mins2 = parseInt(time2[1], 10),
            hours = hours2 - hours1,
            mins = 0;
            if (hours < 0) hours = 24 + hours;
            if (mins2 >= mins1) {
                mins = mins2 - mins1;
            } else {
                mins = (mins2 + 60) - mins1;
                hours--;
            }
            mins = mins / 60; // take percentage in 60
            hours += mins;
            hours = hours.toFixed(2);
            $(".Hours", el).val(hours);
        });
    }
    $(".Time1,.Time2").change(calculate);
    calculate();
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top