Printing Charts in Internet Explorer Rendered By Angular-nvD3 - javascript

I am using Bootstrap v3.2.0 for laying out 3 graphs created using Angular-nvD3. I am trying to render the page for printing. I have some modified CSS in the #media print rule. Everything renders properly for printing in Chrome, but the charts do not resize for printing in IE 11. I have tried to trigger a window resize event in JavaScript, it executes but doesn't make any difference.
My div looks like this:
<div class="container">
<div class="row">
<div class="col-md-3 col-sm-3 col-xs-3">
<div ng-controller="BusinessPieChartController">
<h4>Business Allotment</h4>
<nvd3 options="options" data="data"></nvd3>
</div>
<div ng-controller="LocationTypePieChartController">
<h4>Location Types</h4>
<nvd3 options="options" data="data"></nvd3>
</div>
</div>
<div class="col-md-9 col-sm-9 col-xs-9">
<h4>Growth Over Time</h4>
<div ng-controller="HistoryLineAreaGraphController">
<nvd3 options="options" data="data"></nvd3>
</div>
</div>
</div>
</div>
Here is the JavaScript code I tried to no prevail.
var printTriggered = false;
var beforePrint = function () {
if (printTriggered) {
return
}
printTriggered = true;
setTimeout(function () {
printTriggered = false;
}, 2000)
var event
if (typeof Event === 'function') {
event = new Event('resize')
} else {
event = document.createEvent('Event')
event.initEvent('resize', true, true)
}
window.dispatchEvent(event)
};
if (window.matchMedia) {
var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener(function (mql) {
if (mql.matches) {
beforePrint();
}
});
}
window.onbeforeprint = beforePrint;
Here is how my graphs look from print preview in IE 11.

I shared this exact problem, although with just one graph. Ended up using duplicate elements for the graph.
First, one graph is rendered with width to match the paper size, and, once that's done, it's hidden, and another graph is shown instead:
<div class="graph-for-print"
ng-class="{rendered: vm.graphForPrintRendered}">
<nvd3 options="vm.graphOptions"
data="vm.graphData"></nvd3>
</div>
<div class="hidden-print"
ng-if="vm.graphForPrintRendered">
<nvd3 options="vm.graphOptions"
data="vm.graphData"></nvd3>
</div>
and the css
.graph-for-print {
max-width: 680px;
}
#media screen {
.graph-for-print.rendered {
overflow: hidden;
height: 0;
}
}
vm.graphForPrintRendered is true after a $timeout to ensure all digest cycles are done and the browser has had time to draw the chart.
Not pretty, but works.

Related

JavaScript change background image on-click?

I'm trying to change the background of the body on my HTML doc using some basic JS functions. I have set the function to target a specific ID, and then the style.background tag, if it is the current background image, then set it to another one I specified, else keep the same image. I have tried changing the code countless times now, but still can't seem to get it to change the background. Any help with this would be appreciated.
HTML:
<div class="bg-image"
style="background-image: url('./img/frankie.jpg');
height: 100vh" id="bacgr"> <!--SETS BACKGROUND using id tag to change w/ JS-->
<main role="main" class="container d-flex justify-content-center">
<div class="starter-template">
<h1>Bootstrap starter template</h1>
<p class="lead">Use this document as a way to quickly start any new project.<br> All you get is this text and a mostly barebones HTML document.</p>
</div>
</main>
</div>
JS:
let myImage = document.getElementById('bacgr').style.backgroundImage; //have to target specific image(like an array ([0])), put inside div w/ id.
myImage.onclick = function() {
if(myImage === "url('./img/frankie.jpg')") {
myImage == "url('./img/jesus_mobile.jpg')";
} else {
myImage == "url('./img/frankie.jpg')";
}
}
Try this:
const el = document.getElementById('bacgr');
el.onclick = function() {
if(this.style.backgroundImage === "url('./img/frankie.jpg')") {
this.style.backgroundImage = "url('./img/jesus_mobile.jpg')";
} else {
this.style.backgroundImage = "url('./img/frankie.jpg')";
}
}
Here is the example
You are changing only the URL, but that will not be assigned back to the dom element.
const el = document.getElementById('bacgr');
let prev = 'url("https://images.unsplash.com/photo-1570215171323-4ec328f3f5fa")';
el.onclick = function() {
el.style.backgroundImage = prev === el.style.backgroundImage ? 'url("https://images.unsplash.com/photo-1583508915901-b5f84c1dcde1")' : prev;
}
<div class="bg-image" style="background-image: url('https://images.unsplash.com/photo-1570215171323-4ec328f3f5fa');
height: 100vh" id="bacgr">
<main role="main" class="container d-flex justify-content-center">
<div class="starter-template">
<h1>Bootstrap starter template</h1>
<p class="lead">Use this document as a way to quickly start any new project.<br> All you get is this text and a mostly barebones HTML document.</p>
</div>
</main>
</div>

Copy original HTML code before DOM modification on button press

There is requirement where I need to copy HTML code on click of button. The functionality is not working where we are using a video tag. The video tag somehow gets formatted by brightcove. I tried using <pre> and <code> elements. Can you please suggest something.
$('.copy').on('click', function() {
var section = $(this).next().find('code').html();
var elem = document.createElement('textarea');
//elem.textContent = section;
elem.innerHTML = section;
//elem.classList.add('invisible');
document.body.appendChild(elem);
console.log(elem.innerHTML);
elem.select();
console.log("Hi");
try {
document.execCommand('copy');
} catch (e) {
console.log('ERROR: ' + e);
} finally {
elem.remove();
}
});
<div class="ply-item-ratio-content">
<!-- Start of Brightcove Player -->
<div class="parbase brightcovevideo section">
<div style="margin-bottom: 0;margin-left: 0;margin-right: auto;margin-top: 0;overflow-x: hidden;overflow-y: hidden;text-align: center;width: 1025px;text-align:left; height: 560px;">
<div id="25efba484"> </div>
<script type="text/javascript" src="/etc/polycom/www/global/js/thirdparty/BrightcoveExperiences_embedded.js"></script>
<script>
customBC.createVideo("1000", "567", "4223245001", "cd~~,AddB-EKwxDE~,eUqCcdvdv7u6CqAyJC", "4435446654001", "2768ede1a35dsgfdgffba484");
</script>
</div>
</div>-->
<!-- End of Brightcove Player -->
</div>
</div>
<div class="ply-global-video-description">
<h2>NATO Communications and Information (NCI) Agency Success Story</h2>
<p>Centro to create a relaxed working environment that draws teams closer together and enables better sharing of ideas and insights.</p>
</div>
</div>

jQuery .wrap .unwrap responsive

Forgive me, I am fairly new to javascript. I am trying to remove a div's parent below 980px wide and then add it back in above 980px. I am using the following code that I have put together from looking at other jQuery.
jQuery(window).resize(function () {
var Tags = jQuery( ".case-studies .items-row div.span4" );
var wi = jQuery(window).width();
if (wi < 980) {
if ( Tags.parent().is( "div.items-row.cols-3.row-0.row-fluid" ) ) {
Tags.unwrap();
}
} else {
(Tags.wrap.parent( "<div .items-row.cols-3.row-0.row-fluid></div>" ));}
});
I'm guessing you will realise I am experiencing a few issues!
The jQuery doesn't apply below 980px on page load, however when you start with a large screen size and shrink the width below 980px the jQuery works.
Once the jQuery has fired and the screen size goes above 980px, the div that has been removed does not get reapplied.
Please explain where I have gone wrong as I would like to learn.
Thanks for your time
UPDATE
The html before any jQuery is:
<section>
<div class="items-row cols-3 row-1 row-fluid">
<div class="span4"></div>
</div>
</section>
With the following jQuery:
jQuery(window).load(function () {
var Tags = jQuery( ".case-studies .items-row div.span4" );
var wi = jQuery(window).width();
if (wi < 980) {
if ( Tags.parent().is( "div.items-row.cols-3.row-0.row-fluid" ) ) {
Tags.unwrap();
}
}
else {
Tags.wrap( "<div></div>");
}
});
This now occurs above 980px on page load:
<section>
<div class="items-row cols-3 row-1 row-fluid">
<div>
<div class="span4"></div>
</div>
</div>
</section>
And when i refresh the page below 980px:
<section>
<div class="span4"></div>
</section>
The result below 980px is correct, however only runs when i refresh the screen. The result above 980px is not my intended result, i would like it to remain or return to:
<section>
<div class="items-row cols-3 row-1 row-fluid">
<div class="span4"></div>
</div>
</section>
#1: Call the function once on page load, that way you don't need to resize to get it
#2:
else {
(Tags.wrap.parent( "<div .items-row.cols-3.row-0.row-fluid></div>" ));}
should be
else {
(Tags.wrap( "<div .items-row.cols-3.row-0.row-fluid></div>" ));}

Each not encapsulating blocks

I'm building a site that dynamically positions content in the middle of a group of sections.
Div with image background (Full width image - FWI)
Div with image background (of different height)
My problem is even with the each selector the first div is used to dictate the height to any other divs below it, I'm obviously missing something pretty basic
Jquery
jQuery(window).on("resize", function() {
jQuery('.fwi').each(function() {
jQuery('.image-outer').height(jQuery('.fwi-image').height());
});
}).resize();
jQuery(".fwi-image img").load(function() {
jQuery('.fwi').each(function() {
jQuery('.image-outer').height(jQuery('.fwi-image').height());
});
});
HTML
<div class="fwi">
<div class="relative">
<div class="fwi-image full-width">
<img width="1920" height="1080" src="">
</div>
<div class="outer image-outer" style="height: 1080px;">
my content which is dynamically positioned in the center vertically in my div
</div>
</div>
</div>
<div class="fwi">
<div class="relative">
<div class="fwi-image full-width">
<img width="1920" height="1200" src="">
</div>
<div class="outer image-outer" style="height: 1080px;">
will take height from previous image-outer not its parent - it should be 1200
</div>
</div>
</div>
Place this in you document.
function adjustImageOuterHeight () {
var fwiImage = jQuery(this).parent(".fwi-image");
var imageOuter = fwiImage.next(".image-outer");
imageOuter.height(fwiImage.height());
}
jQuery(document).ready(function () {
jQuery(".fwi-image img")
.load(adjustImageOuterHeight)
.each(function () {
if (this.complete) adjustImageOuterHeight.call(this);
});
});
jQuery(window).resize(function () {
jQuery(".fwi-image img").each(adjustImageOuterHeight);
});
Loose any other jQuery stuff related to .fwi-image. And optionally loose your explicit call to .resize() on the window object.

How can I create custom scrollbar (jScrollPane) with knockout binding?

I have an observableArray for insert message. I want to display all messages using knockout. I want to use a custom scrollbar graphic - jScrollPane. (plugin LINK)
How can I fix my example for display custom scrollbar from jScrollPane?
Example: http://jsfiddle.net/aZpgY/3/
HTML:
<h2>Chat with knockout binding</h2>
<div id="chat-content" data-bind="foreach: messages">
<div data-bind="text: messageText"></div>
</div>
<br />
<form data-bind="submit: sendMessage">
message: <input data-bind="value: message" placeholder="Insert your massage" /><br />
<button type="submit">Add</button>
</form>
<h2>Example content - without knockout binding</h2>
<div id="example-content">
<div>Text</div>
<div>Text</div>
<div>Text</div>
<div>Text</div>
<div>Text</div>
<div>Text</div>
<div>Text</div>
<div>Text</div>
</div>
CSS:
#chat-content, #example-content{
width: 300px;
height: 100px;
overflow: auto;
}
JS:
function Message(data) {
this.messageText = ko.observable(data.messageText);
}
function ChatViewModel() {
// Data
var self = this;
self.messages = ko.observableArray([]);
self.message = ko.observable();
// Operations
self.sendMessage = function() {
self.messages.push(new Message({ messageText: this.message() }));
self.message("");
};
self.removeTask = function(task) { self.tasks.remove(task) };
}
ko.applyBindings(new ChatViewModel());
$(function(){
$('#chat-content').jScrollPane();
$('#example-content').jScrollPane();
});
Create a custom binding handler to initialize and update the jScrollPane instance:
ko.bindingHandlers.jScrollPane = {
init: function(element, valueAccessor) {
var o = valueAccessor() || {};
// initialize
$(element).jScrollPane(o.options);
var reinit = function() {
var scroll = $(element).data("jsp");
if (scroll) {
scroll.reinitialise();
}
};
// handle window resize (though not really necessary if your chat box has a set pixel width)
$(window).resize(reinit);
// add subscription to observable if passed in
if(o.subscribe) {
o.subscribe.subscribe(function() {
// use setTimeout so the DOM finishes updating before reinitialising
setTimeout(reinit, 0);
});
}
}
};
Call the new jScrollPane handler on the #chat-content div, passing in the messages observable so it knows when to refresh the scroll bar. Put the foreach binding handler in a child element to prevent it from interfering with the DOM changes that jScrollPane makes.
<div id="chat-content" data-bind="jScrollPane: { subscribe: messages }">
<div data-bind="foreach: messages">
<div data-bind="text: messageText"></div>
</div>
</div>
JSFiddle: http://jsfiddle.net/aZpgY/7/
jScrollPane binding handler adapted from here: http://jsfiddle.net/rniemeyer/NgNvf/

Categories

Resources