Reputation: 5459
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
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
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
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