Mass deleting picklist values in Salesforce with AJAX javascript hack (2018 version)

More than 5 years ago I wrote an article on how to Mass delete Picklist values in Salesforce, this is still my most visited article and I have been meaning to get back to it for years. At least now it seems like it will be a part of the standard functionality sometime in the near future (mass delete picklist values (setup)) but today I had to do this at a customer so I had to solve it once again.

I tried using my old script but ended up with errors, Lightning doesn’t like loading external JavaScript things into itself. I respect that and switched to Classic, this is a Sysadmin Only exercise anyways.

Aura Content Security Policy directive

It works out of the box in Classic but it’s very quiet about what’s happening and you don’t really know what’s happening. Also if you accidentally clicked the bookmark in a production environment you’re going to have a bad time

Fuck It, We’ll Do It Live

Updated JavaScript looks like this:


var allClear = function() {
var links = document.getElementsByTagName("a");
var whatToDelete = prompt("Do you want to Delete 'Active' or 'Inactive' picklist values?'''", "Inactive");
if(!(whatToDelete === "Active" || whatToDelete === "Inactive")) {
    window.alert("Invalid choice, quitting");
} else {
    var onlyInactive = whatToDelete === "Inactive";

    var delLinks = new Array();
    for (var i = 0; i < links.length-1; i++) {
      var link = links[i];

      if(onlyInactive) {
        if(link.innerHTML === "Activate") {
            var link = links[i-1];
        } else {
      if (link.innerHTML == "Del") {

    if(delLinks.length == 0) {
        window.alert("Nothing to delete");
    } else {
        var goAhead = confirm("You're about to delete " + delLinks.length + " picklist values");
        if(goAhead) {
            for (var i = 0; i < delLinks.length; i++) {
              var delLink = delLinks[i].href
              // Synchronous AJAX style
              xmlhttp = new XMLHttpRequest();
    "GET",delLink, false);
              console.log("Deleting #" + i + ": " +  delLink);

            window.setTimeout(allClear, 2000);

You can still load it from where I store it by creating a bookmark with this URL:

javascript:(function()%7Bvar s = document.createElement("script"); s.src = ""; void(document.body.appendChild(s));%7D)()

Clicking it on a Global Value Set Detail page will give you a prompt:

Clicking ok will go ahead and select the inactive Picklist values and prompt again:

Clicking Cancel will abort at all times.
Clicking on on this last Confirmation dialogue will delete your Inactive picklist values and the page will refresh.

If you want to delete Active Picklist values you'll have to change the "Inactive" string to "Active" after clicking the bookmark:

Same thing will happen next, you're asked to confirm:

Picklists are deleted and page reloaded. If you have a lot of values it might take some time so starting up the Developer Console is not a bad idea:

Deleting #262:
Deleting #263:
Deleting #264:
Deleting #265:
Deleting #266:
Deleting #267: 

I deleted 350 picklist values in just over 2 minutes so it will not take forever, next step for this script would be to add a spinning progressbar and some bells and whistles but for now this at least solves the problem.

Since you need to have at least 1 value in a Value Set it will not be able to delete all of the Active picklist values but at least you'll save some mouse clicks.

You'll get a warning in the browser that synchronous XML requests are deprecated:

Running the requests asynchronous works fine but the browser will be super swamped if you're deleting hundreds of picklist values so this one is better. When the day finally comes and support for synchronous XML requests are removed I'll make sure to update this but until then this hack is good enough.