Friday, May 27, 2011

JavaScript Hack to Add All Fields to Export Template

Faced with the daunting task of creating an export template in ApplyYourself that included all available fields, I decided to try my luck at using JavaScript to do the job for me (with greater accuracy).

The end result is the following hack, which adds all exposed nodes to the template.
javascript:

/* Grab the fields frame. */

var fieldsFrame =
    document.getElementsByName(
        "frameQuestionsTree")[0];
var fieldsWindow = fieldsFrame.contentWindow;
var fieldsDocument = fieldsWindow.document;

/* Grab the actions frame. */

var actionsFrame =
    document.getElementsByName(
        "frameActions")[0];
var actionsWindow = actionsFrame.contentWindow;
var actionsDocument = actionsWindow.document;

/* Find the exposed nodes to add. */

var fieldsATags = fieldsDocument.getElementsByTagName("a");
alert(fieldsATags.length + " A tags found in fields window.");

var nodeIdPattern = /Nod[0-9]+/;
var nodeATags = new Array();
for (var i = 0; i < fieldsATags.length; i++) {
  var fieldsAElem = fieldsATags[i];
  var fieldsAIdAttr = fieldsAElem.attributes["id"];
  if (fieldsAIdAttr) {
    if (fieldsAIdAttr.value.match(nodeIdPattern)) {
      var nodeNumText = fieldsAIdAttr.value.slice(3);
      fieldsWindow.setSelectedNode(parseInt(nodeNumText));
      actionsWindow.BtnAddField_onclick();
    }
  }
}
This hack was tested in...
  • Chrome 11 on Windows 7
  • Internet Explorer 9 on Windows 7

Tuesday, May 24, 2011

JavaScript Hack to Set Visibility for Field-Level Security

Having to click numerous (sometimes over 100) checkboxes just to grant or revoke visibility to certain fields via Field-Level Security settings can be a pain. Here's a JavaScript hack that can mark all of the "Visible" checkboxes on the Field-Level Security edit page.

The following code was tested in Firefox 4 and Chrome 11 on Windows 7. It can probably be adapted easily to work for marking the read-only checkbox and for clearing checkboxes as well.

javascript:

/* Locate the form. */

var flsForm =
    document.getElementById("editPage");

/* Find the form inputs. */

var inputs =
    document.getElementsByTagName("input");

var visibleInputs = new Array();
for(var i = 0; i < inputs.length; i++) {
  var titleAttr = inputs[i].attributes["title"];
  if(titleAttr != null) {
    if(titleAttr.value == "Visible") {
      var visibleInput = inputs[i];
      visibleInputs[visibleInputs.length] =
          visibleInput;
    }
  }
}

/* Mark all checkboxes. */

for(var i = 0; i < visibleInputs.length; i++) {
  var eName =
      visibleInputs[i].attributes["name"].value;
  
  var e = flsForm.elements[eName];
  
  if(!e.checked)
    e.click();
}

Wednesday, May 18, 2011

JavaScript Hack to Mass Delete Custom Picklist Values

As an extension of last night's efforts, I've created what appears to be a working JavaScript hack to delete all picklist values from a custom picklist. This simplifies maintenance of picklist values by allowing an admin to delete all the values and then simply re-add the ones that are desired.

The following code was tested in Chrome 11 on Windows 7.

javascript:

/* Gather all of the a elements on the page. */

var links = document.getElementsByTagName("a");

/* Pick out the Del links. */

var delLinks = new Array();
for (var i = 0; i < links.length; i++) {
  var link = links[i];
  
  if (link.innerHTML == "Del") {
    /*alert("Del link found!");*/
    /*alert(link.attributes['href'].value);*/
    delLinks[delLinks.length] = link;
  }
}

/* Open each Del link to delete the associated
   picklist value.
   
   This code can be augmented as desired
   to only delete certain values.
   
   However, for custom picklists it's probably
   easier to just delete all of the values
   and then re-add the desired values. */

for (var i = 0; i < delLinks.length; i++) {
  var delLink = delLinks[i];
  window.open(
      delLink.attributes['href'].value);
}

As with all hacks, please to use with caution, at your own risk.

Tuesday, May 17, 2011

Mass Deleting Picklist Values

Apparently, the only way one can (relatively) easily mass delete picklist values is by editing the object definition in the Force.com IDE.

To do this:
  1. Open the object definition (e.g., Contact.object).
  2. Delete the picklistValues elements that are no longer desired.

I had to prune a list of 485 picklist values in a language selection picklist to a more reasonable number.

Regardless of this workaround, it would be great if this feature was more easily accessible through the web UI, as per the following idea: "mass delete picklist values (setup)"


Apparently, all I succeeded in doing was shifting the order of the picklist values. At this point I am also at a loss as to how to mass delete picklist values, much to my chagrin.

However, I did eventually create a "sort of" workaround: "JavaScript Hack to Mass Delete Custom Picklist Values"

Thursday, May 12, 2011

Increasing Speed of Command Line Extract/Export with Apex Data Loader

I had a strange problem when I tried to automate a routine, daily export that I was performing with the Apex Data Loader (version 20.0 and 21.0): Exporting through the GUI only took 5 seconds, but exporting through the command line took anywhere from 30 minutes to 1 hour.

After 4 weeks, Salesforce Premier Support finally delivered a solution to the case I logged: Set the sfdc.debugMessages value to false. I'm very glad that Premier Support was able to find a simple solution to this problem.

Apparently, debug messages were so verbose for every record being exported that operation time increased by a ridiculous factor. Luckily for me, debug messages are not that important for an export.

Saturday, May 7, 2011

Bug (?) with ISNULL() Function in Validation Rules

I tried to setup a simple validation rule today in my sandbox to enforce the presence of a value in a Lookup field.

My first attempt for the error formula was:
ISNULL( Source_Program__c )

However, this turned out not to work at all. Whether a value was in the field or not, the formula never generated a validation error.

Then, I switched over to an even more basic formula:
Source_Program__c = null

This worked like a charm. Am I missing something here?