views:

49

answers:

2

I am trying to implement a grid with radio button selector. When the radio button is clicked, the row is set to a different color. Also, when a radio is selected in the grid, it needs to see if there was a previously selected radio button so that it could change the color set.

<script type="text/javascript">
var lastSelectedId = '';
function rowSelected(rdoButton) {

  if (rdoButton.id != lastSelectedId) {
    rdoButton.parentNode.parentNode.origClassName = 
      rdoButton.parentNode.parentNode.className;
    rdoButton.parentNode.parentNode.className = 'rowSelected';

    if (lastSelectedId != '') {
      var lastRadioButton = document.getElementById(lastSelectedId);
      lastRadioButton.parentNode.parentNode.className = 
        lastRadioButton.parentNode.parentNode.origClassName;
    }
  }
  lastSelectedId = rdoButton.id;
}
</script>

<table>
  <tr class="rowOdd">
    <td>
      <input type="radio" name="rdoGrpName" id="rdoId1" onclick="rowSelected(this);" />
    </td>
    <td>Blah</td>
  </tr>
  <tr class="rowEven">
    <td>
      <input type="radio" name="rdoGrpName" id="rdoId1" onclick="rowSelected(this);" />
    </td>
    <td>Blah</td>
  </tr>
</table>

I was wondering how I could remove the dependency on a global variable lastSelectedId to be able to track if there is a selected item? My initial idea is to save it to a dummy variable in the body object. like use this.

function rowSelected(rdoButton) {
  var mainBody = document.getElementByNames('body');
  if (rdoButton.id != mainBody[0].lastSelectedId) {
    // ....
  }
}

I was wondering if this is the right strategy for this. Also to make the code really unobstrusive, I need to add the event handler for the onload to initialize the global variable.

+1  A: 

Couldn't you just check the class name of the td tag and see if it's the selectRow class and then change it if it is?

Avitus
Yes, that would be good. I would need to loop thru all the radio button all the time to see if any of them were previously selected. I was wondering if there is a more elegant way to know what was the previously selected radio button when clicking on a radio button.
Nassign
A: 

Perfectly would it be, when you assigned event-handlers inside the script not by using onclick attributes. Then you could store everything in a separate scope.

Now, you can also store the variable in a separete scope, but still the rowSelected/selectRow function has to stay in the global scope.

BTW. instead of saving the ID you can store the reference to the node itself.

var selectRow = (function(){
   var lastSelected, lastClass;

   return function(rdoButton){
      var p;
      if (rdoButton != lastSelected) {
         if (lastSelected) {
           p = lastSelected.parentNode.parentNode;
           p.className = lastClass;
         }
         p = rdoButton.parentNode.parentNode;
         lastClass = p.className;
         p.className = 'rowSelected';
      }
      lastSelected = rdoButton;
   }
})();
Rafael
Wait, what will be the scope of the lastSelected, lastClass? Are they already in Global scope? If not, how can they save the last variable with a function scope variable?
Nassign
Both variables are inside their "private" scope to which only the inner function (see line return function(rdoButton)) has access. The inner function is then exposed (with return statement) to the global scope in selectRow variable.
Rafael
The code above is a simple example of JavaScript memoizer pattern (http://unscriptable.com/index.php/2009/05/01/a-better-javascript-memoizer/)
Rafael