Auto Complete / Auto Suggest in eSearch Widget in Value Search

924
7
Jump to solution
02-22-2021 02:36 PM
GilbertoMatos
Occasional Contributor II

Hi!

I'm using the eSearch Widget, which is an excellent tool for my application developed with the web appbuilder. What happens is that my bosses at the company asked me to include in the search for value of this widget, for each of the search options by value (I have 4), the option to complete, that is, as the user is typing, value suggestions appear, until he can click on one he wants. Most correct, these values ​​would come from the service possibilities of the layer used in the widget, that is, if the user selects a watershed, they would suggest the possible values ​​for this field, which is the service of the layer itself. I developed a webapi in C #, which has a method (and a url), which receives the values ​​to be searched for each of these attributes. The problem is that I have no idea how to implement this call in the eSearch widget, for each of the different attributes that can be searched in the search by value. Any help will be most welcome.

Just to add: the idea would be to press each key in each of the search options by value, call my api, which returns a json restfull with the values ​​to be suggested. The problem is that everything is assembled dynamically from what I could understand.

Thanks!
Gilberto.

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Esteemed Contributor

Gilberto,

  I have done this on my main website using a custom Suggest_Textbox.js code and a custom .Net web API. So it sound like you may be halfway there already. So in the eSearch\SingleParameter.html file you would add the Suggest_Textbox dijit.

...
        <td>
          <div data-dojo-attach-point="allValueBoxContainer" style="width:100%;padding-bottom:2px;">
            <div data-dojo-attach-point="stringTextBoxContainer" style="display:none;">
              <!-- <input data-dojo-attach-point="stringTextBox" data-dojo-type="dijit/form/TextBox" data-dojo-props="trim:true" style="display:none;width:100%;height:30px;" class="dijit-form-TextBox" /> -->
              <input data-dojo-attach-point="stringTextBox" data-dojo-type="widgets/eSearch/Suggest_TextBox" data-dojo-props="trim:true" style="display:none;width:100%;height:30px;" class="dijit-form-TextBox" />
              <div data-dojo-attach-point="stringCodedValuesFS" data-dojo-type="dijit/form/FilteringSelect"
                   data-dojo-props="searchAttr:'name',intermediateChanges:true" class="dijit-form-FilteringSelect"></div>
            </div>
...

 Notice I comment out the standard TextBox dijit and add the  Suggest_Textbox dijit, having the same 

data-dojo-attach-point name.
 
In the SingleParameter.js you just need to add the 'widgets/eSearch/Suggest_TextBox' to the define array.
I also set the Suggest_TextBox.js searchAlias property which determines which url to use in the Suggest_TextBox.js.
 
Next would be editing the Suggest_TextBox.js file to use your APIs urls.
 
 

View solution in original post

0 Kudos
7 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Gilberto,

  I have done this on my main website using a custom Suggest_Textbox.js code and a custom .Net web API. So it sound like you may be halfway there already. So in the eSearch\SingleParameter.html file you would add the Suggest_Textbox dijit.

...
        <td>
          <div data-dojo-attach-point="allValueBoxContainer" style="width:100%;padding-bottom:2px;">
            <div data-dojo-attach-point="stringTextBoxContainer" style="display:none;">
              <!-- <input data-dojo-attach-point="stringTextBox" data-dojo-type="dijit/form/TextBox" data-dojo-props="trim:true" style="display:none;width:100%;height:30px;" class="dijit-form-TextBox" /> -->
              <input data-dojo-attach-point="stringTextBox" data-dojo-type="widgets/eSearch/Suggest_TextBox" data-dojo-props="trim:true" style="display:none;width:100%;height:30px;" class="dijit-form-TextBox" />
              <div data-dojo-attach-point="stringCodedValuesFS" data-dojo-type="dijit/form/FilteringSelect"
                   data-dojo-props="searchAttr:'name',intermediateChanges:true" class="dijit-form-FilteringSelect"></div>
            </div>
...

 Notice I comment out the standard TextBox dijit and add the  Suggest_Textbox dijit, having the same 

data-dojo-attach-point name.
 
In the SingleParameter.js you just need to add the 'widgets/eSearch/Suggest_TextBox' to the define array.
I also set the Suggest_TextBox.js searchAlias property which determines which url to use in the Suggest_TextBox.js.
 
Next would be editing the Suggest_TextBox.js file to use your APIs urls.
 
 
0 Kudos
GilbertoMatos
Occasional Contributor II

Hi!

Thank you very much for your help Robert. I will test what you suggested, and as soon as I finish, I put as my correct answer and attach my custom widget (based on your eSearch) so that other people can use it too.

Thanks!
Gilberto.

0 Kudos
GilbertoMatos
Occasional Contributor II

Hello Robert! How are you?

Thanks for your help so far. It helped a lot. I did as you instructed, changing the files exactly as you suggested. I pointed to my webapi with the return of the values for the autocomplete. Here the webapi return https://gis.fepam.rs.gov.br/RSAguaWebAPI/api/AutoCompleteFiltroPorValor/retornaValoresAutoComplete

The problem I'm having is that it reports proxy error and colors. I've read some articles about this on the esri forum and on the javascript api help, but I'm not able to understand what I have to do to solve this problem. I have attached a screenshot of my application in chrome, as well as the open console next to it with the error (the description is in Brazilian Portuguese). In the Suggest_Textbox.js file, I added the lines below:

esriConfig.defaults.io.corsEnabledServers.push("gis.fepam.rs.gov.br");

esriConfig.defaults.io.corsEnabledServers.push("zee.rs.gov.br");

esriConfig.defaults.io.corsEnabledServers.push("localhost");

Even adding the possible addresses of my servers, I still couldn't resolve the error. If you can give me more that help, I'll be very grateful.

Note: access to the system can be done through the link https://gis.fepam.rs.gov.br/RSAguaAutoComplete/

Thanks!
Gilberto.

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Gilberto,

Normally I get past these cors issues by using a proxy in my WAB install. I never having any luck using localhost are mixing servers i.e. one portion being on localhost and the other being on a fully qualified domain.

0 Kudos
GilbertoMatos
Occasional Contributor II

Robert,

Thanks for your response. I really don't understand the reason for the error, since both the web api that I built in c# and the application generated and customized with the web appbuilder are on the same web server and hosted on this server's iis. I'm completely out of ideas of what might be going on. I've tried to implement proxy settings in the application, but I'm not able to find myself. If you have any other ideas of what it might be, I would be grateful if you could help me.

Thanks!
Gilberto.

0 Kudos
GilbertoMatos
Occasional Contributor II

Hello @RobertScheitlin__GISP! How are you? I finally managed to fix the bug related to CORS. I just added a package via nuget and did the treatment for the colors inside the api methods.

Now I have just a little bug that I can't find the solution and with that, I'd like to ask you some simple questions regarding the solution you created in your environment to have the autocomplete. I noticed that after I type the third letter inside the text box, there is an attempt to open a drop-down box below the field, to load the options for selection. I created my method in the api, very simple, without passing parameters. When calling the api, it returns all the records contained in a table, without doing a "where like %%". How did you do in your api? Does the solution in the widget you created pass parameters to the api? Below I will detail the link with the results in json of my api, as well as the link and the place where I call the api in the GIS application. I'm asking for this help for you as now no errors are returned to me so I don't know what could be wrong. Thanks for the help.

Thank you!
Gilberto.

1) Gis Application https://gis.fepam.rs.gov.br/rsaguaautocomplete/ in "Filtrar Estações Monitoradas / Região Hidrográfica is" widget.

2) WebApi in Asp.Net C# https://gis.fepam.rs.gov.br/RSAguaWebApi/api/AutoCompleteFiltroPorValor/retornaValoresAutoComplete

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

@GilbertoMatos 

How did you do in your api? Does the solution in the widget you created pass parameters to the api?

My API uses VB.net and one of the API Functions looks like this:

        <WebGet(UriTemplate:="/suggest/parcelnumbers?parcelnum={oParNum}", ResponseFormat:=WebMessageFormat.Json, BodyStyle:=WebMessageBodyStyle.Bare)>
        Public Function GetParcelnumber(Optional ByVal oParNum As String = "") As Message
            Dim parcelnum As New acSuggestions
            Using conn As New SqlConnection()
                conn.ConnectionString = strConn2
                Using cmd As New SqlCommand()
                    cmd.CommandText = "select [PARCEL_NUMBER] from county.OwnerParcel where " & "[PARCEL_NUMBER] like @SearchText + '%'"
                    cmd.Parameters.AddWithValue("@SearchText", oParNum)
                    cmd.Connection = conn
                    conn.Open()
                    Using sdr As SqlDataReader = cmd.ExecuteReader()
                        While sdr.Read()
                            parcelnum.suggestions.Add(String.Format("{0}", sdr("PARCEL_NUMBER")))
                        End While
                    End Using
                    conn.Close()
                End Using
                Dim msg As Message
                Dim formatQueryStringValue As String = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters("f")
                If String.IsNullOrEmpty(formatQueryStringValue) = False Then
                    If formatQueryStringValue.Equals("xml", System.StringComparison.OrdinalIgnoreCase) Then
                        msg = WebOperationContext.Current.CreateXmlResponse(parcelnum)
                    ElseIf formatQueryStringValue.Equals("json", System.StringComparison.OrdinalIgnoreCase) Then
                        msg = WebOperationContext.Current.CreateJsonResponse(parcelnum)
                    ElseIf formatQueryStringValue.Equals("pjson", System.StringComparison.OrdinalIgnoreCase) Then
                        Dim json = JsonConvert.SerializeObject(parcelnum, Newtonsoft.Json.Formatting.Indented)
                        msg = WebOperationContext.Current.CreateTextResponse(json)
                    Else
                        Throw New WebFaultException(Of String)(String.Format("Unsupported format '{0}'", formatQueryStringValue), HttpStatusCode.BadRequest)
                        msg = WebOperationContext.Current.CreateJsonResponse(parcelnum)
                    End If
                Else
                    msg = WebOperationContext.Current.CreateJsonResponse(parcelnum)
                End If
                Return msg
            End Using
        End Function

As far as the code in WAB I sent you the Suggest_TextBox.js code already and you can see in there that _onKeyUp checks for the length of the string in the input and if it matches the this.characters length the it fires the _popup that sends a esriRequest (with parameters) to the API.

 

By the way neither of your posted links work for me.

0 Kudos