views:

672

answers:

1

Hey folks,

I have been working on a scheduling website for the past few weeks. I am showing the schedules as PHP generated html-tables. I use merged cells for showing events. I have come to a problem when trying to delete events using JS. Since those are merged cells, using rowspan, I have to go through the table and re-adding empty cells whenever there is a need when I delete one. My solution is working fine for when my table contains one merged cell among nothing but empty cells, but with a more complex table, it fails. I can't really grasp what's wrong with it, except that it doesn't correctly find the cellIndex anymore. Does anyone have a clue? Here is what I'm talking about:

http://aturpin.mangerinc.com/table.html

(Click on an event to remove it, or attempt to anyhow)

+3  A: 

This sample may help you find your solution. It seems to demonstrate your problem as well as have some sample code to generate a matrix to help you solve it.

EDIT: I liked the puzzle and decided to play with it for a bit, here is a "functioning" example of implementing that sample (although sometimes the table doesn't seem to redraw correctly. This should probably help you get further along the way.

function getTableState(t) {
    var matrix = [];
    var lookup = {};
    var trs = t.getElementsByTagName('TR');
    var c;
    for (var i=0; trs[i]; i++) {
      lookup[i] = [];
     for (var j=0; c = trs[i].cells[j]; j++) {
      var rowIndex = c.parentNode.rowIndex;
      var rowSpan = c.rowSpan || 1;
      var colSpan = c.colSpan || 1;
      var firstAvailCol;

      // initalized the matrix in this row if needed.
      if(typeof(matrix[rowIndex])=="undefined") { matrix[rowIndex] = []; }

      // Find first available column in the first row
      for (var k=0; k<matrix[rowIndex].length+1; k++) {
       if (typeof(matrix[rowIndex][k])=="undefined") {
        firstAvailCol = k;
        break;
       }
      }
      lookup[rowIndex][c.cellIndex] = firstAvailCol;
      for (var k=rowIndex; k<rowIndex+rowSpan; k++) {
       if(typeof(matrix[k])=="undefined") { matrix[k] = []; }
       var matrixrow = matrix[k];
       for (var l=firstAvailCol; l<firstAvailCol+colSpan; l++) {
        matrixrow[l] = {cell: c, rowIndex: rowIndex};
       }
      }
     }
    }

    // lets build a little object that has some useful funcitons for this table state.
    return {
      cellMatrix: matrix,
      lookupTable: lookup,

      // returns the "Real" column number from a passed in cell
      getRealColFromElement: function (cell)
      {
        var row = cell.parentNode.rowIndex;
        var col = cell.cellIndex;
        return this.lookupTable[row][col];       
      },
      // returns the "point" to insert at for a square in the perceived row/column
      getPointForRowAndColumn: function (row,col)
      {
        var matrixRow = this.cellMatrix[row];
        var ret = 0;
        // lets look at the matrix again - this time any row that shouldn't be in this row doesn't count.
        for (var i=0; i<col; i++)
        {
          if (matrixRow[i].rowIndex == row) ret++;
        }
        return ret;
      }
    };
}

function scheduleClick(e)
{
    if (e.target.className != 'event')
     return;

    //Get useful info before deletion
    var numRows = e.target.rowSpan;
    var cellIndex = e.target.cellIndex;
    var rowIndex = e.target.parentNode.rowIndex;
    var table = e.target.parentNode.parentNode;

    var tableState = getTableState(table);

    var colIndex = tableState.getRealColFromElement(e.target);

    //Deletion
    e.target.parentNode.deleteCell(cellIndex);

    //Insert empty cells in each row
    for(var i = 0; i < numRows; i++)
    {
     var row = table.rows[rowIndex + i];
     row.insertCell(tableState.getPointForRowAndColumn(rowIndex+i, colIndex));
    }
}
gnarf
Thanks a lot, this is way better, now I am near the solution!
Xeon06
I just now realized, there are only rendering problems in Firefox. Other browsers are working.
Xeon06
Got it! I feel dumb now. I had no doctype, so I was running in quirks mode in Firefox. Adding a doctype fixed it. Thanks again!
Xeon06