SharePoint – Advanced search box autocomplete preoperty restrictions
When adding properties to the Advanced search web part you are bound to know exactly which metadata is included and how it’s spelled. This could be frustrating.
For some reason MS has decided not to help us spell like every other search component would do nowadays.
Consider you have 3 different metadata tags which is all choice or lookup fields. Now, you might want to autocomplete those fields in the Advanced search property restrictions to make sure that the spelling is correct or just to show the users which choices they have.
I implemented this with jQuery-UI which has jQuery-autocomplete included. I also decided to do all the gets by using the SharePoint client OM.
I will not tell you how to define your metadata properties in the search service or how to make them appear in the Advanced search webpart, you can google that
Here is the javascript. You will have to refer to jQuery js, jQuery-UI js and jQuery-UI css.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
var currentTextbox; var multiChoiceField; var autocompleteSource = new Array(); var fieldName; var allItems; var currentTextbox; $(function () { //find all property select elements. //bind the change event to fetch the autocomplete source. $("select[id*='ASB_PS_plb_']").on("change", function () { var propTitle = $(":selected", $(this)).text(); //find the belonging input text element currentTextbox = $(this).parent().children('input') initGetAutocompleteItems(propTitle); }); }); function initGetAutocompleteItems(propertyValue) { switch (propertyValue) { case "City": getItemsFromList("Cities"); break; case "Country": getItemsFromList("Countries"); break; case "Type": getItemsFromChoiceField(propTitle); break; default: //if the property is not defiened, destroy autocomplete binding if (currentTextbox.data('ui-autocomplete') != undefined) { currentTextbox.autocomplete('destroy'); } break; } } //asks SharePoint for list itemes. function getItemsFromList(listTitle, field) { //use title field if no field is specified fieldName = field != null && field != "Title" ? field : "Title"; includeField = "Include(" + fieldName + ")"; var context = new SP.ClientContext.get_current(); var list = context.get_web().get_lists().getByTitle(listTitle); var query = '<View Scope='RecursiveAll'></View>'; var camlQuery = new SP.CamlQuery(); camlQuery.set_viewXml(query); allItems = list.getItems(camlQuery); context.load(allItems, includeField); context.executeQueryAsync(Function.createDelegate(this, this.getListItemsSuccess), Function.createDelegate(this, this.getSourceFailed)); } //asks SharePoint for choicefield function getItemsFromChoiceField(fieldInternalName) { var context = new SP.ClientContext.get_current(); var web = context.get_web(); //get the choicefield multiChoiceField = context.castTo(web.get_fields().getByInternalNameOrTitle(fieldInternalName), SP.FieldChoice); context.load(multiChoiceField); context.executeQueryAsync(Function.createDelegate(this, this.getChoiceFieldSuccess), Function.createDelegate(this, this.getSourceFailed)); } //sets the autcompleteSource to the choices in the choicefield function getChoiceFielCSuccess() { autocompleteSource = multiChoiceField.get_choices(); autoCompleteAdvancedSearch(); } //sets the autocompleteSource to the items in the list from specified field function getListItemsSuccess() { //Iterate over all items and add them to the source var listItemsEnumerator = this.allItems.getEnumerator(); while (listItemsEnumerator.moveNext()) { var currentItem = listItemsEnumerator.get_current(); var itemValue = currentItem.get_item(fieldName); autocompleteSource.push(itemValue); } autoCompleteAdvancedSearch(); } function autoCompleteAdvancedSearch() { //unbind the current autocomplete source //this must be done if the propery is changed in the dropdown if (currentTextbox.data('ui-autocomplete') != undefined) { currentTextbox.autocomplete('destroy'); } //autcomplete the current textbox currentTextbox.autocomplete({ source: autocompleteSource, matchContains: true, selectFirst: false }); } function getSourceFailed() { //handle error } |
You can put this in your masterpage, a content editor or likewise.
So, I will give you one example. I have a loopkup field called “City” which is looking at a custom list called “Cities” which contains names of cities.
Since the autocomplete source was created when the property dropdown changed the suggestions will show directly, in this case when i type the letter “n”.
If I would change the property in the dropdown to “Country” the autcomplete source in textbox will refresh with a new source from the “Countries” list, same goes for “Type”.