Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>Working solution - <a href="http://codepen.io/jmarroyave/pen/eLkst" rel="nofollow noreferrer">http://codepen.io/jmarroyave/pen/eLkst</a></h2> <p>This is basically the same solution that i presented before, i just changed how to get the column index to remove the restriction of the jquery.position, and did some refactor to the code.</p> <pre><code>function layoutInitialize(tableId){ var layout = String(); var maxCols, maxRows, pos, i, rowspan, idx, xy; maxCols = $(tableId + ' tr').first().children().length; maxRows = $(tableId + ' tr').length; // Initialize the layout matrix for(i = 0; i &lt; (maxCols * maxRows); i++){ layout += '?'; } // Initialize cell data $(tableId + ' td').each(function() { $(this).addClass($(this).parent().attr('color_class')); rowspan = 1; if($(this).attr('rowspan')){ rowspan = $(this).attr("rowspan"); $(this).data("rowspan", rowspan); } // Look for the next position available idx = layout.indexOf('?'); pos = {x:idx % maxCols, y:Math.floor(idx / maxCols)}; // store the column index in the cell for future reposition $(this).data('column', pos.x); for(i = 0; i &lt; rowspan; i++){ // Mark this position as not available xy = (maxCols * pos.y) + pos.x layout = layout.substr(0, xy + (i * maxCols)) + 'X' + layout.substr(xy + (i * maxCols) + 1); } }); } </code></pre> <hr> <h2>Solution: with jquery.position() - <a href="http://codepen.io/jmarroyave/pen/rftdy" rel="nofollow noreferrer">http://codepen.io/jmarroyave/pen/rftdy</a></h2> <p>This is an alternative solution, it assumes that the first row contains all the information about the number of the table columns and the position of each on. </p> <p>This aproach <em>has the restriction that the inizialitation code must be call when the table is visible</em>, because it depends on the visible position of the columns.</p> <p>If this is not an issue, hope it works for you</p> <p><strong>Initialization</strong></p> <pre><code> // Initialize cell data $('td').each(function() { $(this).addClass($(this).parent().attr('color_class')); $(this).data('posx', $(this).position().left); if($(this).attr('rowspan')){ $(this).data("rowspan", $(this).attr("rowspan")); } }); </code></pre> <p><strong>UPDATE</strong> According to this <a href="https://stackoverflow.com/questions/5974323/jquery-get-the-offset-of-hidden-element">post</a> ensuring the visibility of the table can be manage with </p> <pre><code> $('table').show(); // Initialize cell data $('td').each(function() { $(this).addClass($(this).parent().attr('color_class')); $(this).data('posx', $(this).position().left); if($(this).attr('rowspan')){ $(this).data("rowspan", $(this).attr("rowspan")); } }); $('table').hide(); </code></pre> <p>As Ian said, the main issue to solve in this problem is to calculate the position of the cells when merging the hidden with the visible rows.</p> <p>I tried to figure it out how the browser implements that funcionality and how to work with that. Then looking the DOM i searched for something like columnVisiblePosition and i found the position attributes and took that way</p> <pre><code> function getColumnVisiblePostion($firstRow, $cell){ var tdsFirstRow = $firstRow.children(); for(var i = 0; i &lt; tdsFirstRow.length; i++){ if($(tdsFirstRow[i]).data('posx') == $cell.data('posx')){ return i; } } } </code></pre> <p>The js code</p> <pre><code>$(document).ready(function () { add_delete_buttons(); $(window).on("tr_gone", function (e, tr) { add_come_back_button(tr); }); // Initialize cell data $('td').each(function() { $(this).addClass($(this).parent().attr('color_class')); $(this).data('posx', $(this).position().left); if($(this).attr('rowspan')){ $(this).data("rowspan", $(this).attr("rowspan")); } }); }); function calculate_max_rowspans() { // Remove all temporary cells $(".tmp").remove(); // Get all rows var trs = $('tr'), tds, tdsTarget, $tr, $trTarget, $td, $trFirst, cellPos, cellTargetPos, i; // Get the first row, this is the layout reference $trFirst = $('tr').first(); // Iterate through all rows for(var rowIdx = 0; rowIdx &lt; trs.length; rowIdx++){ $tr = $(trs[rowIdx]); $trTarget = $(trs[rowIdx+1]); tds = $tr.children(); // For each cell in row for(cellIdx = 0; cellIdx &lt; tds.length; cellIdx++){ $td = $(tds[cellIdx]); // Find which one has a rowspan if($td.data('rowspan')){ var rowspan = Number($td.data('rowspan')); // Evaluate how the rowspan should be display in the current state // verify if the cell with rowspan has some hidden rows for(i = rowIdx; i &lt; (rowIdx + Number($td.data('rowspan'))); i++){ if(!$(trs[i]).is(':visible')){ rowspan--; } } $td.attr('rowspan', rowspan); // if the cell doesn't have rows hidden within, evaluate the next cell if(rowspan == $td.data('rowspan')) continue; // If this row is hidden copy the values to the next row if(!$tr.is(':visible') &amp;&amp; rowspan &gt; 0) { $clone = $td.clone(); // right now, the script doesn't care about copying data, // but here is the place to implement it $clone.data('rowspan', $td.data('rowspan') - 1); $clone.data('posx', $td.data('posx')); $clone.attr('rowspan', rowspan); $clone.addClass('tmp'); // Insert the temp node in the correct position // Get the current cell position cellPos = getColumnVisiblePostion($trFirst, $td); // if is the last just append it if(cellPos == $trFirst.children().length - 1){ $trTarget.append($clone); } // Otherwise, insert it before its closer sibling else { tdsTarget = $trTarget.children(); for(i = 0; i &lt; tdsTarget.length; i++){ cellTargetPos = getColumnVisiblePostion($trFirst, $(tdsTarget[i])); if(cellPos &lt; cellTargetPos){ $(tdsTarget[i]).before($clone); break; } } } } } } // remove tmp nodes from the previous row if(rowIdx &gt; 0){ $tr = $(trs[rowIdx-1]); if(!$tr.is(':visible')){ $tr.children(".tmp").remove(); } } } } // this function calculates the position of a column // based on the visible position function getColumnVisiblePostion($firstRow, $cell){ var tdsFirstRow = $firstRow.children(); for(var i = 0; i &lt; tdsFirstRow.length; i++){ if($(tdsFirstRow[i]).data('posx') == $cell.data('posx')){ return i; } } } function add_delete_buttons() { var $all_rows = $("tr"); $all_rows.each(function () { // TR to remove var $tr = $(this); var delete_btn = $("&lt;button&gt;").text("x"); delete_btn.on("click", function () { $tr.hide(); calculate_max_rowspans(); $(window).trigger("tr_gone", $tr); }); var delete_cell = $("&lt;td&gt;"); delete_cell.append(delete_btn); $(this).append(delete_cell); }); } function add_come_back_button(tr) { var $tr = $(tr); var come_back_btn = $("&lt;button&gt;").text("come back " + $tr.attr("color_class")); come_back_btn.css({"background": $(tr).css("background")}); come_back_btn.on("click", function () { $tr.show(); come_back_btn.remove(); calculate_max_rowspans(); }); $("table").before(come_back_btn); } </code></pre> <p>if you have any questions or comments let me know.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload