【问题标题】:Info panel below TRsTR 下方的信息面板
【发布时间】:2014-01-30 18:56:01
【问题描述】:

我有一个表格,我想在每行下方添加一个可隐藏/可显示的面板,以获得比表格行合理容纳的更多控件和信息。我的第一个想法是为每个原始 tr 设置一个兄弟 tr,并在其中放置一个带有适当 colspan 的 td:

<tbody>
  <tr>
    <td>...</td>
    ...
  <tr>
  <tr class="tablesorter-childRow">
    <td colspan="4">...</td>
  </tr>
  ...
</tbody>

每个原始行都会有一个按钮来隐藏()或显示()对应的 tr,而子行中的 td 将有所有不需要正常看到的额外控件。

这很棘手,因为我使用 d3 来构建表格,而 d3 不喜欢每个数据有多个元素(请参阅 this stack postthis other thing)。

这也很棘手,因为我使用的是tablesorter,它使用 tds 中的值对表客户端进行排序,因此原始数据必须保持表格式。 (它可以使用 css 类“tablesorter-childRow”将成对的行保持在一起。)我也不相信我可以有多个 tbodies,因为它们没有与行一起排序——每个 tbody 的行都是排序的。

我想过之后使用 jquery 在每个原始 tr 之后插入一个 tr,但是当某些事情发生变化时 d3 不会正确更新表(因为数据不会正确连接),以及我使用 d3 的原因是因为它使构建大量 dom 元素变得更容易(至少对我而言)。

那么,提问时间:我还能如何创建这个面板

  1. 随着原始表格行移动
  2. 不影响排序
  3. 可以隐藏还是显示?

【问题讨论】:

    标签: javascript jquery html d3.js


    【解决方案1】:

    如果您希望两个兄弟元素共享相同的数据,d3 中最简单的方法是将它们分组到父元素下。您为父元素分配数据,然后当您创建它的两个子元素(不分配数据)时,它们都继承父元素的数据。

    在 SVG 中,通常的父元素是 &lt;g&gt;。出于您的目的,自然父元素将是&lt;tbody&gt;,可用于对表行进行分组。 但是,您必须修改您正在使用的表格排序代码,以便对单个 &lt;tbody&gt; 元素而不是单个行进行排序。

    唯一的其他选择是动态设置信息行的内容,并在每次要显示时将其插入正确的位置,类似于有多少工具提示示例的工作方式:它是相同的工具提示,只是四处移动和与新数据。如果您使用 d3 将事件处理程序附加到表行上,它会将单击行的数据对象传递给事件处理函数,因此您可以使用该数据填充信息内容而无需创建数据-加入。要在点击的&lt;tr&gt; 元素之后插入信息行,可以使用d3's insert() 函数,但格式不理想;最好使用plain Javascript 或 JQuery。在运行排序之前,您还必须删除信息行。

    tableRows.on("click", showInfo);
    /* remember to give your rows a tabIndex, so that keyboard users can 
       trigger the click action */
    
    /* Create the persistent info box */
    var infoRow = d3.select( document.createElement("tr") )
                //create a new <tr>, unattached to the document
                    .attr("class", "infoBox";//set class to allow unique formatting
    
    infoRow.append("td") //add a <td> within the <tr>
           .attr("colspan", colNames.length); //set to fill all columns
    
    
    /* Show the info row for a clicked element */
    function showInfo(d,i) {
    
        /* Hide info box if currently shown */
        infoRow.style("display", "none");
    
        /* Set content to match clicked row */
        infoRow.select("td") //select the <td> element
               .html(/* create html from the d object
                        you don't need a function(d), just
                        concatenate the string. */)
    
        /* Insert the row in the correct place.
           This will automatically remove it from any current location */
        this.parentNode.insertBefore(infoRow, this.nextSibling);
           //"this" is the tableRow object that received the click event
    
        infoRow.style("display", null); 
           //revert to default display setting (i.e. table-row)
    }
    
    function sort(/*parameters*/) {
         infoRow.remove(); 
         //remove the infoRow element from the document, 
         //so it only exists as a Javascript object again
    
         /* Run your sort code */
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-31
      • 2016-11-18
      • 1970-01-01
      • 1970-01-01
      • 2023-02-17
      • 2012-04-29
      • 1970-01-01
      相关资源
      最近更新 更多