Sharepoint SIG

Thoughts and ideas from your SharePoint support team

Replacing a Drop-Down List in Nintex Forms with an Autocompleting Textbox Using jQuery

| 0 comments

An annoyance that often occurs in forms is having to select an item in a drop-down list with dozens or hundreds of items. No one enjoys scrolling through these giant lists. For the form I was working on, I needed to replace a potentially large drop-down list with an auto-completing textbox. Some issues that arose with this were that the drop-down list was linked to a lookup column in the list, and also applied a filter to a second drop-down list. To solve this problem, I wrote a jQuery plugin which replaces a drop-down list with an autocompleting textbox, and disables a second drop-down list until a value is chosen for the first field.

Getting started with jQuery in Nintex Forms is easy because both jQuery and jQuery UI are already included by Nintex. You can just go ahead and start using them. It is worth noting that I am using Nintex Forms 2010 version 1.2.1.3, which uses an older version of jQuery (1.6.1).

Some Setup

I needed to alter the form itself before I could get too far into anything. Initially the form just contained the two drop-down lists. I dragged a single line textbox onto the form and placed it where the first drop-down list was originally. The drop-down list can be moved to anywhere on the form. It doesn’t matter where it is because it will be completely hidden in the end.

Although I planned on using the autocomplete textbox to select the value, the original drop-down is still needed as it is linked to the lookup column, so it is still there to pull the values from. I didn’t want the drop-down to still be shown though so I had to add a simple CSS class and apply it to the drop-down. You can add the custom CSS class through the Form Designer page. When on the Form Designer page, click Settings in the ribbon at the top, expand the Custom CSS section, and add the following class.

.hidden {
    visibility: hidden;
}

To apply the CSS class to the drop-down we want to hide, simply click on the drop-down field in the Form Designer. When you have the field selected there should be a CSS class textbox in the ribbon at the top. All you have to do is enter “hidden” (without the quotes) in this textbox.

Another small piece of initial setup that I had to do was tell the Nintex Form to store the IDs of the two drop-down fields and the text box in JavaScript variables. This can be done from the Form Designer page. Double-clicking on a field will bring up the Control Settings modal window. In this modal window expand the Advanced section, and change the Store Client ID in JavaScript Variable setting to Yes. This will make a text box appear where a variable name can be entered. You can give these variables any meaningful name you like.

NOTE: There seems to be a problem with the plugin if the field that we hide is set as required. If you set the hidden drop-down as not required and set the textbox as required instead it should solve the problem.

Using the Plugin

A ZIP of the finished plugin can be found at autocompleteplugin.js

After the previously mentioned setup is done, the next thing that needs to be done is include the plugin .js file in the form. First upload the file somewhere in your SharePoint site; I put mine in Site Assets. Then you can include the file by going to the Form Designer page. Once in the designer, open up the form settings modal by clicking Settings in the top ribbon. Inside the settings modal you want to expand the Advanced section and put either the relative or absolute path to the plugin JavaScript file in the Custom JavaScript Includes textbox. Lastly, we need to activate the plugin. Still in the same modal window, expand the Custom JavaScript section and call the plugin within a document ready handler. For the arguments you just need to pass in the names of the JavaScript variables that you told Nintex Forms to store the field IDs in. For example:

NWF$(document).ready(function() {
    NWF$.dropdownAutocomplete(autocompleteDropDown,
            autocompleteTextbox, secondaryDropDown);
});

Activating the plugin this way should take care of everything else and the autocomplete textbox should be up and running. For details on how it works, keep reading.

The Code

I started out the code with just pulling the values from the first drop-down list into the autocompleting textbox. (Note that in my snippets I use jQuery using $ since I made it into a plugin; if you’re trying to just copy and paste these snippets into Nintex Forms instead of using the completed plugin then you’ll have to use NWF$ instead.)

var textbox = $("#" + textBoxId);
var dropDown1 = $("#" + dropDown1Id);
enableOrDisableSecondDropDown();

textbox.autocomplete({
    source: function(request, response) {
        var autocompleteVals = [];

        $(dropDown1).children().each(function() {
            if ($(this).text() != "(None)" 
                    && $(this).text().toLowerCase()
                    .indexOf(request.term.toLowerCase()) >= 0) {
                autocompleteVals.push($(this).text());
            }
        });

        response(autocompleteVals);
    },
    minLength: 1,
    select: function(event, ui) {
        var fieldOption = $("#" + dropDown1Id + " option")
                .filter(function() {
            return $(this).html() == ui.item.value;
        });

        $(fieldOption).attr("selected", true);
        $(dropDown1).change();
    }
});

First I use jQuery selectors to grab the textbox and the drop-down list. Then I call jQuery UI’s autocomplete function with 3 options:

  • source
    • This is where the autocomplete values come from.
    • Can be an array, or a function.
    • When you use a function to generate the autocomplete values, the function must have two parameters: request and response. Request contains the text in the textbox, and response is a callback function. Once you have an array of autocomplete values you must call response with the array as a parameter.
    • I grab the values from the drop-down list and populate the autocomplete values array with them.
  • minLength
    • This is how many characters you want to be typed before the autocompleting starts.
    • I want autocompleting to start right away so I set it to 1.
  • select
    • The event handler for when a user picks something from the autocomplete list.
    • Is a function with two parameters: event and ui.
    • For my purposes I only had to use ui, which contains the value selected by the user.
    • In my select function, I set the item that the user picked as selected in the hidden drop-down list (because it links to the lookup column, and to the second drop-down).
    • Secondly, I fire off the onchange event for the hidden drop-down. This causes it to update the available values in the second drop-down list.

Close to the beginning of the previous code block I call a function called enableOrDisableSecondDropDown(). This function simply checks if the value currently in the textbox matches a value in the first drop-down list. If it matches, the second drop-down list is enabled, otherwise it’s disabled. The implementation is as follows.

function enableOrDisableSecondDropDown() {
    var found = false;
    // Check if the value in the textbox is valid.
    $(dropDown1).children().each(function() {
        if ($(textbox).val() == $(this).text()) {
            found = true;
            return false; //break
        }
    });

    if (found) {
        $("#" + dropDown2Id).attr("disabled", false);
    }
    else {
        $("#" + dropDown2Id).attr("disabled", true);
    }
}

I also want enableOrDisableSecondDropDown() to be called whenever the value of the textbox is changed, to check whether the second drop-down should be enabled. I did this by added a textbox change event handler.

textbox.change(function() {
    enableOrDisableSecondDropDown();
});

This covers pretty much all the code. The only other thing I wanted to do was make this code as reusable as possible. I accomplished this by making the code into a jQuery plugin by wrapping all the above code in:

(function($) {
    $.dropdownAutocomplete = function(dropDown1Id, textboxId,
            dropDown2Id) {
        ...
    }
})(NWF$)

Leave a Reply