unable to display table and cell borders while printing - html

I have a dynamically generated table in an asp.net View
I have used the same code to print another table and it prints..lines and all..
but when i try to print this table i get only the text and no html
here is my code..(i dont have the reputation to post screenshots)
#model AECS1.Controllers.DailyReportModel
#{
ViewBag.Title = "AECS : Daily Report";
}
<html>
<head>
<style >
table.gridtable {
font-family: verdana,arial,sans-serif;
font-size: 11px;
color: #333333;
border-width: 1px;
border-color: #666666;
border-collapse: collapse;
width: 400px;
}
table.gridtable th {
padding: 8px;
border: 1px solid #666666 ;
background-color: #23819C;
color:white;
}
table.gridtable td {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
}
.aclass {
background-color: #23819C;
color: white;
font-size: 25px;
padding: 2px 2px 2px 2px;
height: 5%;
display: block;
text-decoration: none;
margin-left:10%;
width:10%;
}
</style>
<style media="print">
td,th
{color:black}
</style>
<script>
function printer() {
var divToPrint = document.getElementById("printable");
newWin = window.open("");
newWin.document.write("<h1>Weekly Report</h2>")
newWin.document.write(divToPrint.outerHTML);
newWin.print();
newWin.close();
}
</script>
</head>
<body>
<div style="text-align:center">
<h2>Daily Report</h2>
<button id="print" onclick="printer()" class="aclass">print</button>
<h3>#ViewBag.date</h3>
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.Report_Date, new { #class = "input1", #id = "datepicker", #readonly = "readonly" })
<br />
<input type="submit" value="Get Report" />
#Html.ValidationSummary()
}
#{
int i = 0;
}
<div id="printable">
<table align="center" >
#foreach (var item in ViewBag.list){
i++;
if (#i % 3 == 1)
{
#:<tr>
}
<td>
<table class="gridtable">
<tr>
<th>
UNIT NAME
</th>
<th>
DOCTOR NAME
</th>
<th>
STATUS
</th>
</tr>
#foreach (var item1 in item)
{
<tr>
<td>
#item1.UnitName
</td>
<td>
#item1.dr_name
</td>
<td>
#item1.info
</td>
</tr>
}
</table>
</td>
if (#i % 3 == 0)
{
#:</tr>
}
}
</table>
</div>
</div>
</body>
</html>

I was suffered from same problem, i got issue why it was not print the table border?
It because of CSS : "border-collapse: collapse;"
So what i do is use #media and write CSS as below for screen and print.
In your case do as :
#media screen {
table.gridtable
{
font-family: verdana,arial,sans-serif;
font-size: 11px;
color: #333333;
border-width: 1px;
border-color: #666666;
border-collapse: collapse;
width: 400px;
}
}
and for print :
#media print{
table.gridtable {
font-family: verdana,arial,sans-serif;
font-size: 11px;
color: #333333;
border-width: 1px;
border-color: #666666;
width: 400px;
}
}
in print remove CSS line border-collapse: collapse;
Because this is reason for disappearing border in printing.
Hope this work for you.

Store the css in an external stylesheet, say style.css
Link to the printing window.
newWin.document.write('<link rel="stylesheet" href="images/style.css" type="text/css" />');
OR
write the CSS within the DIV (< div id="printable" >) which going to print.
In your code the css part is outside . It should be within the div

The table is being copied to a new window, and your CSS is not being retained.
Pass some relevant CSS across to the new window in your document.write() method.
Like This
$("#printtbl").on('click', function() {
var printContents = document.getElementById('print-table').innerHTML;
var originalContents = document.body.innerHTML;
// Your Css
var htmlToPrint = '' +
'<style type="text/css">' +
'table {' +
'border-spacing: 0;' +
'border-collapse: collapse;' +
'}'+
'table tr {' +
'border-top: 1px solid gray !important;' +
'}' +
'</style>';
htmlToPrint += printContents;
var printWindow = window.open('', 'PRINT');
printWindow.document.write(htmlToPrint);
printWindow.print();
printWindow.close();
}

Related

Editable popup textarea for table td

I have a textarea in the td cell of each row in column 3, to hold description specific to each row.
When the user clicks on the td, the current description in the textarea inside the td should be copied over to the textarea inside #div_toggle
Here is what I am trying to accomplish.
The user would make changes to the description in #div_toggle, and when done, will click 'X' to close the div. This should cause the contents to be transferred from the textarea in #div_toggle to the td cell textarea.
Would you be able to help me achieve this goal? Or am I complicating this? Is there a better approach?
Below is the code I have thus far, but it does not work as desired or described above. Please help.
Best regards.
<!DOCTYPE html>
<html>
<head>
<style>
th,
td {
border: solid 1px lightgrey;
}
#div_toggle {
display: none;
border: 1px solid black;
margin: 10px;
}
#div_toggle textarea {
width: 200px;
height: 150px;
border: 3px solid #cccccc;
padding: 5px;
font-family: Tahoma, sans-serif;
}
#close_text {
position: absolute;
right: 27px;
cursor: pointer;
padding: 5px;
background: #cfd0d1;
border-radius: 4px;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<script>
$(document).ready(function() {
//Show textarea
$('.cell_id').click(function() {
$('#div_toggle').slideToggle('slow');
});
//Close textarea
$('#close_text').click(function() {
var tbl = $('#itemtable');
var rows = $('tr', tbl);
//get toggle div text area contents into td cell textarea
rows.eq(clickedrowindex).find('td:nth-child(3)').text() = $('#div_toggle textarea#notescopy').val();
$('#div_toggle').slideToggle('slow');
});
var clickedrowindex;
$('#itemtable').find('tr').click( function(){
clickedrowindex = $(this).closest('tr').index();
//get td cell textarea contents into the toggle div text area
var notestext = $(this).find('td:nth-child(3)').text();
$('#div_toggle textarea#notescopy').val(notestext);
});
});
</script>
</head>
<body>
<div class="left" style="margin-top:5px; border: solid #666 1px;">
<table id="itemtable" class="" style="width: 300px; margin: 10px;">
<thead style="color:black;">
<tr>
<th>Year</th>
<th>Model</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td> 2013</td>
<td> Toyota</td>
<td class='cell_id'><textarea name='reqnotes'></textarea></td>
</tr>
<tr>
<td> 2001</td>
<td> Honda</td>
<td class='cell_id'><textarea name='reqnotes'></textarea></td>
</tr>
</tbody>
</table>
<div id="div_toggle"><textarea id='notescopy'></textarea>
<span id="close_text" title="Click to close">X</span>
</div>
</div>
</body>
</html>
You do not need that much of code and its can simplified to just two functions to achieve your desired results.
Firstly, we just need to make sure that we save the our current target (td > textarea) in variable and use that variable to assign val to the textarea accordingly.
Also, we need to use a class .div_toggle selector not an id #div_toggle - Since id will only pick the element which is found firstly but in our case we need to change value dynamically on each slideDown and SlideUp event.
Lastly, for this you need to use slideDown and slideUp on X button click. Its work the same way as slideToggle. Using slideToggle will create a weird behaviour.
When you click the X the content you typed in the toggle div textarea will be transfered to the td you clicked on as your target
Live Working Demo:
$(document).ready(function() {
let currentTar; //save current target
let divToggle = $('.div_toggle') //get element
//Show textarea
$('.cell_id').click(function(event) {
currentTar = event.currentTarget
divToggle.slideDown('slow');
let getText = $(this).find('textarea').val()
divToggle.find('textarea').val(getText)
});
//Close textarea
$('#close_text').click(function() {
divToggle.slideUp('slow');
let assignVal = divToggle.find('textarea').val();
$(currentTar).find('textarea').val(assignVal)
});
});
th,
td {
border: solid 1px lightgrey;
}
.div_toggle {
display: none;
border: 1px solid black;
margin: 10px;
}
.div_toggle textarea {
width: 200px;
height: 150px;
border: 3px solid #cccccc;
padding: 5px;
font-family: Tahoma, sans-serif;
}
#close_text {
position: absolute;
right: 27px;
cursor: pointer;
padding: 5px;
background: #cfd0d1;
border-radius: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="left" style="margin-top:5px; border: solid #666 1px;">
<table id="itemtable" class="" style="width: 300px; margin: 10px;">
<thead style="color:black;">
<tr>
<th>Year</th>
<th>Model</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td> 2013</td>
<td> Toyota</td>
<td class='cell_id'><textarea name='reqnotes'>Test</textarea></td>
</tr>
<tr>
<td> 2001</td>
<td> Honda</td>
<td class='cell_id'><textarea name='reqnotes'>Foo</textarea></td>
</tr>
<tr>
<td> 2040</td>
<td> Elon Musk</td>
<td class='cell_id'><textarea name='reqnotes'>Tesla</textarea>
</td>
</tr>
</tbody>
</table>
<div class="div_toggle"><textarea id='notescopy'></textarea>
<span id="close_text" title="Click to close">X</span>
</div>
</div>
</body>
A few minor changes. Utilize $(this).val() instead of doing a find for the closest :)
You'll notice the code is much cleaner as well.
$(document).ready(function() {
$("textarea").click(function(){
var contents = $(this).val();
$('#notescopy').val(contents);
});
//Show textarea
$('.cell_id').click(function() {
$('#div_toggle').slideToggle('slow');
});
//Close textarea
$('#close_text').click(function() {
$('#div_toggle').slideToggle('slow');
});
});
th,
td {
border: solid 1px lightgrey;
}
#div_toggle {
display: none;
border: 1px solid black;
margin: 10px;
}
#div_toggle textarea {
width: 200px;
height: 150px;
border: 3px solid #cccccc;
padding: 5px;
font-family: Tahoma, sans-serif;
}
#close_text {
position: absolute;
right: 27px;
cursor: pointer;
padding: 5px;
background: #cfd0d1;
border-radius: 4px;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
</head>
<body>
<div class="left" style="margin-top:5px; border: solid #666 1px;">
<table id="itemtable" class="" style="width: 300px; margin: 10px;">
<thead style="color:black;">
<tr>
<th>Year</th>
<th>Model</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td> 2013</td>
<td> Toyota</td>
<td class='cell_id'><textarea name='reqnotes'></textarea></td>
</tr>
<tr>
<td> 2001</td>
<td> Honda</td>
<td class='cell_id'><textarea name='reqnotes'></textarea></td>
</tr>
</tbody>
</table>
<div id="div_toggle"><textarea id='notescopy'></textarea>
<span id="close_text" title="Click to close">X</span>
</div>
</div>
</body>
</html>

how to check a condition for a <td> value in a table depending on its table header

I want to change th, td values-based values ..suppose align numbers to right(except s.no) and text to left.
<button type="submit" class="btn btn-raised btn-primary mr-5"
(click)="productPrintSection('productSection')">
<i class="fa fa-check-square-o"></i> Print
</button>
my Html code is bellow and these data getting dynamically ...
<div id="invoice-items-details" class="pt-2">
<div class="row">
<div class="table-responsive col-sm-12">
<table class="table">
<thead>
<tr>
<th
*ngFor="let column of productColumns">
{{column.name}}
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let list of productSource; let i=index">
<td
*ngFor="let column of productColumns">
{{ list[column['value']] }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
my print section code is
productPrintSection = function (reportSection) {
let printContents, popupWin;
printContents = document.getElementById(reportSection).innerHTML;
popupWin = window.open('', '_blank', 'top=0,left=0,height=100%,width=auto');
popupWin.document.open();
popupWin.document.write(`
<html>
<head>
<style>
body { width: 99%;}
h1 {
text-align:center;
}
ul {
list-style: none;
padding: 0;
margin: 0;
}
label { font-weight: 400;
font-size: 13px;
padding: 2px;
margin-bottom: 5px;
}
table, td, th {
border: 1px solid silver;
}
table td {
text-align: center;
font-size: 13px;
}
table th {
font-size: 13px;
}
table {
border-collapse: collapse;
width: 98%;
}
th {
height: 26px;
}
</style>
</head>
<body onload="window.print();window.close()">${printContents}</body>
</html>`
);
popupWin.document.close();
}
my output screen
could u please suggest me how to show align of numbers to right(except s.no) and text to left.
well I could not find any css selector for selecting specific cells with numbers in them. That's why I've made a javascript function to check whether the cellmate can be converted to a number or not with !isNaN(col.innerText). Just call the styleTable function whenever you need it.
The following snippet contains an example based on the by you provided code.
var table = document.getElementById("products");
window.onload = function() {
styleTable(table)
};
function styleTable(table) {
//loop through the second row to check what kind of value they have
for (var i = 1, row; row = table.rows[i]; i++) {
//exclude the first column "S.no"
for (var j = 1, col; col = row.cells[j]; j++) {
//check if the column value is a number
if (!isNaN(col.innerText)) {
col.style.textAlign = "right";
}
}
}
}
body {
width: 99%;
}
h1 {
text-align: center;
}
ul {
list-style: none;
padding: 0;
margin: 0;
}
label {
font-weight: 400;
font-size: 13px;
padding: 2px;
margin-bottom: 5px;
}
table,
td,
th {
border: 1px solid silver;
}
table td {
text-align: center;
font-size: 13px;
}
table th {
font-size: 13px;
}
table {
border-collapse: collapse;
width: 98%;
}
th {
height: 26px;
}
<table id="products">
<tr>
<th>S.no</th>
<th>Product Name</th>
<th>Product code</th>
<th>Purity</th>
<th>Store</th>
<th>city</th>
<th>state</th>
<th>quantity</th>
<th>weight</th>
<th>total</th>
<th>total orders</th>
</tr>
<tr>
<td>1</td>
<td>xyzzy</td>
<td>1001010</td>
<td>54.00</td>
<td>Default</td>
<td>Hyderabad</td>
<td>dashdsaf</td>
<td>10</td>
<td>2135.5000</td>
<td>239280324.09</td>
<td>12</td>
</tr>
<tr>
<td>2</td>
<td>xyzzy</td>
<td>1001010</td>
<td>54.00</td>
<td>Default</td>
<td>Hyderabad</td>
<td>adsfsdf</td>
<td>0</td>
<td>2135.5000</td>
<td>239280324.09</td>
<td>13</td>
</tr>
</table>
Hope this helps!
Edit:
Provided a more dynamic way of styling each cell accordingly.

Changing table row borders query

For some reason my tr borders aren't showing internally, I have no idea why and have never had an issue with it? Its meant to be a dynamic table where an x and a y value can be placed within an input and it then creates it.
html:
<body>
<label id="h">x :</label>
<input type="number" id="width">
<label id="w">y :</label>
<input type="number" id="length">
<input type="submit" id="submit">
<table style="width:40%" id="table">
</table>
<script type="text/javascript" src="TableGenerator.js"></script>
</body>
css:
body{
background-color:#929caa;
}
#w{
color:white;
}
#h{
color:white;
}
table{
background-color:#d5dce5 ;
border-collapse: separate;
position: fixed;
margin-top: 10px;
color: black;
}
tr{
border: 1px solid black;
}
JS: (Column insertion is sill in process)
var submit = document.getElementById("submit");
submit.addEventListener("click", function(){
InsertNewRow();
InsertNewCol();
})
function InsertNewRow () {
for (var i = 0; i < document.getElementById("width").value; i++) {
var table = document.getElementById ("table");
var row = table.insertRow (-1);
row.className = "row";
row.innerHTML = "New Row";
}}
function InsertNewCol(){
}
tr border works only with border-collapse: collapse not with separate. So try to change border-collapse value to collpase in table css
table {
background-color: #d5dce5;
border-collapse: collapse;
position: fixed;
margin-top: 10px;
color: black;
}
tr {
border: 1px solid black;
}
<table>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
</tr>
</table>
Try border-collapse: collapse; it will show the lines between the rows.

css specificity for hovering

I'm having css specificity issues.
I want the <td> style to be colored different if there are 'no bills', so I set the style with an if statement. If there are no bills, the style is style = "id=\"no-bills\"";. I got this to work with css. Now, if the user hovers over it, I want the background to go red - so I modified the css and added #bill-list #no-bills td:hover, which has td:hover to add some extra specificity when you hover over it. Unfortunately, this doesn't work (the background stays the same).
here's my css:
#bill-list
{
font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif;
font-size: 12px;
/*margin: 45px;*/
width: 100%;
text-align: left;
border-collapse: collapse;
}
#bill-list th
{
font-size: 13px;
font-weight: normal;
padding: 8px;
background: #b9c9fe;
border-top: 4px solid #aabcfe;
border-bottom: 1px solid #fff;
color: #039;
}
#bill-list td
{
padding: 8px;
background: #e8edff;
border-bottom: 1px solid #fff;
color: #669;
border-top: 1px solid transparent;
}
#bill-list tr:hover td
{
background: #d0dafd;
color: #339;
}
#bill-list #bill td
{
background: white;
}
#bill-list #no-bills
{
background: #FFCC99;
}
#bill-list #no-bills td:hover
{
color: orange;
background: red /*#FFCC66*/;
}
here's my code (snippet):
<table id="bill-list">
<thead>
<tr>
<% for (int i=0; i<vecHeader.size(); i++) { %>
<th><%=vecHeader.get(i) %></th>
<% } %>
</tr>
</thead>
<tbody>
<% int uniqueId = 0;
for (int i=0; i < vecValue.size(); i++) {
boolean hasBills = true;
String style = "";
if ( vecBills.get(i) == null || vecBills.get(i).size() == 0 ) {
hasBills = false;
style = "id=\"no-bills\"";
}
%>
<tr id="bill<%=i%>" onclick="javascript:showBillDetails(<%=i%>)">
<% for (int j=0; j < vecHeader.size(); j++) {
prop = (Properties)vecValue.get(i);
%>
<td <%=style%>><%=prop.getProperty((String)vecHeader.get(j), " ") %> </td>
<% } %>
</tr>
...
...
Anyone have any ideas?
You should post the HTML code, not the code that generates it, it's irrelevant here.
First problem: are you certain there can't be 2 no-bills id on the same page?
Then your problem: you're trying to style td:hover that is a descendant of #no-bills. The latter is the same td, not an ascendant! You should then style #bill-list #no-bills:hover, which appears to be a td being hovered.
try
#bill-list #no-bills:hover
instead of
#bill-list #no-bills td:hover
If there are multiple no-bills, you should use class over id.

Strange border behavior in Chrome when expanding table row divs

I have a table with expand/collapse div elements in td.
When expanding in IE9, all is OK, but in Google Chrome (version 16.0.912.75 m) I get unexpected solid borders on differing spots.
It seems as if the colspan=3 tr's have something to do with this, as the solid borders appear above and under those. Also, the div width values seem to influence this: the behavior changes when choosing other values for these.
See below html. I added 4screen prints: initial view, expand row1, expand row2, expand both.
What is causing this odd behavior and how can I prevent it?
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
<title>Example</title>
<style type="text/css">
table {
border: solid black 1pt;
border-collapse: collapse;
padding: 0;
border-spacing: 0;
}
th {
background: rgb(255, 255, 153);
border-style: solid;
border-color: black;
border-width: 1pt;
padding: 0cm 5pt;
color: black;
font-family: Verdana;
font-size: 10pt;
font-style: normal;
vertical-align: top;
}
td {
border-style: dotted dotted none none;
border-color: black;
border-width: 1pt;
padding: 0cm 5pt;
color: black;
font-style: normal;
font-family: Verdana;
font-size: 10pt;
vertical-align: top;
margin-bottom: 4.5pt;
margin-top: 0pt;
}
div.QUAL {
margin-left:4pt;
font-size: 90%;
}
input.buttonQUAL {
color: blue;
background: white;
border: none;
margin-left:0pt;
margin-top: 0px;
margin-bottom: 0px;
font-size: 100%;
}
div.listQUALdesc {
color: black;
background: white;
font-size: 100%;
}
</style>
<script type="text/javascript" language="javascript">
//expand and collapse functions based on id
function toggleMe(a){
var e = document.getElementById(a);
if(!e) return true;
if( e.style.display == "none")
{
e.style.display = "block"
}
else {
e.style.display = "none"
}
return true;
};
function expandByIdStart(IdStart){
var divs = document.getElementsByTagName('div');
for (var i=0; i<divs.length; i++) {
if (divs[i].id.match("^"+IdStart) == IdStart) {
divs[i].style.display = "block";
}
}
return true;
}
function collapseByIdStart(IdStart){
var divs = document.getElementsByTagName('div');
for (var i=0; i<divs.length; i++) {
if (divs[i].id.match("^"+IdStart) == IdStart) {
divs[i].style.display = "none";
}
}
return true;
}
</script>
</head>
<body>
<p/>
<table style='table-layout:fixed word-break:break-all'>
<col width="70"><col width="70"><col width="70">
<thead><tr><th>Col1</th><th>Col2</th><th>Col3</th></tr></thead>
<tbody>
<tr>
<td>
<input
type="button"
class="buttonQUAL"
onclick="toggleMe('row1'); return true;"
onMouseOver="this.style.cursor='hand'"
value="row1"/>
</td>
<td>text1
<div id="row1" class="listQUALdesc" style="width:100; display:none">
text2
</div>
</td>
<td></td>
</tr>
<tr>
<td><div class="QUAL">xxx</div></td>
<td>text3</td>
<td></td>
</tr>
<tr>
<td colspan="3">Start</td>
</tr>
<tr>
<td>
<input
type="button"
class="buttonQUAL"
onclick="toggleMe('row2'); return true;"
onMouseOver="this.style.cursor='hand'"
value="row2"/>
<div id="row2" class="QUAL" style="display:none;width:65">
text5<br/>
</div>
</td>
<td>text4</td>
<td></td>
</tr>
<tr>
<td colspan="3">End</td>
</tr>
</tbody>
</table>
</body>
</html>
See comments - adding < !doctype html > partly solves the issue
Addition
There are some issues to be found on the web that point at an error in Chrome and Safari (which use webkit) like the following: webkit-colspan-table-border-bug.
It seems that using colspan and bottom-border in combination with border-collapse: collapse leads to border display issues, just as in my example.