wannabeprogrammer
wannabeprogrammer

Reputation: 37

jquery adding and subtracting values while clicking on radio buttons

I am trying to add and subtract values when the user clicks on the radio button. All the radio buttons are dynamically created from database values.

There maybe multiple categories inside one heading but user will be able to choose only one. I am stuck in subtracting the value when the user selects another option.

If you are kind enough ;), you can check this pasting in your editor (oh yeah.. I am a total newbie when it comes to programming.)

Any solution or different approach will be much much much appreciated.

Thanks...

Code

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="jquery.js"></script>
<style type="text/css">
.active {
 background: #ccc;
}
.program {
 border:1px solid blue;
}
.program td, .program th {
 padding:10px;
 border:1px solid grey;
}
.grandTotal {
 width:200px;
 height:35px;
 font-size:18px;
 font-weight:bold;
 text-align:center;
 line-height:35px;
 background-color:#999;
 margin-top:35px;
}
</style>
</head>

<body>
<div class="program-box">
  <span>You can select or deselect the radio button</span>
  <h2>Heading1</h2>
  <table class="program" cellpadding="0" cellspacing="1">
    <tr>
      <th class="w-5"></th>
      <th class="w-35">Name</th>
      <th class="w-30">Location</th>
      <th class="w-10">#days</th>
      <th class="w-10">Price</th>
    </tr>
    <tr>
      <td><input name=cat1 value=3 id=3 type='radio' class='v'/></td>
      <td>categeory 1</td>
      <td>location1</td>
      <td>5</td>
      <td class="price1">100</td>
    </tr>
  </table>
  <h2>Heading2</h2>
  <table class="program" cellpadding="0" cellspacing="1">
    <tr>
      <th class="w-5"></th>
      <th class="w-35">Name</th>
      <th class="w-30">Location</th>
      <th class="w-10">#days</th>
      <th class="w-10">Price</th>
    </tr>
    <tr>
      <td><input name=cat2 value=1 id=1 type='radio' class='v'/></td>
      <td>category2</td>
      <td>location2</td>
      <td>4</td>
      <td class="price1">200</td>
    </tr>
    <tr>
      <td><input name=cat2 value=2 id=2 type='radio' class='v'/></td>
      <td>category2</td>
      <td>location3</td>
      <td>8</td>
      <td class="price1">150</td>
    </tr>
  </table>

  <div class="price">
    <div class="grandTotal">1800</div>
  </div>
</div>
</div>
<script type="text/javascript">

$(document).ready(function () {

  $("input[type='radio']").mousedown(function(e) {
                if ($(this).attr("checked") == true) {

                   setTimeout("$('input[id=" + $(this).attr('id') + "]').removeAttr('checked');", 200);
       }
                else {
                    return true
                }
            });


});

 $(".v").click(function() {


  $(this).toggleClass("active");


  $(this).closest('.program').find('.v').not(this).removeClass('active');


  var actPrice = 1800; // default 1800
  actPrice = parseInt(actPrice); // convert this to integer


  var isSet = $(this).hasClass("active");


  var grandTotal=$(".grandTotal").text();

  if (grandTotal=="")
  {
   //alert('no total till now');
   var grandTotal=0;
  } else {
   grandTotal=parseInt(grandTotal);
   //alert(grandTotal);
  }


  var div=parseInt($(this).closest('tr').find(".price1").text());

  if(isSet)
  {
   if(grandTotal>0){
    var total = grandTotal+div;
   } else {
    var total = actPrice+div;
   }
   //alert(total);
   $(".grandTotal").html(total);
  } else 
  {
   var div2 = parseInt($(this).closest('tr').find(".price1").text());
   var newTotal = grandTotal-div2;
   $(".grandTotal").html(newTotal);

  }


 });


</script>
</div>
</body>
</html>

Upvotes: 2

Views: 2606

Answers (1)

Andrew Whitaker
Andrew Whitaker

Reputation: 126072

You were pretty close! I modified your code slightly and cleaned some things up, but you were almost there:

$(document).ready(function() {
    $("input[type='radio']").mousedown(function(e) {
        var self = this;
        /* Use 'checked' property instead of wrapping in jQuery object */
        if (self.checked) {
            /* Use setTimeout with a function instead of JS string */
            setTimeout(function() {
                self.checked = false;
            }, 200);
        }
        else {
            return true;
        }
    });
    /* Assign click handler inside document.ready: */
    $(".v").click(function() {
        /* Cache selectors that are used over and over: */
        var $this = $(this);
        var $grandTotalContainer = $(".grandTotal");

        /* Call parseInt with radix parameter: */
        var grandTotal = parseInt($grandTotalContainer.text(), 10);
        var price =
            parseInt($this.closest('tr').find(".price1").text(), 10);
        var siblingAmounts = 0;
        var name = $this.attr("name");

        /* Find prices of items in the same "group": */   
        $("input[name='" + name + "'].active")
            .not($this)
            .each(function() {
                siblingAmounts +=
                    parseInt($(this).closest("tr").find(".price1").text(), 10);
            });

        $this.toggleClass("active");
        $("input[name='" + name + "']").not($this).removeClass("active");

        if ($this.hasClass("active")) {
            grandTotal -= siblingAmounts;
            grandTotal += price;
        }
        else {
            grandTotal -= price;
        }
        $grandTotalContainer.html(grandTotal);
    });
});

Notes:

  • Calling setInterval with a JavaScript string instead of a function is considered bad practice because it calls eval() which can cause problems.
  • Directly accessing DOM element properties where it works is preferrable to wrapping this in a jQuery object and using jQuery methods to access those properties.
  • Calling parseInt with the radix parameter is highly recommended because otherwise JavaScript tries to assume the radix.
  • I removed the code that worked with a default grand total and just parsed out the value inside the grand total div.
  • I select siblings of the clicked input using the attribute equals selector
  • Make sure and cache jQuery results that you use over and over. There's overhead to executing jQuery functions that you can avoid if you cache the results of queries.
  • You shouldn't use integers as ids for HTML elements, as they're invalid under the HTML 4.01 specification.

Here's a working example: http://jsfiddle.net/andrewwhitaker/8Atf8/1/

Hope that helps!

Upvotes: 1

Related Questions