Dropdown field - first item should be blank

2019-03-30 10:49发布

问题:

Using sharepoint build in lookup column and it set to required field. SharePoint automatically selects the first item in the dropdown box (kinda misleading for the end users).

Is there a way to display blank or Null for the first row of this drop down box?

(I am open to any solution. I prefer javascript type solution)

回答1:

For Choice fields, the default value is configured in the column settings. If the "Default value" input box is populated, delete the value in order to use no default value.

Edit

For Lookup fields, the field seems to change dramatically if it is required. Fields that are NOT required have a "(None)" value by default. However, toggling the field to required will remove the "(None)" value and the first value is selected automatically.

One thing I found, is that if you use JavaScript to add the null value to the dropdown and then try to press OK you get an error page: "An unexpected error has occurred." As a workaround, I wrote some more code to do a quick validation that the field has a value before the form is submitted. If the field has no value, then it will prompt the user and cancel the submit. (Note: this code is only attached to the OK buttons so you may get errors while editing EditForm.aspx.. just choose a value for your lookup field and you'll be able to edit like normal)

Anyways, onto the code... I think the only line you'll need to change is var fieldTitle = 'Large Lookup Field'; to update it to the name of your field.

<script type="text/javascript">

function GetDropdownByTitle(title) {
    var dropdowns = document.getElementsByTagName('select');
    for (var i = 0; i < dropdowns.length; i++) {
        if (dropdowns[i].title === title) {
            return dropdowns[i];

        }
    }
    return null;
}

function GetOKButtons() {
    var inputs = document.getElementsByTagName('input');
    var len = inputs.length;
    var okButtons = [];
    for (var i = 0; i < len; i++) {
        if (inputs[i].type && inputs[i].type.toLowerCase() === 'button' && 
             inputs[i].id && inputs[i].id.indexOf('diidIOSaveItem') >= 0) {
             okButtons.push(inputs[i]);
        }
    }
    return okButtons;
}

function AddValueToDropdown(oDropdown, text, value, optionnumber){
    var options = oDropdown.options;
    var option = document.createElement('OPTION');
    option.appendChild(document.createTextNode(text));
    option.setAttribute('value',value);
    if (typeof(optionnumber) == 'number' && options[optionnumber]) {
        oDropdown.insertBefore(option,options[optionnumber]);
    }
    else {
        oDropdown.appendChild(option);
    }
    oDropdown.options.selectedIndex = 0;
}

function WrapClickEvent(element, newFunction) {
    var clickFunc = element.onclick;
    element.onclick = function(event){
        if (newFunction()) {
            clickFunc();
        }
    };
}

function MyCustomExecuteFunction() {
    // find the dropdown
    var fieldTitle = 'Large Lookup Field';
    var dropdown = GetDropdownByTitle(fieldTitle);
    if (null === dropdown) {
        alert('Unable to get dropdown');
        return;
    }

    AddValueToDropdown(dropdown, '', '', 0);

    // add a custom validate function to the page
    var funcValidate = function() {
        if (0 === dropdown.selectedIndex) {
            alert("Please choose a value for " + fieldTitle + ".");
            // require a selection other than the first item (our blank value)
            return false;
        }
        return true;
    };

    var okButtons = GetOKButtons();
    for (var b = 0; b < okButtons.length; b++) {
        WrapClickEvent(okButtons[b], funcValidate);
    }
}

_spBodyOnLoadFunctionNames.push("MyCustomExecuteFunction");

</script>


回答2:

In response Kit Menke, I've made a few changes to the code so it will persist previous value of the dropdown. I have added the following lines of code to AddValueToDropdown()....

function AddValueToDropdown(oDropdown, text, value, optionnumber){
        var selectedIndex
        if (oDropdown.options.selectedIndex)
                selectedIndex = oDropdown.options.selectedIndex;
        else
                selectedIndex = -1;

        // original code goes here

        // changed last line of code (added "selectedIndex+1")
        oDropdown.options.selectedIndex = selectedIndex+1;
}


回答3:

To improve on top of Aaronster's answer: AddValueToDropdown can be done that way:

var injectedBlankValue = false;
function AddValueToDropdown(oDropdown, text, value, optionnumber) {
    for (i = 0; i < oDropdown.options.length; i++) {
        option = oDropdown.options[i];
        if(option.getAttribute('selected')) // If one is already explicitely selected: we skip the whole process
            return;
    }

    var options = oDropdown.options;
    var option = document.createElement('OPTION');
    option.appendChild(document.createTextNode(text));
    option.setAttribute('value', value);
    if (typeof (optionnumber) == 'number' && options[optionnumber]) {
        oDropdown.insertBefore(option, options[optionnumber]);
    }
    else {
        oDropdown.appendChild(option);
    }
    // changed last line of code (added 'selectedIndex+1')
    oDropdown.options.selectedIndex = 0;
    injectedBlankValue = true;
}

This is needed for document libraries where "add" and "set properties" are two distinct pages.
And funcValidate starts with:

var funcValidate = function () {
    if (!injectedBlankValue)
        return true;

All these changes is to make the whole thing work with document libraries.