TRs下面的信息面板

时间:2014-01-30 18:56:01

标签: javascript jquery html d3.js

我有一张桌子,我想在每一行下方添加一个可隐藏/可展示的面板,以获得更多的控件和信息,而不是合理地放在表格行中。我的第一个想法是为每个原始tr设置一个sibling tr,并在内部添加一个适当的colspan:

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

每个原始行都有一个隐藏()或show()相应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. 可以隐藏还是显示?

1 个答案:

答案 0 :(得分:0)

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

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

唯一的另一个选择是动态设置信息行的内容,并在每次要显示时将其插入正确的位置,类似于工具提示示例的工作量:它是相同的工具提示,只是移动和有了新数据。如果您使用d3在表行上附加事件处理程序,它会将单击行的数据对象传递给事件处理函数,这样您就可以使用该数据填充信息内容而无需创建数据 - 加入。要在单击的<tr>元素后插入信息行,您可以使用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 */
}