Document won't load into iframe with changed, but proper, name - javascript

What I'm trying to achieve is being able to load contents of href in to one of three iframes, by changing thier names via java.
The problem is: Chrome will always load contents into first iframe, ignoring it's name change, this problem does not occur in Firefox.
function change_name()
{
document.getElementById('frame1').name = "#" ;
document.getElementById('frame2').name = "main_frame" ;
};
.frame {
width:100px;
height:100px;
}
<iframe id="frame1" name="main_frame" class="frame"></iframe>
<iframe id="frame2" name="#" class="frame"></iframe>
<iframe id="frame3" name="#" class="frame"></iframe>
<input type="submit" onclick="change_name()" value="change iframe name"/>
load page into iframe
jsfiddle demonstrating what I'm trying to do: http://jsfiddle.net/514y7v4m/1/
Any help is much appreciated

Stumbled upon this link: http://help.dottoro.com/ljbimuon.php
After some modification of your script, i believe this could be the solution. Changing the contenWindow.name instead of name alone seems to do the trick.
function change_name() {
var one = document.getElementById('frame1');
one.contentWindow.name = "#";
console.log("The name is: " + one.name);
console.log("The name of the window: " + one.contentWindow.name);
var two = document.getElementById('frame2');
two.contentWindow.name = "main_frame";
console.log("The name is: " + two.name);
console.log("The name of the window: " + two.contentWindow.name);
};

Related

Using CEFSharp to edit <textarea>

I am able to edit a regular textbox within an iFrame in CefSharp like so:
Browser1.GetBrowser().GetFrame("iFrame1").ExecuteJavaScriptAsync("document.getElementById('ElementID').value=" + '\'' + "1234" + '\'');
However, because a textarea doesn't have a value:
<iframe id="iFrame1" name="iFrame1">
<textarea name="txtareaname" id="txtareaname1">sometexthere</textarea>
</iframe>
I am unable to execute a similar line of code to edit the text in the textarea:
textarea.Browser1.GetBrowser().GetFrame("iFrame1").ExecuteJavaScriptAsync("document.getElementById('txtareaname1').value=" + '\'' + "1234" + '\'');
I have also tried:
textarea.Browser1.GetBrowser().GetFrame("iFrame1").ExecuteJavaScriptAsync("document.getElementById('txtareaname1').innertext=" + '\'' + "1234" + '\'');
How do I adjust my code to edit this textarea?
OP: However, because a textarea doesn't have a value I am unable to
execute a similar line of code to edit the text in the textarea.
The assumption is wrong, setting value attribute works fine for teaxtarea.
You should just make sure the document, including the iframe has been loaded and you have selected the correct iframe using correct name and then you have selected the correct textarea using correct id.
Example
Here is a minimal complete verifiable example which shows how you can find the iframe and set the value of a textarea inside the iframe.
To make the example independent from externals sources and make verification easier, instead of initializing iframe using its src attribute, I've initialized iframe using script.
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
var content = new HtmlString(#"
<!DOCTYPE html>
<html>
<body>
<iframe id=""iFrame1"" name=""iFrame1"" src=""about:blank""></iframe>
<script>
var doc = document.getElementById('iFrame1').contentWindow.document;
doc.open();
doc.write('<html><head><title></title></head><body>' +
'Address:<br>' +
'<textarea id=""myTextarea"">342 Alvin RoadDucksburg</textarea>' +
'</body></html>');
doc.close();
</script>
</body>
</html>
");
var browser = new ChromiumWebBrowser(content)
{ Dock = DockStyle.None, Size = new Size(400, 200), Location = new Point(8, 42) };
Controls.Add(browser);
var button = new Button() { Text = "Click Me", Location = new Point(8, 8) };
Controls.Add(button);
button.Click += (obj, args) => {
browser.GetBrowser().GetFrame("iFrame1")
.ExecuteJavaScriptAsync("document.getElementById('myTextarea').value=" +
"'Fifth Avenue, New York City'");
};
}

How can I search iframe content (text) using an input field that is on the parent page?

Yes, I know something like this has been asked over here before and I have searched but the one that is closest to what I'm trying to achieve doesn't have an answer ( Search iframe content with jquery and input element on parent page ) and the one that does is making use of nested iframes ( Access the content of a nested Iframe ) and I didn't quite understand the solution (VERY new with javascript so please bear with me). Honestly, it's getting a bit frustrating (it's quite late over here) so I thought I might as well ask.
I have an iframe that displays a page from my site therefore the page is from the same domain. What I would like to do is to search the iframe for some text using javascript (not jquery). The search input box, however, is on the parent page.
I've done something similar to this before by putting the search input box in the page displayed in the iframe instead ( I followed this tutorial: http://help.dottoro.com/ljkjvqqo.php ) but now I need to have the search input box on the parent page because I going to make it "sticky" so that it will follow the user as they scroll down the page. I've resized the parent page height to be the same as the length of the page in the iframe by also using javascript.
So, my question is: How can I use javascript to search text that is in the iframe by using a search input box that is on the parent page?
My HTML so far:
<input type="text" name="page_no" size="3"/>
<input type="submit" name="goto" value="Go"/>
<iframe id='iframe2' src="http://example.com/files/<?php echo $filename;?>" frameborder="0" style="text-align:center; margin:0; width:100%; height:150px; border:none; overflow:hidden;" scrolling="yes" onload="AdjustIframeHeightOnLoad()"></iframe>
<script type="text/javascript">
function AdjustIframeHeightOnLoad() { document.getElementById("iframe2").style.height = document.getElementById("iframe2").contentWindow.document.body.scrollHeight + "px"; }
function AdjustIframeHeight(i) { document.getElementById("iframe2").style.height = parseInt(i) + "px"; }
Not sure how to move on from there. I'd really appreciate some help.
Thanks in advance!
EDIT:
The search works now (saw that I put the javascript above the html so I put it under it to get it working) so this is what I want to do with the search results:
I intend to use the search box to enter a page number such that when the user clicks "Go" the search will look for that page and scroll the user down to where the result (that is, the page number) is.
EDIT 2: I just thought I'd mention that my page numbers are written like this: -2- for page 2, -3- for page 3, etc.
I believe this is the solution you need,
HTML:
<!--added an id of search to the input element-->
<input id="search" type="text" name="page_no" size="3"/>
<!--changed input type to button and added an id of go-->
<input id="go" type="button" name="goto" value="Go"/>
<iframe id='iframe2' src="iframe.html" frameborder="0" style="text-align:center; margin:0; width:100%; height:150px; border:none; overflow:hidden;" scrolling="yes" ></iframe>
Javascript(make sure the iframe is in the same domain):
//on click event for the button with an id of go
var go = document.getElementById("go").onclick = function(){//begin function
//get the search value
var search = document.getElementById("search").value;
//get the html of the iframe(must be in the same domain)
var iframe = document.getElementById("iframe2").contentDocument.body;
/*create a new RegExp object using search variable as a parameter,
the g option is passed in so it will find more than one occurence of the
search parameter*/
var result = new RegExp(search, 'g');
//set the html of the iframe making the found items bold
iframe.innerHTML = iframe.innerHTML.replace(result,"<b>" + search + "</b>" );
};//end function
Here is a link that will explain some additional flags you can use with the RegExp object. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
Below is an improved version of Javascript to scroll to Page Number.
Place it inside of your on click event for the go button. The code requires that you place an id with the page number inside of an element at the top of each page. Example <h3 id="3">Page 3</h3>.
//get the search value
var search = document.getElementById("search").value;
//get the id of the search term
var iframe = document.getElementById("iframe2");
//the url of the page loaded in the iframe
var iframeURL = "iframe.html";
//set the source of iframe appending a link to an element id
iframe.src = iframeURL + "#" + search;
Solved! Thanks Larry Lane for your help.
Here is the present Javascript. Hope it helps someone.
<script type="text/javascript">//on click event for the button with an id of go
var go = document.getElementById("go").onclick = function(){//begin function
//get the search value
var search = document.getElementById("search").value;
//put hyphens for the page number
var pagehyph = '-' + search + '-';
//get the html of the iframe(must be in the same domain)
var iframe = document.getElementById("iframe2").contentDocument.body;
//remove the hash from the iframe src if there is one
var url = document.getElementById("iframe2").src, index = url.indexOf('#');
if(index > 0) {
var url = url.substring(0, index);
}
var newurl = url + "#" + search;
/*create a new RegExp object using search variable as a parameter,
the g option is passed in so it will find more than one occurrence of the
search parameter*/
var result = new RegExp(pagehyph, 'g');
//set the html of the iframe and add a page anchor
iframe.innerHTML = iframe.innerHTML.replace(result,"<a id='" + search + "'>" + search + "</a>" );
//set new src for the iframe with the hash
document.getElementById("iframe2").src = newurl;
};//end function
</script>
As you can see from the code, I've added a page anchor so the page scrolls to the page anchor when they click 'Go'.
function myFunction(x) {
var att = document.querySelector("iframe[id=iframe2]").getAttribute(x);
alert(att);
}
<input type="text" name="page_no" size="3"/>
<input type="submit" name="goto" onclick="myFunction(document.querySelector('input[name=page_no]').value)" value="Go"/>
<hr />
<iframe id='iframe2' src="https://www.example.com" frameborder="0" style="text-align:center; margin:0; width:100%; height:150px; border:none; overflow:hidden;" scrolling="yes" ></iframe>

Form gives error when trying to append after question mark

I'm trying to send visitors to http://www.facebook.com/plugins/comments.php?href=http://google.com?c
Gives the error
The comments plugin requires an href parameter.
This part is rendered correctly: http://www.facebook.com/plugins/comments.php
but the stuff after the question mark fails to be included
<script>
function go(){
var uri = 'http://www.facebook.com/plugins/comments.php'
+ encodeURI('?href=http://google.com?c');
window.frames[0].document.body.innerHTML =
'<form target="_parent" method="get" action="'
+ uri
+ '"></form>';
window.frames[0].document.forms[0].submit();
}
</script>
<iframe onload="window.setTimeout('go()', 99)" src="about:blank" style="visibility:hidden"> </iframe>?
Change to:
var uri = 'http://www.facebook.com/plugins/comments.php?'
+ encodeURIComponent('href=http://google.com?c');
If you encode the first ? it no longer serves to separate the URL from its parameters.
Only the keys and value of the query should be encoded, not the ?,& or = as these are the characters that structure the query.
var uri = 'http://www.facebook.com/plugins/comments.php?href='
+ encodeURIComponent('http://google.com?c');

delay javascript function until after file has been uploaded on asp page

Can someone please tell me how to delay the resetting of a div background-image until a file upload has completed? All the parts individually work, however
I have to delay the setting of the background by having an alert pop up and then leave a while before clicking ok - I can't have since a user will not know how long to leave before pressing...
Any help appreciated though I should say that I briefly looked at jquery/ajax but found that it would only work in IE once before requiing a page refresh
Html...
<iframe id="MyFrame" name="MyFrame" style="display:none;"></iframe>
<form id="browseform" method="post" action="disp_photosave.asp" enctype="multipart/form-data" target="MyFrame">
<p>Please select your photo...</p>
<img src="Images/button_browse.gif">
<input type="hidden" name="tab" value="0">
<input type="file" id="upload" name="filesent" onchange="this.form.submit(); load_bk_photo()">
<input type="hidden" name="tempid" value="<%=(TId)%>">
<input type="hidden" name="side" value="<%=(strSide)%>">
<input type="hidden" name="varid" value="<%=(Request.querystring("varid"))%>">
<input type="hidden" name="prodid" value="<%=(Request.querystring("prodid"))%>">
</form>
javascript...
function load_bk_photo(){
var activeId = '<%=(activeTempStoreId)%>'
var redStr_id = "side1"
d = new Date();
time_temp = d.getTime();
photoUrl = "photos/merged_"+activeId+"_"+redStr_id+".png?"+d.getTime()
alert ("timebbb = "+time_temp )
$('#resizable-img').css('background-image','url("' + photoUrl + '")');
$('#resizable-img').css('display','block');
}
vbscript on disp_photosave.asp...
<%
Set Upload = Server.CreateObject("csASPUpload.Process")
Set Image = Server.CreateObject("csImageFile.Manage")
prodid = prodSet.Fields.Item("id").Value
redStr = "side1"
fieldPrefix = "front_"
If Upload.FileQty > 0 Then
Image.ReadVariant Upload.FileData(0)
Image.WriteFile Server.MapPath("this works ok"
Image.ResizeFit scale_width, scale_height
Image.WriteFile Server.MapPath("this works ok"
storeHeight = Image.Height
storeWidth = Image.Width
Set MyConn=Server.CreateObject("ADODB.Connection")
MyConn.Open "dsn=xxx;uid=xxx;password=xxx;"
SQLString = "this works ok"
MyConn.Execute(SQLString)
MyConn.Close
Set MyConn = Nothing
End if
%>
I also need to return the value storeHeight and storeWidth to the main page to use later so if anyone can advise me on that too.
Thanks in advance for any help.
Your load_bk_photo function has some issues (missing semi-colons, creating global variables), try changing to this:
function load_bk_photo(){
//we can use the `var` keyword once and separate each variable declaration by a comma, then finish all the declarations with a semi-colon
var activeId = '<%=(activeTempStoreId)%>',
redStr_id = "side1",
d = new Date(),
time_temp = d.getTime(),
photoUrl = "photos/merged_" + activeId + "_" + redStr_id+".png?" + time_temp;
alert ("timebbb = " + time_temp );
//you can use one `.css()` function call to do both operations
$('#resizable-img').css({
'background-image' : 'url("' + photoUrl + '")',
display : 'block'
});
}
You were creating global variables which is only necessary if you are changing the value of variables outside the scope of this function.
Onto your main question, you can set a load event handler for the <iframe> element as a callback function on your upload:
$('#MyFrame').on('load', function () {
//The iframe has loaded and you can do what you want, including get the contents of the iframe (server-response)
var response = $(this).contents().find('body').text();
});
Make sure to set this binding before the source of the <iframe> is changed.
Note that .on() is new in jQuery 1.7 and in this case is the same as .bind().
.on(): http://api.jquery.com/on
UPDATE
I don't know asp classic but if you output something like storeWidth|storeHeight in your asp code then you can get that response in you JavaScript and do what you want with it:
$('#MyFrame').on('load', function () {
//The iframe has loaded and you can do what you want, including get the contents of the iframe (server-response)
var response = $(this).contents().find('body').text().split('|');
alert(response[0] + 'x' + response[1] + 'px');
});
I would use a global callback method:
JavaScript:
window.uploadComplete = function (returnData) {
$('#resizable-img').css('background-image','url("' + returnData.photoUrl + '")');
$('#resizable-img').css('display','block');
alert(returnData.storeHeight + "|" + returnData.storeWidth);
}
And in ASP, return this to the iFrame:
<script>
parent.uploadComplete({photoUrl: "urltophoto",storeHeight: "<value from asp var>", storeWidth: "<value from asp var>"});
</script>

Changing data content on an Object Tag in HTML

I have an HTML page which contains an Object tag to host an embedded HTML page.
<object style="border: none;" standby="loading" id="contentarea"
width="100%" height="53%" type="text/html" data="test1.html"></object>
However, I need to be to change the HTML page within the object tag. The current code seems to create a clone of the object and replaces the existing object with it, like so:
function changeObjectUrl(newUrl)
{
var oContentArea = document.getElementById("contentarea");
var oClone = oContentArea.cloneNode(true);
oClone.data = newUrl;
var oPlaceHolder = document.getElementById("contentholder");
oPlaceHolder.removeChild(oContentArea);
oPlaceHolder.appendChild(oClone);
}
This seems a rather poor way of doing this. Does anyone know the 'correct' way of changing the embedded page?
Thanks!
EDIT: In response to answers below, here is the full source for the page I am now using. Using the setAttribute does not seem to change the content of the Object tag.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Test</title>
<script language="JavaScript">
function doPage()
{
var objTag = document.getElementById("contentarea");
if (objTag != null)
{
objTag.setAttribute('data', 'Test2.html');
alert('Page should have been changed');
}
}
</script>
</head>
<body>
<form name="Form1" method="POST">
<p><input type="button" value="Click to change page" onclick="doPage();" /></p>
<object style="visibility: visible; border: none;" standby="loading data" id="contentarea" title="loading" width="100%" height="53%" type="text/html" data="test1.html"></object>
</form>
</body>
</html>
The Test1.html and Test2.html pages are just simple HTML pages displaying the text 'Test1' and 'Test2' respectively.
You can do it with setAttribute
document.getElementById("contentarea").setAttribute('data', 'newPage.html');
EDIT:
It is also recommended that you use the window.onload to ensure that the DOM has loaded, otherwise you will not be able to access objects within it.
It could be something like this:
function changeData(newURL) {
if(!document.getElementById("contentarea"))
return false;
document.getElementById("contentarea").setAttribute('data', newURL);
}
window.onload = changeData;
You can read more about window.onload here
This seems to be a browser bug, setAttribute() should work. I found this workaround, which seems to work in all browsers:
var newUrl = 'http://example.com';
var objectEl = document.getElementById('contentarea');
objectEl.outerHTML = objectEl.outerHTML.replace(/data="(.+?)"/, 'data="' + newUrl + '"');
The above solutions did not work properly in Firefox, the Object tag doesn't refresh for some reason. My object tags show SVG images.
My working solution for this was to replace the complete Object node with a clone:
var object = document.getElementById(objectID);
object.setAttribute('data', newData);
var clone = object.cloneNode(true);
var parent = object.parentNode;
parent.removeChild(object );
parent.appendChild(clone );
Here's how I finally achieved it. You can do
document.getElementById("contentarea").object.location.href = url;
or maybe
document.getElementById("contentarea").object.parentWindow.navigate(url);
The Object element also has a 'readyState' property which can be used to check whether the contained page is 'loading' or 'complete'.
I found a very simple solution that also works in Chrome. The trick is to make the object (or a parent element) invisible, change the data attribute, and then make the object visible again.
In the code below, it is assumed that object_element is the object element and parent_element is the parent, and url is the url of the data.
parent_element.style.display = 'none'; // workaround for Chrome
object_element.setAttribute('data', url);
parent_element.style.display = '';
Following user2802253, I use this one on Safari and Firefox, which also forces a redraw. (sorry, not enough reputation to post as a simple comment).
theObject.style.visibility = null;
theObject.setAttribute("data", url);
theObject.style.visibility = "visible";
var obj = document.getElementById("pdfDoc");
obj.setAttribute('data', newPdf);
worked on Chrome version 54 and Safari, but didn't work on IE 11
what worked on them all
var obj = document.getElementById("pdfDoc");
obj.setAttribute('data', newPdf);
var cl = obj.cloneNode(true);
var parent = obj.parentNode;
parent.removeChild(obj);
parent.appendChild(cl);
This snippet did the job in my case
var object = document.getElementById(objectID);
object.setAttribute('data', newData);
var clone = object.cloneNode(true);
var parent = object.parentNode;
parent.removeChild(object );
parent.appendChild(clone );
<div id='myob'>
<object style="border: none;" standby="loading" id="contentarea"
width="100%" height="53%" type="text/html" data="test1.html"></object>
</div>
$('#myob').html($('#myob').html());
Changing the data attribute should be easy. However, it may not work perfectly on all browsers.
If the content is always HTML why not use an iframe?
Antoher way of doing it, you could embed the object in a DIV
var newUrl = 'http://example.com';
var divEl = document.getElementById('divID');
var objEl = document.getElementById('objID');
objEl.data = newUrl;
// Refresh the content
divEl.innerHTML = divEl.innerHTML;
I think this is a better way to achieve your objective.
Html:
<div id="mytemplate"><div>
Js:
function changeTemplate(t){
var mytemplate = document.getElementById("mytemplate");
mytemplate.innerHTML = '<object type="text/html" data=' + t + '></object>';
}
changeTemplate('template.html');
changeTemplate('whatever.html');
var content_area = document.getElementById("contentarea");
content_area.data = newUrl;
Refreshes object in Chrome Version 42.0.2311.90 m
the main reason of this issue is using "/" in local files.
The Wrong Code :
var obj = document.getElementById("hostedhtml");
obj.setAttribute('data', "pages\page2.html");
The Right Code :
var obj = document.getElementById("hostedhtml");
obj.setAttribute('data', "pages\\page2.html");

Categories