how to add class in table in python using Dominate library - html

I have created Table using Dominate Library but Now I want to change my table class. can someone help me to do that ?
doc1 = dominate.document(title='Dominate your HTML')
with doc1:
with div():
attr(cls='body')
h1('Survey Report : Survey Report')
oc = dominate.document(title="whatever")
with doc1:
tags.style(".calendar_table{width:880px;}")
tags.style("body{font-family:Helvetica}")
tags.style("h1{font-size:x-large}")
tags.style("h2{font-size:large}")
tags.style("table{border-collapse:collapse}")
tags.style("th{font-size:small;border:1px solid gray;padding:4px;background-color:#DDD}")
tags.style("td{font-size:small;text-align:center;border:1px solid gray;padding:4px}")
with tags.table():
with tags.thead():
tags.th("Nominee", style = "color:#ffffff;background-color:#6A75F2")
tags.th("counts", style = "color:#ffffff;background-color:#6A75F2")
with tags.tbody():
for i in range(0,len(nom)):
with tags.tr(): #Row 1
tags.td(nom[i], style = "font-size:small;text-align:center;padding:4px")
if int(count_nom[i]) > 1:
tags.td(count_nom[i], style = "font-size:small;text-align:center;padding:4px;background-color:#F4D8D2")
else:
tags.td(count_nom[i], style = "font-size:small;text-align:center;padding:4px")
with tags.tr(): #Row 1
tags.td(b("Grand Total"), style = "font-size:small;text-align:center;padding:4px")
tags.td(b(sum(count_nom)), style = "font-size:small;text-align:center;padding:4px")
with open('/root/survey/'+'survey'+'.html', 'w') as f:
f.write(doc1.render())
with this I am able to create Table in HTML
<div class="body">
<h1>Survey Report</h1>
</div>
<style>.calendar_table{width:880px;}</style>
<style>body{font-family:Helvetica}</style>
<style>h1{font-size:x-large}</style>
<style>h2{font-size:large}</style>
<style>table{border-collapse:collapse}</style>
<style>th{font-size:small;border:1px solid gray;padding:4px;background-color:#DDD}</style>
<style>td{font-size:small;text-align:center;border:1px solid gray;padding:4px}</style>
<table>
<thead>
<th style="color:#ffffff;background-color:#6A75F2">Nominee</th>
<th style="color:#ffffff;background-color:#6A75F2">counts</th>
</thead>
<tbody>
<tr>
<td style="font-size:small;text-align:center;padding:4px">Deepesh Ahuja</td>
<td style="font-size:small;text-align:center;padding:4px">1</td>
</tr>
<tr>
<td style="font-size:small;text-align:center;padding:4px">Sabyasachi Mallick</td>
<td style="font-size:small;text-align:center;padding:4px">1</td>
</tr>
<tr>
<td style="font-size:small;text-align:center;padding:4px">Raju Singh</td>
<td style="font-size:small;text-align:center;padding:4px">1</td>
</tr>
<tr>
<td style="font-size:small;text-align:center;padding:4px">Abarna Ravi</td>
<td style="font-size:small;text-align:center;padding:4px;background-color:#F4D8D2">2</td>
</tr>
<tr>
<td style="font-size:small;text-align:center;padding:4px">
<b>Grand Total</b>
</td>
<td style="font-size:small;text-align:center;padding:4px">
<b>5</b>
</td>
</tr>
</tbody>
</table><br><br><br>
Now How I will set table class in python code like
<table class='calender_tabe'>
Can someone help me to set class of table and other tag using python dominate library?

Using the example syntax from github's documentation
from dominate.tags import *
testTable = table(border = 1)
print testTable
which will return:
<table border="1"></table>
with the print statement. However since you can't use the word "class" to refer to the html attribute (class being a python-reserved word) you have to go about it indirectly:
testTable.set_attribute('class','my_class_name')
Adding the above to the original instance of testTable will result in:
<table border="1" class="my_class_name"></table>

Related

how to display data for a specific month in a table

is it possible to display the data on which column month of the table?
below is the sample dashboard to achieve
and this is my DB
currently this is my dashboard. I want to align the data base on the period in the DB.
what should be my tboby look like to achieve the desired dashboard
this is my index html
<div class="w3-container w3-padding-64 w3-theme-l5">
<div class="w3-padding-16"><span class="w3-xlarge w3-border-purple w3-bottombar">COUNT PER BUSINESS UNIT</span></div>
<div>
<table id="businessUnit-tbl" class="table table-bordered display nowrap">
<thead>
<tr style="/*color:white;*/ align-content:center">
<td>MONTH</td>
</tr>
<tr #*style="color:white"*#>
<td>Business Unit</td>
<td id="jan">January</td>
<td id="feb">February</td>
<td id="mar">March</td>
<td id="apr">April</td>
<td id="may">May</td>
<td id="june">June</td>
<td id="july">July</td>
<td id="aug">August</td>
<td id="sept">September</td>
<td id="oct">October</td>
<td id="nov">November</td>
<td id="dec">December</td>
<td id="total">Total</td>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
According to my understanding of the topic, I suggest leaving tbody blank and trying to fill it with javascript
// append column to the HTML table
function appendColumn() {
var tbl = document.getElementById('my-table'), // table reference
i;
// open loop for each row and append cell
for (i = 0; i < tbl.rows.length; i++) {
createCell(tbl.rows[i].insertCell(tbl.rows[i].cells.length), i, 'col');
}
}

How to convert HTML table to angular material table (mat-table)?

I have new to Angular Material and trying to convert basic Angular table to Angular material table using
mat-table
I am not sure where to start from. How can I convert below table to mat-table?
Here is my .html file which contains table
<div>
<h2>Count Data</h2>
<ng-container>
<table style = 'width: 50%;'>
<tr>
<td>Select 1 {{newFinal.color}}</td>
<td>{{newFinal.zind}}</td>
</tr>
<tr>
<td colspan = '3' class = 'bold'> Wasi Final: {{newFinal.Queue}} ({{newFinal.selection}}) </td>
</tr>
<tr>
<td colspan = '3' class = 'bold'> Collar Final: ({{newFinal.Titir}}) </td>
</tr>
</table>
</ng-container>
</div>
https://material.angular.io/components/table/overview
the doc is amazing and full of example

How to populate an array with text from html webscraping in ruby

I have used the nokogiri ruby gem to webscrape an html file for only the text under the tableData class. The html code is setup like so:
<div class="table-wrap">
<table class="table">
<tbody>
<tr>
<td class="tableData"> Jane Doe</td>
<td class="tableData"> 01/01/2017</td>
<td class="tableData">01/09/2017 </td>
<td class="tableData">Vacation</td>
</tr>
<tr>
<td class="tableData">John Doe</td>
<td class="tableData"> 01/01/2017</td>
<td class="tableData">01/09/2017 </td>
<td class="tableData">Vacation</td>
</tr>
</tbody>
</table>
</div>
and the code I used to webscrape looks like this:
vt = page.css("td[class='tableData']").text
puts vt
Which gives this output:
Jane Doe 01/01/201701/09/2017 VacationJohn Doe 01/01/201701/09/2017 Vacation
I want to populate an array within an array with only the 4 text values pertaining to each person. Which should look like this:
[[Jane Doe, 01/01/2017, 01/09/2017, Vacation], [John Doe, 01/01/2017, 01/09/2017, Vacation]]
I am new to coding and I'm not sure how to create a for loop to iterate over either the html code itself or the vt variable to produce an array of arrays. I know there are some push statements involved following the for loop but its the actual structure of the for loop that I am having trouble putting together. If you could provide some explanation in your answer for how the for loop works in this situation it would be much appreciated.
This is the basic structure you need. map is needed :
html=%q(<div class="table-wrap">
<table class="table">
<tbody>
<tr>
<td class="tableData"> Jane Doe</td>
<td class="tableData"> 01/01/2017</td>
<td class="tableData">01/09/2017 </td>
<td class="tableData">Vacation</td>
</tr>
<tr>
<td class="tableData">John Doe</td>
<td class="tableData"> 01/01/2017</td>
<td class="tableData">01/09/2017 </td>
<td class="tableData">Vacation</td>
</tr>
</tbody>
</table>
</div>)
require 'nokogiri'
doc = Nokogiri::XML(html)
array = doc.xpath('//tr').map do |tr|
tr.xpath('td').map{ |td| td.text }
end
p array
# [[" Jane Doe", " 01/01/2017", "01/09/2017 ", "Vacation"], ["John Doe", " 01/01/2017", "01/09/2017 ", "Vacation"]]
Try parsing the snippet as XML, finding all "tr" elements via XPath, and collecting their "td//text()" children:
require 'nokogiri'
doc = Nokogiri::XML(get_html_snippet)
data = doc.xpath('//tr').map do |tr|
tr.xpath('td').map { |td| td.text.strip }
end
data # => [["Jane Doe", "01/01/2017", "01/09/2017", "Vacation"], ["John Doe", "01/01/2017", "01/09/2017", "Vacation"]]

HTML parsing with XPath: flattened hierarchical data

My target HTML is a flattened table of elements with 2 levels of data defined by class attribute:
<tr>
<td class="type">Type 1</td>
</tr>
<tr>
<td class="name">name1</td>
<td class="year">1970</td>
<td class="rank">1</td>
</tr>
<tr>
<td class="name">name2</td>
<td class="year">1982</td>
<td class="rank">3</td>
</tr>
Goal is parse out list of name, year, rank elements, which I accomplish with these xpath expressions:
//td[#class = 'name']/text()
//td[#class = 'year']/text()
//td[#class = 'rank']/text()
Each element is under immediately preceding
<tr>
<td class="type">Type 1</td>
</tr>
I would like to have "Type 1" assigned to each element parsed above. It could be separate list of the same length. Of course, my target HTML contains many such elements within the same 2-level hierarchy: type - element (name, year, rank).
The following rather clumsy xpath concatenates the closest, previous #type td to the name td matched above.
concat(//td[#class = 'name']/preceding::td[#class='type'][1]/text(), '-',
//td[#class = 'name']/text())
This probably makes more sense when shown in the following xsl
<xsl:for-each select="//td[#class='name']">
<Name>
<xsl:value-of select="concat(preceding::td[#class='type'][1]/text(),
'-', ./text())" />
</Name>
</xsl:for-each>
Applied to the following xml
<xml>
<tr>
<td class="type">Type 1</td>
</tr>
<tr>
<td class="name">name1</td>
<td class="year">1970</td>
<td class="rank">1</td>
</tr>
<tr>
<td class="name">name2</td>
<td class="year">1982</td>
<td class="rank">3</td>
</tr>
<tr>
<td class="type">Type 2</td>
</tr>
<tr>
<td class="name">name3</td>
<td class="year">1971</td>
<td class="rank">2</td>
</tr>
<tr>
<td class="name">name4</td>
<td class="year">1983</td>
<td class="rank">4</td>
</tr>
</xml>
With the result
<Name>Type 1-name1</Name>
<Name>Type 1-name2</Name>
<Name>Type 2-name3</Name>
<Name>Type 2-name4</Name>
Solution 1
First, find the td elements of interest. For example, the name tds with the following pseudo-code:
name_tds = doc.evalXPath("//td[#class = 'name']")
Then you can find the corresponding type td using a name td as context node like this:
type_td = name_td.evalXPath("../preceding-sibling::tr[td[#class = 'type']][1]/td")
Solution 2
Simply iterate all the tds and remember the last type you found. Pseudo-code:
foreach (td in doc.evalXPath("//td") {
class = td.getAttribute("class");
if (class == "type") {
type = td.textContent();
}
else if (class == "name") {
name = td.textContent();
println("type: " + type + ", name: " + name);
}
// Same for year and rank.
}

HTML Table issues

I have a main table and then insert sub tables each td. Like below The problem is lets say I have:
<table id = "main>
<tr>
<th id = "header1">blah</td>
<th id = "header2">blah</td>
<th id = "header3">blah</td>
</tr>
<tr><td>
<table id = "sub1">
<tr><td headers='header1'>1</td></tr>
</table>
</td>
<td>
<table id = "sub2">
<tr><td headers='header2'>2</td></tr>
</table>
</td>
<td>
<table id = "sub3">
<tr><td headers='header3'>3</td></tr>
</table>
</td>
</tr>
</table>
now if sub1 has only 4 rows in it but sub 2 and 3 each have 100 rows the table keeps putting sub1 table in the middle of the rest of the table. How would i stop it from doing that?
Try this:
<td valign="top">
You have to specify, where to align the content of td
Look in to valign
<td valign='top'>
Updated source
<table id = "main>
<tr>
<th id = "header1">blah</td>
<th id = "header2">blah</td>
<th id = "header3">blah</td>
</tr>
<tr><td valign='top'>
<table id = "sub1">
<tr><td headers='header1'>1</td></tr>
</table>
</td>
<td>
<table id = "sub2">
<tr><td headers='header2'>2</td></tr>
</table>
</td>
<td>
<table id = "sub3">
<tr><td headers='header3'>3</td></tr>
</table>
</td>
</tr>
</table>
If you are increasing/decreasing the no. of rows/cols in your tables, you may need to adust the same through rowspan and colspan properties. Also displaying text at the top of any cell needs valign="top" property
Make the second table row (after the header row) opening tag <tr style="vertical-align:top">. That will work and there is no need for rowspan or colspan.