History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: APF-933
Type: Improvement Improvement
Status: Open Open
Priority: Trivial Trivial
Assignee: Matt Raible
Reporter: Greg Ederer
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
AppFuse

Individual links in displaytag table cells

Created: 10/Oct/07 11:21 PM   Updated: 03/May/08 11:09 PM
Component/s: Web - General
Affects Version/s: 2.0 Final
Fix Version/s: 2.1


 Description  « Hide
The highlightTableRows function in global.js causes an entire row of a table to link to the href of the first anchor in the first cell in the row if the first cell contains an anchor. So, if the table looks like:

<table>
  <tr>
    <td>My Link</td>
    <td>Something here</td>
    <td>My Other Link</td>
  </tr>
</table>

then the whole row is linked to mylink.html, and clicking on 'My Other Link' goes to mylink.html instead of myOtherLink.html.

I changed this so that a) If there is more than one link in the entire row, it doesn't assign any onclick behavior to the row so each individual link works; b) If there is exactly one link in the row, it uses that link even if it is not in the first column.

Code:

function highlightTableRows(tableId) {
    var previousClass = null;
    var table = document.getElementById(tableId);
    var tbody = table.getElementsByTagName("tbody")[0];
    var rows;
    if (tbody == null) {
        rows = table.getElementsByTagName("tr");
    } else {
        rows = tbody.getElementsByTagName("tr");
    }
    // add event handlers so rows light up and are clickable
    for (i=0; i < rows.length; i++) {
        rows[i].onmouseover = function() { previousClass=this.className;this.className+=' over' };
        rows[i].onmouseout = function() { this.className=previousClass };
        // GE: Added conditional to prevent whole row from becoming a link when more than
        // one link is present in the row. Also, gets the first link in the entire column
        // rather than the first link in the first row.
        if(rows[i].getElementsByTagName("a").length == 1)
        {
          var _row = rows[i];
rows[i].onclick = function() {
var link = _row.getElementsByTagName("a")[0];
if (link.onclick) {
call = link.getAttribute("onclick");
if (call.indexOf("return ") == 0) {
call = call.substring(7);
}
// this will not work for links with onclick handlers that return false
eval(call);
} else {
location.href = link.getAttribute("href");
}
this.style.cursor="wait";
return false;
}
        }
    }
}


 All   Comments   Change History   FishEye      Sort Order:
Greg Ederer - 11/Oct/07 12:48 PM
I noticed that this solution actually didn't work properly with rows containing exactly one link. I traced this to some odd event bubbling behavior, and did some major surgery to fix it. I have tested this code in Safari and Firefox. Please let me know if you encounter problems in other browsers.

I also changed the mouse pointer from an hourglass (???) to a hand.

function highlightTableRows(tableId) {
    var previousClass = null;
    var table = document.getElementById(tableId);
    var tbody = table.getElementsByTagName("tbody")[0];
    var rows;
    if (tbody == null) {
        rows = table.getElementsByTagName("tr");
    } else {
        rows = tbody.getElementsByTagName("tr");
    }
    // add event handlers so rows light up and are clickable
    for (i=0; i < rows.length; i++) {
        rows[i].onmouseover = function() { previousClass=this.className;this.className+=' over' };
        rows[i].onmouseout = function() { this.className=previousClass };
        // GE: Added conditional to prevent whole row from becoming a link when more than
        // one link is present in the row. Also, gets the first link in the entire column
        // rather than the first link in the first row. Also, changed cursor style to
        // from 'wait' (an hourglass) to 'pointer' (a hand).
        if(rows[i].getElementsByTagName("a").length == 1)
        {
                rows[i].onclick = function(evt) {
                    evt = (evt) ? evt : ((window.event) ? window.event : "")
                                            if (evt) {
                                                var elem
                                                if (evt.target) {
                                                    elem = (evt.target.nodeType == 3) ? evt.target.parentNode : evt.target
                                                } else {
                                                    elem = evt.srcElement
                                                }
                                                if (elem) {
                                                    var nodeName = elem.nodeName.toLowerCase();
                                                    var link;
                                                    if(nodeName == 'a')
                                                    {
                                                      link = elem;
                                                    }
                                                    else
                                                    {
                                                      while(nodeName != 'tr')
                                                      {
                                                        elem = elem.parentNode;
                                                        nodeName = elem.nodeName.toLowerCase();
                                                      }
                                                     
                                                      link = elem.getElementsByTagName('a')[0];
                                                    }
                                                   
                                              if (link.onclick) {
                                                  var call = link.getAttribute("onclick");
                                                  if (call.indexOf("return ") == 0) {
                                                      call = call.substring(7);
                                                  }
                                                  // this will not work for links with onclick handlers that return false
                                                  eval(call);
                                              } else {
                                                  location.href = link.getAttribute("href");
                                              }
                                              this.style.cursor="pointer";
                                                }
                                            }
                                           
                    return false;
                }
        }
       
    }
}

J. David Mendoza R. - 06/Dec/07 09:41 AM
I use this solution... what it does is leave the last column without any links so that you can put the links or buttons you want there and they'll work fine, and if you clic on the rest of the row it will do what it does right now, that is take the first column's link and go there.

function highlightMyTableRows(tableId) {
    var previousClass = null;
    var table = document.getElementById(tableId);
    var tbody = table.getElementsByTagName("tbody")[0];
    var rows;
    if (tbody == null) {
        rows = table.getElementsByTagName("tr");
    } else {
        rows = tbody.getElementsByTagName("tr");
    }
    // add event handlers so rows light up and are clickable
    for (var i=0; i < rows.length; i++) {
        rows[i].onmouseover = function() { previousClass=this.className;this.className+=' over' };
        rows[i].onmouseout = function() { this.className=previousClass };
        var cells = rows[i].getElementsByTagName("td");
        for(var j=0; j < cells.length-1; j++) {
            cells[j].onclick = function() {
                var cell = this.parentNode.getElementsByTagName("td")[0];
                var link = cell.getElementsByTagName("a")[0];
                location.href = link.getAttribute("href");
                this.style.cursor="wait";
                return false;
            }
        }
        cells[cells.length-1].onclick = function() {
            var cells = this.parentNode.getElementsByTagName("td");
            var actionLink = cells[cells.length-1].getElementsByTagName("a")[0];
            if (actionLink != null && actionLink.getAttribute("href") != null) {
             location.href = actionLink.getAttribute("href");
            }
            this.style.cursor="wait";
            return false;
        }
    }
}

Matt Raible - 03/May/08 11:09 PM
Moving to future release since neither proposed solution contains workarounds necessary for this script to work with Tapestry and JSF. Sure I could modify them to do so, but I'm lazy. ;-)