Today I want to talk about how to enable search feature in your SharePoint New/Edit Form for SharePoint Lookup field… I’m gonna use jQuery and jQuery UI’s Autocomplete widget to fulfill this feature.
Let’s assume you have a list called “Lookup” with all your items (to be lookup) and a list “Lookup Test” that lookup to list “Lookup”‘ title. By default, a lookup field does not allow you to do “contains” search (which is kinda very common to have nowadays).
I’m attaching the comparison of the before and after applying the tricks that I’m gonna cover in this post.
This is assuming that you already have a SharePoint Designer 2013 and you’ve created two lists as mentioned above.
First of all, Open your SharePoint Designer, navigate to your SharePoint Site and Open the New Form of the “Lookup Test” list.
Once it is opened, make sure you have already click “Advanced Mode” in order to edit the NewForm.aspx
Scroll to place holder “PlaceHolderAdditionalPageHead” content placeholder and include the necessary JS/CSS
[sourcecode]
<script src="https://code.jquery.com/jquery-1.11.3.min.js" type="text/javascript"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.11.4/themes/ui-lightness/jquery-ui.css"/>
<style>
.custom-combobox {
position: relative;
display: inline-block;
}
.custom-combobox-toggle {
position: absolute;
top: 0;
bottom: 0;
margin-left: -1px;
padding: 0;
}
.custom-combobox-input {
margin: 0;
padding: 5px 10px;
}
</style>
[/sourcecode]
Scroll to right before the closing tag of placeholder “PlaceHolderMain” and insert the following JS Code
[sourcecode language=”html”]
<script type="text/javascript">
(function( $ ) {
$.widget( "custom.combobox", {
_create: function() {
this.wrapper = $( "<span>" )
.addClass( "custom-combobox" )
.insertAfter( this.element );
this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
},
_createAutocomplete: function() {
var selected = this.element.children( ":selected" ),
value = selected.val() ? selected.text() : "";
this.input = $( "<input>" )
.appendTo( this.wrapper )
.val( value )
.attr( "title", "" )
.addClass( "custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" )
.autocomplete({
delay: 0,
minLength: 0,
source: $.proxy( this, "_source" )
})
.tooltip({
tooltipClass: "ui-state-highlight"
});
this._on( this.input, {
autocompleteselect: function( event, ui ) {
ui.item.option.selected = true;
this._trigger( "select", event, {
item: ui.item.option
});
},
autocompletechange: "_removeIfInvalid"
});
},
_createShowAllButton: function() {
var input = this.input,
wasOpen = false;
$( "<a>" )
.attr( "tabIndex", -1 )
.attr( "title", "Show All Items" )
.tooltip()
.appendTo( this.wrapper )
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass( "ui-corner-all" )
.addClass( "custom-combobox-toggle ui-corner-right" )
.mousedown(function() {
wasOpen = input.autocomplete( "widget" ).is( ":visible" );
})
.click(function() {
input.focus();
// Close if already visible
if ( wasOpen ) {
return;
}
// Pass empty string as value to search for, displaying all results
input.autocomplete( "search", "" );
});
},
_source: function( request, response ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
response( this.element.children( "option" ).map(function() {
var text = $( this ).text();
if ( this.value && ( !request.term || matcher.test(text) ) )
return {
label: text,
value: text,
option: this
};
}) );
},
_removeIfInvalid: function( event, ui ) {
// Selected an item, nothing to do
if ( ui.item ) {
return;
}
// Search for a match (case-insensitive)
var value = this.input.val(),
valueLowerCase = value.toLowerCase(),
valid = false;
this.element.children( "option" ).each(function() {
if ( $( this ).text().toLowerCase() === valueLowerCase ) {
this.selected = valid = true;
return false;
}
});
// Found a match, nothing to do
if ( valid ) {
return;
}
// Remove invalid value
this.input
.val( "" )
.attr( "title", value + " didn’t match any item" )
.tooltip( "open" );
this.element.val( "" );
this._delay(function() {
this.input.tooltip( "close" ).attr( "title", "" );
}, 2500 );
this.input.autocomplete( "instance" ).term = "";
},
_destroy: function() {
this.wrapper.remove();
this.element.show();
}
});
})( jQuery );
</script>
[/sourcecode]
The similar javascript can be found in jQuery UI Autocomplete Combobox example
Within the same location, insert the following script to convert the lookup field into combo box with search feature.
[sourcecode language=”javascript”]
//Change the lookupField base on the internal field name that you want to enable search feature.
var lookupField = "Lookup";
ExecuteOrDelayUntilBodyLoaded(function(){
$(‘select[id^="’ + lookupField + ‘"][id$="LookupField"]’).combobox();
});
[/sourcecode]
Save your NewForm.aspx and you will be prompted warning message saying that the page will no longer base on the site definition, which is okay. Click Yes to see the miracle!
Once you are happy, make sure you do the same steps for your EditForm.aspx.
Thank you very much for sharing this. Is it hard to adapt it to use multiple values? http://jqueryui.com/autocomplete/#multiple
I’m trying to implement this, but I can’t make it work, is there anything else we need to change beside the var lookupField = “Lookup”; to our own field?
Can you double check if you are able to pull the jQuery Min and UI Min JS and CSS successfully?
I used sharepoint 2010, all javascript above already copied to correct location and JQuery min and UI min and CSS able to pulled but the script still not function. the combo box not change still like before.
Hi Johan,
If your lookup field is still like before, i believe could be due to the following code not being able to Convert the ootb drop down into jquery combobox
Search for section (var lookupField = “Lookup”;)
Make sure you have the right FIELD name, replace the “Lookup” to the right column name if you havent done so.
If it is the same, try to run the following JS in developer console and see if there is any error or so.
$(‘select[id^=”‘ + lookupField + ‘”][id$=”LookupField”]’).combobox();
Sp2010 may have different dom selector requirement, but it shouldn’t vary much.
Any ideas why it doesn\’t work in other languages besides English? I\’m trying to run it at polish version of SP2013.
At english site it runs perfectly.
Not too sure about Polish but i’m sure it has got to do with the following Selector
$(‘select[id^=”‘ + lookupField + ‘”][id$=”LookupField”]’).combobox();
We are assuming the ootb Drop Down is of “Select and with Id StartsWith the lookupfield name and EndsWith “LookupField” literally, it may be due to the “LookupField” is not literally used for Polish language, i suggest maybe you can do a browser Inspect element and find out the actual DOM ID of the drop down. Change the selector and it should be able to hook up and initialize the control
Any idea why it does not work in calendar list?
Hello, thanks for good post. Its working for single value, but how to implement for multiple values. Request you to assist on this.