[SalesForce] Add Google Doc button into custom ‘notes and attachments’ Visualforce component

I had built a nice custom VF component some months back that replaced the Notes And Attachments related list. The component replaced the Attach File button and added some new left hand side actions in addition to the built-in Edit – View – Del (e.g. 'Archive')

Now the business wants to add Google Docs so I duly enabled the feature in sandbox. But how to get it to work within the custom notes and attachments component?

While I can use SOQL to query the GoogleDoc SObject to populate the related list, and I can see how to URL hack the Edit | View | Del buttons, the Add Google Doc button is a bit more complex and when clicked, invokes a bunch of Javascript loaded by SFDC, presumably if the Notes and Attachments related list is present on the page.

enter image description here

So, options I'm thinking about (but not happy with any of them):

Option 0: Drop the custom VF component and hack into the built-in Notes and Attachments related list to get back the functionality I have

  1. Hacking involves replacing the 'attach file' button and adding new left hand side actions (e.g. 'archive')

Not nuts about this as solution is fragile and dependent on SFDC-generated HTML.

Option 1: Have two related, mutually exclusive lists on the page

  1. Custom VF component that only shows Notes and Attachments plus …
  2. Standard apexRelatedList list="CombinedAttachments" with some jQuery that hides the New Note, Attach File and View All buttons as well as removing any Notes or Attachments in the list – essentially making the list a Google Docs related list only.

As with option 0, the jQuery has to manipulate SFDC-generated HTML and is thus fragile.

Option 2: Duplicate lists of Notes and Attachments

  1. Custom VF component that only shows Notes and Attachments plus …
  2. Standard apexRelatedList list="CombinedAttachments"

This would thus show each Note or Attachment twice with standard buttons on the second list. No SFDC coding required; much user confusion. Yuck.

Option 3 Hack away:

  1. Extend my custom component to include Add Google Doc button/submenu. Include as rows any GoogleDocs found under the parent record.
  2. Include on the VF page the apex:relatedList CombinedAttachments but dont render it (so the Google javascript gets included)
  3. Cross my fingers that I can recreate a custom button in the VF custom component that mimics the Add Google Doc dropdown button and actions (and that there are no cross browser issues)

Still fragile.

The best answer would be if there were URLFOR $Action global variables to add Google Doc / spreadsheet / presentation / existing but no such $Action variables exist.

I'm leaning towards Options 0 or 3 but am hoping there is some easier solution I've overlooked.

UPDATE: Per Marty C, I tried option 3 with the following jQuery (jQuery framework more elaborate than required but is standard pattern I follow):

<apex:includescript value="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" />

<script>
    $j = jQuery.noConflict();       //  reassign $ to $j to avoid conflict with VF
    $j(function() {                 //  jQuery shorthand for $(document).ready(function() ..  Wait until page loads 
        //  define the application
        var AccountView = {};

        (function(app) {            //  Define anon function
            //  --------------------------
            //  variable defintions
            //  --------------------------

            //  --------------------------
            //  init:   do initializations
            //  --------------------------
            app.init    = function() {
                app.bindings();                     //  establish bindings
                app.moveAddGoogleDocsBtnToCustomRL();
                app.hideCombinedAttachmentsRL();    //  we need to load this HTML to get 'Add Google Docs' button but we want to hide the relatedList and use our custom component instead

            };              
            //  -----------------------------------
            //  bindings:  events to event handlers
            //  -----------------------------------
            app.bindings = function() {
                // set up binding for events
    //          $j('somefilter').someEvent(function(e) {        // attach anonymous fn as event handler to <event> for all DOM matching <somefilter> $j(this) available
    //          });                                                 // end binding
            };                                                      // end all bindings             
            //  -----------------------------------
            //  moveAddGoogleDocsBtnToCustomRL
            //  -----------------------------------
            app.moveAddGoogleDocsBtnToCustomRL = function () {
                $j('td [id$="noaButtons"]').prepend($j('div [id="mutton"]'));   // locate custom component pageBlockButtons and prepend the 'Add Google Docs' div. This moves the div
            };              
            //  ------------------------------------
            //  hideCombinedAttachmentsRL:  hide the relatedList
            //  ------------------------------------
            app.hideCombinedAttachmentsRL = function() {
                $j('div[id$="combinedAttachments"]').hide();

            };

            app.init();         // Anon function invokes its own init function
        }) (AccountView);       // Execute anon function passing in an object representing our application


    }); 
</script>

This sort of worked in Winter 14/Spring 14 wherein you could link to existing Google Docs but the New Document, New Spreadsheet, New Presentation submenu buttons would show, you could fill out the dialog, but when submitted, the authentication redirect would not work and the user would be taken to the SFDC Home tab. No error message given.

I noted that this behavior would happen even with normal apex:relatedList list="CombinedAttachments" leading me to suspect that there is some authentication requirement that the link to Google Docs only come from the out-of-box standard page related list (just a suspicion). Case opened with SFDC support.

Best Answer

crop1645, there's usually no great solution in situations like this. Definitely not ones supportable by Salesforce. So, with that said, maybe you can tweak Option 3 to work like this:

  1. Extend your component as you described
  2. Include the standard related list, and do render it
  3. Hide the standard list using style="display:none"
  4. Use JavaScript to "lift" the Salesforce-generated button and move it into your custom component

This is still prone to breaking, but you should have fewer cross-browser issues. Plus, you won't have to build the button; Salesforce will have built it for you.