Thursday, May 14, 2015

SalesForce LightBox/Modal dialog on Standard Page

In visual force page, it is quite easy to implement light box using any of the jquery plugin or even with just use of css. However when we have standard page and want to open light box upon button/link click, it wasn't straightforward:

Option 1: Lightbox inside Visual Force
Include visual force page inside standard page and put light box logic inside visual force page. 
This option doesn't work well, as when we include the visualforce page in standard page, it includes that page inside iframe. Hence if you open the light box from visualforce page, it will stay inside that iFrame.

Option 2 : Modal Dialog
When we create custom button to open the visual force page, it always opens in new page, to open as modal dialg, we can use below java script:


Javascript
In below script, it opens up the visual force page using modal dialog. It updates the parent page's onFocus and onClick event so it is disabled when the child window is open.

1:  var popupWindow;  
2:  var previousOnFocus;  
3:  var previousOnClick;  
4:    
5:  function parent_disable() {   
6:   if(popupWindow && !popupWindow.closed) {  
7:     popupWindow.focus();  
8:   } else if(popupWindow && popupWindow.closed) {  
9:     window.onfocus = previousOnFocus;  
10:     window.onclick = previousOnClick;  
11:   }  
12:  }       
13:    
14:  function openModel(pageURL) {  
15:    var w = (window.innerWidth * 80 / 100);  
16:    var h = (window.innerHeight * 80 / 100);  
17:    previousOnFocus = window.onFocus;  
18:    previousOnClick = window.onClick;  
19:    window.onfocus = parent_disable;  
20:    window.onclick = parent_disable;  
21:    var left = (screen.width/2)-(w/2);  
22:    var top = (screen.height/2)-(h/2);  
23:    popupWindow = window.open(pageURL,'Workspace',   
24:    'height='+h+',width='+w+',top='+top+',left='+left+',toolbar=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,modal=yes');  
25:    popupWindow.focus();  
26:  }  
27:    
28:  openModel('/apex/WorkspaceIF?id={!Account.Id}');  




Option 3 : LightBox
In this option we will use javascript to insert lighbox on the fly. For this option we had to get JQuery loaded which helps with DOM manipulation (and also we had to get some content from server so had to make rest calls).



in JavaScript block, load JQuery, JQueryUI and JQueryCSS. Once JQuery is loaded, the lightbox function is called (as mentioned in line 27).

1:  lightBox_click();  
2:    
3:  function lightBox_click() {  
4:   xxLoadJQuery();  
5:  }  
6:    
7:  function xxLoadScript(url, callback) {   
8:   var head = document.getElementsByTagName('head')[0];   
9:   var script = document.createElement('script');   
10:   script.type = 'text/javascript';   
11:   script.src = url;   
12:   script.onreadystatechange = callback;   
13:   script.onload = callback;   
14:   head.appendChild(script);   
15:  }  
16:    
17:  function xxLoadJQuery() {  
18:   xxLoadScript("https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js", xxLoadJQueryUI);  
19:  }  
20:    
21:  function xxLoadJQueryUI() {  
22:   xxLoadScript("https://code.jquery.com/ui/1.11.3/jquery-ui.min.js", xxLoadJQueryCSS);   
23:  }  
24:    
25:  function xxLoadJQueryCSS() {   
26:   $("<link/>", { rel: "stylesheet", type: "text/css", href: "https://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css"}).appendTo("head");   
27:   xxLightBox();  
28:  }   
29:    

Now, in xxLightBox function, required div and css are inserted to enable the lightbox.

1:  function xxLightBox() {  
2:     $("<style>.modalDialog {position: fixed;font-family: Arial, Helvetica, sans-serif;top: 0;right: 0;bottom: 0;left: 0;background: rgba(0,0,0,0.8);z-index: 99999;opacity:0;-webkit-transition: opacity 400ms ease-in;-moz-transition: opacity 400ms ease-in;transition: opacity 400ms ease-in;pointer-events: none;} .modalDialog:target {opacity:1;pointer-events: auto;} .modalDialog > div {width: 95%;position: relative;margin: 1% auto;padding: 1px 1px 1px px;border-radius: 5px;background: #fff;background: -moz-linear-gradient(#fff, #999);background: -webkit-linear-gradient(#fff, #999);background: -o-linear-gradient(#fff, #999);}.close {background: #606061;color: #FFFFFF;line-height: 25px;position: absolute;right: -12px;text-align: center;top: -10px;width: 24px;text-decoration: none;font-weight: bold;-webkit-border-radius: 12px;-moz-border-radius: 12px;border-radius: 12px;-moz-box-shadow: 1px 1px 3px #000;-webkit-box-shadow: 1px 1px 3px #000; box-shadow: 1px 1px 3px #000;} .close:hover { background: #00d9ff; } </style>").appendTo("head");  
3:     var height = ( $( document ).height() * 90 / 100 );  
4:     var iFrameURL = xxGetIFramURL();  
5:     var lighboxDiv = '<a id="openModelLink" href="#openModal"></a><div id="openModal" class="modalDialog"><div><a id="closeModelLink" href="#close" class="close">X</a><iframe frameborder="0" height="' + height + '" scrolling="auto" src="' + iFrameURL + '" style="background-color: transparent; border: 0px none transparent;padding: 0px" width="100%"></iframe></div></div>';  
6:     if( iFrameURL == null || iFrameURL == '' ) {  
7:        lighboxDiv = '<a id="openModelLink" href="#openModal"></a><div id="openModal" class="modalDialog"><div><a id="closeModelLink" href="#close" class="close">X</a>Workspace does not exist.</div></div>';  
8:     }   
9:     $( "body" ).append(lighboxDiv);  
10:    document.getElementById("openModelLink").click();  
11:  }  
12:    


Extra note here (not needed for this example), we are displaying iFrame inside lightbox and I had to get iFrame URL from server, hence I had to make Rest call using JQuery as below (also explained in detail here)

1:  function xxGetIFramURL() {  
2:     var iFrameURL = '';  
3:     $.ajax({  
4:        url:  '/services/apexrest/WorkspaceService?salesForceId={!Account.Id}',  
5:        beforeSend: function(xhr) {  
6:           xhr.setRequestHeader('Authorization', 'Bearer {!$Api.Session_ID}');  
7:        },  
8:        success: function(result) {  
9:           iFrameURL = result;  
10:       },  
11:       async:  false  
12:    });  
13:    return iFrameURL;  
14:  }  





1 comment:

Unknown said...

Excellent, thanks for the post!!