I have a feature service published out of data from our enterprise geodatabase. I need to implement autosuggest/autocomplete functionality based on attributes of
feature class of published service. Has anyone implemented anything similar ? any pointers will be greatly appreciated.
Roger,
I have personally developed my own RESTful .Net web service that handles auto complete for me then I built a custom dijit "Suggest_TextBox" that connects with my webservice. There may be an easier way but for a developer like me this was the easy route.
Thank you Robert for your quick response.
Would you mind posting some sample code on how to do that ?
Roger,
Here is the Suggest_TextBox.js code:
define(['dojo/_base/declare',
'dojo/_base/html',
'dijit/form/ValidationTextBox',
'dijit/_HasDropDown',
'dojo/on',
'esri/request',
'dojo/_base/lang',
'dojo/Deferred',
'dijit/Menu',
'dijit/MenuItem',
'dojo/_base/array',
'dijit/focus',
'dojox/html/entities',
'dojo/query'],
function (declare, html, ValidationTextBox, _HasDropDown, on, esriRequest, lang,
Deferred, Menu, MenuItem, array, focusUtil, entities, query) {
return declare([ValidationTextBox, _HasDropDown], {
required: false,
trim: true,
characters: 3,
searchAlias: null,
enterPressed: false,
postCreate: function () {
this.own(on(this, 'keyup', lang.hitch(this, '_onKeyUp')));
this.own(on(this, 'keydown', lang.hitch(this, '_onKeyDown')));
},
_onKeyDown: function (evt) {
if(evt.key === 'Enter' && this.dropDown){
this.enterPressed = true;
this.closeDropDown();
}
this.enterPressed = false;
return true;
},
_onKeyUp: function (evt) {
if(evt.key === 'Enter' && this.dropDown){
this.enterPressed = true;
this.closeDropDown();
return;
}
this.enterPressed = false;
if (this.get('value').length >= this.characters) {
this._popup(evt.key);
}
},
_popup: function (key) {
var value = this.get('value');
var def = new Deferred();
if(key === 'ArrowDown' && this.dropDown){
if(focusUtil.curNode){
focusUtil.curNode.blur();
}
focusUtil.focus(this.dropDown);
return;
}
if(key === 'Enter' && this.dropDown){
this.closeDropDown();
this.enterPressed = true;
return;
}
def.then(lang.hitch(this, function (resp) {
// Create our new Menu (the drop down)
this.dropDown = new Menu({});
array.map(resp.suggestions, lang.hitch(this, function(val){
var item = new MenuItem({
label: val,
onClick: lang.hitch(this, function (evt) {
this.closeDropDown();
var evtObj;
if(evt.target.tagName === 'TR'){
evtObj = query('.dijitMenuItemLabel',evt.target)[0].innerHTML;
}else{
evtObj = evt.target.innerHTML;
}
this.attr('value', entities.decode(evtObj));
})
});
this.dropDown.addChild(item);
}));
if(this.enterPressed){return;}
this.openDropDown();
}), lang.hitch(this, function (err) {
console.info(err);
}));
var endPointUrl;
var content;
switch(this.searchAlias){
case 0:
endPointUrl = "http://mywebservice/suggest/ppins";
content = {ppin: value,f: 'json'};
break;
case 1:
endPointUrl = "http://mywebservice/suggest/parcelnumbers";
content = {parcelnum: value,f: 'json'};
break;
case 2:
endPointUrl = "http://mywebservice/suggest/ownernames";
content = {owner: value,f: 'json'};
break;
case 3:
endPointUrl = "http://mywebservice/suggest/addresses";
content = {address: value,f: 'json'};
break;
}
esriRequest({
url: endPointUrl,
content: content,
handleAs: "json",
timeout: 10000
},{useProxy: true, usePost: false, disableIdentityLookup: true}).then(lang.hitch(this,function(response){
def.resolve(response);
}), lang.hitch(this, function(err){
def.reject(err);
}));
}
});
});
and a portion of the web service that deals with suggestions:
<WebGet(UriTemplate:="/suggest/ownernames?owner={owner}", ResponseFormat:=WebMessageFormat.Json, BodyStyle:=WebMessageBodyStyle.Bare)>
Public Function GetOwner(Optional ByVal owner As String = "") As acSuggestions
Dim owners As New acSuggestions
Using conn As New SqlConnection()
conn.ConnectionString = strConn2
Using cmd As New SqlCommand()
cmd.CommandText = "select Name from county.OwnerParcel where " & "Name like @SearchText + '%'"
cmd.Parameters.AddWithValue("@SearchText", owner)
cmd.Connection = conn
conn.Open()
Using sdr As SqlDataReader = cmd.ExecuteReader()
While sdr.Read()
owners.suggestions.Add(String.Format("{0}", sdr("Name")))
End While
End Using
conn.Close()
End Using
Return owners
End Using
End Function
and the acSuggestions class:
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Runtime.Serialization
Imports System.Text
Namespace ParcelRestServices
Public Class acSuggestions
Public Property suggestions() As New List(Of String)
End Class
End Namespace
Thank you Robert. This was useful.