dojo/dijit and Printing - javascript

I want to be able to provide a button to my users to just print a particular portion of my dojo/dijit application. There seems to be a general lack of documentation and examples when it comes to printing.
For example, I have a specific dijit.layout.ContentPane that contains the content that I would like to print, but I wouldn't want to print the rest of the document. I have seen some pure JavaScript examples on the web where the node.innerHTML is read into a "hidden" iframe and then printed from there. I suspect that would work, but I was wondering if there was a more dojo centric approach to printing.
Any thoughts?

I have decided to go down the path of reading into <iframe> and printing from there, but because I am using a rendered dojox.gfx surface, a direct read from the target ContentPane to the invisible iframe did not work correctly in some browsers. So what I do is set the "src" of the iframe to a page which re-renders the diagram and then prints itself out when it is finished. In the main document it looks something like this:
<iframe id="printIFrame4" src="#" style="width: 0px; height:0px;
border: none; background: transparent"></iframe>
<button dojoType="dijit.form.Button" style="margin-top: -3px;" id="buttonPrintMap4">
Print...
<script type="dojo/method" event="onClick" args="event">
dojo.byId("printIFrame4").src = "logmap/docMap.php?id=4";
</script>
</button>
And then the page does the necessary dojo stuff to redrew the diagram and then once it is loaded it does a:
this.focus();
this.print();
Which then follows through with the printing.

One solution would be to create a print-only stylesheet while the first rule hiding everything by default:
body {
display: none;
}
Then, a second CSS rule, also in your print-only stylesheet, displays only the Dojo content pane:
#contentPaneId {
display: block;
}
The Dojo ContentPane ID needs to match what you use for #contentPaneId in the CSS.
Finally, you can instruct browsers that it's a print-only CSS file using media="print" in your link tag:
<link rel="stylesheet" type="text/css" href="printOnly.css" media="print"/>

Related

SlidesJS for JavaScript Disabled User

I am pretty new to JavaScript.
I am using SlidesJS, which works perfectly fine.
However, when dealing with JavaScript disabled users, it is kind of tricky. For JavaScript disabled users, the images will be lined up. And I don't know how to deal with it because the images are embedded in the HTML code.
<div id="slides">
<img src="http://placehold.it/940x528">
<img src="http://placehold.it/940x528">
</div>
<script>
$(function(){
$("#slides").slidesjs({
......
</script>
Is there a way to use SlidesJS still, but for JavaScript disabled user, the webpage shows one default image, and hides all the other images?
Use CSS and Modernizr, which can add a class to the HTML element if and only if JavaScript is enabled.
#slides > img + img {
display: none; // may need to make this !important
}
.js #slides > img + img {
display: block;
}
(Note that modernizr.js should be run before any other JS on the page.)
If all you want is JavaScript detection, you don't even need Modernizr -- just one line of code and the above CSS:
document.getElementsByTagName("html")[0].className = "js";
or, to be non-destructive about it:
document.getElementsByTagName("html")[0].className
= document.getElementsByTagName("html")[0].className + " js";

Styling content inserted in the Shadow DOM

I have this example:
http://codepen.io/dbugger/pen/IuDxw
Where I have an insertion point inside the Shadow DOM and I try to apply an style to it, making it disappear. But the image is still visible. I suspect there is some principle I haven't undestood propely from the Web Components.
Can someone explain me what am I doing wrong?
The trick is that the image is not, as kkemple mentioned, part of the Shadow DOM, but rather the Light DOM, which means it's not directly accessible from inside the component. It's user provided content, like the parameters passed into a class constructor in an OOP language. If at all possible, then, the user should provide their own styles to go with it.
That being said, there are definitely valid use cases where the component author wants to style user-provided content. Hiding certain parts of the user-provided markup based on attributes on the host, events (clicks), etc. is definitely one of those. In that case, wrap the <content> element in a Shadow DOM element and hide that:
<template>
<style>
.image {
display: none;
}
</style>
<div class="image">
<content></content>
</div>
</template>
http://codepen.io/anon/pen/rCGqD
On a side note: It is technically possible to apply styles directly to Light DOM elements, but be aware that in many cases this is considered leaking implementation details to the outside world. If the first solution works, use that instead.
It is not working is because your code is not in the shadow DOM, the div and image is still accessible through default styling. I forked your codepen and added the styling so you could see.
var host = document.querySelector(".host");
var template = document.getElementById( 'template' );
var root = host.webkitCreateShadowRoot();
root.appendChild( template.content );
<template id="template">
<style>
.wrapper {
display: none;
}
</style>
<div class="wrapper">
<content selector=".img"></content>
</div>
<h2>In the Shadows</h2>
</template>
<style>
img {
border: 1px solid black;
}
</style>
<div class="host">
<img class="img" src="http://placehold.it/200x275&text=1" alt="" />
</div>
http://codepen.io/kkemple/pen/euBKs
I didn't go in to why it was not creating a shadow DOM element as your JS looked correct to me but here is a great article on shadow DOM web-ponents:
http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/

JavaScript not loading in onLoad (Android webView browser issue)

My javascript does not seem to load at all when i am using android's webview but loads fine on a desktop browser
Here is my html and script under one html file:
<script>
function initialiseFields(){
var name = "John Smith";
var staffId = "9877878";
alert( 'initialiseFields' );
$("#list").append('<li><h3>Additional Information:</h3><div data-role="fieldcontain"><input type="text" name="claimTitle" id=/"textFieldJourneyFrom" value="" /></div></li>');
$('#list').listview('refresh');
}
</script>
<body onLoad="initialiseFields();">
<div data-role="content">
<ul class="ui-li" data-role="listview" id="list" data-inset="true" data-scroll="true">
</ul>
</body>
Basically trying to execute the initialiseFields that displays an alert and add some field into the listView.
The alert and the listView never gets invoked/updated.
Edit: Also, whatever list item I add via javascript, it doesnt apply the default jquery mobile css style either.
Any reason why?
Another Edit:
Solution is provided by the person i have accepted the answer, however a word of warning. if you are using a datepicker and its assets. the soltuons provided doesnt work i.e it doesnt load your JS for some strange reason:
<link href="jQueryAssets/jquery.ui.core.min.css" rel="stylesheet" type="text/css">
<link href="jQueryAssets/jquery.ui.theme.min.css" rel="stylesheet" type="text/css">
<link href="jQueryAssets/jquery.ui.datepicker.min.css" rel="stylesheet" type="text/css">
<link href="jQueryAssets/jquery.ui.button.min.css" rel="stylesheet" type="text/css">.
Also, i tried the above snippet of code by simply setting the theme and it managed to apply the theme on the text and header and background but on the actual field it does not apply it to the input field
$("#list").append('<li data-theme="c"><h3>Additional Information:</h3><div data-role="fieldcontain" data-theme="c"><input type="text" name="information" id=/"textFieldInformation value="" data-theme="c"/></div></li>');
edit 2:
Code was tested and working ok except for the theme of the input fields, however, my JS does not work at all on an android device.
When working with jQuery Mobile don't use inline javascript function initialization. Mainly because this problem could happen.
jQuery Mobile page is not a normal web page. Unlike classic web development jQuery Mobile will restyle whole page when it is initially loaded into the DOM. This will work fast on desktop browsers but it will take time to run on mobile browsers / web views (no matter is it Android or iOS). Because this restyling takes time this inline function will execute before content is full loaded/enhanced inside the DOM. This is also a reason why document ready should not be used with jQuery Mobile, because it will usually trigger before it can be useful.
To counter this problem you should use jQuery Mobile page events. They are specially created to cover page loading states from initial DOM loading up to final page show.
But to make it work you will need to change your HTML a bit. Your div with data-role="content" must be wrapped into a div with an attribute data-role="page", something like this:
<body>
<div data-role="page" id="index">
<div data-role="content">
<ul class="ui-li" data-role="listview" id="list" data-inset="true" data-scroll="true">
</ul>
</div>
</div>
</body>
For page event to work you web app MUST have data-role="page" divs.Also your data-role="page" div must have an id, we will use this id to initialize your function.
Now to make it work just initialize your function like this:
$(document).on('pagebeforeshow', '#index', function(){
initialiseFields();
});
If you want to find out more about page events read this ARTICLE, to be transparent it is my personal blog. One last thing, you need to know how jQuery Mobile handles multiple pages and javascript initialization so find more about it HERE.
You can test it here: http://jsfiddle.net/qhvne/2/embedded/result/

How to show hidden content where the contents images don't load until the content is shown?

What would be a good way to show hidden content with javascript, without having the image elements <img src="myimage.jpg"> of the hidden content load their images in google chrome or any other browsers until the content is actually shown?
hiding the content with the css rule display: none will not prevent the images from loading, and I would like to avoid using ajax calls.
EDIT 1 as discussed in the comments, a better alternative would be to use a template. As an example I picked John Resig’s Microtemplating engine:
<div id="content_container">
<script type="text/html" id="content">
<div>
<img src="..."/>
</div>
</script>
</div>
<button onclick="document.getElementById('content_container').innerHTML = tmpl('content', {});">show div</button>
See fiddle
EDIT 2
As the original poster commented, it's perfectly possible to grab the contents of a <script type="text/html"> element. Templating engine's not necessary:
<div id="content_container">
<script type="text/html" id="content">
<div>
<img src="..."/>
</div>
</script>
</div>
<button onclick="document.getElementById('content_container').innerHTML = document.getElementById('content').innerHTML;">show div</button>
First Answer
(see in edits)
To do what you want within your requirements you could have javascript write the content when you want it displayed. So you would store your HTML in a javascript string and just use script to then insert it into the page when you want it. Its not a very nice way of doing it but it would mean that it would only load images at that point.
Alternatively you could put the HTML in but have the images pointing at nothing (or a blank placeholder, etc.) and then use script to programatically populate the image sources to the correct values when you call the show function to show the page.
Which of these you choose is probably more about readability than anything else though I would favour the second approach (just tweaking the image sources).
First, define a CSS style:
.invisible {
display: none;
}
Add this class to the objects in the HTML. Then anywhere in the JavaScript, simply add or remove the class, or change the display to block or float etc. In jQuery:
http://api.jquery.com/addClass/
http://api.jquery.com/show/
EDIT:
If you don't want the image to load, then use an AJAX call instead.
http://api.jquery.com/jQuery.get/
jQuery.get('myImage.jpg', function(data) {
jQuery('.imageContainer').html(data);
});
EDIT 2:
Load the src into the img once it's needed. You could check the scroll position etc.
http://jsfiddle.net/LYMRV/
Seems like it is possible to hide content using a script tag with type="text/html", it even prevents any images and iframes from loading in the background,
for example:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
document.addEventListener('click',function(e){
if(e.target.id=='content_show'){
e.preventDefault();
document.getElementById('content_visible').innerHTML = document.getElementById('content_hidden').innerHTML;//document.getElementById('content_hidden').text also works
}
});
</script>
</head>
</body>
<img src="image1.jpg"/>
<script type="text/html" id="content_hidden">
<img src="image2.jpg"/>
<img src="image3.jpg"/>
<img src="image4.jpg"/>
</script>
Show Content
<div id="content_visible"></div>
</body>
</html>
Only thing to keep in mind is to avoid placing script tags inside #content_hidden.
Now if anyone is friendly enough to point out every flaw in this method, so that we can all benefit.

Hiding page loading

My HTML markup looks like that
<html>
<body>
<div id="loading"><img src="core/design/img/load/load.gif" /></div>
<div id="wrap"></div>
<div id="footer"></div>
</body>
</html>
I'm trying to hide whole page loading process with following solution.
CSS Rules:
#loading {
position:fixed;
left:0;
top:0;
width:100%;
height:100%;
background-image:url("img/load/tr.png");
z-index:100;
}
#loading img {position: absolute; margin-left:-110px; margin-top:-9px; left:50%; top:50%}
And Jquery
$(document).ready(function(){
$('#loading').fadeOut(500);
});
Now, the problem is page loads like that:
first ugly draft of page (for 1-2 seconds)
appears loading div
loading whole content
disappears loading div
You can see it in action
I don't understand why loading div appears after 1-2 seconds?
I want to prevent 1).
I think this is a pretty simple one.
First make sure jQuery is called in your section.
First, wrap all the content of your page (except the loading div) in a div called
<div id="content-wrapper">
CONTENT HERE
</div>
Then using CSS set:
#content-wrapper {
visibility:hidden;
}
Then just make the jQuery into a function like this:
$(window).load(function(){
document.getElementById("content-wrapper").style.visibility="hidden";
$('#loading').fadeOut(500, function()
{
document.getElementById("content-wrapper").style.visibility="visible";
});
});
and I can see you're using Nivo Slider. Me too ;)
Edit: I fixed it, now it works perfectly. (You don't need the onload event in your body tag anymore)
Check out the example here: JSFiddle
Try moving the styles for loading to be inline instead of relying on the full external css file to load. If you look at Google Chrome Developer Tools and the Network tab, or a similar tool, you'll see the content of the page loads first, as expected, but then you have to wait until the external css is loaded and downloaded, and then the referenced image in the css file is loaded. Placing the style inline should assist in getting the loading element to display as soon as it can, or at least sooner.
<div id="loading" style="position: fixed;left: 0;top: 0;
width: 100%;height: 100%;background-image: url(core/design/img/load/tr.png);z-index: 100;"><img src="core/design/img/load/load.gif"></div>
Why not start everything else inside a <div style="display: none;" id="loaded">, and then when the loading has finished use $("#loaded").fadeIn()?

Categories