How do I set the default attributes for my cells when there is no initial data - datatables

I have a scenario where I am filling my data table based on data received over a websocket. So I guess the best approach would be to create an empty table in html and then add the data via the API.
So say I want my final table to appear something like:
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name">Tiger Nixon</td>
<td class="position">System Architect</td>
<td class="office">Edinburgh</td>
<td class="age">61</td>
<td class="start-date">2011/04/25</td>
<td class="salary">$320,800</td>
</tr>
<tr>
<td class="name">Garrett Winters</td>
<td class="position">Accountant</td>
<td class="office">Tokyo</td>
<td class="age">63</td>
<td class="start-date">2011/07/25</td>
<td class="salary">$170,750</td>
</tr>
</tbody>
</table>
When dynamically loading my table I would only define the first part:
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
</table>
And then call row.add() in my javascript as the data is received.
But how do I set the default classes for my column cells this way?

When you use row.add(), the return value is the newly created (but not yet displayed) row.
You can use this value to iterate over the cells in the row, where class names can be added. Finally you can draw the row, so it is displayed.
The following shows the basic approach, where we have a pre-defined array of the class names you want to handle:
$(document).ready(function() {
var classNames = [ 'name', 'position' ];
var table = $('#example').DataTable();
var row = table.row.add( ['Quinn Flynn', 'Accountant'] );
var i = 0;
row.cells().every( function () {
var node = this.node();
$( node ).addClass( classNames[i++] );
} );
row.draw();
});
That final section of code from row creation to the row draw would be placed in a function, in your case.
This produces an HTML body as follows:
<tbody>
<tr role="row" class="odd">
<td class="name sorting_1">Quinn Flynn</td>
<td class="position">Accountant</td>
</tr>
</tbody>

Related

How custom element can have multiple <tr> components

I want create a one <table> where multiple custom elements can have multiple <tr> components.
I tried using containerless, but element get rendered outside of <table>.
<table>
<thead>
<tr>
<th>Position</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<order-line repeat.for="line of lines" line.to-view="line" containerless></order-line>
</tbody>
</table>
And custom element looks like
<template>
<tr>
<td>${line.position}</td>
<td>${line.name}</td>
</tr>
<tr if.to-view="detailsVisible">
<td colspan="2">${line.complicatedDescription}</td>
</tr>
</template>
How I can get a table row with details as another <tr> element within one aurelia CustomElement?
This is a limitation of the html spec. A <table> element cannot contain elements other than <tbody>, <tr>, etc.
You can use as-element to overcome this limitation:
<tr as-element="order-line" repeat.for="line of lines" line.to-view="line" containerless></tr>
This tells the template compiler that this <tr> is in fact an order-line custom element and to process it as such. At the same time, it "fools" the browser into thinking that this is just an ordinary <tr>
<table> can contain multiple <tbody> elements, this will allow to wrap multiple <tr> elements inside custom element with <tbody>.
/* custom element */
<template>
<tbody>
<tr>
<td>${line.position}</td>
<td>${line.name}</td>
</tr>
<tr if.to-view="detailsVisible">
<td colspan="2">${line.complicatedDescription}</td>
</tr>
</tbody>
</template>
Use as custom element inside
<table>
<thead>
<tr>
<th>Position</th>
<th>Name</th>
</tr>
</thead>
<order-line repeat.for="line of lines" line.to-view="line"></order-line>
</table>

rowSpan hides rows

<table>
<tr> <td rowspan="2">1</td> <td>2</td> </tr>
<tr> <td rowspan="2">3</td> </tr>
<tr> <td>4</td> </tr>
</table>
seemingly only displays two rows:
The reason for hiding the second row [1 3] is, that the cells with text 1 and 3 are reduced in height. Is there a way to ensure, that the second row is visible in the display (not only in DOM)?
The problem gets clearer, if you look at the same table with an additional column:
<table>
<tr> <td rowspan="2">1</td> <td>2</td> <td>0</td> </tr>
<tr> <td rowspan="2">3</td> <td>0</td> </tr>
<tr> <td>4</td> <td>0</td> </tr>
</table>
which is displayed like:
You can add a height property to the row:
<table border=1>
<tr>
<td rowspan="2">1</td>
<td>2</td>
</tr>
<tr style="height: 1.5em">
<td rowspan="2">3</td>
</tr>
<tr>
<td>4</td>
</tr>
</table>
One suboptimal option could be to add an empty column:
<table>
<tr> <td rowspan="2">1</td> <td>2</td> <td class="void"></td> </tr>
<tr> <td rowspan="2">3</td> <td class="void"></td> </tr>
<tr> <td>4</td> <td class="void"></td> </tr>
</table>
CSS:
table,td {border:1px solid}
.void {height:1em;padding:0;border:0}
However, the spacing between columns leads to unnecessary space for the added column:
As this problem could be solved with padding-left for TD and a cellspacing of 0 for the table, this solution would not be general enough, so I'm still waiting for a good idea.

Simple table with colspan giving errors with datatables

I have this simple html table
<table id="mytable">
<thead>
<tr>
<th>Name</th>
<th colspan="2">Actions</th>
</tr>
<tr>
<th>Delete</th>
<th>Update</th>
</tr>
</thead>
<tbody>
<tr>
<td>MyName</td>
<td onclick="delete()">X</td>
<td onclick="update()">U</td>
</tr>
</tbody>
</table>
<script>
$(document).ready(function(){
$('#mytable').DataTable();
});
</script>
If i open this on the browser i get
"Cannot read property 'mData' of undefined".
I don't undestand where is the problem.. I am following the official example: https://datatables.net/examples/basic_init/complex_header.html
Thank you all!
your html have unmatched number of columns, notice the first row of your header has colspan while the second row doesn't.
what you can do is to provide a rowspan.
<thead>
<tr>
<th rowspan="2">Name</th>
<th colspan="2">Actions</th>
</tr>
<tr>
<th>Delete</th>
<th>Update</th>
</tr>
</thead>
here's a link to the datatables example of complex headers. https://datatables.net/examples/basic_init/complex_header.html

vb.net: Get data from Xelement <table></table>

I have loaded a Xelement from my SharePoint site.
Dim elTable2 As XElement = <table border="1" id="table2" style="font-size:1em;border-collapse:collapse;display:inline;width:100%">
<tbody>
<tr class="ms-rteTableHeaderRow-default" style="text-align:center">
<th class="ms-rteTableHeaderFirstCol-default">​</th>
<th class="ms-rteTableHeaderOddCol-default">LAN IP​</th>
<th class="ms-rteTableHeaderEvenCol-default">Username​</th>
<th class="ms-rteTableHeaderOddCol-default">Password​</th>
<th class="ms-rteTableHeaderEvenCol-default">Port​</th>
<th class="ms-rteTableHeaderOddCol-default">OS​</th>
<th class="ms-rteTableHeaderEvenCol-default">Extra Info​</th>
</tr>
<tr class="ms-rteTableOddRow-default" style="text-align:center">
<th class="ms-rteTableFirstCol-default">Netasq</th>
<td class="ms-rteTableOddCol-default"></td>
<td class="ms-rteTableEvenCol-default"></td>
<td class="ms-rteTableOddCol-default">​</td>
<td class="ms-rteTableEvenCol-default">​</td>
<td class="ms-rteTableOddCol-default">​</td>
<td class="ms-rteTableEvenCol-default">​</td>
</tr>
</tbody>
</table>
The table will have an unknown number of rows. Can I loop trough all the rows and check what data is in the first column?
You could leverage Html Agility Pack for that purpose. It is a .NET code library that allows to parse HTML content and supports plain XPATH or XSLT.
Example
Dim table As XElement = <table border="1" id="table2" style="font-size:1em;border-collapse:collapse;display:inline;width:100%">
<tbody>
<tr class="ms-rteTableHeaderRow-default" style="text-align:center">
<th class="ms-rteTableHeaderFirstCol-default">​Val</th>
<th class="ms-rteTableHeaderOddCol-default">LAN IP​</th>
<th class="ms-rteTableHeaderEvenCol-default">Username​</th>
<th class="ms-rteTableHeaderOddCol-default">Password​</th>
<th class="ms-rteTableHeaderEvenCol-default">Port​</th>
<th class="ms-rteTableHeaderOddCol-default">OS​</th>
<th class="ms-rteTableHeaderEvenCol-default">Extra Info​</th>
</tr>
<tr class="ms-rteTableOddRow-default" style="text-align:center">
<td class="ms-rteTableFirstCol-default">Netasq</td>
<td class="ms-rteTableOddCol-default"></td>
<td class="ms-rteTableEvenCol-default"></td>
<td class="ms-rteTableOddCol-default">​</td>
<td class="ms-rteTableEvenCol-default">​</td>
<td class="ms-rteTableOddCol-default">​</td>
<td class="ms-rteTableEvenCol-default">​</td>
</tr>
</tbody>
</table>
Dim html = New HtmlDocument()
html.LoadHtml(table.ToString())
For Each row In html.DocumentNode.SelectNodes("//tr[position()>1]") 'XPath expression to select table rows and skip table header
Dim cell As HtmlNode = row.SelectSingleNode("td[1]") 'Get cell for first column
Console.WriteLine(cell.InnerText)
Next

Nested tables with related parent content

Having a semantics issue. I have a basic table with a standard header and footer. Each row contains an order, beneath each row I need to display another table, that will contain a break down of costs relating to that order. Additionally, these inner tables will be displayed with a jQuery accordion to hide and show when required (but I'm just concentrating on the HTML for now)
How can I semantically approach this in HTML?
<table>
<thead>
<th>Package number</th>
<th>Date placed</th>
<th>Placed by</th>
<th>Total cost</th>
</thead>
<tr>
<td>1</td>
<td>Weds</td>
<td>Jonno</td>
<td>£15</td>
</tr>
<tr>
<td colspan="4">
<table>
<thead>
<th>Part number</th>
<th>Description</th>
<th>Qty shipped</th>
<th>Weight</th>
</thead>
<tbody>
<td>18293</td>
<td>Blah blah blah</td>
<td>72</td>
<td>20Kg</td>
</tbody>
</table>
</td>
</tr>
<tr>
<td>2</td>
<td>Thurs</td>
<td>Jonno</td>
<td>£1</td>
</tr>
<tr>
<td>3</td>
<td>Fri</td>
<td>Jonno</td>
<td>£7</td>
</tr>
</table>
Here's a fiddle: http://jsfiddle.net/yuW7f/ - The problem here is that the row containing the inner table, is totally unrelated to the order row
If you are looking for a parent element you can use to group related rows, you can use <tbody> elements. A table can have multiple <tbody> elements:
<table>
<thead>
<tr>
<th>Package number</th>
<th>Date placed</th>
<th>Placed by</th>
<th>Total cost</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Weds</td>
<td>Jonno</td>
<td>£15</td>
</tr>
<tr>
<td colspan="4">
<table>
<thead>
<tr>
<th>Part number</th>
<th>Description</th>
<th>Qty shipped</th>
<th>Weight</th>
</tr>
</thead>
<tbody>
<tr>
<td>18293</td>
<td>Blah blah blah</td>
<td>72</td>
<td>20Kg</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
<tr>
<td>2</td>
<td>Thurs</td>
<td>Jonno</td>
<td>£1</td>
</tr>
<tr>
<td>3</td>
<td>Fri</td>
<td>Jonno</td>
<td>£7</td>
</tr>
</table>
Whether or not that makes your code more semantically correct is debatable. You could also give your rows classes to indicate whether the row is a summary row or a detail row, or attributes to indicate relationships to other rows. Semantically, it seems fine as it is to me.
By the way, you are missing some <tr> elements. A <tbody>, <thead>, or <tfoot> element does not replace a <tr> element.