Embedding dynamically an object with javascript - javascript

I'm trying to dynamically add an embed code into an HTML page at run time using javascript, but when I add it nothing is shown.
The object I want to embed is a report from Tableau Server. If I put the code directly in the HTML page is correctly displayed (you can try yourself uncommenting the div static-container in the fiddle), but if I use javascript to add the report it fails:
document.getElementById('dynamic-container').innerHTML ='<div class="tableau-report-viewer">' + decodeURIComponent(data[0].TableauCode.replace(/\+/g, '%20')) + '</div>';
After running the above script I can see that the code is correctly added to the DOM.
Please note that the function is called after an ajax call has retrieved the data object (stored as a js variable in the example). The DOM is fully loaded when the function is called.
here is the jsfiddle: https://jsfiddle.net/1mknywt5/

The tableau script will not load when you use update the innerHTML of the div, because the browser tries to prevent a cross site scripting attack. You have to preload the script, and then you code will work (You may also want to remove the script tag from the json). In your example it will be something like this:
<script type='text/javascript' src='https://analytics.wfp.org/javascripts/api/viz_v1.js'></script>
<h2>Hello world</h2>
<div id="dynamic-container"></div>
<hr/>
You will find a better explanation about why you cannot inject tags using innerHTML in the following link under Security Considerations section:
https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML

Related

cURL returns full HTML via AJAX - how to display to user?

I am building a Wordpress plugin to display a list of jobs to a user pulled from a recruiting platform API. On click of a job, a cURL request is sent to the API that pulls the job details as a full HTML page (the online job advertisement). I have everything working fine in terms of pulling the HTML, but I cannot figure out how to display it to the user.
How can I either:
Open a new tab to display the HTML pulled from the AJAX request
or
Open the full HTML within a div on the same page (i.e. a modal)
I would prefer to open the HTML in a new page, but don't know how to use jQuery to do this... Opening within the page in a modal is also fine, but as far as I understand iFrames (which I would rather not use anyway), you have to pass a url (and I simply have the full markup). Is there a way to display this within a page, perhaps using canvas? It carries its own links to CSS and Javascript that need to apply only within that sub-page.
EDIT:
As a clarification, I know that I can simply place the HTML within the page. My issue is that it is a full page. This means it has a <head> <body>, and its own CSS links. Just putting it in the page messes with the rest of the CSS and produces invalid HTML.
This is what I already have:
$.post(ajaxurl, data, function(response) {
$('.sg-jobad-full').html(response);
});
It places the response within the page perfectly well... but it messes up the page by introducing a <body> within a <body> and competing CSS.
If you put the response in a <div>, it will mess the markup because css/js/meta definitions may not be put into the <body>.
If there is a way to retrieve the data without the markup already beeing in, you could parse the data and let it print via a javascript, which is the method I'd prefere.
According to your comment, you should really go with iframes, all other methods will alter your markup to have <html> tags inside <html>, which is very bad practice.
Iframes can be styled just like a <div> element, and it is realy not dirty to use iframes for the purpose you mentioned (it does not load from a foreign host, it is not hidden, it does not track).
<iframe class="job-offers-plugin" src=".../wp-content/plugins/yourplugin/getJobs.php">
</iframe>
Put some style into it like width;height;padding;margin;overflow; place it where you like..
This helps you with the databse:
Using WPDB in standalone script?
Add permalinks to your plugin script:
http://teachingyou.net/wordpress/wordpress-how-to-create-custom-permalinks-to-use-in-your-plugins-the-easy-way/
If you get the full HTML in an jQuery.ajax(...) call, you can always just show it in a certain div on your page.
$.ajax({
success: function (resp){
// resp should be your html code
$("#div").html(resp);
}
});
You can use the $(selector).html(htmlCode) everywhere you want. You can insert it into modals, divs, new pages...
If you have to inject a whole HTML page you can:
strip the tags you don't need
or
use an iframe and write the content to that iframe: How to set HTML content into an iframe
iframes aren't my favourite thing... but it's a possibility

Javascript: running OnLoad code without access to <body> or <head>?

I'm modding a web page that's generated by a third party project. The project essentially does something like this when your browser requests a page (pseudocode):
<?php
include: project's fixed library INCLUDE's
include: my freeform php code
?>
(project's fixed HTML <head>...</head> and <scripts/> sections)
(project's fixed HTML <body> tag and page header + frames)
(my freeform php/HTML code)
(project's fixed HTML footer, frame closures, and </body> tag)
The page contains form elements and HTML that's generated and filled in by php based on $_GET/$_POST. My HTML contains "OnChange=ValidateItems();" for most fields; when the user changes data on the page, error messages will appear inline if relevant.
What I want is to also trigger "ValidateItems();" after the page loads, when the initial user-provided values are set up in the HTML ready for the user. But I don't have access to usual or placements due to the above loading structure. I'm wondering how else to make it happen.
One option I was thinking was to add a tiny invisible frame/frameset/iframe or other object that does support onload and isn't reliant on the or tags, and 'bootstrap' myself from an onload= call of that, to then manually add onload to the body, or hook the usual onload event somehow, in order to call ValidateItems() once at the right time, then exit the snippet once it's set up or done. I have no idea what the best way to do this - how I'd initially get any code to execute, what I'd then hook or modify etc so it happens appropriately (not too early or late); this is leagues past me technically. Help and example code would be very much appreciated.
Add this somewhere inside your 'freeform html' code:
<script>
window.onload = ValidateItems;
<script>

Load pages via AJAX and execute javascript and CSS

I've been searching for a while now, but I can't figure out how to load an entire page via AJAX and still execute all javascript and css.
Mostly I just end up with the plain text without any CSS.
Is there a way to do this? I tried jQuery.get, jQuery.load and jQuery.ajax, but none really work like that.
I have a different solution. You may try it with an iframe. Use jQuery to append an iframe script including all relevant codes into some part of your page (like some div). This may do it for you including CSS, like;
$('<iframe src="your_page.html"/>').appendTo('#your_div');
Or you may try something like;
$('<iframe src="your_page.html"/>').load(function(){
alert('the iframe is done loading');
}).appendTo('#your_div');
I have solved similar problem as following.
Download the webpage over ajax
Iterate it over and find any <script> and </script> tags
Get content from within these tags as text
Create new <script> element and insert there the code
Append the tag to your webpage
Another thing is you will need to somehow call the script..
I have done it this way:
I set standardized function names like initAddedScript callback which I am calling after appending the script to the page. Same as I have deinitScript called when I do not need the code (and its variables,..) anymore.
I must say this is awful solution, which likely means you have bad application architecture so as I have had:)
With css is it the same, but you do not need any handlers. Just append the style tag to your documents head.
If the page you load doesn't have any style data, then the external stylesheets must have relative paths that are not correct relative to the invoking document. Remember, this isn't an iFrame - you aren't framing an external document in your document, you're combining one document into another.
Another problem is that loading your complete page will also load the doctype, html, head, and body tags - which modern browsers will cope with most of the time, but the results are undefined because it's not valid HTML to jam one document into another wholesale. And this brings me to the third reason why it won't work: CSS links outside of the head section aren't valid, and the misplaced head section caused by your haphazard document-in-document collage.
What I'd do for compliance (and correct rendering) is this, which would be implemented in the Success callback:
Copy all link elements to a new jQuery element.
Copy the contents of all script in the head section
Copy the .html() contents from the loaded document's body tag
Append the link elements (copied out in step 1) to your host document's head
Create a new script tag with your copied script contents and stick it in the head too
Done!
Complicated? Kind of, I guess, but if you really want to load an entire page using AJAX it's your only option. It's also going to cause problems with the page's JavaScript no matter what you do, particularly code that's supposed to run during the initial load. There's nothing you can do about this. If it's a problem, you need to either rewrite the source page to be more load-friendly or you could figure out how to make an iFrame suit your needs.
It's also worth considering whether it'd work to just load your external CSS in the host document in the first place.
I suppose you are looking for something like this:
your page div --> load --> www.some-site.com
After a quik search the closest solution seems to be the one by "And": Load website into DIV
You have to run a web server and create a proxy.php page with this content:
Then your JQuery load() function should be like this:
$("#your_div_id").load("proxy.php?url=http://some-site.com");
NB. I have tested this solution and it should not load all the CSS from the target page, probably you'll have to recreate them. For example the image files stored on the remote server will not loaded, I suppose due to authentication policy.
You will be also able to view only the target page without the possibility to browse the target site.
Anyway I hope this could be a step forward to your solution.
Get your entire webpage as text using ajax
document.open();
document.write(this.responseText);
document.close();
OR
document.documentElement.outerHTML = this.responseText;
But you need to change the path of css and js pages in original webpage if the resulting webpage is in another directory.

Changing the content type of an iframe to xml to display xml and manipulate it through DOM

I would like to use JavaScript to do the following:
Build an XML file
display it in an iframe
manipulate the content through DOM
I'm building an XML editor and am having trouble displaying the xml in an iFrame.
this is the code that I'm using at the moment.
function previewContent(what){//changes the content of an iFrame
var tsite = document.getElementById('xmlinside').contentDocument;
tsite.open();
tsite.contentType('text/xml');
tsite.writeln(what);
tsite.close();
}
function makeXML(){
var tester = '<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\
<bookstore>test</bookstore>';
previewContent(tester);
}
without the tsite.contentType('text/xml') the iframe simply displays test.
when I check the source it's still in HTML with the added line <bookstore>test</bookstore> added and the xml version as a comment.
I would like it to display like a browser without a stylesheet. I know Safari displays it as a raw xml file if there is no formatting associated with it. This would be perfect. Is it the content type that is messing up? That's why I tried changing it but this is the wrong code. Any help would be great!
A few things to keep in mind...
1.) If it's content loaded via AJAX you will need to use the application/xml media type/mime and the first element has to have a namespace...
<div id="root_most_ajax_element" xmlns="http://www.w3.org/1999/xhtml">
<p>ajax content</p>
</div>
2.) Never use innerHTML (and frameworks as they rely heavily on innerHTML) and most especially never use it in conjunction with loading AJAX loaded content, the proprietary Microsoft method does not correctly register the DOM so you sort of see that the code is there but it's not really there thus making your code wholly unreliable at that point. If using JavaScript use the importNode method to load AJAX loaded content (instead of using an iframe, you can import it to a division element instead).
3.) You won't (and shouldn't) be able to access (X)HTML of an iframe if it's not loaded from the same domain so if it's being loaded from a third party website forget about it otherwise you could say manipulate the text and discover their information (phone, email, etc if they're signed in to something).
If you meet those three conditions you should be able to work with code as if there were no iframes or AJAX involved to begin with.

jQuery append doesn't work fully with <script> tag

Appending a script element using jquery rather than putting it in the html by hand seems to lead to very different results. For instance
snaphtml = '<script src="http:\/\/seadragon.com\/embed\/lxe.js?width=auto&height=400px"><\/script>';
$('#content').append(snaphtml);
destroys the layout of my page, but putting the script element in the page directly works fine.
I have posted a test case online:
Working example with script in html.
Broken example with script appended via jquery.
The second div should not be deleted / invisible once the silverlight object is added.
Ideas?
I would recommend you to use $.getScript method for loading external script files programmatically:
$.getScript('path/to/script.js', function() {
alert('Script loaded.');
});
The script load is made asynchronously, and as you see in the above example, you can specify a callback function that will be executed when your external file has been loaded and is ready to use.
Tristan, you will not be able to include the script you reference dynamically onto the page after it has finished loading. The external script is using document.write which will only work correctly when called before the page has finished loading. This is why your static implementation works fine, and your dynamic one tears the page apart.
You might want to put together a dummy HTML file that just has a basic HTML structure and this script in it already. Then dynamically add an iframe to your page that loads the HTML. There are even more dynamic ways to make it work with an iframe, but that would be the easiest.
Try to use $.getScript:
$.getScript("http://seadragon.com/embed/lxe.js?width=auto&height=400px");
Edit:
The provided script is using document.write, which is likely causing your problems: you cannot add it dynamically at the middle of the page. Try loading SeaDragon as shown here:
http://www.seadragon.com/developer/ajax/getting-started/
try to break script tag like
snaphtml = '</sc'+'ript>'

Categories

Resources