Mendix in an iframe. How to scroll the main page to the top

1
For a client we have made a Job page with a list of the current available jobs. Now when you are down the list and open the job description the other window does not scroll to the top. I tried a couple of tricks mentioned here: http://stackoverflow.com/questions/1852518/how-to-get-scrolltop-of-an-iframe but these do not seem to work. The best I got was a second scrollbar IN my iframe that was at the top but since the scrollbar of the window around my iframe is still at the bottom position this is not what I want. Is there a way to influance the scrollbar of the window around the iframe from inside the iframe? Regards, Ronald  
asked
1 answers
3

Got this working with an old created widget. Here are the code snippets, feel free to create the widget with the new boilerplate and share :)

widget snippet:

dojo.provide("IFrameScrollTo.widget.IFrameScrollTo");
dojo.declare("IFrameScrollTo.widget.IFrameScrollTo", mxui.widget._WidgetBase, 
{
	inputargs: { 
			height : '0',
			speed : '100'
    },
	
   postCreate : function() 
	{
		var pass_data = { 'action':'scrollTo', 'height':this.height, 'speed':this.speed};
		setTimeout(function(){
			window.parent.postMessage(JSON.stringify(pass_data),'YOURMENDIXURL');
		},1000);
    },
});;

 

this will pass a JSON command to the parent site. Capture this on the site with these snippets:

postmessage js:

/*!
 * jQuery postMessage - v0.5 - 9/11/2009
 * http://benalman.com/projects/jquery-postmessage-plugin/
 * 
 * Copyright (c) 2009 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */

(function($){
  '$:nomunge'; // Used by YUI compressor.
  
  // A few vars used in non-awesome browsers.
  var interval_id,
    last_hash,
    cache_bust = 1,
    
    // A var used in awesome browsers.
    rm_callback,
    
    // A few convenient shortcuts.
    window = this,
    FALSE = !1,
    
    // Reused internal strings.
    postMessage = 'postMessage',
    addEventListener = 'addEventListener',
    
    p_receiveMessage,
    
    // I couldn't get window.postMessage to actually work in Opera 9.64!
    has_postMessage = window[postMessage] && !$.browser.opera;

  $[postMessage] = function( message, target_url, target ) {
    if ( !target_url ) { return; }
    
    // Serialize the message if not a string. Note that this is the only real
    // jQuery dependency for this script. If removed, this script could be
    // written as very basic JavaScript.
    message = typeof message === 'string' ? message : $.param( message );
    
    // Default to parent if unspecified.
    target = target || parent;
    
    if ( has_postMessage ) {
      // The browser supports window.postMessage, so call it with a targetOrigin
      // set appropriately, based on the target_url parameter.
      target[postMessage]( message, target_url.replace( /([^:]+:\/\/[^\/]+).*/, '$1' ) );
      
    } else if ( target_url ) {
      // The browser does not support window.postMessage, so set the location
      // of the target to target_url#message. A bit ugly, but it works! A cache
      // bust parameter is added to ensure that repeat messages trigger the
      // callback.
      target.location = target_url.replace( /#.*$/, '' ) + '#' + (+new Date) + (cache_bust++) + '&' + message;
    }
  };
  
 
  
  $.receiveMessage = p_receiveMessage = function( callback, source_origin, delay ) {
    if ( has_postMessage ) {
      // Since the browser supports window.postMessage, the callback will be
      // bound to the actual event associated with window.postMessage.
      
      if ( callback ) {
        // Unbind an existing callback if it exists.
        rm_callback && p_receiveMessage();
        
        // Bind the callback. A reference to the callback is stored for ease of
        // unbinding.
        rm_callback = function(e) {
          if ( ( typeof source_origin === 'string' && e.origin !== source_origin )
            || ( $.isFunction( source_origin ) && source_origin( e.origin ) === FALSE ) ) {
            return FALSE;
          }
          callback( e );
        };
      }
      
      if ( window[addEventListener] ) {
        window[ callback ? addEventListener : 'removeEventListener' ]( 'message', rm_callback, FALSE );
      } else {
        window[ callback ? 'attachEvent' : 'detachEvent' ]( 'onmessage', rm_callback );
      }
      
    } else {
      // Since the browser sucks, a polling loop will be started, and the
      // callback will be called whenever the location.hash changes.
      
      interval_id && clearInterval( interval_id );
      interval_id = null;
      
      if ( callback ) {
        delay = typeof source_origin === 'number'
          ? source_origin
          : typeof delay === 'number'
            ? delay
            : 100;
        
        interval_id = setInterval(function(){
          var hash = document.location.hash,
            re = /^#?\d+&/;
          if ( hash !== last_hash && re.test( hash ) ) {
            last_hash = hash;
            callback({ data: hash.replace( re, '' ) });
          }
        }, delay );
      }
    }
  };
  
})(jQuery);

and this:


//setten voor cross domain
document.domain="YOURDOMAIN";


//LISTENER voor postmessages vanuit Mendix
function listener(event){

try 
{
  pass_data = JSON.parse(event.data);
} 
catch (exception) 
{
  pass_data = null;
}

if (pass_data) {
 
	//nu we meerdere berichten sturen, messages switchen op message action.
	switch(pass_data['action']) {
		case 'setHeight':
			//min top, header, -negative margin on wrap, footer, bottom 30+232-33+30+46 (sum=305)
			//UIT TE REKENEN OP BASIS VAN THEMA
			var windowHeight = jQuery( window ).height()-305;
			var newHeight = Math.max(
					windowHeight,
					pass_data['height']
			);
		  	jQuery('.iframeclass').height(newHeight); 
		  	jQuery('.iframeWrap').height(newHeight);
			break;	
		case 'scrollTo':
			var scrollLoc = pass_data['height'];
			var scrollSpeed= pass_data['speed'];
			jQuery( "html,body" ).animate({scrollTop: scrollLoc},scrollSpeed);
			break;
	}
}
}
//attach listnere
if (window.addEventListener){
  addEventListener("message", listener, false)
} else {
  attachEvent("onmessage", listener)
}

 

the frame looks like this: 

<style>
 iframe {
	overflow-x: auto !important;
}
</style>
<div id="iframewrap" class="iframeWrap"><script>
var iframe = document.createElement("iframe");
iframe.id = Math.random();
iframe.src = "MENDIXURL/link/homepage/?rand=" + Math.random();
iframe.height = "2000";
iframe.style.height = "3000px";
iframe.setAttribute("frameborder", 0);
iframe.setAttribute("scrolling", "no");
iframe.setAttribute("seamless", "seamless");
iframe.setAttribute("class", "iframeclass");
document.getElementById("iframewrap").appendChild(iframe);
</script></div>

mention the random numbers because of Safari sometimes caches the frame url...

 

good luck !

answered