How to pass a large number of selections from a standard list view to a Visualforce page

Buttons can be defined and added to an object’s standard list view and these buttons can access the selected objects:

listview

If only a few items are selected then the IDs can be passed on to a Visualforce page like this (a “List Button” with “Display Checkboxes” checked that has behavior “Execute JavaScript” and content source “OnClickJavaScript”):

var ids = {!GETRECORDIDS($ObjectType.Contact)};
if (ids.length) {
    if (ids.length <= 100) {
        window.location = '/apex/Target?ids=' + ids.join(',');
    } else {
        alert('Select 100 or less');
    }
} else {
    alert('Select one or more Contacts');
}

The limit of 100 selected items is imposed because 2k characters is generally considered the longest URL that works safely everywhere, and a GET requires that each 15 character ID is appended to the URL together with a delimiter (to pass the values).

So what if you need to support more than 100 selected objects? (The standard list view UI does allow selections to be made on multiple pages and allows a single page to show up to 200 objects.) Using a POST instead of a GET where the ID values are part of the request body rather than the URL avoids the URL length problem. Here is how to do that:

var ids = {!GETRECORDIDS($ObjectType.Contact)};
if (ids.length) {
    var form = document.createElement("form");
    form.setAttribute("method", "POST");
    form.setAttribute("action", "https://c.na15.visual.force.com/apex/Target");
    var hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", "ids");
    hiddenField.setAttribute("value", ids.join(','));
    form.appendChild(hiddenField);
    document.body.appendChild(form);
    form.submit();
} else {
    alert('Select one or more Contacts');
}

This JavaScript creates a form and posts it to the server. An important part of making this work is that the full target URL needs to be specified as described in this Get POST data via visualforce page article otherwise the Apex controller can’t pickup the posted data via ApexPages.currentPage().getParameters(). An obscure trick to say the least.

This page:

<apex:page controller="Target">
    <h1>Target</h1>
    <apex:repeat value="{!ids}" var="id">
        <div>{!id}</div>
    </apex:repeat>
</apex:page>

and controller:

public with sharing class Target {
    public String[] ids {
        get {
            if (ids == null) {
                String s = ApexPages.currentPage().getParameters().get('ids');
                if (s != null) {
                    ids = s.split(',');
                } else {
                    ids = new String[] {};
                }
            }
            return ids;
        }
        private set;
    }
}

can be used to demonstrate that the IDs are passed correctly for both versions of the JavaScript button.

Advertisements

One thought on “How to pass a large number of selections from a standard list view to a Visualforce page

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s