Wednesday 9 February 2011

Layered Visualforce Lookup

Following on from an earlier post that explained how to replicate the standard Salesforce lookup in Visualforce, I now present the new and improved Layered Lookup. If you haven't read the original, I'd recommend you read that first as it covers how the lookup actually gets populated, which I haven't reproduced here.

This new lookup provides the same functionality as the original, but displays the lookup in a layer in the existing browser window, rather than opening a new popup.

The image below shows the new lookup in action:



Diving into the page, here are the key aspects to providing a layer.  First the styling that will display it correctly:

<style>

#popupcontent{
   position: fixed;
   top: 10%;
   left: 25%;
   width: 50%;
   height: 80%;
   display: none;
   overflow: auto;
   border:3px solid #585858;
   background-color:white;
   //border:1px solid #333;
   z-index:100;
   padding:5px;
   line-height:20px;
}
#opaque {
    position: fixed;
    top: 0px;
    left: 0px;
    width: 100%;
    height: 100%;
    z-index: 1;
    display: none;
    background-color: gray;
    filter: alpha(opacity=80);
    opacity: 0.8;
    -moz-opacity:0.8;
    -khtml-opacity:0.8
}
* html #opaque {
    position: absolute;
}
</style>

the popupcontent style specifies the styling for my layer that replaces the popup, while the opaque style is used to turn the rest of the page grey so that the new layer stands out. Note that the both of these styles have a display setting of "none" - this means they will be hidden when the page is displayed.

Next there is the actual content that will be popped up:

<div id="opaque"/>
   <div id="popupcontent">
  <apex:form id="form" >  
        
     <div style="width 100%">
        <apex:pageBlock title="Lookup" id="block">
           
          <apex:pageBlockSection id="section">
              Enter search text and click Go<br/>
              <apex:inputText value="{!query}" id="query"/> 
              <apex:commandButton value="Go" action="{!runQuery}" rerender="results"/>
          </apex:pageBlockSection>
        </apex:pageBlock>

        <apex:pageBlock id="results">
          <apex:pageBlockSection columns="1">
              <apex:pageBlockTable value="{!accounts}" var="account">
                <apex:column headerValue="Name">
                  <apex:outputLink value="#" onclick="fillIn('{!account.Name}', '{!account.id}')">{!account.Name}</apex:outputLink>       
                </apex:column>
                <apex:column headerValue="Street" value="{!account.BillingStreet}"/>
                <apex:column headerValue="City" value="{!account.BillingCity}"/>
                <apex:column headerValue="Postcode" value="{!account.BillingPostalCode}"/>
              </apex:pageBlockTable>    
          </apex:pageBlockSection>
        </apex:pageBlock>
        <button type="button" onclick="hidepopup();">Close Window</button>
     </div>
   </apex:form>
 </div>

and finally there are a couple of javascript methods that handle switching the display of the opaque and popup elements to make them visible and invisible on demand:

function showpopup()
   {
      document.getElementById('opaque').style.display='block';
      var popUp = document.getElementById("popupcontent");
      
      popUp.style.display = "block";
      
   } 
   
   function hidepopup()
   {
      var popUp = document.getElementById("popupcontent");
      popUp.style.display = "none";
      document.getElementById('opaque').style.display='none';
   }
   

When the user clicks the Lookup button, the showpopup() javascript is invoked to grey the page out and render the lookup "popup". If the user searches, finds results and clicks on the name, a javascript method is invoked to fill in the account name and id and execute the closepopup() method. Clicking the Close Window button simply executes the closepopup() method.

The code and page can be downloaded here - note that there's now just a single page and controller!

8 comments:

  1. great help , thanks

    ReplyDelete
  2. This is great.

    I have an application that requires the custom look up to be a member of a dataTable. Any suggestion on how to get the correct component id path to the fillIn function?

    ReplyDelete
  3. You should be able to use the $Component mechanism. As long as you do this inside the column element that contains the lookup, Visualforce should handle it.

    ReplyDelete
  4. i used this logic in pageblock table column and its working fine. The requirement is to open the popup inline..I used the " Css display :inline" but what is happening is when i click on any of the values in column it opens the pop up inline to the first row only.. Could you please help me out. Its on an urgent basis..

    I would be good if u give me ur mail id.. I will share my code with u

    ReplyDelete
    Replies
    1. I'm afraid I can't provide help on a 1-1 basis. Best I can suggest is that you post your code up to the developerforce visualforce discussion board.

      Delete
  5. very good from here Nicaragua, Central America also are programming on this platform

    ReplyDelete
  6. Hi Bob,

    Could you please help me with this ?
    Https://developer.salesforce.com/forums/ForumsMain?id=906F0000000A4hWIAS

    Thanks

    ReplyDelete