Skip to content

Instantly share code, notes, and snippets.

@Oblongmana
Last active December 24, 2015 08:29
Show Gist options
  • Save Oblongmana/6771197 to your computer and use it in GitHub Desktop.
Save Oblongmana/6771197 to your computer and use it in GitHub Desktop.
A reasonably quickly pluggable way of getting a #modal #dialog into a #visualforce page. You need to include jQuery (tested with 1.9.1) and jQueryUI (tested with 1.10.3) that has been customised with CSS SCope ".jqueryuidialog", as well as (of course?) the javascript file included in this gist. May blog about it a bit more in depth at some point…
/*------------------------------------------------------------------------------
common-modal.js
Description:
Contains common functions for dealing with the creation, opening,
and closing of modals
Dependencies:
jQuery (tested with 1.9.1)
jQueryUI customised containing, at minimum, "dialog" (designed for version 1.10.3), and CSS scoped to ".jqueryuidialog"
Usage Notes:
General Notes:
Note that the open & beforeClose functions for the modals generated
here have been extended to wrap modal[s] in div[s] with class
"jqueryuidialog" on launch, and unwrap on close. The reason for this
is that the jQueryUI css file used in this project was generated on
with a custom scope called [you guessed it] "jqueryuidialog".
Methods:
initialiseDialogs(selectorsArray):
the selectors array givs divs which are to be turned into
modals. Note of course that this isn't a lot of use to you
unless you also have a way to pop the modal [see below]
initialiseDialogOpeners(dialogSelectorsArray,openerSelectorsArray):
dialogSelectorsArray contains selectors for the divs initialised
in initialiseDialogs(selectorsArray), while openerSelectorsArray
contains selectors for the elements (buttons, links, etc) for
launching the modals.
initialiseDialogClosers(dialogSelectorsArray,closerSelectorsArray):
dialogSelectorsArray contains selectors for the divs initialised
in initialiseDialogs(selectorsArray), while closerSelectorsArray
contains selectors for the elements (buttons, links, etc) for
closing the modals.
------------------------------------------------------------------------------*/
var modal = {
initialiseDialogs : function(jQueryDialogSelectorsArray) {
var retVal = [];
for(var i =0; i < jQueryDialogSelectorsArray.length; i++) {
retVal.push(
$(jQueryDialogSelectorsArray[i]).dialog({
autoOpen: false,
height: 500,
minWidth: 800,
modal: true,
finishListener: function(event){
event.preventDefault(); //stop form submit here
},
//See http://stackoverflow.com/questions/8326853/jquery-ui-custom-css-scope-dialog-quirks
// Open and Close functions ensure jQueryUI scoped css applied to (and ONLY to) the dialog
open: function () {
$('.ui-widget-overlay').each(function () {
$(this).next('.ui-dialog').andSelf().wrapAll('<div class="jqueryuidialog" />');
});
},
beforeClose: function () {
$('.ui-widget-overlay').each(function () {
$(this).next('.ui-dialog').andSelf().unwrap();
});
}
})
);
}
return retVal;
},
initialiseDialogOpeners : function(jQueryDialogSelectorsArray,jQueryOpenerSelectorsArray) {
modalRegistry = jQueryDialogSelectorsArray;
for(var dialogIter =0; dialogIter < jQueryDialogSelectorsArray.length; dialogIter++) {
$( jQueryOpenerSelectorsArray[dialogIter] )
.click(
function(modalSelector) {
return function (event) {
event.preventDefault();
$( modalSelector ).dialog( "open" );
};
} (jQueryDialogSelectorsArray[dialogIter])
);
}
},
initialiseDialogClosers : function(jQueryDialogSelectorsArray,jQueryCloserSelectorsArray) {
modalRegistry = jQueryDialogSelectorsArray;
for(var dialogIter =0; dialogIter < jQueryDialogSelectorsArray.length; dialogIter++) {
$( jQueryCloserSelectorsArray[dialogIter] )
.click(
function(modalSelector) {
return function (event) {
event.preventDefault();
$( modalSelector ).dialog( "close" );
};
} (jQueryDialogSelectorsArray[dialogIter])
);
}
}
};
<apex:page sidebar="false" title="My Modal Page">
<!-- NOTE RE JQUERYUI - MUST READ - PARTICULARLY IMPORTANT DUE TO UNFORTUNATELY BAD USER EXPERIENCE ON JQUERYUI WEBSITE :(
Go to http://jqueryui.com/download/
Pick any components you want to include (MUST include dialog however)
Scroll to bottom of page
Change the CSS scope box to ".jqueryuidialog" - being sure to include the period/fullstop
Now (and here comes the confusing user experience):
Click the "Design a custom theme" link, and you'll be taken away from the page
Customize the theme as you see fit (or don't, that's fine too) - I'd suggest checking out the options in the ThemeROller->Gallery tab
Go back to the ThemeRoller->Roll Your Own tab in the left nav (if you're not already there)
Click Download Theme
Right, now you're back at the customised download page, and you'll see your customised css scope is still there
Download it! :)
Once that's done, I'd recommend doing the following:
Unzip it.
Rename the root folder to jqueryui
Zip it up again, making sure the zip archive is entitled jqueryui.zip
Upload this to SF as a public Static Resource called jqueryui.
This should now play nice with the stylesheet import in this example
-->
<apex:includeScript value="{!$Resource.jQuery}"/>
<apex:includeScript value="{!$Resource.modal')}"/>
<apex:stylesheet value="{!URLFOR($Resource.jqueryui, 'jqueryui/css/jqueryuidialog/jquery-ui-1.10.3.custom.min.css')}"/>
<script type="text/javascript" language="javascript">
$(document).ready(function()
{
var dialogSelectors = ["#modal-div"];
var dialogOpenerSelectors = [".show-modal"];
var dialogCloserSelectors = [".hide-modal"];
modal.initialiseDialogs(dialogSelectors);
modal.initialiseDialogOpeners(dialogSelectors,dialogOpenerSelectors);
modal.initialiseDialogClosers(dialogSelectors,dialogCloserSelectors);
});
</script>
<!-- primary page content -->
<apex:form>
<apex:sectionHeader title="Content" />
<apex:pageMessages />
<apex:pageBlock >
<apex:pageBlockButtons >
<!-- pop the modal -->
<input type="button" class="btn show-modal" value="Show Modal"/>
</apex:pageBlockButtons>
<apex:pageBlockSection showHeader="true" title="Content Section" columns="1" collapsible="false" >
Yo, I'm your general page content
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
<!-- modal popup, note the display:none; - don't touch it -->
<div id="modal-div" title="Modal Content" style="display:none;">
Hey, I'm your modal content.
<input type="button" class="btn hide-modal" value="Hide Modal"/>
</div>
</apex:page>
@jasonjuela
Copy link

I tried to implement this sample from this post in my sf org, http://salesforce.stackexchange.com/questions/17491/creating-a-popup-panel-on-a-standard-detail-page-layout/17495#17495. However I'm having issues. My reputation is only 22 on StackExchange and it won't allow me to comment. Is this a good place to ask for help? Sorry. Let me know if there is a better place to message you if you can help. Thanks!

Error from Dev Tools on Chrome:

Uncaught TypeError: Object [object Object] has no method 'dialog' modal:43
modal.initialiseDialogs modal:43
(anonymous function) modalpage:29
fire jQuery:1037
self.fireWith jQuery:1148
jQuery.extend.ready jQuery:433
completed jQuery:103

@Oblongmana
Copy link
Author

Sorry, github didn't notify me of your comment! That message generally means jQueryUI hasn't been imported into the page, or hasn't been imported properly. The other possibility is that you are using an old version of jQueryUI or a version that doesn't include the dialog functionality - I believe it is possible to exclude dialog from a custom packaging. Check that out and let me know? Couldn't find your username on StackExchange and can't message you on github unfortunately, otherwise I'd try to contact you direct!

@kpmc
Copy link

kpmc commented Oct 31, 2014

Hi, thanks for posting this! One question: where is the jquery-ui script being referenced? I see where the .css is referenced, but don't you also need something like:

<apex:stylesheet value="{!URLFOR($Resource.jqueryui, 'css/jqueryuidialog/jquery-ui-1.10.4.custom.css')}"/>

Or am I missing something?

Thanks again.

@sigalmaya
Copy link

exactly , to make it work you must add <apex:includeScript value="{!URLFOR($Resource.jqueryui, 'jqueryui/js/jquery-ui-1.9.2.custom.min.js')}"/> as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment