GregH
GregH

Reputation: 5459

JQuery issue using closest to find text inputs

I currently am outputting two tables in each iteration of a foreach loop (c# razor view although that isn't too relevant here). I wrap these two tables in a div with class = jq-roundContainer and each input in both tables has class jq-hitOrMiss. I am trying to sum up the number of X's entered into the text inputs as follows but variable sum is 0 (when I know it shouldnt be) and inputs.length is 0 also. html and simple jquery function below

html:

<div class="jq-roundContainer">
    <table class="table table-bordered">
        <thead>
            <tr class="active">
                <th colspan="2" class="text-center">1</th>
                <th colspan="2" class="text-center">2</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td style="display:none">
                    @Html.Hidden("EventId", Request.Params["eventId"]);
                    @Html.Hidden("UserId", Request.Params["userId"]);
                    <input type="hidden" name="scoreCards[@i].UserProfile" value="@round.UserProfile" />
                </td>
                <td>
                    <input class="jq-hitOrMiss" onchange="SumHits();" name="scoreCards[@i].Hit1StationOneShotOne" pattern="[xXoO]" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit1StationOneShotOne)" />
                </td>                                

                @{i++;}
            </tr>
        </tbody>
    </table>

    <table class="table table-bordered">
        <thead>
            <tr class="active">
                <th colspan="2" class="text-center">14</th>
                <th class="text-center">TOTAL</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>
                    <input class="jq-hitOrMiss" onchange="SumHits();" name="scoreCards[@i].Hit27StationThreeShotSeven" pattern="[xXoO]" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit27StationThreeShotSeven)" />
                </td>
                <td class="text-center total jq-total">@round.Score</td>
                @{i++;}
            </tr>
        </tbody>
    </table>
</div>

and jquery function:

 function SumHits() {

        var sum = 0;
        var inputs = $(this).closest('.jq-roundContainer').find('.jq-hitOrMiss');
        $.each(inputs, function (index, value) {
            var value = $(value).val();
            if (value == 'X' || value == 'x') {
                sum++;
            }
        });
        var totalInput = $(this).closest('.jq-roundContainer').find('.jq-total');
        totalInput.text(sum);
    }

Upvotes: 1

Views: 95

Answers (3)

Fran&#231;ois Dupont
Fran&#231;ois Dupont

Reputation: 426

This works for me, remove the on change on your html it is difficult to maintain

$('div.jq-roundContainer input.jq-hitOrMiss').change(function () {
    var $parent = $(this).parents('.jq-roundContainer');
    var sum = 0;
    var inputs = $parent.find('.jq-hitOrMiss');
    inputs.each(function () {
        var value = $(this).val();
        if (value == 'X' || value == 'x') {
            sum++;
        }
    });
    var totalInput = $parent.find('.jq-total');
    totalInput.text(sum);
});

or if you want to keep your function

$('div.jq-roundContainer input.jq-hitOrMiss').change(SumHits);

function SumHits(){
    var $parent = $(this).parents('.jq-roundContainer');
    var sum = 0;
    var inputs = $parent.find('.jq-hitOrMiss');
    inputs.each(function () {
        var value = $(this).val();
        if (value == 'X' || value == 'x') {
            sum++;
        }
    });
    var totalInput = $parent.find('.jq-total');
    totalInput.text(sum);
}

Upvotes: 0

Satpal
Satpal

Reputation: 133403

The problem arise to the this element which refers to window not the element which triggered the event. Thus you are getting the result

As you are using jQuery bind event using it like and get rid of ulgy inline-click handler.

$('.jq-hitOrMiss').on('change', SumHits)

Upvotes: 1

Rajaprabhu Aravindasamy
Rajaprabhu Aravindasamy

Reputation: 67207

Inside normal function this will points to window. So when you are using an inline handler, you have to pass the this explicitly, receive it inside the function and use it.

function SumHits(_this) {
  var inputs = $(_this).closest('.jq-roun.....

And in html,

<input class="jq-hitOrMiss" onchange="SumHits(this);".....

Upvotes: 3

Related Questions