Pages

Wednesday, December 21, 2011

Now you see it... Now you don't!

Part of a recent project requirement was to display a set of fields on a record from a related record.  One possibility could have been formula fields for each related field that needed to be displayed.  Sigh...

Another would have been to open a second window on a second monitor.  Nah... too easy

Of course you could create a Visualforce page that pulls these fields in and add it to the page layout.  That would work, but ah... the panel is part of the page, meaning you scroll - it moves.  Suddenly you're scrolling up and down and you might as well have had two windows open.  Forehead slap!

What do you do?

I'm a huge fan of the Force.com Quick Access Menu; one of the best time savers rolled out in a recent release.

It's just a small menu panel that floats at the side of the page.  The cool part about this is if you scroll, it moves with you.  Now, how in the world are you supposed to recreate that?

Fortunately for me, I didn't want it always displayed.  Because of that, I knew I had access to Custom Links and Custom buttons (read more).  They aren't just good for linking to pages, you can use them for launching onClick Javascripts too!
//Start of Custom Javascript Button Code
{!REQUIRESCRIPT("/soap/ajax/15.0/connection.js")}
 //Let's create a new DIV
var newdiv = document.createElement("div");
var result = sforce.connection.query("Select ID From ObjectID where ID = '{!ObjectID.ID}' AND other criteria if required);

//In my case, not every record would have a related record, so to avoid unnecessary errors we'll add make sure we have a result.  Granted, in your scenario, you may return more than one record.

if(result.size>0){
    var records = result.getArray("records");
    var newdiv = document.createElement('div');
    //I'm just going to build out my URL + parameters here
    var string1 = "apex/yourVFpage?core.apexpages.devmode.url=1&id=";
    var string2 = records[0].Id;
    var string3 = string1 + string2;
    newdiv.setAttribute('id', "thepanel");
    newdiv.style.width = "85%";
    newdiv.style.height = "255px";
    newdiv.style.position = "fixed";
    newdiv.style.left = "220px";
    newdiv.style.top = "0px";
    newdiv.style.background = "#FFFFFF";
    newdiv.style.border = "1px solid #000";
    newdiv.style.zIndex = "1000";
    newdiv.style.padding = "0px";
    //Use a regular old iframe to pull in your VF page
    newdiv.innerHTML = "<iframe src='"+string3+"' width='100%' height='240px' scrolling='false'/>";

//This DIV displays the up arrow graphic and provides the onClick functionality for hiding the panel
    var newdivUp = document.createElement('div');
    newdivUp.setAttribute('id', "UpPanel");
    newdivUp.style.width = "46px";
    newdivUp.style.height = "46px";
    newdivUp.style.position = "fixed";
    newdivUp.style.left = "174px";
    newdivUp.style.top = "0px";
    newdivUp.style.background = "transparent";
    newdivUp.style.zIndex = "1000";
    //Display the image and onClick hide this panel, display the down graphic panel, and hide the info panel
    newdivUp.innerHTML = "<img id='up' src='yourUpGraphic.png' onClick='document.getElementById(\"UpPanel\").style.display=\"none\";document.getElementById(\"DownPanel\").style.display=\"block\";document.getElementById(\"thepanel\").style.display=\"none\";document.getElementById(\"DownPanel\").style.display=\"block\";'/>";

//This DIV displays the down arrow
    var newdivDown = document.createElement('div');
    newdivDown.setAttribute('id', "DownPanel");
    newdivDown.style.width = "46px";
    newdivDown.style.height = "46px";
    newdivDown.style.position = "fixed";
    newdivDown.style.left = "174px";
    newdivDown.style.top = "0px";
    newdivDown.style.background = "transparent";
    newdivDown.style.zIndex = "1000";
    newdivDown.style.display = "none";
    //Displays the image and onClick hide this panel, display the up graphic and the info panel
    newdivDown.innerHTML = "<img src='youDownGraphic.png' id='down' onClick='document.getElementById(\"DownPanel\").style.display=\"none\";document.getElementById(\"UpPanel\").style.display=\"block\";document.getElementById(\"thepanel\").style.display=\"block\";' />";

//These three lines will add the DIVs created above to your page
    document.body.appendChild(newdiv);
    document.body.appendChild(newdivUp);
    document.body.appendChild(newdivDown);
}
//And just in case you don't return any records, display an error message
else if(result.size==0){
    alert('This record is not associated with an \'yourObject\' record. Please check the \'yourObject\' field and try again.');
}

Here's my end result in the "opened" state:

In the closed state:
And since you each DIV's position attribution to be "fixed", the panel, "x," or "+" will float at the top of your page for easy use when related data is needed for comparison purposes.

...or of course you could just open two browser windows.  Your choice.