Forum Moderators: open
I'm trying to build a getCellIndex function to get the position of a cell in its row.
I know you can easily read out the cellIndex attribute or count the cells in front of the target cell, but I want to take spanning into account. colspan is not that much of an issue, we can just count the cells in front of the target cell by their colspan, but it's the rowspan (of cells above that reaches onto the row of the target cell) that's really being a pain. How do you know whether such a cell that's spanning to the row of our target cell is in front of the target cell or not?!
I've been wrapping my mind around this problem for some time now and I think I finally got to the correct solution.
First I just plainly count the cells in front of the target cell (by their colspan) and remember it as initIndex
Then I check every row above the row of the target cell to see if there is any cell spanning to the row of our target cell. To be sure to only check the columns that can be in front of the target cell I check initIndex + 1 cell in each row. Now on every cell I find to be spanning down onto the row of the target cell I break and start over with an initIndex increased by 1. I mark such cells by adding an attribute to them to be able to recognize them in the next run.
I increase the initIndex because the cell spanning down onto the row of the target cell is 'pushing' the target cell no position to the right. And I restart because we have been checking not enough cell in the rows above up untill now.
This happens again for every cell I find spanning down to the row of the target cell.
Then next to cells spanning all the way down to the row of the target cell I also keep record of cells just spanning down. This to know that we need to check less cell in the rows below. For this I keep an array on which I push an element for every cell spanning down, with the value of the element being the rowspan of the detected cell. After every row I decrease every value in the array and for the next row I count the element in the array whose value is higher than 0. That's the number of cells spanning down onto the row we're currenlty checking and thus can skip or in more technical term: the cells we need to check on every row is initIndex + 1 - number of cells spanning down.
I also take the colspan into account on each row, counting the cells their colspan instead of the cells themselves.
The initIndex when we reach the row of the target cell is the real index of the cell! (first cell in a row is at index 0)
Testing this procedure manually to these example tables below brings up the correct index, so I believe this is the solution.
If anyone can think up something better or can correct me if I'm wrong, please do :)
Paul
[edited by: jatar_k at 5:20 pm (utc) on Oct. 8, 2008]
[edit reason] no urls thanks [/edit]
ok, if you've got this far I'm not going to bore you with arrays and things. I think the method I would use is to build a grid (AoA), then give each cell an ID as you count it.
Each square of the grid would represent a cell 1 row by 1 column. Then you fill in the squares with each cells ID.
So if a cell spans 3 rows, fill in 3 squares in the row. If a cell spans 4 rows, fill in 4 squares in the column.
Then all you have to do is look up X * Y to get the cell that occupies that position.
Anyway, here's how the grid would look for all 3 of your tables. The numbers are cell id's, not array references!
Table 1:
1...2...3...4...5...6...7..
1...8...9...10..5...11..12.
1...8...9...10..5...13..14.
1...8...9...10..5...15..16.
1...8...9...10..5...17..18.
19..8...9...10..20..21..22.
23..24..9...25..26..27..28.
Table 2:
1...2...3...4...5...6...7..
1...2...8...9...10..11..12.
1...2...13..14..15..16..17.
18..2...19..20..21..22..23.
24..25..26..27..28..29..30.
31..32..33..34..35..36..37.
38..39..40..41..42..43..44.
Table 3:
1...2...3...4...5...6...7..
1...8...3...4...9...6...10.
1...11..3...4...12..6...13.
14..11..15..4...16..6...17.
18..11..19..4...16..6...20.
21..11..22..4...23..6...24.
25..26..27..28..29..30..31.
Using this grid you could easily write both your functions.
As for a working code example, not really got time at the moment but maybe in the next few days.
This should give me
Table 2:
1...2...3...4...5...6...7.
1...2...10...11...12..13..14.
1...2...17..18..19..20..21.
22..2...24..25..26..27..28.
29..30..31..32..33..34..35.
36..37..38..39..40..41..42.
43..44..45..46..47..48..49.
the to get the row index of the target cell I walk the concurring row in the grid and read elements until the found index % 7 > the plain cellIndex (the cellIndex attribute or the number of cells in front of the target cell, which would be 1 for the target cell in table 2) AND index > (rowindex-1) x cellindex (which would be 3x7=21)
By the way, what I'm trying to do is to build a table wizard for users to be able to construct a table (or layout).
Although I think this method gives me the same as the cellIndex attribute would
This is NOT actually a method, just a way or organising your data regarding the table.
In your example, you've missed out a few numbers. This is not the correct term for the cell index. The cell index is 19, as in my example. It's the 19th cell. I think you are trying to retrieve the cell position. However there's no reason why you couldn't build the table like that instead.
The cell position could be worked out with
(row *7) +col? If you then wanted to account for your rowspans, just (using the table) see if the cell above has the same id. If it has, return that number instead.
[edited by: Dabrowski at 10:45 am (utc) on Oct. 9, 2008]
I'm trying to build a getCellIndex function to get the position of a cell in its row.So yes, it's the position that I would like to get.
What table should be used for the cell position? I guess you are referring to the grid, but which one? My version or yours? And what do you mean by taking the number of the cell above if it has the same id? (the ids and numbers are the same if I understand correctly). That would get me 2 for the second cell on the fourth row, which is not what I want, it should be 3 (24%7) as the position of the cell is pushed by one position by the rowspan from a cell above.
Table 2:
1...2...3...4...5...6...7..
1...2...8...9...10..11..12.
1...2...13..14..15..16..17.
18..2...19..20..21..22..23.
24..25..26..27..28..29..30.
31..32..33..34..35..36..37.
38..39..40..41..42..43..44.
My numbers represent the cell index. The cell position could be achieved by row/column, so this way gives you more flexibility.
So, to get the id of the cell at position 3 x 4 (19 in this example), you'd just look it up in the grid:
// Remember, grid starts at 0 so coords have been -1'd
var cellId = myTable[2][3]; // 19
If you wanted to exclude the rowspans, you could write a function to tell check each cell and see if it's spanned from the row above:
function findUniqueCell( col, row) {
var cell = 0;
// Check each cell in this row -- includes rowspans
for( var c = 0; c < col; c++) {
// If the ID of cell at in this row is DIFFERENT to the cell in the row above
// The cell above this one cannot be rowspanned to this row, so this cell
// Is unique to this row
if( myTable[row][c] != myTable[row -1][c]) cell++;
}
return cell;
}
I finally got back to this thing and managed to get a working script! I first create the grid/map like I desribed in my post #:3761891 and then use that grid/map to get the cell's position/number. This differs from the way I though to be able to do it and described in that same post. I start with the plain cellIndex from the target cell; then run through the row of the grid/map concurring with the cell's row and increase the index when detecting rowspan or colspan; when (the number found in the map % number of columns in the table) is the same as the index, it's that number what we want... Well my testpages make it understandable :p
Thanks!
Btw, I think my initial idea still works, but when you need to find multiple cell their position/number in the same table, then this script is faster.
Now on with the next functionalities :)
split cells vertically, horizontically
add row before, after; delete row
add column before, after; delete column
cell properties
table properties