4

I created an HTML rubric that allows a user to select a cell and have it add up the earned points versus the points possible. Right now, I have a function that only allows one td per row to be selected. When a cell is selected, it adds the points to a variable. The issue is, when I change the selection for the row, it just adds the new selection on top of the variable, it doesn't subtract and replace the value.

For example, if I had an 8 point selection made, but change it to 6, instead of the variable value being 6, it adds the 6 to the 8.

The function I have to add up the points 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 could alter the function to replace the value instead of adding on to it?

3 Answers 3

1

I think it will be easier if you use a single 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 retain your code structure

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

Sign up to request clarification or add additional context in comments.

Comments

1

It's a simple fix. Right now you have pointsEarned += parseFloat(target);. Change that to simply pointsEarned = parseFloat(target);

JSFiddle: http://jsfiddle.net/voveson/f6u2pjgu/2/

2 Comments

Right, that displays the correct value for the specific row, but now I need it to add up all the rows correctly!
So in the fiddle example, if all 4 rows have the 8 pt selection made, the total should be 32 points.
1

I think it would be a good idea to separate the calculation from the actual event handling.

To help with this, you could calculate the points per column beforehand:

var pointsPerColumn = $('#ldrm-rubric-loaded tr.points th').map(function() {
    return +$(this).text();
});

Then, write a small function that calculates the points earned on-the-fly; it uses the earlier pointsPerColumn variable 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 quite 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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.