Load PDF inside a Bootstrap Accordion - object

I have been trying to load some PDFS that will show inside a Bootstrap accordion. The problem is that they load in a lot of different ways depending on the browser. I've been trying iframe and object html tags with different results and i have a huge flow in Safari where the accordion functionality breaks completely when i embed a PDF inside a panel.
So i guess my question is: Is there any sort of standard regarding crossbrowsing in order to make embeded PDF'S work in Chrome, Safari, IE11 and Firefox ?
Since i need this to work on mobile the situation is even worst. Some advice will be really appreciated.

Create a canvas element with the class "panel-body" and give it an id of your choosing. Then add the following code to your document ready event.
PDFJS.getDocument('YOURPDF.pdf').then(function(pdf) {
pdf.getPage(1).then(function(page) {
var scale = 1;
var viewport = page.getViewport(scale);
var canvas = document.getElementById('pdfOne'); // The id of your canvas
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
});
});
That will get the first page rendered. You'll need to create buttons to let the user navigate through the document but it should be easy enough to get that working based on what I've provided and the samples.

Related

Google Analytics Tracking Code Causing Slow Down of Iframe-Resizer?

I have an iframe with dynamic content inside that needs to be displayed on a page and I'd like it to show as quickly as possible. However, there seems to be some lag between when the content of the iframe is loaded and when the iframe is resized on the host page. Currently, the initial dimensions of the iframe are height = 0 and width = 100% so that when the content is loaded in the iframe, iframe-resizer will automatically adjust it to the correct height.
However, I noticed that if there is an autoplay video within the iframe, I can hear the audio for as long as a minute before the iframe will get resized. When checking the browser console, I'll see warning messages of iframe-resizer being unresponsive, but after a minute or so, the iframe will get resized and the content will be revealed.
I have a google analytics tracking code within the iframe content and noticed that if I removed it, the iframe-resizer becomes much more responsive and the content gets loaded quicker. How can I get the iframe to act responsive with the google analytics tracking code running inside of it? How can I get the iframe-resizer to work before the GA script finishes loading?
Also, is setting the initial iframe height to 0 and then allowing iframe-resizer to size the frame the proper way to initially load dynamic iframe content?
edit (adding code):
here's the code i run on the host page
var hzframe = iFrameResize({
checkOrigin: false,
initCallback: function(){
var x = document.getElementsByClassName("hzload");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
},
resizedCallback: function() {
var x = document.getElementsByClassName("hzload");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
}
},".hzframe");
if you want to see the whole thing in action you can check out this jsfiddle
Currently, I have the same code that hides the loading gif in the initCallback and resizedCallback because the gif doesn't always get hidden by the initCallback.
If your just hosting a video in your iFrame then this might work better for you.
https://css-tricks.com/NetMag/FluidWidthVideo/Article-FluidWidthVideo.php
The issue with GA is very strange, can you defer it running if it is blocking the page load event firing?

Issue in scraping with cheerio

I have been trying to scrape 10 websites for a website we are building with links to the original sites, on node.js using cheerio, problem we are getting is that some of the sites have changed which now uses ajax calls to bring their data, my question is how can we get that information, for instance trigger a button click first and then get the DOM.
secondly: same dom structure is not getting me all data, it is retrieving information for one page, but not getting the the elements on another page with identical DOM structure. any help would be appreciated.
Thanks and regards.
Edit 1: Relevant code
$('#ProductContent').filter(function(){
var price = undefined;
var ukulele = false;
var model = $(this).find('.ProductSubtitle').text().replace(/\n\s*/g,"");
if(model.indexOf(/m/i) != 0){
var description = $(this).find('.RomanceCopy').text().replace(/\n\s*|\r/g,"");
.
.code removed for brevity and the variables present here are populated
.
//this children is populated only for one page.
children = $(this).find('.SpecsColumn .SpecsTable table tbody').children('tr');
console.log('children: '+children.length)
console.log(guitar_url);
children.each(function(){
var key = $(this).children('td').first().text();
var value = $(this).children('td').last().text();
specs[key] = value;
console.log(specs);
});
Edit 2: Cherios Initialization
request(guitar_url,function(error,response,html){
if(!error){
var $ = cheerio.load(html);
$("#content #right-content").filter(function(){..children and other variables are populated inside here....})
}
})
To summarise all the comments you received:
Cheerio is minimalistic DOM reader inspired by jQuery. Its design is focused about reading data, and is not a browser emulator, where you could click a button.
Alternative is to use headless browsers like PhantomJS or CasperJS.
Those two are outside of Node.js scope, and you may have hard times transmitting the data back and forth from Node.js to headless browser.
If it is important for you to keep inside of Node.js environment, then you can use JSDOM.
All of them are more complicated to use than Cheerio, but if you want to manipulate the DOM, execute JavaScript on the DOM, etc... Then this is your best bet.
Removing the 'tbody' tags solved the problem, once they were removed it started to fetch the data normally for all three sites.

Creating an SVG Document in SVG.js issue?

I am new to SVG.js and javascript in general, and I was going over the documentation here http://documentup.com/wout/svg.js#usage/svg-document and was having some issues.
Usage
Create a SVG document
Use the SVG() function to create a SVG document within a given html element:
var draw = SVG('drawing').size(300, 300)
var rect = draw.rect(100, 100).attr({ fill: '#f06' })
so I was assuming from this they want us to call a function so what I've gathered from messing around a little in Three.js is that I need to do
<script>
function SVG()
{
//Use the SVG() function to create a SVG document within a given html
var draw = SVG('drawing').size(300, 300)
var rect = draw.rect(100, 100).attr({ fill: '#f06' })
}
</script>
within the body tag. This doesn't work however. When calling SVG(); I get an error
Uncaught RangeError: Maximum call stack size exceeded (15:22:47:898 | error, javascript)
at SVG (:18:13)
at SVG (:20:12)
at SVG (:20:12)
at SVG (:20:12)
at SVG (:20:12)
at SVG (:20:12)
There are other ways I can do it as mentioned, but it seems that the easiest method would be to call a function, but again I'm not sure if I'm doing this correctly.
I have a background in Java, just getting off of a project with JMonkeyEngine, so I'm not new to programming, but confused with what exactly I need to do with this, since the documentation is extremely vague and seems to suggest that you need to understand their terminology as to where to put the code.
I have also found a few other librarieslike snap.svg, d3, and raphael
http://d3js.org/
raphaeljs.com/
snapsvg.io/
I'm really just trying to create a bunch of pictures/colored boxes (interchangable so essentially a box with an image that can then be turned off and be displayed as a color) with borders, that can respond to mouse even of clicking and dragging around on desktop and mobile browsers. Essentially not much, but it seems like these all have similar features just a different coding feel.
Any advice?
Thank you everyone!
As said by Nils, there is a Hello World example here: https://stackoverflow.com/tags/svg.js/info
You also find plenty of documentation and examples to see what you have to do.
//Use the SVG() function to create a SVG document within a given html
var canvas = SVG(idOfElement)
// now an svg was created in the element with the id
// draw a rectangle
canvas.rect(100,100)

Create custom view for Spotify playlist

I'm trying to create a custom view for a spotify playlist. right now I create a playlist view in my app using the following:
var playlist = models.Playlist.fromURI(myPlaylist);
var playerView = new views.Player();
playerView.track = playlist.get(0);
playerView.context = playlist;
var cover = playlist.get(0).data.album.cover;
$('#grid').append(playerView.node);
The default spotify playlist view has the album compilation for the art, and clicking on the playlist also provides direct access to the playlist. I'd like to change this so that I can set the playlist art to the cover variable above (or other custom image), and restrict the hyperink so that it doesn't access the playlist but only initiates play/pause.
I tried to edit the node innerHTML directly but then the playlist doesn't actually begin playing either. Is there an easy way to either edit the default spotify view or is there available sample code for creating a custom view?
If it's just in the app itself, you can override CSS and HTML of the player. Here is how I did :
First in the CSS :
.sp-image-loaded { opacity: 0; }
In the HTML :
player.node.firstChild.style.backgroundImage = "url(myimage.jpg)";
Hope, it's working for you.

Spotify App API: tab pages, playlist UI refresh

I am building a Spotify App with four tab pages. The content of all tabs are loaded on initial load of the app. Each tab contain one or more playlists that are being populated with data from 3rd party web apis that are resolved into spotify tracks.
The selected tab works fine. the playlist show up a expected. The problem is with tabs that are initially hidden but later selected. Here the playlist looks like this when selected:
not fully rendered playlist
Looking in the Inspector I can see that the content has not yet rendered:
<div class="sp-list sp-light" tabindex="0">
<div style="height: 100px; ">
</div>
</div>
When I do a resize of the Spotify desktop app, the playlist is finally rendered:
rendered playlist after resize
To populate the playlist I use the 'standard' spotify models and views:
var playlist = new views.List(tempPlaylist);
//where tempPlaylist is a new models.Playlist();
//that has been populated with tempPlaylist.add(search.tracks[0].uri);
playerPlaylistDiv.append(playlist.node);
I am only seing this issue when using tabs. When displaying all content on one long page all playlists are fully rendered. I wonder if it has to do with timing: that I am hiding content that has not yet fully rendered? Any thoughts much appreciated.
I handle tab changes this way:
/* Handle URI arguments */
models.application.observe(models.EVENT.ARGUMENTSCHANGED, tabs);
/* Handle tab changes */
function tabs() {
var args = models.application.arguments;
// Hide all sections
$('section').hide();
// Show current section
$("#" + args[0]).show();
}
FYI I am using the Spotify preview 0.8.10.3.
I am not sure this is the same thing, but I ran into similar issues trying to create tracklistings from playlist-uris on the fly; also couldn't track it down any closer (the containing DOM was certainly rendered and ready); and it only happened on certain playlists, never e.g. on albums.
I was able to circumentvent this problem by "cloning" playlist - obviously there's a "performance" hit ...
// assuming uri is the playlist's URI
models.Playlist.fromURI( uri, function(originalPlaylist) {
var tempPlaylist = new model.Playlist();
$.each(originalPlaylist.tracks, function(t) { tempPlaylist.add(t); });
var tracklist = new views.List(tempPlaylist);
// etc...
}
I am not sure what's on here, but maybe that helps you along :)
PS. Also - make sure you have a doctype-declaration in index.html (), the spotify client does some weird things if you don't.
The solution I've found is this:
I arrowed it down to being an issue with showing/hiding the content since showing the full content without tabs never causes issues. So instead of using .show()/.hide() I now hide and show the content by setting the height of the sections to 100%/0:
// Hide all other sections
$("section#" + args).siblings().height('0');
// Show current section
$("section#" + args).height('100%');
Not sure why this works, but it does (for me at least).
I had the same problem (see Spotify List objects created from localStorage data come up blank) and fixed it by doing the hide()/show() of divs before any processing. Previously I was constructing the playlist and then show()ing the div after which led to a blank list.
I think I've actually managed to solve this and I think it's bulletproof.
Basically I was trying to solve this by trying to convince the API that it needed to redraw the playlist by hiding things/scrolling things/moving things which worked occasionally but never consistently. It never occurred to me to change the playlist itself. Or at least make the API think the playlist has changed.
You can do so by firing an event on the Playlist object.
var models = sp.require('$api/models');
...
// playlist is your Playlist object. Usually retrieved from models.Playlist.fromURI
playlist.notify(models.EVENT.CHANGE, playlist);
These are just standard Spotify functions and the list updates because it thinks something has changed in the playlist. Hope this helps someone!

Resources