table borders disappearing in tcpdf - tcpdf

I'm setting up tcpdf to generate invoices on the fly for customers, but when I add an image, the borders are disappearing from my table. Here's the code:
/*
if ($status == "Paid") {
$pdf->Image("/wp-content/themes/Feather/images/Paid.jpg", 10, 60, 190, '', '', '', 'T', false, "300", '', false, false, 0, false, false, false);
} elseif ($status == "Overdue") {
$pdf->Image("/wp-content/themes/Feather/images/Overdue.jpg", 10, 60, 190, '', '', '', 'T', false, "300", '', false, false, 0, false, false, false);
} elseif ($status == "Cancelled") {
$pdf->Image("/wp-content/themes/Feather/images/Void.jpg", 10, 60, 190, '', '', '', 'T', false, "300", '', false, false, 0, false, false, false);
}
*/
$pdf->SetXY($x=20, $y=30);
$pdf->writeHTML($html, true, false, true, false, '');
$pdf->lastPage();
Here's the HTML I'm using:
$html = $html . '
<br/><br/><br/>
<table width="600px" cellspacing="1" cellpadding="4" border="1">
<tr>
<th width="200px">Product</th>
<th width="65px">Code</th>
<th width="65px">Quantity</th>
<th width="65px">Unit Price</th>
<th width="65">VAT Rate</th>
<th width="65">VAT Amount</th>
<th width="65">Line Total</th>
</tr>';
foreach ($inv_lines as $inv_line) {
$html = $html .
'<tr>
<td>' . $inv_line['item_desc'] . '</td>
<td>' . $inv_line['item_no'] . '</td>
<td>' . $inv_line['quantity'] . '</td>
<td>' . $inv_line['unit_price'] . '</td>
<td>' . $inv_line['vat_rate'] . '</td>
<td>' . ($inv_line['quantity'] * $inv_line['vat_rate'] * $inv_line['unit_price'] * 0.01) . '</td>
<td>' . $inv_line['line_total'] . '</td>
</tr>';
The table appears fine with the code as above, but as soon as I uncomment the image bits, the image appears, but the table borders disappear. I've tried adding inline borders to individual cells, but that doesn't make any impact.
Does anyone have any ideas?

First off, make absolutely certain you're always including the end table tag. TCPDF's html parser can be picky about having opening and closing tags. (I only say this because it's missing in the question.) It relies on correct markup to function properly.
Now I'm not sure just by looking at your coordinates, but does the table overlap the image? If it does and you want the borders to be drawn on top of the image, you'll need to call setPageMark after you draw the image. If you don't, the borders will be drawn below the image no matter what order you have the Image and writeHTML calls in.
<?php
//In my test PDF I had to do something like this as some of my borders
//were disappearing underneath my test image.
$pdf->Image(...);
$pdf->setPageMark();
$pdf->setXY(...)
$pdf->writeHTML(...);
If the border is still not there, that is neither of the above help, you might wanna try setting the draw color after placing the image. I'm not sure if that would do anything, but it's worth a shot.
Of course, make sure you're on an updated version of TCPDF, depending on your version there may be border rendering fixes.

Always use "1" (double quotes)not single quotes border='1' as table border value.

Related

Tablesorter custom equations on calculated data

I need to sum two columns, then find the difference between those two. The use case is simple: in one column I have all the purchases and the second one contains all the transactions, the user will see the difference.
Here is the relevant code for the calculation:
<tfoot>
<tr>
<th>Total</th>
<th data-math="col-sum"></th>
<th data-math="col-sum"></th>
<th data-math="row-difference"></th>
</tr>
</tfoot>
And the formula can be something really simple like
$.tablesorter.equations['difference'] = function(arry) {
return arry[1] - arry[2];
};
How would you make it work?
The way the math widget is set up, it prioritizes rows calculations before column calculations. So in this case, the footer row will try to calculate the row difference before calculating the column sum.
To fix this, change the math_priority widget option so that the 'col' comes before 'row' (demo):
$(function() {
$.tablesorter.equations.difference = function(arry) {
return arry[1] - arry[2];
};
$("table").tablesorter({
theme: 'blue',
widgets: ['math', 'zebra'],
widgetOptions: {
// default [ 'row', 'above', 'below', 'col' ]
// move 'col' first in this case
math_priority: ['col', 'row', 'above', 'below']
}
});
});

Large image causing sidescroll in Jquery-UI pop-up

<tr width="900px;">
<td colspan="2">#trim(messages.message)#</td>
</tr>
.dialog({
autoOpen: false,
draggable: false,
maxHeight: 600,
overflow: scroll,
width: 900,
I have inserted a large image over 900px (using tinymce plugin) in width and it causes sidescrolling. How can I prevent this and shrink the image instead
Setting the width of the image to a percentage might fix your problem.
<img src="smiley.gif" alt="Smiley face" class="maxWidthImage" width="100%">
Or from css:
.maxWidthImage{
max-width:100%;
}
This will set the image width to the width of the above element.(when it's bigger than the above element)
In your case this is the dialog.

reset filter on tablesorter when going back to page and filtered select drop-down returns no records

I am using tablesorter on a page where I display products. One of the column is the status displayed in a drop-down. When I click a product I can edit it and change its status. When I go back to the product list, the list is still filtered which is OK but if the product was the last with this status, the product list is, of course, empty and the drop-down shows no selection because the status does not exist anymore. I want to clear the filter on the drop-down when I get back on the product list page and there is no more product with this status. How can I achieve this?
My code:
<table cellspacing="1" cellpadding="1" id="ProductTable" class="tablesorter">
<thead>
<tr>
<th class="reorder-false reorder-block-left">Product Name</th>
<th class="">Description</th>
<th class="filter-select filter-onlyAvail">Status</th>
<th class="">Status Change Date</th>
</tr>
</thead>
<tbody id="ProductList">
<tr class="ProductRows" id="P_1906">
<td ><a style="text-decoration:none" href="/Product/Index/1906">Product #1</a></td>
<td><span class="">Test #1</span></td>
<td><span class="">Active</span></td>
<td><span class="time">2015/07/13 16:41:03</span></td>
</tr>
<tr class="ProductRows" id="P_1993">
<td ><a style="text-decoration:none" href="/Product/Index/1993">Test #2</a></td>
<td><span class="">Test #2</span></td>
<td><span class="">Backorder</span></td>
<td><span class="time">2015/08/25 10:39:23</span></td>
</tr>
</tbody>
</table>
$("#ProductTable").tablesorter({
theme: 'blue',
widthFixed: false,
widgets: [ "zebra", "filter", "resizable" ],
widgetOptions: {
filter_childRows: false,
filter_columnFilters: true,
filter_filteredRow: 'filtered',
filter_hideFilters: true,
filter_ignoreCase: true,
filter_liveSearch: true,
filter_onlyAvail: 'filter-onlyAvail',
filter_reset: 'button.reset',
filter_saveFilters: true,
filter_searchDelay: 300,
filter_serversideFiltering: false,
filter_startsWith: false,
filter_useParsedData: false,
filter_defaultAttrib: 'data-value'
}
});
Thank you.
I made it using the following code:
var FilterCallOnce = false;
$("#ProductTable").tablesorter({
theme: 'blue',
widthFixed: false,
widgets: [ "zebra", "filter", "resizable" ],
widgetOptions: {
filter_childRows: false,
filter_columnFilters: true,
filter_filteredRow: 'filtered',
filter_hideFilters: true,
filter_ignoreCase: true,
filter_liveSearch: true,
filter_onlyAvail: 'filter-onlyAvail',
filter_reset: 'button.reset',
filter_saveFilters: true,
filter_searchDelay: 300,
filter_serversideFiltering: false,
filter_startsWith: false,
filter_useParsedData: false,
filter_defaultAttrib: 'data-value'
}
}).bind('filterEnd', function(e, filter){
var table = document.getElementById("ProductList");
var nrow = 0;
var nfiltered = 0;
if (FilterCallOnce == false)
{
FilterCallOnce = true;
if (table != null)
{
for (var i = 0, row; row = table.rows[i]; i++)
{
nrow++;
if (!hasClass(row, 'filtered'))
nfiltered++;
}
if ((nrow > 0) && (nfiltered == 0))
$('#ProductTable').trigger('filterReset');
}
}
});
function hasClass(element, cls)
{
return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}

jsPDF Table Width & Font Size

I thought this would be relatively simple but I cannot find an answer anywhere, I have had a good hunt in Stack Overflow. Apologies if I have missed something obvious!
How on earth do you set the table width in jsPDF? I simply want my table to stretch to 100% of the page width. Here is the code I am using:
<script>
function demoFromHTML() {
var pdf = new jsPDF('p', 'pt', 'a4');
source = $('#pdf')[0];
specialElementHandlers = {
'#bypassme': function (element, renderer) {
return true
}
};
margins = {
top: 80,
bottom: 40,
left: 40,
width: 600
};
pdf.fromHTML(
source,
margins.left,
margins.top, {
'width': margins.width,
'elementHandlers': specialElementHandlers
},
function (dispose) {
pdf.output('datauri');
}, margins);
}
</script>
I am using standard, unformatted HTML table.
<table class="reference">
<tbody><tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Points</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>Adam</td>
<td>Johnson</td>
<td>67</td>
</tr>
</tbody></table>
The table only stretches about 60% across the PDF, which just seems to be a random amount. In addition the text inside the table is a different font and size to the text outside the table.
Any help would be greatly appreciated.

one idea for jqgrid print view

I would like to have two views in jqgrid:
1) the regular grid view with sortable columns, pagination, etc (It's great and works really well...love it!).
2) a "print view" which can easily be styled with css and customized for print. The class structure should not be too complicated because I want to easily make my own style sheet. One important thing is to be able to repeat the column headers on each printed page. (I do not like to print from a jqgrid. Even when I add the jqgrid stylesheet with "media=print", the printed results are very hard to control.)
So, what I did was to first create a jqGrid. Then, using it's data, create my own table and print from that. It's a bit of a hack. But it works.
1- Create the grid and insert it into a div. Note I called "build_print_view" in the "loadComplete" function, based on the presence of a variable. This allows me to control whether I want to show "print view" or a "grid view" first:
function classGrid(select_val, showgrid){
jQuery.get('/lookupgrid/lookupgrid/get_grid', function(data) {
var _html= jQuery(data);
jQuery('#resultdiv').html(_html);
var gridtable = jQuery("#list");
var formdata = new Array();
formdata.push({
name: "var1",
value: "whatever"
});
formdata.push({
name: "var2",
value: "whateverelse"
});
var lastsel;
console_log("in classGrid");
gridtable.jqGrid({
url:'/lookupgrid/lookupgrid/class_grid',
colNames:['var1','var2'],
colModel :[
{
name:'var1',
index:'var1',
width:95
},
{
name:'var2',
index:'var2',
width:95
}],
datatype: 'json',
mtype: 'POST',
pager: '#pager',
rowList:[10,20,30],
loadComplete: function() {
if(!showgrid){
build_print_view();
}
},
onSelectRow: function(id){
var rowdata = gridtable.jqGrid('getRowData',id);
alert('Selected row ID ' + id + " var1 is " + rowdata.var1);
},
loadonce: true,
postData:formdata,
width: 800,
height: 300,
pgtext:"Page {0}",
viewrecords: true,
gridview: true,
caption: 'Class Results'
});
gridtable.jqGrid('navGrid','#pager',{
edit:false,
add:false,
del:false
});
});
}
2 - In build_print_view() you can extract the data from the jqgrid and put it into a table, which can be styled however you like with your own stylesheets.
function build_print_view(){
var gridtable = jQuery("#list");
var lista = gridtable.jqGrid('getGridParam','data');
var tablestr = "";
for(var i=0;i<lista.length;i++){
var rowData = lista[i];
tablestr += "<tr>"
tablestr += "<td class=\"wide cycle\" style=\"width:50px;\" id=\"sku\">"+rowData.var1+"</td>";
tablestr += "<td class=\"wide cycle\" style=\"width:300px;\" id=\"skudesc\">"+rowData.var2+"</td>";
tablestr += "</tr>";
}
jQuery.get('/lookupgrid/lookupgrid/get_print_view', function(data) {
var _html= jQuery(data);
_html.find('#printresults').append(tablestr);
jQuery('#resultdiv').html(_html);
});
}
3 - The rest of the table, and etc tags are returned by the ajax "get" call to "/lookupgrid/lookupgrid/get_print_view" and I just plop tablestr into "#printresults" div, i.e.:
<div id="printview">
<table id="clsitems" class="wide">
<thead>
<tr>
<th colspan="10" class="wide" id="label">
</th>
</tr>
<tr>
<td class="wide label">
var1:
</td>
<td class="wide label">
var2:
</td>
</tr>
</thead>
<tbody id="printresults">
</tbody>
</table>
</div>
4 - The only weirdness is that if "print view" is requested, the jqGrid gets created and flashes on the screen for a second, and then the print view table replaces it in its div.
Actually, if there were a good way to just construct the jqGrid without displaying it, I would prefer that. I could then display the jqGrid later if "screen view" were requested.

Resources