|
Ох эти таблицы
Доброго времени суток, форумчане. Встал вопрос о том, как удалить колонку в таблице, притом с colspan ами и rowspan ами. Подате хотя бы идею как это сделать.
Надеюсь на вашу помощь. Прошу проверять вот на этой табличке: <table border="1"> <tr> <td rowspan="3">1111</td> <td colspan="2">22222</td> <td colspan="2">33333</td> </tr> <tr> <td>44444</td> <td colspan="2" rowspan="2">55555</td> <td>66666</td> </tr> <tr> <td>77777</td> <td>88888</td> </tr> <tr> <td colspan="5">99999</td> </tr> </table> |
Интересная задачка. :)
На оптимальность решения не претендую, безупречность не гарантирую. Но всё же, вот что у меня получилось... <script type="text/javascript"> // table: элемент DOM Table, THead, TBody или TFoot // col: позиция колонки function deleteTableCol (table, col) { var rows = table.rows, cells, cell, prevCell; var cx, cy, cw, ch, coff; var map = [], mx, my, mw = 0, mh = 0; for (cy=0; cy<rows.length; cy++) { cells = rows[cy].cells; for (cx=0, coff=0; cx<cells.length; cx++, coff+=cw) { cell = cells[cx]; cw = cell.colSpan; ch = cell.rowSpan; if (cw == 0 || ch == 0) { return false; // динамическую растяжку ячеек по <colgroup> (при colspan=0) // и по <thead> / <tbody> / <tfoot> (при rowspan=0) // сложно обработать; поэтому, чтобы не напортачить, выходим } while (mh < cy+ch) { map[mh++] = []; } while (map[cy][coff] !== undefined) { coff++; } for (my=cy; my<cy+ch; my++) { for (mx=coff; mx<coff+cw; mx++) { if (map[my][mx] !== undefined) { return false; // при подсчете размеров и позиций у нас получилось, // что ячейки якобы "накладываются" друг на друга; // такую ситуацию тоже сложно обработать, выходим } map[my][mx] = cell; } } if (coff+cw > mw) { mw = coff+cw; } } } if (col >= mw) { return true; // ячеек в указанной позиции нет, // поэтому ничего делать не надо, выходим } for (my=0; my<mh; my++) { cell = map[my][col]; if (cell !== prevCell && cell !== undefined) { cw = cell.colSpan; if (cw > 1) { cell.colSpan = cw-1; } else { rows[my].removeChild(cell); } prevCell = cell; } } return true; } onload = function () { var table = document.getElementById("table1"); var tableCols = 5; var i, button; for (i=0; i<tableCols; i++) { button = document.createElement("input"); button.type = "button"; button.value = i; button.id = "delete" + i; button.onclick = (function (i) { return function () { deleteTableCol(table, i); document.body.removeChild(document.getElementById("delete" + (--tableCols))); }})(i); document.body.appendChild(button); } } </script> <table id="table1" border="1"> <tr> <td rowspan="3">11111</td> <td colspan="2">22222</td> <td colspan="2">33333</td> </tr> <tr> <td>44444</td> <td colspan="2" rowspan="2">55555</td> <td>66666</td> </tr> <tr> <td>77777</td> <td>88888</td> </tr> <tr> <td colspan="5">99999</td> </tr> </table><br> Некоторые соображения: 1. Условно-пустые строки (все <tr> , в которых не осталось ни одного <td> ) - не удаляются, а остаются как есть, чтобы не нарушать структуру таблицы с учетом ячеек, растянутых по вертикали.2. Полностью пустые строки (те, с которыми не пересекается ни одна вертикально растянутая ячейка) - тоже пока не удаляются. Но это можно допилить. 3. Все colspan'ы в таблице должны быть указаны арифметически корректно, то есть так, чтобы, например, не пытаться втиснуть двойную ячейку туда, где есть место только для одинарной: <table> <tr> <td>1111</td> <td rowspan="2">2222</td> </tr> <tr> *!* <td colspan="2">3333</td> */!* </tr> </table>С такой таблицей ничего не произойдет и функция просто вернет false .4. Поведение ячеек с colspan="0" и rowspan="0" обрабатывать слишком муторно, поэтому, наткнувшись на таковые, функция опять-таки ничего не сделает и вернет false .5. Относительно <table> строки извлекаются сразу изо всех имеющихся секций (<thead> , <tbody> и <tfoot> ), то есть будут обработаны ВСЕ <tr> насквозь, как будто они имеют одного общего родителя. Поэтому, если секции указаны явно, то, на всякий случай, функцию лучше вызывать для каждой из них по отдельности.Только прошу сперва тщательно всё потестировать. :) |
Цитата:
Произвольную ? (Или только первую) С произвольной - вряд ли универсально - посколь для каждого случая нужен алгоритм - что делать с ячейками с соlspan более этой колонки |
Я бы предложил добить таблицу недостающими ячейками c display: none, а потом решать какие ячейки будете удалять, где-то тут есть тема про нахождение соседних ячеек в таблице
http://javascript.ru/forum/events/29...i-rowspan.html |
Дзен-трансгуманист,
благодарю. Это везде пашет, то есть на любых таблицах? Deff, как раз то универсал нужен. Эту таблицу дал якобы со всеми случаями жизни. bes, не вариант. Пока буду разбирать код первого поста. Очень хорош... |
Цитата:
- я сталкивался с данной задачей: - седни бухгалтера говорят - алгоритм удаления такой - завтра иначе - Итоговый Вариант: - все ячейки в строках,( вплоть для идентичных повторяющих друг друга строк) - Бух задаёт явно явно кликая по ним в исходнике, и составляя граф удаления - в строках с идентичной структурой - алгоритм задается единожды |
А что если просканировать всю таблицу и записать в массив colspan ы, если rowspan>1?? и записать еще в следующие ячейки до rowspan значения? Тогда вероятно получится получить реальные значения ячеек, где длина их в строке меньше максимальной в данной таблице...
|
Apollo_440,
Да структуировать и восстановить пол-дела - но при удалении колонки - не ячейки - встают вопросы что делать с нижестоящей ячейкой у которой colspan более чем 1 она она по центру (к примеру) под удаляемой колонкой и забита текстом без переноса(цифры) - Переносить цифры ? |
Поэтому кажый раз придумывать реализацию под новые требования легче, когда все ячейки на руках. ;)
|
Deff,
colspan-1. Вроде как бы еще действует. Получили индекста удаляемых ячеек - а затем при удалении обновляем colspan на единицу меньше. Думаю работать будет. Конечно массив шаблона не самое лучшее решение, так как придется сканировать всю таблицу (размеры таблицы играют большую роль). Самое важное сейчас для меня - получить реальный индекс в строке. |
Часовой пояс GMT +3, время: 14:42. |
|