show each div content individually in each page - javascript

I am exporting the data present inside the div to PDF when user click on the export button. I want to show each div content to show in individual pages inside the PDF.
The above scenario is working in the demo https://plnkr.co/edit/KvkVlYmmmJiZ71sghb1l?p=preview
The same when applied to below code, it is not working.
Demo here : https://plnkr.co/edit/P9nUSRY5TytkonM6dUHl?p=preview
js code:
$scope.export = function() {
var pdf = new jsPDF('landscape');
var source = $('#append-source');
$('.myDivClass').each(function(){
var html = "<div>"+$(this) + "</div><!--ADD_PAGE-->";//the code is broken with this line
// var html = $(this);
source.append(html);
});
console.log(source);
pdf.addHTML(
source, 0, 0, {
pagesplit: true
},
function(dispose){
pdf.save('test3.pdf');
}
);
}

It is not recommended to use jquery like this inside an angular app. To see why look here: Can we use both jQuery and Angular in our Web Application?
However what you want to do is possible if you put the following into your controller:
$scope.export = function() {
var pdf = new jsPDF('landscape');
var source = "";
var width1 = pdf.internal.pageSize.width;
$('.myDivClass').each(function(){
var textForPdfPage = $(this).children().eq(1).children()[0].textContent;
var html = "<div>"+ textForPdfPage + " </div><!--ADD_PAGE-->";
source+=html;
});
margins = {
top: 80,
bottom: 60,
left: 10,
width: '100%'
};
pdf.fromHTML(
source, // HTML string or DOM elem ref.
margins.left, // x coord
margins.top, { // y coord
'width': width1 // max width of content on PDF
},
function (dispose) {
pdf.save('test.pdf');
},
margins
);
}
Your main problem is that when you where trying to create your html string you only used $(this). $(this) gives you a jquery object. The string you want to put on the page is inside this object and is accessed using the jquery .children() method.

Here is a way of doing what you asked using addHTML() instead of fromHTML():
$scope.export = function() {
var pdf = new jsPDF('landscape');
var pdfName = 'test.pdf';
var options = {};
var $divs = $('.myDivClass') //jQuery object of all the myDivClass divs
var numRecursionsNeeded = $divs.length -1; //the number of times we need to call addHtml (once per div)
var currentRecursion=0;
//Found a trick for using addHtml more than once per pdf. Call addHtml in the callback function of addHtml recursively.
function recursiveAddHtmlAndSave(currentRecursion, totalRecursions){
//Once we have done all the divs save the pdf
if(currentRecursion==totalRecursions){
pdf.save(pdfName);
}else{
currentRecursion++;
pdf.addPage();
//$('.myDivClass')[currentRecursion] selects one of the divs out of the jquery collection as a html element
//addHtml requires an html element. Not a string like fromHtml.
pdf.addHTML($('.myDivClass')[currentRecursion], 15, 20, options, function(){
console.log(currentRecursion);
recursiveAddHtmlAndSave(currentRecursion, totalRecursions)
});
}
}
pdf.addHTML($('.myDivClass')[currentRecursion], 15, 20, options, function(){
recursiveAddHtmlAndSave(currentRecursion, numRecursionsNeeded);
});
}
I left the other answer so people can see both ways of doing it.

Related

How do I get a DIV to follow a transform

Long story short, I'm trying to put text inside a box that is animated with javascript.
var two = new Two({
fullscreen: true,
autostart: true
}).appendTo(document.body);
const card = two.makeRoundedRectangle(230/2, two.height/2, 230, 130, 10);
const div = document.createElement("div"); // THIS IS THE IMPORTANT STUFF
const text = document.createTextNode("This is text."); //
div.appendChild(text); // THIS IS THE IMPORTANT STUFF
two.update(); // this needs to be here to add to the dom
card._renderer.elem.style.cssText = 'position:relative;width:230px;height:130px;'; // THIS IS THE IMPORTANT STUFF
div.style.cssText = 'position:absolute;width:200px;height:200px;'; //
card._renderer.elem.appendChild(div); // THIS IS THE IMPORTANT STUFF
two.bind('update', function (framNum)
{
card.translation.x += 1
if (card.translation.x > two.width - 230/2)
{
card.translation.x = 230/2
}
}).play()
<script src="https://two.js.org/third-party/two.js"></script>
here's what I've tried. I'm trying to put document.createTextNode("This is text."); inside a parent that is moving
I was expecting the to see the text, or even a div with the inspector, but its not highlighting.
Any help would be greatly appreciated
You need to use two's text functionality instead of using DOM related functions. It appears that in this context, two renders to an SVG format, thus adding HTML tags won't work.
var two = new Two({fullscreen: true, autostart: true}).appendTo(document.body);
const card = two.makeRoundedRectangle(230/2, two.height/2, 230, 130, 10);
var styles = { size: 24, family: 'Calibri' };
var text = new Two.Text("This is text.", 120, 100, styles);
var group = two.makeGroup(card, text);
two.update(); // this needs to be here to add to the dom
card._renderer.elem.style.cssText = 'position:relative;width:230px;height:130px;';
two.bind('update', function (framNum)
{
group.translation.x += 1
if (group.translation.x > two.width - 230/2)
{
group.translation.x = 230/2
}
}).play()
<script src="https://two.js.org/third-party/two.js"></script>

PDFJS is not defined in pdf.worker.js (Backbone+Marionette+pdf.js)

I want to render a PDF inside a Backbone.js/Marionette View with pdf.js, but PDFJS is not defined in pdf.worker.js. It is however defined in the Backbone View itself and also accessible via the console.
This is the code for the View:
module.exports = PDFView = Marionette.ItemView.extend({
template: require('../../../templates/pdf_frame.hbs'),
onRender: function(){
var PDF_PATH = '../../pdf/websummitpitch.pdf';
var PAGE_NUMBER = 1;
var PAGE_SCALE = 1.5;
var SVG_NS = 'http://www.w3.org/2000/svg';
if (PDFJS) {
console.log("PDFJS is loaded in Backbone View");
} else {
console.log("PDFJS is NOT loaded in Backbone View");
}
PDFJS.workerSrc = "/js/pdf.worker.js";
console.log("workerSrc is set to ", PDFJS.workerSrc);
// Loading document and page text content
PDFJS.getDocument({url: PDF_PATH}).then(function (pdfDocument) {
console.log("get document");
pdfDocument.getPage(PAGE_NUMBER).then(function (page) {
console.log("get page");
var viewport = page.getViewport(PAGE_SCALE);
page.getTextContent().then(function (textContent) {
// building SVG and adding that to the DOM
var svg = this.buildSVG(viewport, textContent);
// render svg in <canvas id="render"> in template
document.getElementById('render').appendChild(svg);
});
});
});
},
buildSVG: function(viewport, textContent) {
// Building SVG with size of the viewport (for simplicity)
var svg = document.createElementNS(SVG_NS, 'svg:svg');
svg.setAttribute('width', viewport.width + 'px');
svg.setAttribute('height', viewport.height + 'px');
// items are transformed to have 1px font size
svg.setAttribute('font-size', 1);
// processing all items
textContent.items.forEach(function (textItem) {
// we have to take in account viewport transform, which incudes scale,
// rotation and Y-axis flip, and not forgetting to flip text.
var tx = PDFJS.Util.transform(
PDFJS.Util.transform(viewport.transform, textItem.transform),
[1, 0, 0, -1, 0, 0]);
var style = textContent.styles[textItem.fontName];
// adding text element
var text = document.createElementNS(SVG_NS, 'svg:text');
text.setAttribute('transform', 'matrix(' + tx.join(' ') + ')');
text.setAttribute('font-family', style.fontFamily);
text.textContent = textItem.str;
svg.appendChild(text);
});
return svg;
}
});
This is the console output:
The blue is console input, so PDFJS is accessible via the console.
This is where the reference error occurs (in pdf.worker.js):
PDFJS.version = '1.0.233';
It is one of the very first lines, where the version number is set. However PDFJS seems to be undefined.
This is my question:
Why is it not defined? How should I fix this?
I got the pdf viewer to work. Instead of using:
PDFJS.workerSrc = "/js/pdf.worker.js";
I just disabled the worker like this:
PDFJS.disableWorker = true;
Now it magically works. Not sure why though.

How to properly use jsPDF library

I want to convert some of my divs into PDF and I've tried jsPDF library but with no success. It seems I can't understand what I need to import to make the library work. I've been through the examples and I still can't figure it out. I've tried the following:
<script type="text/javascript" src="js/jspdf.min.js"></script>
After jQuery and:
$("#html2pdf").on('click', function(){
var doc = new jsPDF();
doc.fromHTML($('body').get(0), 15, 15, {
'width': 170
});
console.log(doc);
});
for testing purposes but I receive:
"Cannot read property '#smdadminbar' of undefined"
where #smdadminbar is the first div from the body.
you can use pdf from html as follows,
Step 1: Add the following script to the header
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
or download locally
Step 2: Add HTML script to execute jsPDF code
Customize this to pass the identifier or just change #content to be the identifier you need.
<script>
function demoFromHTML() {
var pdf = new jsPDF('p', 'pt', 'letter');
// source can be HTML-formatted string, or a reference
// to an actual DOM element from which the text will be scraped.
source = $('#content')[0];
// we support special element handlers. Register them with jQuery-style
// ID selector for either ID or node name. ("#iAmID", "div", "span" etc.)
// There is no support for any other type of selectors
// (class, of compound) at this time.
specialElementHandlers = {
// element with id of "bypass" - jQuery style selector
'#bypassme': function (element, renderer) {
// true = "handled elsewhere, bypass text extraction"
return true
}
};
margins = {
top: 80,
bottom: 60,
left: 40,
width: 522
};
// all coords and widths are in jsPDF instance's declared units
// 'inches' in this case
pdf.fromHTML(
source, // HTML string or DOM elem ref.
margins.left, // x coord
margins.top, { // y coord
'width': margins.width, // max width of content on PDF
'elementHandlers': specialElementHandlers
},
function (dispose) {
// dispose: object with X, Y of the last line add to the PDF
// this allow the insertion of new lines after html
pdf.save('Test.pdf');
}, margins
);
}
</script>
Step 3: Add your body content
Run Code
<div id="content">
<h1>
We support special element handlers. Register them with jQuery-style.
</h1>
</div>
Refer to the original tutorial
See a working fiddle
You only need this link jspdf.min.js
It has everything in it.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
According to the latest version (1.5.3) there is no fromHTML() method anymore.
Instead you should utilize jsPDF HTML plugin, see: https://rawgit.com/MrRio/jsPDF/master/docs/module-html.html#~html
You also need to add html2canvas library in order for it to work properly: https://github.com/niklasvh/html2canvas
JS (from API docs):
var doc = new jsPDF();
doc.html(document.body, {
callback: function (doc) {
doc.save();
}
});
You can provide HTML string instead of reference to the DOM element as well.
This is finally what did it for me (and triggers a disposition):
function onClick() {
var pdf = new jsPDF('p', 'pt', 'letter');
pdf.canvas.height = 72 * 11;
pdf.canvas.width = 72 * 8.5;
pdf.fromHTML(document.body);
pdf.save('test.pdf');
};
var element = document.getElementById("clickbind");
element.addEventListener("click", onClick);
<h1>Dsdas</h1>
<a id="clickbind" href="#">Click</a>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.3/jspdf.min.js"></script>
And for those of the KnockoutJS inclination, a little binding:
ko.bindingHandlers.generatePDF = {
init: function(element) {
function onClick() {
var pdf = new jsPDF('p', 'pt', 'letter');
pdf.canvas.height = 72 * 11;
pdf.canvas.width = 72 * 8.5;
pdf.fromHTML(document.body);
pdf.save('test.pdf');
};
element.addEventListener("click", onClick);
}
};
how about in vuejs how is it applicable?
function onClick() {
var pdf = new jsPDF('p', 'pt', 'letter');
pdf.canvas.height = 72 * 11;
pdf.canvas.width = 72 * 8.5;
pdf.fromHTML(document.body);
pdf.save('test.pdf');
};
var element = document.getElementById("clickbind");
element.addEventListener("click", onClick);
<h1>Dsdas</h1>
<a id="clickbind" href="#">Click</a>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.3/jspdf.min.js"></script>
Shouldn't you also be using the jspdf.plugin.from_html.js library? Besides the main library (jspdf.js), you must use other libraries for "special operations" (like jspdf.plugin.addimage.js for using images). Check https://github.com/MrRio/jsPDF.
first, you have to create a handler.
var specialElementHandlers = {
'#editor': function(element, renderer){
return true;
}
};
then write this code in click event:
doc.fromHTML($('body').get(0), 15, 15, {
'width': 170,
'elementHandlers': specialElementHandlers
});
var pdfOutput = doc.output();
console.log(">>>"+pdfOutput );
assuming you've already declared doc variable.
And Then you have save this pdf file using File-Plugin.

Ext.Ux.Printer Print Image doesn't work

i have downloaded the https://github.com/edspencer/Ext.ux.Printer and
import the Printer.js and Base.js
in Base.Js i added the image rendder code:
Ext.ux.Printer.imageRenderer = Ext.extend(Ext.ux.Printer.BaseRenderer, {
generateBody: function(image) {
return String.format("<div class='image-print'>{0}</div>", image.body.dom.innerHTML);
}
});
Ext.ux.Printer.registerRenderer('image', Ext.ux.Printer.imageRenderer);
this is the place display the image with id displayimage
items: [Printtoolbar,{
xtype : 'image',
id : 'displayimage',
style: {
'display': 'block',
'margin': 'auto'
},
width: 320,
height: 240,
}]
When Pressed Print Button Print The Image
var PrintImgBtn = Ext.getCmp('btnPrint');
PrintImgBtn.on('click', function(){
printImg = Ext.getCmp('displayimage');
Ext.ux.Printer.print(printImg);
Unfortunately when i pressed the print button,nothing happen.
You can just open a window and print it. In your button handler:
...
handler: function() {
var img = Ext.getCmp('displayimage');
if(img) {
var html = img.container.dom.innerHTML;
var win = window.open();
win.document.write(html);
win.print();
win.close();
}
}
...
Example with print: http://jsfiddle.net/wXfFN/3/
if your are using Iframe 'Ext.ux.iFrame', then you can use something like this
var iframe = this.down('iframe');
iframe.getFrame().contentWindow.print();
if you want to add some additional content along with iframe content
var iframe = this.down('iframe');
var contentWindow = iframe.getFrame().contentWindow;
var iFrameNewContent = "<div>This will be helpfull</div>" + contentWindow.document.body.innerHTML;
// set iFrameNewContent to content window
contentWindow.document.body.innerHTML = iFrameNewContent;
contentWindow.print();
Advantage is that all the styles applied to iframe content, you can see in print document
Also check this link whether it comes usefull
https://druckit.wordpress.com/2014/02/15/ext-js-4-printing-the-contents-of-an-ext-panel/

Fade in image only after finish loading

I've some images on a page which are loaded randomly and they are over 100kbs, is it possible to have it fully loaded then fade it in rather than progressively loading it?
My JS looks like this...
(function($){
$.randomImage = {
defaults: {
//you can change these defaults to your own preferences.
path: '_images/', //change this to the path of your images
myImages: ['hero_eagle.jpg', 'hero_giraffe.jpg', 'hero_owl.jpg', 'hero_rabbit.jpg']
}
}
$.fn.extend({
randomImage:function(config) {
var config = $.extend({}, $.randomImage.defaults, config);
return this.each(function() {
var imageNames = config.myImages;
//get size of array, randomize a number from this
// use this number as the array index
var imageNamesSize = imageNames.length;
var lotteryNumber = Math.floor(Math.random()*imageNamesSize);
var winnerImage = imageNames[lotteryNumber];
var fullPath = config.path + winnerImage;
//put this image into DOM at class of randomImage
// alt tag will be image filename.
$(this).attr( { src: fullPath });
});
}
});
})(jQuery);
Should be able to, just set the image to display:none in your stylesheet and modify the bit of the script that sets the src to this:
$(this).attr( { src: fullPath }).load(function() {
$(this).fadeIn()
});
Start with the images hidden using CSS. Then use:
$(document).ready(function() {
// Code goes here.
});
and have the fade-in execute there.
There's another SO question that discusses preloading images using jQuery right here: Preloading images with jQuery
Quoting from the top answer:
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
// Alternatively you could use:
// (new Image()).src = this;
});
}
// Usage:
preload([
'img/imageName.jpg',
'img/anotherOne.jpg',
'img/blahblahblah.jpg'
]);
if you want all images to preload before fading in, and display a loading message to the user, you can use something like this:
var gotime = imgArray.length;
$(".maxCount").text(gotime);
var imgCounter = 0;
$.each(imgArray, function(){
$(new Image()).load(function(){
imgCounter++;
$(".presentCount").text(imgCounter);
if (--gotime < 1) {
$("#content").fadeIn();
}
}).attr('src', this);
});

Categories

Resources