I have a comparison table that is comparing two things on several properties. The way I have the table designed right now, the first column lists the properties the thing is being compared on, and the second and third columns list the values of the properties of the two things being compared. However, this leaves an empty cell in the top-left corner of the table. I'm wondering, what is the proper way to code this empty cell? I've read that it's bad practice to insert empty cells in tables.
Related
Evidently, HTMLTableRow.prototype.cells property allows one to get an array of cells that a table row element contains as its children. But for tables which contain cells that span multiple rows, retrieving cells that can be said to "naturally" apply to that row, becomes a non-trivial operation, especially for tables of arbitrary layout (meaning one where you can't assume some known row span for all of its cells).
Am I right in that I would have to design an algorithm myself for retrieving cells that would naturally belong in a row, as described? To explain what I mean by "naturally belong", consider first the following table with two cells that span two rows each:
<table>
<tbody>
<tr><td>A</td><td>B</td><td>C</td><td rowspan="2">D</td></tr>
<tr><td>E</td><td rowspan="2">F</td><td>G</td></tr>
<tr><td>H</td><td>I</td><td>J</td></tr>
</tbody>
</table>
I would like to know, for example, which cell values naturally -- as rendered -- belong to the second row. For the above table as table, the expression table.rows[1].cells evaluates to an array of 3, not 4 table cell elements. It seems to merely mirror the amount of children for the row element, no more no less (table.rows[1].children is also a collection of the same 3 elements). That does not express that the cell denoted "D" also applies to the second row, which beget my question -- how to compute the collection of cells that belong to a given row?
Now, I am not saying that what the cells property lets me retrieve is wrong in any way, mind you, just that I need a different view on which cells belong to a row.
For example, for the second row, such "view" would be the ordered collection of cells denoted "E", "F", "G" and "D", since "D" spans to the end of the second row and thus can be said to naturally apply to that row as well.
Is there such an API that would allow me to compute such views, or in the worst case some third party library?
I'm creating a report that has 5 columns. However, one column can have no data and in that case I need to hide it. This works using the 'Hidden' property of column but when the column is hidden, I want to make the first column wider. Is there any way to do this in expression?
The only solution I found is to have multiple same tablixes with different column count and then show or hide each tablix appropriately if the specific column has no data. (by checking 'Max' value in column).
Unfortunately, it's not possible to enter an expression to the column width property but if you simply need to change the width of one other column when the first is hidden, I've come up with a workaround that works fairly well.
The idea is a little easier and requires less data to load than your current solution. Basically, you'll create an identical width column that is simply empty -- but set the borders to appear as if it is simply part of another column. So you'll simple reverse the expression used to hide the column with no data in the hidden property. To achieve this, depending on where you choose to add the extra space column, you'll have to adjust the borders of the adjoining cells where there is no right border on the cell to the left and a left border on the cell to the right. Depending on your layout, you would only need a top and bottom border on the extra space column cells.
I did something similar with a report that has 3 pages and 11 columns -- but 8 of the columns changed from page to page. I had to hide one column, show another, and used expressions in column headers and detail rows to simply change the data in each column based on a field that returns the type of the data.
I am trying to create a header row for a matrix in my SSRS report. Currently my matrix is configured as the following:
If I right+click to add a new row, it will insert a row above but I cannot merge the entire row of cells to form a single row, the grouping columns stay separate:
My work-around has been to add a text box above the matrix, but will not keep the the rows together in a page break:
Is it possible to add the header row? And if so, what would be a good way to accomplish this task?
I had the same issue! I wish they would let you merge across the row header; or add a new region of matrix called "title" .
My tablix also had dynamic columns, so I needed the width of the box on the top to expand and collapse with the rest of the table.
There are two ways you can handle it (that I know of)
1. Create a "parent" list object with two rows and insert the table in the second row
2. Put all the columns to the right of the row header
To solve my problem I tried both. First, I added the list with one column and two rows and I copied the entire table into the second row. The first row of the outer list is now centered and spans the entire table. It was messy because I had dynamic columns with a toggle for visibility. The outer list had to have columns that lined up with the visibility set to the same toggle. It was a messy work around because of that.
I decided to try the second method above and insert new columns on the other side of the row header.
The challenge is that row header group labels will repeat for each row... in your example RoleID would repeat down each detail row. I created an expression to only show when it was the first row of the group.
=iif(RowNumber("roleid_group") = 1,
max(Fields!roleID.Value,"roleid_group"),
"")
I used an expression to only show the border when it was the last row in the group:
=iif(RowNumber("roleid_group") = countrows("roleid_group"),"Solid","None")
This gives the illusion of a grouped row. Don't delete the row header columns (column 1 and 2) until you get it working because its hard to add them back.
Careful: This method though doesn't work well if the text of the row title needs to wrap. (The first row of the group will be wider --row height is set to can grow.)
If there is another way I would love to know. These are both somewhat tricky but get the job done.
I've used alternate table row shading before (using the ::nth-child selector), but I noticed it can't get the job done when you have irregular table structure. I've come across one specific case for which I'd like to come up with a solution.
In the picture below, you can see that the rows are styled with ::nth-child(even) to give every other row a background color:
The problem here is that in some cases, the first column cell spans two rows, causing the rest of the cells in that "row" (which is really two rows) to appear disjointed or misaligned. The cells in the rows spanned by "Cole" should have the same background color as the first column's cell, because the following columns are all related to the first one. Is this achievable using strictly CSS?
I would just change the structure of the table, but the people entering this content are using a CMS with a built-in text editor, and they have no control over the format. I'd have to manually change every table on their site, which would be a huge undertaking (and it wouldn't account for future tables).
I want to be able to extract all cells under a certain column with xpath.
There are/may be occasionally colspans.
Is there any way to do this, by which I suppose I'm asking, is there any inherent relationship between a table header and the cells below it? Or is there no inherent relationship and despite being fairly easy to do visually, its outside the ability of pure xpath?
Scenario:
We have an HTML table with a dozen columns and several rows. The columns have headers, and some of the column headers span more than one column.
One of those column headers (we don't know which one) has the textual content "Pick Me".
I want to be able to select all the cells under that cell in the table.
You can do it in XPath 1. I assume that only one column has the desired header and the rowspan attribute does not occur.
tbody/tr/td[
count(preceding-sibling::td[not(#colspan)])
+ sum(preceding-sibling::td/#colspan)
= count(../../tr[1]/th[.='Pick Me']/preceding-sibling::th[not(#colspan)])
+ sum(../../tr[1]/th[.='Pick Me']/preceding-sibling::th/#colspan)]
The above expression yields all cells starting in the leftmost column of the Pick Me header. By duplicating a lot of the logic, you can get the cells starting in any column spanned by Pick Me or the cells sharing a column with Pick Me, perhaps the broadest interpretation of your question:
tbody/tr/td[
count(preceding-sibling::td[not(#colspan)])
+ sum(preceding-sibling::td/#colspan)
< count(../../tr[1]/th[.='Pick Me']/preceding-sibling::th[not(#colspan)])
+ sum(../../tr[1]/th[.='Pick Me']/preceding-sibling::th/#colspan)
+ count(../../tr[1]/th[.='Pick Me'][not(#colspan)])
+ sum(../../tr[1]/th[.='Pick Me']/#colspan)
and count(preceding-sibling::td[not(#colspan)])
+ sum(preceding-sibling::td/#colspan)
+ not(#colspan)
+ sum(#colspan)
> count(../../tr[1]/th[.='Pick Me']/preceding-sibling::th[not(#colspan)])
+ sum(../../tr[1]/th[.='Pick Me']/preceding-sibling::th/#colspan)]
The strategy here is to compute the "position" of both the left and right side of each cell and the Pick Me header, where "position" means the number of columns to something's left. The cell overlaps the header's column(s) if, and only if, the cell's left is left of the header's right and the cell's right is right of the header's left. That is the meaning of the numeric comparisons.
No, there is no association in xpath between column headers in a table and the column they fall within.
The only way to find cells that fall beneath a specific column header is, using some other code, to count the columns (account for colspans) until the desired table header is found, and then count that many columns in each row to extract the cells.
In case you need to grab specific column for example the first:
//tr/td[1]