Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1318
  • Last Modified:

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

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
Sivakatirswami
Asked:
Sivakatirswami
  • 4
  • 4
1 Solution
 
Element1910Commented:
Try this:
$(window).resize(function(){
    $("#id_of_content_div").height($(window).height()-$(".app").height());
});

Open in new window

0
 
SivakatirswamiAuthor Commented:
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
 
Element1910Commented:
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
SivakatirswamiAuthor Commented:
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
 
SivakatirswamiAuthor Commented:
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
 
Element1910Commented:
Sivakatirswami - I stay from Hawaii too, brah! :) Glad I could help out a fellow islander.
0
 
SivakatirswamiAuthor Commented:
Aloha... if you are ever on Kauai, come visit!
0
 
Element1910Commented:
will do...get friends from there. I stay from Waialua, Oahu (currently live Makakilo though).
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

  • 4
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now