output specific data from div and print it via printer - javascript

I've spent all day in getting a solution for my need but since i'm not an experienced coder it's time for me to ask you guys for a little help.
My scenario is:
I have some php code like:
<div id="unique_name">
<?php function_show_qrcode()?>
<?php function_show_text1()?>
<?php function_show_text2()?>
<?php function_show_text3()?>
</div>
What i want to achieve is to print the content of "unique_name" div (qrcode and some additional info) directly to a label printer attached via wireless on my smartphone and PC, printer that prints on continuous paper with a width of 62mm.
I have tried a lot of codes that i found but with no success because of browsers behavior regarding window.print()
The following code is working on firefox and chrome on pc but it is not working on safari mobile
<script>
function printDiv(unique_name) {
var printContents = document.getElementById(unique_name).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
window.print();
document.body.innerHTML = originalContents;
}
</script>
Print label
I am stuck on that and i think that something like converting the content of unique_name div into an image, save it and print it after that should work but there are a lot of steps to do and we want to do it more easy something like click and print or click and popup and then print and the most important thing is that it needs to work on mobile browsers
Thank you in advance!

try this :
<script>
function printDiv(myId){
var HiddenElements = document.querySelectorAll( 'body *' ); // get all the elements in the body
var VisibleElements = document.querySelectorAll( '#' + myId + ' *' ); // gets the elements inside the div to be printed
var index = 0, length = HiddenElements.length;
for ( ; index < length; index++) {
HiddenElements[index].style.visibility = "hidden"; // hide all the elements in the body
}
index = 0;
length = VisibleElements.length;
for ( ; index < length; index++) {
VisibleElements[index].style.visibility = "visible"; // show all the elements inside the div to be printed
}
// display the element to be printed
myElement = document.getElementById(myId);
myElement.style.visibility = "visible"
var oldPos = myElement.style.position;
myElement.style.position = "absolute";
myElement.style.left = 0;
myElement.style.top = 0;
setTimeout(window.print, 1000); // Wait a bit for the DOM then Print ( Safari :/ )
// wait for the data to be sent to the printer then display the previous content
setTimeout(function(){
index = 0;
length = HiddenElements.length;
for ( ; index < length; index++) {
HiddenElements[index].style.visibility = "visible";
}
myElement.style.position = oldPos;
}, 5000);
}
</script>
Print label
JsFiddle : https://jsfiddle.net/2m5ha1ta/67/
i don't know why on JsFiddle the onclick doesn't work, so i added an id to the a and added an eventListener to it and it's working ( check the fiddle )

i don't know why exactly but apparently in Safari , Window.print is executed before the DOM is manipulated,
try putting the window.print() in a timeout:
replace this line window.print(); with setTimeout(window.print, 1000);
give it some time to print, then put back the original content :)
setTimeout(function(){
document.body.innerHTML = originalContents;
}, 2000)
you can play with the timeout's number of milliseconds until you get the sweet spot, it doesn't have to be 2000.

Related

clientHeight of Element in PDF different to Element in Browser

I'am trying to identify with javascript if I need to force a page break in my document.
One element that is overflow hidden. I loop through each of the elements within this document. I remove all last childs until the height of the element within the overflow:hidden element is smaller. Now I know, when to page break and I push all removed childs in the new page.
Works fine in browser. But not in PDF...
I'am using http://wkhtmltopdf.org/
See problem here: Left: PDF, Right: Browser (Chrome)
Height of 3262px vs 358px...
Same if I use .clientHeight or jQuery .height().
Does anyone know a workaround to get heights the same?
Some code:
function isOverflowed(element){
// return element.scrollHeight > element.clientHeight;
// console.log(element.clientHeight);
// console.log(element.parent().height() +'>'+ element.height());
return element.parent().height() < element.height();
}
// var daysWrapper = document.getElementById('days');
// var days = daysWrapper.querySelectorAll(".section.day");
var days = $('#days .section.day');
// console.log(days);
days.each(function() {
var $this = $(this);
var area = $this.find('.day-info');
var content = area.children();
var lasts = $( '<div class="lasts">' );
var test = 0;
while(isOverflowed(content)) {
var last = content.children().last();
// lasts.append( $( last ) );
last.clone().prependTo(lasts);
last.remove();
test++;
if (test > 6) break;
}
content.find('h1').html(area.height() + ' - ' + content.height());
if (lasts.children().length ) {
var newPage = $this.clone();
newPage.insertAfter($this);
newPage.find('.day-image').remove();
newPage.find('.day-info').removeClass('overflow');
newPage.find('.day-info').children().html(lasts.html());
}
});
Thanks!

Delay Display of Text in Qualtrics using Javascript

(This is related to the unanswered question https://stackoverflow.com/questions/26745762/delaying-presentation-of-text-in-qualtrics)
I am working on a Qualtrics survey. I want to delay some text (say, text) being displayed - it should be hidden for 5 seconds, then display.
I found a resource here - Javascript for Qualtrics - that I can't get to work.
Drawing from this example, I try to replicate it by delaying the display of a photo. I do this to see if I can get this working before I go on to delaying the display of text as opposed to a photo.
In the HTML part, I put:
Time: <span id="time1">30</span><br>
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/%C3%81guila_calva.jpg/1280px-%C3%81guila_calva.jpg" style="width: 133px; height: 115px;" class='pic1' />
In the Javascript part, I have:
started = false;
function countDown1() {
if (!started)
started = true;
else {
var value1 = parseInt($('time1').innerHTML);
$('time1').innerHTML = value1 - 1;
if (value1 == 26) {
var styling1 = document.getElementsByClassName('pic1')[0];
styling1.style.display = "none";
}
}
setTimeout(countDown1, 1000);
}
Event.observe(window, 'load', countDown1);
For some reason, nothing happens at all with the timer or the photo.
Do I need to wrap the above Javascript in:
Qualtrics.SurveyEngine.addOnload(function()
{
});
I tried this as well, but no change.
So I really have two questions. 1. How do I modify the above code to get it working. And 2. How do I modify the working version of the code to display text after a certain amount of time?
You're making it more complex than need be.
Here is example html for the question:
This is a question. <span id="hiddentext" style="display:none">This text
will display after five seconds.</span>
Here is the javascript for the question:
Qualtrics.SurveyEngine.addOnload(function()
{
setTimeout("$('hiddentext').style.display = 'inline'",5000);
});
This hides the radiobuttons or Choices in a multiple choice question for 2 seconds. If you need to hide the next button as well you can add a Timing question from the ones already provided in Qualtrics and set it to "Enable submit after (seconds)".
Qualtrics.SurveyEngine.addOnload(function() {
var QID = this.questionId;
console.log(QID);
for (var i = 1; i < 4; i++) {
document.getElementById( QID + "-" + i + "-label" ).style.display="none";
}
(function(delay_container){
for (var i = 1 ; i < 4 ; i ++){
document.getElementById(QID + "-" + i + "-label").style.display="block";
}
}).delay(2,this.questionContainer);
});
Let's say you have two sentences that are two separate Descriptive text boxes. And you want the second box to appear some seconds after the first. The following worked for me when assigned for the second box. The same code works for following boxes as well. You can again put a Timing question at the end of the page to hide Next button.
Qualtrics.SurveyEngine.addOnload(function() {
var QID = this.questionId;
console.log(QID);
for (var i = 1; i < 4; i++) {
document.getElementById( QID).style.display="none";
}
(function(delay_container){
for (var i = 1 ; i < 4 ; i ++){
document.getElementById(QID).style.display="block";
}
}).delay(2,this.questionContainer);
});

Reload a content almost invisibly and no blinking effect using JAVASCRIPT

I'm writing a small progam wherein I'm getting data using $.get then display the data so far so good and then there's this part then when I click a certain link it refresh the page but it has this blinking effect. Is there a way on how to reload the content get the new updated content then replace the previously loaded data.
NOTE: I didn't use setInterval or setTimeout function because it slows down the process of my website. any answer that does not include those functions are really appreciated.
Here's the code
function EmployeeIssues(){
$('#initial_left').css({'display' : 'none'});
var table = $('#table_er');
$.get('admin/emp_with_issues', function(result){
var record = $.parseJSON(result);
var data = record.data,
employees = data.employees,
pages = data.pages;
if(employees){
$('#er_tab_label').html('<b>Employees with Issues</b>');
for (var i = 0; i < employees.length; i++) {
$('#table_er').fadeIn('slow');
table.append(write_link(employees[i])); // function that displays the data
}
if(pages){
$('#pagination').html(pages);
}
}else{
$('#er_tab_label').html('<b>No employees with issues yet.</b>');
}
});
table.html('');
}
then this part calls the function and display another updated content
$('#refresh_btn').on('click', function(e){
e.preventDefault();
var tab = $('#tab').val();
if(tab == 'er'){
EmployeeIssues();
}
});
What should I do to display the content without any blinking effect?
thanks :-)
This section might be the issue :
if(employees){
$('#er_tab_label').html('<b>Employees with Issues</b>');
for (var i = 0; i < employees.length; i++) {
$('#table_er').fadeIn('slow');
table.append(write_link(employees[i])); // function that displays the data
}
if(pages){
$('#pagination').html(pages);
}
} else ...
It seems you're asking table_er to fade in once per run of the loop whereas s there can only be one such table, you only need to do it once ?
first try re-arringing it like this:
if(employees){
$('#er_tab_label').html('<b>Employees with Issues</b>');
$('#table_er').hide(); // hide it while we add the html
for (var i = 0; i < employees.length; i++) {
table.append(write_link(employees[i])); // function that displays the data
}
$('#table_er').fadeIn('slow'); // only do this after the table has all its html
if(pages){
$('#pagination').html(pages);
}
} else ....
Another possibility is that you're running through a loop and asking jquery to do stuff while the loop is running. It might be better to work out the whole HTML for the new page data in a string and then get the screen to render it in one line. I cna't do this for you as I don't know what's in write_link etc but something like this ..
if(employees){
$('#er_tab_label').html('<b>Employees with Issues</b>');
var sHTML ="";
$('#table_er').hide(); // hide it while we add the html
for (var i = 0; i < employees.length; i++) {
sHTML+=write_link(employees[i]); // maybe this is right ? if write_link returns an HTML string ?
}
table.append(sHTML); // add the HTML from the string in one go - stops the page rendering while the code is running
$('#table_er').fadeIn('slow'); // now show the table.
if(pages){
$('#pagination').html(pages);
}
} else ...

Block existing scripts

I am making an addon for firefox. I want to extract a video from a HTML page and display it on a black background. Here is what i've got.
//main.js
var pageMod = require("page-mod");
pageMod.add(new pageMod.PageMod({
include: "http://myserver.fr/*",
contentStyleFile: data.url("modify.css"),
contentScriptFile: data.url('hack.js'),
contentScriptWhen: 'start'
}));
//hack.js
video = document.body.innerHTML;
document.body.innerHTML = '';
video = video.substring(video.lastIndexOf("<object"),video.lastIndexOf("</object>"));
video = "<div id='fond'></div><div id='mavideo'>"+video+"</div>"
document.body.innerHTML = video;
document.body.style.backgroundColor = "black";
document.body.style.margin = "0";
My code works but the probleme is that I have to wait "for hours" while the other javascript is beeing executed. I've tried to use contentScriptWhen: 'start' but i dosent change a thing.
Any idea to block the other script of the page ?
Blocking scripts from loading is going to be a little difficult, we can quickly remove them instead.
// remove all scripts
var scripts = document.getElementsByTagName("script");
var parent = null;
for (var i = 0; i < scripts.length; i += 1) {
parent = scripts.item(i).parentNode;
parent.removeChild(scripts.item(i));
}
This code tries to remove all the script tags from your page which would stop the loading of any scripts and allows you to run the rest of your code. Put this at the top of your hack.js script.
I don't know the page you're looking at so it's hard to know what else is going on but your use of substring, and lastIndexOf aren't going to be very fast at all either. We can get rid of those and see if you get any noticible speed increase.
Try using query selectors and Document Fragments instead. Here's an example:
//hack.js
var fragment = document.createDocumentFragment();
var objects = document.getElementsByTagName("object");
// create your div objects and append to the fragment
var fond = document.createElement("div");
fond.setAttribute("id", "fond");
fragment.appendChild(fond);
var mavideo = document.createElement("div");
mavideo.setAttribute("id", "mavideo");
fragment.appendChild(mavideo);
// append all <object> tags to your video div
for (var i = 0; i < objects.length; i += 1) {
mavideo.appendChild(objects.item(i));
}
// clear and append it all in
document.body.innerHTML = '';
document.body.appendChild(fragment);
That code throws all the objects into a document fragment so you can wipe the whole page away and then append it all back in; no libraries required. Your divs fond & mavideo are in there as well.
I didn't really test all this code out so hopefully it works as expected.

JS - print only <div> from another file

Now I'm using onClick="window.print(); return false;"...
But I need to print a div content form another file.
Example:
I have the file buttons.html, but in this file is my print button with window.print().
I need when this button is pressed to print only div content (e.g. div id=...), but from the file index.html.
I hope you understand me.
*Please give more detailed code, I'm new.
Thanks!
function printDivs()
{
var divs = document.getElementsByTagName("div");
var text = "";
for( var i=0; i<divs.length; i++ )
{
var div = divs[i];
if (typeof(div.nodeName) !== "undefined")
{
text = text + div.innerHTML + "<br /><br />";
}
}
document.body.innerHTML = text;
window.print();
}
That should work, as long if its executed on the same page. Is this what you mean or do you mean something else?
You can call this script by using: Print for example.
That's unusual, but certainly possible:
// buttons.html, Using jQuery
$('button').click(function() {
$.get('index.html', function(h) {
$('body').html($('div#content', h).html());
window.print();
}, "html");
});

Categories

Resources