Solved

Can a parent page div dynamically respond to changes in the height of an iFrame it contains?

Posted on 2013-01-25
8
1,267 Views
Last Modified: 2013-02-01
1) go to this page:  http://www.himalayanacademy.com/view/lexicon
2) click the letter "e" to get all words beginning with the letter "e"
3) scroll way down the page until the header and everything is scrolled out of view.
4) now click on one of the "See:" entries at the end of a word

Voila! You will see your screen goes blank... now scroll up to see the definitions related to the "See also" entry.

So problem/challenge: This is an enyo javascript app that we are putting into an iFrame. The enyo app dynamically renders results fetched with an Ajax call to the MySQL database with the words, definitions and their related  "See:" entries.

The only way I could make sure the parent page would hold all the definitions was do so a silly hack and set the dev that hold the iframe to class "app" and set the height to 20,000 px.

So, yes, it holds all the definitions (well not even 20,000 holds  all definitions for "s", but it works) but when we do a new Ajax call to fetch for example see entries for some word that only has 2-3 matches, these are rendered back into the same div/iframe, but the parent page has no idea about the content change. I tried to set .app{height:auto;} but that did not work. It opens fine with the list of letters to click on, but when you click on a letter and the JS calls data from the server and fills in the div, containing div that holds the iFrame does not grow to match the required entries.

Any ideas for a solution to this?

Of course the best answer is: don't use iFrames for this kind of content. In the long run I think I need to get our page assembly system (RevIgniter) to drive the enyo app (renderInto(#SOME DIV# should work)  directly into it's own page and not use and iFrame, but until then, I'm hoping for a solution to the issue:

Getting in iFrame's parent page to dynamically respond to changes in the height of the iFrame content.
0
Comment
Question by:Sivakatirswami
  • 4
  • 4
8 Comments
 
LVL 7

Expert Comment

by:Element1910
ID: 38821494
Try this:
$(window).resize(function(){
    $("#id_of_content_div").height($(window).height()-$(".app").height());
});

Open in new window

0
 

Author Comment

by:Sivakatirswami
ID: 38822559
OK looks promising but I'm not getting anywhere.

Testing now on the staging server... I removed the .app height: 20000px;  declaration for now. So we are stuck here:

http://dev.himalayanacademy.com/view/lexicon/

which dynamically assembles the page by calling the iFrame into the main site wide wrapper. In the DOM, the iFrame is inserted into the first div class="article-wrapper" (view the generated source), which I'm assuming should be the responsive DOM element since it is the immediate parent of the iFrame (Perhaps that is not what we should be targeting... )

So I was thinking I would need to implement your solution as:

$(window).resize(function(){
    $(".article-wrapper").height($(window).height()-$(".app").height());
});

Open in new window


in the iFrame itself, because the event listeners are all in the iFrame, so I'm again assuming when we click, e.g. "e" and the app fetches data requiring, say 1800px in vertical space to show... that would be the window resize trigger as well, which then tells the div "article-wrapper" to change height. But it's not happening.

http://dev.himalayanacademy.com/media/apps/web/lexicon

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
		<title>Hindu Lexicon</title>
		<link rel="shortcut icon" href="assets/favicon.ico"/>
		<!-- -->
		<meta http-equiv="Content-Type" content="text/html; charset=utf8"/>
		<meta name="apple-mobile-web-app-capable" content="yes"/>
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
		<!-- css -->
		<link href="/media/apps/web/lexicon/build/enyo.css" rel="stylesheet"/>
		<link href="/media/apps/web/lexicon/build/app.css" rel="stylesheet"/>
		<!-- js -->
		<script src="/media/apps/web/lexicon/build/enyo.js"></script>
		<script src="/media/apps/web/lexicon/build/app.js"></script>
		<script>
		$(window).resize(function(){
                    $(".article-wrapper").height($(window).height()-$(".app").height());
                          });
          </script>		

	</head>
	<body class="enyo-unselectable">
		<script>
					
			if (!window.App) {
				alert('No application build found, redirecting to debug.html.');
				location = 'debug.html';
			}
			new App().renderInto(document.body);

		</script>
	</body>
</html>

Open in new window


I also tried insert your resize function into the main wrapper just above the iFrame call

like this

<script>
$(window).resize(function(){
    $(".article-wrapper").height($(window).height()-$(".app").height());
});
</script>

<style type="text/css">
	.app {
		width: 100%;
		height: auto;
	}
</style>

<iframe class="app" src="/media/apps/web/[[ gData["record"]["file_id"] ]]"></iframe>

Open in new window


That also does nothing.

Assuming your idea is the solution and I'm just implementing it wrongly, then, I'm missing something. If need be, our page assembly system can dynamically insert that JS into the head element if that helps (should not matter, right?)
0
 
LVL 7

Accepted Solution

by:
Element1910 earned 500 total points
ID: 38822987
My solution was just a suggested solution that might work for you (like it has worked for me in the past) :)

Somebody from SO got it working on their iframe contained within a div by doing this: http://stackoverflow.com/questions/7024574/get-and-set-iframe-content-height-auto-resize-dynamically-easy-solution-expandin
0
 

Author Comment

by:Sivakatirswami
ID: 38824874
Well the solution at SO is only partial: i) resizes on initial opening ii) offers a user toggle. But I'm not seeing the option for the parent page to dynamically resize it's height when the iFrame grows vertically. Your solution looks like it could work if I knew how to implement.  Let me ask more descrete questions:

1) Did you put your window re-size function in the iFrame or the parent page that holds it?
2) do these functions work with classes or just ID?

Meanwhile... still digging...
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 

Author Comment

by:Sivakatirswami
ID: 38845919
We found a solution which used some input from SO as suggest by Element1910. Actually we only got a bit of info from Stack Overflow and my brainy developer in Brazil made it work. We will award points to Element, at least for the sake of participation.   For documentation porpoises (we live in Hawaii) in case it is helpful future users needing a solution to this challenge :

1) It's important to realize that for security reasons, the parent page of an iFrame cannot execute Javascript on page of the iFrame. OTOH: the iFrame *is* allowed to call functions declared in the parent page.

2) The parent page/ page containing the has this JS:  (we had to do a lot of writing to the log to determine the event timing:)
<script type="text/javascript">
function alertsize(pixels){
	console.log("somebody called alertsize to change the size to "+pixels);
	$('#webapp').height(pixels+50);
}]

Open in new window

# where the iFrame is dynamically instantiated by our RevIgniter page assembly system.

<iframe id="webapp" src="/media/apps/web/[[ gData["record"]["file_id"] ]]"></iframe>

# the generated path is:

<iframe id="webapp" src="/media/apps/web/lexicon/"></iframe>

3) the inferred call in the URL is (obviously) "/media/apps/web/lexicon/ index.html"  which is the actual Enyo app container with this...
#head of doc: 
		<link href="/media/apps/web/lexicon/build/enyo.css" rel="stylesheet"/>
		<link href="/media/apps/web/lexicon/build/app.css" rel="stylesheet"/>
		<!-- js -->
		<script src="/media/apps/web/lexicon/build/enyo.js"></script>
		<script src="/media/apps/web/lexicon/build/app.js"></script>
	</head>
<body class="enyo-unselectable">
		<script>					
			if (!window.App) {
				alert('No application build found, redirecting to debug.html.');
				location = 'debug.html';
			}
			new App().renderInto(document.body);

		</script>
	</body>

Open in new window

4) Now the tricky bit is to get the enyo app to trigger the "alertsize" function *after* it fetches new content from the AJAX call for data from the data base... so Andre added this function in the app.js where the enyo "this.render" triggers the "rendered" function, which in turn triggers the parent page to resize:
rendered: function() {
	    this.inherited(arguments);
	    this.log("Rendered!");
		var el = this.$.wordList.hasNode();
		var newsize = el.scrollHeight + 500;
		this.log("trying to change the size of the iframe to "+newsize);
	    parent.alertsize(newsize);
		this.log("after the alertsize call");
	},
	  processSearchResults: function(inRequest, inResponse) {
	    if (!inResponse) return;
	    this.$.wordList.destroyClientControls();
		if (!inResponse.error) {
			this.log("found " + inResponse.entries.length+" words");
		    enyo.forEach(inResponse.entries, this.addDefinition, this);
		} else {
			this.$.wordList.setContent(inResponse.error);
		}
	    this.render();		
	  }

Open in new window

It Works!
0
 
LVL 7

Expert Comment

by:Element1910
ID: 38845999
Sivakatirswami - I stay from Hawaii too, brah! :) Glad I could help out a fellow islander.
0
 

Author Comment

by:Sivakatirswami
ID: 38846001
Aloha... if you are ever on Kauai, come visit!
0
 
LVL 7

Expert Comment

by:Element1910
ID: 38846030
will do...get friends from there. I stay from Waialua, Oahu (currently live Makakilo though).
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Importing and exporting data Magento 1.x ? 4 37
Box Model and Styling 12 21
Flexbox in CSS3 2 26
Phone Dialer 5 36
I annotated my article on ransomware somewhat extensively, but I keep adding new references and wanted to put a link to the reference library.  Despite all the reference tools I have on hand, it was not easy to find a way to do this easily. I finall…
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
This Micro Tutorial will demonstrate how to add subdomains to your content reports. This can be very importing in having a site with multiple subdomains.
This Micro Tutorial will demonstrate how nuggets on the Web are formatted by using Chrome Developer Tools. These tools would not only view the site's CSS but it can also modify it and save the CSS to use on your own site.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now