IE Issue: Submitting form to an iframe using javascript - javascript

I was trying to create an iframe element using javascript, like so:
var iframe = document.createElement('iframe');
iframe.setAttribute('name', 'frame_x');
However, when I tried submitting a form using the newly-created iframe as target, IE opens up a new window, instead of using the iframe.
form.setAttribute('target', 'frame_x');
form.submit();
This works perfectly in Firefox. Also, the iframe gets created, but is not used.

You've hit a bug in Internet Explorer.
You CAN NOT set the name attribute of ANY element in IE using the standard DOM Method .setAttribute('name', value);
In IE (before version 8 running in IE8 standards mode) this method will not work to set the name attribute.
You need to use one of the following:
//A (any browser)
var iframe = document.createElement('iframe');
iframe.name = 'frame_x';
//B (only in IE)
var iframe = document.createElement('<iframe name="frame_x"/>');
//C (use a JS library that fixes the bug (e.g. jQuery))
var iframe = $('<iframe name="frame_x"></iframe>');
//D (using jQuery to set the attribute on an existing element)
$('iframe:first').attr('name','frame_x');

Welcome to SO.
One issue I saw in your code is that you're never actually displaying the iframe. In order for it to appear on the page, you have to insert it into your document. In my example, I create a <span> tag to act as the slot where the iframe will get inserted.
See if this does what you're looking for.
<!-- http://stackoverflow.com/questions/2181385/ie-issue-submitting-form-to-an-iframe-using-javascript -->
<html>
<head>
<script type="text/javascript">
function submitFormToIFrame(){
var form=document.getElementById('myform');
form.setAttribute('target', 'frame_x');
form.submit();
}
</script>
</head>
<body>
<h1>Hello Erwin!</h1>
<form id="myform" name="myform" action="result.html">
<input type="button" value="Submit the Form" onClick="submitFormToIFrame();">
</form>
<span id="iframeSlot">
<script type="text/javascript">
var iframe = document.createElement('iframe');
iframe.setAttribute('name', 'frame_x');
document.getElementById('iframeSlot').appendChild(iframe);
</script>
</span>
</body>
</html>
UPDATE:
I found that this solution is only working in Firefox. So I did some experimenting. It seems that if you define the iframe in the html (instead of generating it via JS/DOM) then it works. Here is the version that works with IE and Firefox:
<html>
<head>
<script type="text/javascript">
function submitFormToIFrame(){
//IE
if( document.myform ){
document.myform.setAttribute('target','frame_x');
document.myform.submit();
//FF
} else {
var form=document.getElementById('myform');
form.setAttribute('target', 'frame_x');
form.submit();
}
}
</script>
</head>
<body>
<h1>Hello Erwin!</h1>
<form id="myform" name="myform" action="result.html" target="">
<input type="button" value="Submit the Form" onClick="submitFormToIFrame();">
</form>
<span id="iframeSlot">
<iframe name="frame_x">
</iframe>
</span>
</body>
</html>

function sendForm(idform){
var nfi = "RunF"+tagRandom();
$("body").append("<iframe name=\""+nfi+"\" id=\""+nfi+"\" class=\"runAgents\" src=\"#\"></iframe>");
$("#"+idform).attr("target",nfi);
$("#"+idform).submit();
}

To continue #scunliffe’s answer, if using Prototype.js:
var iframe = Element('iframe', {name: 'frame_x'});
which works because this helper function detects HAS_EXTENDED_CREATE_ELEMENT_SYNTAX for IE, working around the .name = … bug.

Related

button onclick function is not called

I'm making a webpage and when a button is clicked, it will delete every element inside the HTML element and append an iframe. Although, it doesn't seem to be working.
index.html:
<html id="html">
<head>
<script type="text/javascript" src="/freevpn/script.js"></script>
</head>
<body>
<input type="text" id="input" value="https://">
<button onclick="submit()">Go!</button>
</body>
</html>
script.js:
function submit() {
var submit = document.getElementById("submit");
var input = document.getElementById("input");
var iframe = document.createElement("iframe");
var html = document.getElementById("html");
iframe.setAttribute("src", input.value);
html.innerHTML = "";
html.appendChild(iframe);
iframe.requestFullscreen();
}
I'm not sure why this isn't working, but it has to be something. Thanks in advance!
NEW UPDATE: There were a few problems. It is linking to the javascript, I fixed the function, and I added parenthesis, but it doesn't seem to be updated in the browser. I've cleared my cache and everything, and it still isn't updating. My website is linked through Freenom, Cloudflare, Google Analytics and Search Console, so does it just take a while to update? And if so, is there a way to make it faster?
Try this, you are calling the function incorrectly.
You must use the () to call a function:
<button onclick="submit()">Go!</button>
function submit() {
var submit = document.getElementById("submit");
var input = document.getElementById("input");
var iframe = document.createElement("iframe");
var html = document.getElementById("html");
iframe.setAttribute("src", input.value);
html.innerHTML = "";
html.appendChild(iframe);
iframe.requestFullscreen();
}
<html id="html">
<head>
<script type="text/javascript" src="/freevpn/script.js"></script>
</head>
<body>
<input type="text" id="input" value="https://www.youtube.com/embed/_70Q-Xj3rEo">
<button onclick="submit()">Go!</button>
</body>
</html>
You are missing the parentheses when you are calling your JavaScript function. Try the below:
<button onclick="submit()">Go!</button>
Here is a handy reference for the onclick Event: https://www.w3schools.com/jsref/event_onclick.asp
Also it is a good idea to call put your <script> tag at the bottom of the body (i.e. below the button in your code snippet). This is because the Javascript file will be loaded first and the HTML elements may not have been created yet that you are accessing with the DOM.

Google Extension to Fix Webpage

I'm trying to write a chrome extension to fix a webpage. I don't have access to change the webpage or I would.
The HTML elements that are breaking the page don't have IDs, but NAMEs. However, looking at the javascript, it's doing a multiple document.getElementById() calls using NAMEs. This works fine in IE, but not Chrome or Firefox.
My idea is to write a Chrome Extension to insert the needed element IDs. Is this possible?
background.js:
var dateChange = document.getElementsByName('DateChange');
dateChange.id = 'DateChange';
mainpage.html:
<html>
<head>
<script>
function do_stuff()
{
var elem = document.getElementById('DateChange');
// do some more stuff
}
</script>
</head>
<body>
<form name="myForm">
<input type="hidden" name="DateChange" value="false" />
</form>
</body>
</html>
You should be able to use attribute selectors such as
input[name="DateChange"] { color: red }
Also see the relatively new document.querySelector and document.querySelectorAll calls.
I must have been doing something wrong before when trying to set the IDs. However, I have found the following to work for my purposes:
var myForm = document.getElementsByName('myForm')[0];
var elLength = myForm.length;
for (i=0; i<elLength; i++)
{
myForm.elements[i].id = myForm.elements[i].name;
}

Cross domain iframe src changes

I have an application which contains an iframe. I can modify the contents of the iframe, but not the whole page itself, e.g.:
<html><head></head>
<body>
<iframe>
<!-- my code -->
</iframe>
</body></html>
I have a requirement in which I need to change contents of the iframe to a different page (possibly on a different domain) and go back. Currently I do it like this:
The first page (it is inside the iframe executionPanelApplications):
<html>
<head>
<script type="text/javascript">
function replaceIFrameUrl() {
var doSubmit = "<c:out value='${param.doSubmit}'/>";
if (doSubmit == 1) {
document.forms['testForm'].submit();
}
else {
var adfUrl = "<fuego:fieldValue att='instJs.adfUrl' onlyValue='true'/>";
var bpmSrc = parent.document.getElementById('executionPanelApplications').src;
var bpmSrcParams = bpmSrc.split('&');
var activityId = (bpmSrcParams[1].split('='))[1];
var url = adfUrl +"&actionType=0&activityId="+activityId;
parent.document.getElementById('executionPanelApplications').src = url;
}
};
</script>
</head>
<body onload="replaceIFrameUrl();">
<form method="post" id="testForm" name="testForm" />
</body>
</html>
The second page (it should be inside the iframe executionPanelApplications as well):
<script>
function leave(e) {
var iframe = parent.parent.document.getElementById("executionPanelApplications");
iframe.src = url;
};
</script>
If both sites are in localhost it works like a charm. Unfortunatelly if they are in different domains - the second page is opened in a new window. Tested in ie 8. As i said - i can't change the contents of the page that contains the iframe. I can only work from inside the iframe. I need this to work only in ie.
Any ideas?
I would not use iframes, because there are different security restrictions (cross domain communication)
But I think, this one can help you: http://softwareas.com/cross-domain-communication-with-iframes

Open a new browser window/iframe and create new document from HTML in TEXTAREA?

I'm trying to write a web application using the new offline capabilities of HTML5. In this application, I'd like to be able to edit some HTML—a full document, not a fragment—in a <textarea>, press a button and then populate a new browser window (or <iframe>, haven't decided yet) with the HTML found in the <textarea>. The new content is not persisted anywhere except the local client, so setting the source on the window.open call or the src attribute on an <iframe> is not going to work.
I found the following question on StackOverflow: "Putting HTML from the current page into a new window", which got me part of the way there. It seems this technique works well with fragments, but I was unsuccessful in getting an entirely new HTML document loaded. The strange thing is when I view the DOM in Firebug, I see the new HTML—it just doesn't render.
Is it possible to render a generated HTML document in a new window or <iframe>?
EDIT: Here's a "working" example of how I'm attempting to accomplish this:
<!doctype html>
<html>
<head>
<title>Test new DOM</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
function runonload() {
return $("#newcode")[0].value;
}
$(function() {
$("#runit").click(function() {
w=window.open("");
$(w.document).ready(function() {
$(w.document).html(w.opener.runonload());
});
});
});
</script>
</head>
<body>
<textarea id="newcode">
<!doctype html>
<html>
<head>
<title>New Page Test</title>
</head>
<body>
<h1>Testing 1 2 3</h1>
</body>
</html>
</textarea>
<br/>
<button id="runit">Run it!</button>
</body>
</html>
I think you are overcomplicating this...
try this:
<SCRIPT LANGUAGE="JavaScript">
function displayHTML(form) {
var inf = form.htmlArea.value;
win = window.open(", ", 'popup', 'toolbar = no, status = no'); win.document.write("" + inf + ""); } // </script>
<form>
<textarea name="htmlArea" cols=60 rows=12> </textarea> <br> <input type="button" value=" Preview HTML (New Window)" onclick="displayHTML(this.form)"> </form>
$(w.document).html(w.opener.runonload());
You can't set innerHTML—or, consequently, jQuery's html()—on a Document object itself.
Even if you could, you wouldn't be able to do it using html(), because that parses the given markup in the context of an element (usually <div>) from the current document. The doctype declaration won't fit/work, putting <html>/<body>/etc inside a <div> is invalid, and trying to insert the elements it creates from the current ownerDocument into a different document should give a WRONG_DOCUMENT_ERR DOMException. (Some browsers let you get away with that bit though.)
This is a case where the old-school way is still the best:
w= window.open('', '_blank');
w.document.write($('#newcode').val());
w.document.close();
Whilst you can inject innerHTML into a pop-up's document.documentElement, if you do it that way you don't get the chance to set a <!DOCTYPE>, which means the page is stuck in nasty old Quirks Mode.

Write elements into a child iframe using Javascript or jQuery

I have something like this:
<!doctype html>
<html>
<body>
<iframe id="someFrame"></iframe>
</body>
</html>
And I would like to use jQuery to write elements such that the full equivalent HTML would be like this:
<!doctype html>
<html>
<body>
<iframe id="someFrame">
<!-- inside the iframe's content -->
<!-- <html><body> -->
<div>A</div>
<div>B</div>
<div>C</div>
<!-- </body></html> -->
</iframe>
</body>
</html>
Alternatively, any plain-old-Javascript would be fine.
Thanks.
Edit: After a little more research, it seems I am looking for an IE-equivalent of the contentDocument property of an iframe. "contentDocument" is a W3C standard which FF supports, but IE does not. (surprise surprise)
You can do both, you just have to target differently:
var ifrm = document.getElementById('myIframe');
ifrm = ifrm.contentWindow || ifrm.contentDocument.document || ifrm.contentDocument;
ifrm.document.open();
ifrm.document.write('Hello World!');
ifrm.document.close();
After some research, and a corroborating answer from Mike, I've found this is a solution:
var d = $("#someFrame")[0].contentWindow.document; // contentWindow works in IE7 and FF
d.open(); d.close(); // must open and close document object to start using it!
// now start doing normal jQuery:
$("body", d).append("<div>A</div><div>B</div><div>C</div>");
There are two reliable methods to access the document element inside an iframe:
1. The window.frames property:
var iframeDocument = window.frames['iframeName'].document; // or // var iframeDocument = window.frames[iframeIndex].document;
Demo
2. The contentDocument property:
var iframeDocument = document.getElementById('iframeID').contentDocument; // or // var iframeDocument = document.getElementById('iframeID').contentWindow.document;
Demo
I am going out on a limb here and suggest that the answers proposed so far are not possible.
If this iframe actually has a src="somepage.html" (which you ought to have indicated, and if not, what is the point of using iframe?), then I do not think Jquery can directly manipulate html across frames in all browsers. Based on my experience with this kind of thing, the containing page cannot directly call functions from or make any sort of Javascript contact with the iframe page.
Your "somepage.html" (the page that loads in the iframe) needs to do two things:
Pass some kind of object to the containing page that can be used as a bridge
Have a function to set the HTML as you desired
So for example, somepage.html might look like this:
<!doctype html>
<html>
<head>
<script src="jquery.js">
</script>
<script language=JavaScript>
<!--//
var bridge={
setHtml:function(htm) {
document.body.innerHTML=htm;
}
}
$(function() { parent.setBridge(bridge); });
//--></script>
</head>
<body></body>
</html>
and the containing page might look like this:
<!doctype html>
<html>
<head>
<script src="jquery.js">
</script>
<script language=JavaScript>
<!--//
var bridge;
var setBridge=function(br) {
bridge=br;
bridge.setHtml("<div>A</div><div>B</div><div>C</div>");
}
//-->
</script>
</head>
<body><iframe src="somepage.html"></iframe></body>
</html>
This may appear a bit convoluted but it can be adapted in a number of directions and should work in at least IE, FF, Chrome, and probably Safari and Opera...
I have found this to be cross-browser compatible... a little crossing of previous answers and a bit of trial & error of my own. :)
I'm using this for a download of a report, or, if an error (message) occurs, it's displayed in the iFrame. Most of the users will probably have the iFrame hidden, I'm using it multi-functional.
The thing is I have to clear the contents of the iFrame every time I click the report download button - the user can change parameters and it happens there are no results which then is displayed in the iFrame as a message. If there are results, the iFrame remains empty - because the code below has cleared it and the window.open(...) method generates a Content-Disposition: attachment;filename=... document.
var $frm = $("#reportIFrame");
var $doc = $frm[0].contentWindow ? $frm[0].contentWindow.document : $frm[0].contentDocument;
var $body = $($doc.body);
$body.html(''); // clear iFrame contents <- I'm using this...
$body.append('<i>Writing into the iFrame...</i>'); // use this to write something into the iFrame
window.open(Module.PATH + 'php/getReport.php' + Report.queryData, 'reportIFrame');
I do not have a browser that supports contentDocument but I've coded it this way so I'm leaving it. Maybe someone has older browsers and can post compatibility confirmation/issues?

Categories

Resources