How to reset a jQuery variable based on the selected element?
I created an HTML heading that allows the user to select a cell and add its earned points against possible points. Right now I have a function that only allows you to select one td
for each row. When a cell is selected, it adds points to the variable. The problem is that when I change the selection for a row, it just adds a new selection on top of the variable, it doesn't subtract or replace the value.
For example, if I had an 8 point selection selected, but change it to 6, instead of the variable value 6, it will add 6 to 8.
The function I have to add is as follows:
jQuery('#ldrm-rubric-loaded td.choice').click(function () {
// Obtain points earned
var ndx = jQuery(this).index() + 1;
var target = jQuery('#ldrm-rubric-loaded thead tr.points th:nth-child('+ndx+')').html();
if(!isNaN(target) && target.length != 0) {
pointsEarned += parseFloat(target);
}
jQuery('#ldrm-points-earned').html('Points Earned: '+pointsEarned);
alert(pointsEarned);
});
http://jsfiddle.net/f6u2pjgu/1/
Any ideas on how I can change the function to replace the value instead of adding to it?
source to share
I think it will be easier if you use one handler like
var total = 0,
$headers = jQuery('#ldrm-rubric-loaded thead tr.points th');
jQuery('#ldrm-rubric-loaded td.choice').click(function () {
var $this = jQuery(this),
$prev;
if (!$this.hasClass('selected')) {
$prev = $(this).siblings('.selected').removeClass('selected');
if ($prev.length) {
total -= +$headers.eq($prev.index()).html() || 0;
}
total += +$headers.eq($this.index()).html() || 0;
$this.addClass('selected');
jQuery(this).siblings().removeClass('selected');
var trackChanges = jQuery('#ldrm-rubric-loaded').clone().html();
jQuery('#ldrm_assignment_content').val(trackChanges);
jQuery('#ldrm-points-earned').html('Points Earned: ' + total);
alert(total);
} //else don't do anything since it is already selected
});
Demo: Fiddle
If you want to keep the structure of your code
jQuery('#ldrm-rubric-loaded td.choice').click(function () {
var $this = jQuery(this),
$tr = $this.closest('tr'),
prevValue = $tr.data('selected') || 0;
// Obtain points earned
var ndx = $this.index() + 1;
var value = +jQuery('#ldrm-rubric-loaded thead tr.points th:nth-child(' + ndx + ')').html() || 0;
pointsEarned -= prevValue;
pointsEarned += value;
$tr.data('selected', value)
jQuery('#ldrm-points-earned').html('Points Earned: ' + pointsEarned);
alert(pointsEarned);
});
Demo: Fiddle
source to share
This is a simple fix. You have it right now pointsEarned += parseFloat(target);
. Change this to justpointsEarned = parseFloat(target);
JSFiddle: http://jsfiddle.net/voveson/f6u2pjgu/2/
source to share
I think it would be nice to separate the computation from the actual event handling.
To help with this, you can pre-calculate the points per column:
var pointsPerColumn = $('#ldrm-rubric-loaded tr.points th').map(function() {
return +$(this).text();
});
Then write a small function that calculates the scores on the fly; it uses the earlier variable pointsPerColumn
for each selected cell and returns the sum:
function pointsEarned(sel)
{
var total = 0;
$(sel).find('td.choice.selected').each(function() {
total += pointsPerColumn[$(this).index()];
});
return total;
}
Then your click handler becomes pretty simple:
jQuery('#ldrm-rubric-loaded td.choice').click(function () {
alert(pointsEarned('#ldrm-rubric-loaded'));
});
function addHandlers($cubric, $target) {
var pointsPerColumn = $cubric.find('tr.points th').map(function() {
return +$(this).text();
});
function pointsEarned() {
var total = 0;
$cubric.find('td.choice.selected').each(function() {
total += pointsPerColumn[$(this).index()];
});
return total;
}
$cubric
.find('td.choice')
.click(function() {
$(this).addClass('selected').siblings().removeClass('selected');
$target.val($cubric.clone().html());
})
.click(function() {
alert(pointsEarned());
});
}
jQuery(function($) {
addHandlers($('#ldrm-rubric-loaded'), $('#ldrm_assignment_content'));
});
#ldrm-rubric-loaded {
margin-top: 15px;
}
#ldrm-rubric-loaded .ldrm tr.remove {
display: none;
}
#ldrm-rubric-loaded .ldrm tr.points th:first-child {
display: none;
}
#ldrm-rubric-loaded .ldrm tbody tr td:first-child {
display: none;
}
#ldrm-rubric-loaded .choice {
cursor: pointer;
}
#ldrm-rubric-loaded .choice.selected {
background: #d1e0be;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ldrm-rubric-loaded">
<table class="ldrm" cellspacing="0">
<thead>
<tr class="remove">
<th></th>
<th></th>
<th></th>
<th><span class="btn"></span>
</th>
<th><span class="btn"></span>
</th>
<th><span class="btn"></span>
</th>
</tr>
<tr class="points">
<th></th>
<th></th>
<th class="rb-top">8</th>
<th class="rb-top">6</th>
<th class="rb-top">4</th>
<th class="rb-top">2</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td class="rb-left">Category</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
</tr>
<tr>
<td><span class="btn"></span>
</td>
<td class="rb-left">Category</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
</tr>
<tr>
<td><span class="btn"></span>
</td>
<td class="rb-left">Category</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
</tr>
<tr>
<td><span class="btn"></span>
</td>
<td class="rb-left">Category</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
<td class="choice">Enter the details of how to earn this amount of points!</td>
</tr>
</tbody>
</table>
</div>
source to share