我有一张桌子,我想在每一行下方添加一个可隐藏/可展示的面板,以获得更多的控件和信息,而不是合理地放在表格行中。我的第一个想法是为每个原始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 post和this other thing)。
这也很棘手,因为我正在使用tablesorter,它使用tds中的值对表客户端进行排序,因此原始数据必须保持表格格式。 (它可以使用css类“tablesorter-childRow”将行对保持在一起。)我也不相信我可以拥有多个tbodies因为它们没有与行一起排序 - 每个tbody的行都被排序。
我考虑过在之后使用jquery在每个原始tr之后插入一个tr,但是当某些内容发生变化时d3将无法正确更新表(因为数据无法正常连接),以及我使用d3的原因是因为它使得构建大量dom元素变得更容易(对我来说至少)。
所以,质疑时间:我怎么能创建这个面板
答案 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 */
}