JSPDF Autotable breaks rows - javascript

In web app I'm using the JSPDF Autotable to build a PDF.
The problem is that the data will be dynamic (I'm going to use AngularJS 1.x) and so the rows can have differents height.
In some cases, Autotable breaks the last row of the page, continuing to the next one. How can I prevent this behavior, and set up Autotable to take the last row (which default would break) and bring it to the next page?
This is my code: https://jsfiddle.net/9vgxvfkh/1/
I guess I have to change some settings in the style:
styles: {
cellPadding: 1.5,
overflow: 'linebreak',
valign: 'middle',
halign: 'center',
lineColor: [0, 0, 0],
lineWidth: 0.2
},
pageBreak: 'always'
But I tried, and it didn't work.
P.S.: The margin top on the header is because then I will add an image.

Using the latest version this particular example is fixed. But for other cases where you don't want a multi line row to be split you can use rowPageBreak: 'avoid'.

Unfortunately, there is no way to do it using some parameters or styles.
I did a quick debug and found a solution for your problem, you need to modify the source code slightly.
In the source code I found that, for each row a method printFullRow is called, after that there is a check if the row can fit on the page (method canFitOnPage).
If row cannot fit on page, there is a check how many lines of text does it contain (in my case it is 10). Row is being split, because number of lines is bigger than 1.
You need to change this number to something bigger. In order to avoid further bugs you need to ensure how many lines would fit entire page height and put this number instead of 1. If you would choose some enormous amount, in case of really long text that wouldn't even fit entire page, it wouldn't be rendered at all, because common_1.addPage() would be executed endlessly.
To sum up, change line 470 to something like this:
if (row.maxLineCount <= 50) {
Unless 50 lines can't fit on page...
Before:
After:
Please check updated fiddle:
https://jsfiddle.net/9vgxvfkh/2/

Related

Create truly working tables with fixed headers

I'm trying to make the table with fixed header and auto-adjusted height to fill reaming space of wrapper div with tbody. I've spent over few days to solve the issue but every solution have it's own issues and I would love to ask you for help.
I'm working on Vue and Gridstack as I want to have resizable and draggable modules.
$(document).ready(function(){
$(function () {
$('.grid-stack.outer').gridstack({
cellHeight: 80,
verticalMargin: 20,
horizontalMargin: 10
});
$('.grid-stack.inner').gridstack({
cellHeight: 70,
verticalMargin: 20,
horizontalMargin: 10
});
});
});
I. https://codepen.io/anon/pen/eMpXrN
- works on Mac (Chrome and Safari)
- don't work on Windows, Edge: header is not fixed
- don't work on Windows, Chrome: when scroll is visible on tbody, the headers does not mach the columns (tbody is moved); example: https://www.dropbox.com/s/e730d7z4p10wpoe/Zrzut%20ekranu%202018-03-13%2011.20.30.png?dl=0)
II. https://codepen.io/anon/pen/LdpaKz
- works almost perfectly but if we scroll horizontally, the headers won't follow the content - example: https://www.dropbox.com/s/jqe0b0k8a3qcr0v/Zrzut%20ekranu%202018-03-13%2011.25.18.png?dl=0
Sum up:
I've spent few days so far, trying to build working table. I've tried flexbox based tables (which worked great beside that it was no possibility to fix the headers), regular tables. I've failed miserably.
What I'm looking for is to create table that:
- won't require jQuery (it can use vanilla JS)
- have fixed header
- scroll horizontally both headers with content
- auto-adjust the width of the cells in case user will resize it (and keep the same width for both column and header for that column)
Is it truly something impossible to achieve? I event wanted to watch the width of column and adjust the width of header accordingly, but with gridstack, the DOM is not updating it's width in vue.
PS. I have to get regular DOM (not something like only injecting array of data) I can modify as there might be complex elements in table.
I've tried datatables but I cannot make it to fill the gridstack wrapper when it's resizing.
Thanks!

Ext JS make paging toolbar smaller

I have a very simple question but I don't seem to find a simple answer. In fact, I haven't found any answer how to make the paging toolbar of a Ext JS grid smaller.
I made a very simple fiddle to investigate how this works, and it looks like at some point ExtJS will dynamically calculate the positions of the elements in the paging toolbar. Specifically the 'left' css attributes are set.
So I would like to know how to tweak the function that calculates these values so I can decrease these values. I could use jQuery/Javascript to do this but that just sounds so wrong so I prefer a clean ExtJS way to do this.
So instead of something like this...
I would like to see this:
For instance, the 'previous page' button in my sample has an inline css style declared (most likely done by the paging toolbar widget) with 41px to left whereas the separator icon has 81px for the same 'left' style. This goes on until the entire width of the toolbar is covered.
So to conclude, what I want is to intercept the calculations and decrease the values of the elements to lower the entire width of the toolbar.
Any suggestions would be welcome.
First set the width of your button.
new Ext.Button({
width: 100, <<== width of the button
text: 'Smaller paging toolbar',
// ...
Then you can move your element to the right with a Toolbar Separator just before your button :
[
{xtype: 'tbseparator', width: 200 },
new Ext.Button({
// ...
Here is your corrected fiddle
Thought I'd post the answer to my own question. There's a config that enables horizontal scrolling when the toolbar gets too small:
Ext.create('Ext.PagingToolbar', {
overflowHandler: 'scroller'
}

page based load epub when changing font

I am doing ebook reader app like as iBooks. I have succesfully read a .epub file. But my problem is:-
I have to add Font size increase and decrease and font changing functionality. I have to adjust pages When i increase and decrease font size . How can I split HTML string in pages ? .
You can see in both images . After changing font size the html string gets separated and the formatting is getting collapsed.
Thanks in advance
Well, this is really a hard question...
I have an idea for a method that splits a HTML page into two parts: the first page, and the rest. You can then repeatedly call that method on the "rest" to get all pages.
Set $num_words = 100
Take the first $num_words words from the page => $first_page_html;
Put $first_page_html into UIWebView and "render" it (see note below).
Check height of UIWebView. Does it fit? If yes, return from algorithm.
If the words don't fit into the UIWebView, do $num_words--;
Otherwise, do $num_words++;
GOTO 2
This is a first algorithm that should work somehow. However, there are optimization opportunities and hidden problems:
You should probably do something like a binary search instead of a linear search. So $num_words should not be 100, 99, 98, 97, 96, ..., 62, but rather 100, 80, 60, 70, 65, 64, 63, 62. It would be even faster to ask the webview how much it is bigger or smaller than expected. I.e. if the webview is 30% too big in height, it means that you should reduce it by (1-1/(1+30%))=23%, so you should probably multiply the word-count by 0.77 in the first step.
When there are hard page-breaks in the document, your function should take that into account.
You get the height of the UIWebView by calling webView.scrollView.contentSize.height. I think you have to wait for the UIWebView to finish rendering before you can check the height though.
If you know a bit more about the structure of your HTML you may be able to use the -stringByEvaluatingJavaScriptFromString: method from UIWebView to add individual words and see what happens. That way the webview doesn't have to re-render everything all the time.
Note: by "rendering" I mean calling -loadHTMLString:baseURL: and then waiting for the -webViewDidFinishLoad: delegate method to be called.
If performance is an issue it may be faster (for the device) to encode this algorithm in Javascript somehow, but I think that would be much harder.
Finally I got answer .It is very simple . In ios 7 you don't need to write javascript for pagination or any logic .
Just set UIWebview Property . Here is my code.
self.webView.paginationMode = UIWebPaginationModeLeftToRight;
self.webView.paginationBreakingMode = UIWebPaginationBreakingModePage;
self.webView.scrollView.delegate = self;
self.webView.scrollView.pagingEnabled = YES;
self.webView.scrollView.alwaysBounceHorizontal = YES;
self.webView.scrollView.alwaysBounceVertical = NO;
self.webView.scrollView.bounces = YES;
Here is sample code a : https://github.com/kalpesh22m/Epub-Reader-With-Pegination
first to increase font size you need to give font size in em . before using em you need to give the body font-size:62.5% and for the elements inside div give font-size like 1.2em (which will act as 12px). so when you want to increase any Div's font-size you just have to increase font size of body by 10%.
And you don't need to calculate characters for adjusting pages and this is not good practice for if you are making responsive book. use column property off css, let css handle flow of your pages.
See below link for font size and flowable html structure
js fiddle
Js Fiddle
and also see "readium js for chrome". which will give you idea about how to render epub file on browser

Make column width same for 2 tables

I am trying to implement a table structure in which the header remains fixed when i scroll down. I have used 2 tables for this purpose. The first table has the header values and the second table have the corresponding data(length of data in each column might vary as the data is populated dynamically). The problem is that the header width and data column width are not matching exactly.
I have written some code like shown below to dynamically alter the column width
$('#tdCheckAllBody').width($('#tdCheckAllHead').width());
$('#tdLoginBody').width($('#tdLoginHead').width());
$('#tdStatusBody').width($('#tdStatusHead').width());
$('#tdFNameBody').width($('#tdFNameHead').width());
$('#tdLNameBody').width($('#tdLNameHead').width());
$('#tdCompBody').width($('#tdCompHead').width());
But it doesnt seem to work properly. Any help appreciated.
Use this method
$(window).scroll(function(){
$("#id of the table header").offset({top:$("#id of the control which u placed the scrolling").scrollTop()});
});
Created a working fiddle for this:
http://jsfiddle.net/terjeto/dx7H5/
Offcourse if your case is different, you might need to tweak a litle. In my opinion the problematic areas are if the table use dynamic or % width and coping with the "auto" scrollbar which takes up approx 18px, and offcourse if the table needs horizontal scrollbars it complicates things a litle needing the onscroll event.
Could it be that your exmple is not accurate because of lacking reset-css code?
I use this: http://developer.yahoo.com/yui/reset/

Table Row SHOW / HIDE *Without* Column Width Resizing, w/ TableLayout: auto

I have table with multiple rows, showing items for sale. When the user clicks on a row, a Javascript inserts / shows a new row right beneath it with details about the item. The issue is when the description is long, it forces the column widths to readjust / resize. This shifts the columns positions and is really annoying, especially for the user. Right now, I have my table.style.tableLayout: auto. I actually prefer it this way, because the columns are adjusted to the content.
My question is: how do I dynamically "lock" the widths of the columns in my table so that when I insert / show the new row, the columns do not readjust / resize?
I've tried:
dynamically setting the table to temporarily "tableLayout: fixed"
inserting / showing my new row
changing the table back to "tableLayout: auto"
Actions 1 & 2 works in in FireFox, but not in Safari and IE (6 & 7). However, doing all three seems to prevent the columns from shifting too much.
The frustration is unbearable ... loosing lots of sleep ... please help!
Thanks.
For those looking for the code (this is done in jQuery). This also assumes the first row has the proper widths for each cell. Pretty easy changes if needed.
$('table.class_of_table_to_fix tr:first td').each(function() {
$(this).css({'width': $(this).width()+"px"});
});
I would set a percent width on each column simply as a guide. Set it just once on the TH of each column. The browser will still adjust the columns to content if necessary, but the columns will stay in place more consistently.
Next, I would never put css "white-space:nowrap" anywhere on that table. A long description should not break the table layout, it should wrap around properly on multiple lines, and be readable if you set the widths on each column to suit the type of data. Similarly I would keep the use of (non breakable spaces) to dates, times and numbers and allow the text to wrap.
Other than that, I do this at my job on a dialy basis, and there's a time when you need to stop ulling hairs asking the browser to do something it's not designed to do. Content should flow and adapt. Locking column widths to pixels is 99.99999% of the time a bad idea.
PS: If you really, reeally, REALLY need to lock columns, the only solution I'm aware of that works with CSS2 and accross all browsers is to use images. You could insert a 1px high transparent gif image in each column, and counting in the padding of the cells (TD), set a pixel width on each image (IMG), instead of on the columns (TH/TD). You could hide those in the TH for example. You can leave the images at 1 pixel wide and set percent widths on TDs, and when you open a new row, you would get each column width minus TD Padding, and set that to the corresponding IMG. I haven't tried! I just know that in many projects I've worked on, I've used small gif images to lock a minimum vertical spacing between columns, for example.
I had a similar problem when I was implementing a table with groups that could be toggled. I wanted the initial ratio between the columns to stay the same without fixing the widths of the columns. By default the browser would change the widths depending on the visibility of the table's rows, which was undesirable.
I went ahead and followed #faB's suggestion of applying percentages, but doing so using a small script that would calculate the percentages of the th elements and apply them after the initial render. This made my columns stay the same width, even with all rows hidden.
Here's the script, which uses jQuery:
(function($){
var lock_widths = function() {
var total_width = $('table').innerWidth();
var headers = $('table th');
var leftover = 100;
$.each(headers, function(ix, el) {
var header = $(el), width;
// on the last call use the leftover percentage
if (ix == headers.length - 1) {
width = leftover;
} else {
leftover -= width = header.outerWidth() / total_width * 100;
}
header.css({'width': width + '%'});
});
};
$(document).ready(lock_widths);
})(jQuery);
Tested in IE7+, Firefox and Chrome. This works for my special case because I have header columns as a reference, but it could be rewritten to measure some other columns.
You can display the details of the row beneath the clicked one in DIV and set its
style="overflow:auto";
so that details will wrap and scrollbar will be available to display entire text.
I don´t know if you´re familiar with jquery, but that´s what I would use - in combination with a separate class for the column that´s causing resizing in the new row - to:
Calculate / get the with of the column
Set the with of the afore mentioned class
Add the row
I haven´t tried it, but that should do it.
By the way, there are probably other ways to do it, I´m just more familiar with jquery (for point 1. and 2.).

Categories