Auto Complete / Auto Suggest in eSearch Widget in Value Search

2446
12
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
3 Solutions

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

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
RobertScheitlin__GISP
MVP Emeritus

So this is the response I get from my web service

{"suggestions":["123","1231","1232","1233","1234","1235","1236","1237","1238","1239","12333","12334","12335","12335","12336","12337","12339","12340","12341","12342","12343","12344","12345","12346","12347","12348","12349"]}

And yours is:

[{"texto":"Arroio Areal"},{"texto":"Arroio Arenal"},{"texto":"Arroio Baje"},{"texto":"Arroio Bolacha"},{"texto":"Arroio Candiota"},{"texto":"Arroio Caracá"},{"texto":"Arroio Castelhano"},{"texto":"Arroio Cavera"},{"texto":"Arroio Chico Loma"},{"texto":"Arroio Chuí"},{"texto":"Arroio da Pintada"},{"texto":"Arroio das Lavras"},{"texto":"Arroio Del Rei"},{"texto":"Arroio Do Bote"},{"texto":"Arroio dos Ratos"},{"texto":"Arroio Francisco Alves"},{"texto":"Arroio Garupa"},{"texto":"Arroio Grande"},{"texto":"Arroio Ibacuru"},{"texto":"Arroio Ibirocai"},{"texto":"Arroio Jacaré"},{"texto":"Arroio Jaguarão-Chico"},{"texto":"Arroio João Dias"},{"texto":"Arroio Não Sabia"},{"texto":"Arroio Pelotas"},{"texto":"Arroio Pequiri"},{"texto":"Arroio Petim"},{"texto":"Arroio Pinhal"},{"texto":"Arroio Pirai"},{"texto":"Arroio Portão"},{"texto":"Arroio Ribeiro"},{"texto":"Arroio Ribeiro Pequeno"},{"texto":"Arroio Saicã"},{"texto":"Arroio São Lourenço"},{"texto":"Arroio Sutil"},{"texto":"Arroio Taquara"},{"texto":"Arroio Taquarembozinho"},{"texto":"Arroio Telho"},{"texto":"Arroio Vacaquá"},{"texto":"Arroio Velhaco"},{"texto":"Arroio Vira Carreta"},{"texto":"Lagoa dos Barros"},{"texto":"Rio Carreiro"}]

The BIG difference is you are returning an array of objects and mine is returning an object that has a property containing an array of strings...

So in the def.then of my code I am doing

array.map(resp.suggestions, lang.hitch(this, function(val){

iterating through the resp.suggestions (where resp is an object and suggestions is a property of that object and is an array). In your case it would be more like:

array.map(resp, lang.hitch(this, function(val){
  var item = new MenuItem({
    label: val.texto,
    onClick: lang.hitch(this, function (evt) {
...

View solution in original post

GilbertoMatos
Occasional Contributor II

Perfect Robert!

It worked correctly. Thanks for the help once again.

Hug

View solution in original post

0 Kudos
12 Replies
RobertScheitlin__GISP
MVP Emeritus

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
GilbertoMatos
Occasional Contributor II

Hello @RobertScheitlin__GISP! How are you?

 

After more than a year, I needed to support this functionality. What happens is that after the user enters three characters or more, the search code through my api works correctly, bringing a total of 43 options (for the value 'arr' without the quotes). What happens is that it is not opening the options as a suggestion. I have already debugged the code and no errors were reported in the console. Could you give me any suggestions as to what might be going on? I notice that below the field, something tries to open, but it seems to open empty.

 

Thank you very much in advance.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

So are you saying that in the Suggest_TextBox.js code you are getting the results you would expect from your C# web service inside the def.then portion of the _popup function? I do not see 'arr' variable in the code I provided so I am a little confused.

0 Kudos
GilbertoMatos
Occasional Contributor II

Yea! I'm getting the expected results from my C# service in Suggest_TextBox.js correctly. The problem is in the moment of mounting this on the screen for the user to select the desired option. I just see that something "flashes" below the textbox where it's being typed, but the options don't load and no errors show up on the screen for me. 'arr' is not a code variable. It is a value to be searched in the api that I type in the textbox field to return the data I need to filter. Sorry for my mess. My language is Brazilian Portuguese. I'll leave below the link to my example api service, the system link and a print with an arrow pointing to where the information is typed.

 

Api Link: https://gis.fepam.rs.gov.br/RSAguaWebAPI/AutoCompleteFiltroValor/ListarOpcoes?texto=arr 

 

App Link: https://gis.fepam.rs.gov.br/RSAguaAutoComplete/# 

 

Thanks!

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

So this is the response I get from my web service

{"suggestions":["123","1231","1232","1233","1234","1235","1236","1237","1238","1239","12333","12334","12335","12335","12336","12337","12339","12340","12341","12342","12343","12344","12345","12346","12347","12348","12349"]}

And yours is:

[{"texto":"Arroio Areal"},{"texto":"Arroio Arenal"},{"texto":"Arroio Baje"},{"texto":"Arroio Bolacha"},{"texto":"Arroio Candiota"},{"texto":"Arroio Caracá"},{"texto":"Arroio Castelhano"},{"texto":"Arroio Cavera"},{"texto":"Arroio Chico Loma"},{"texto":"Arroio Chuí"},{"texto":"Arroio da Pintada"},{"texto":"Arroio das Lavras"},{"texto":"Arroio Del Rei"},{"texto":"Arroio Do Bote"},{"texto":"Arroio dos Ratos"},{"texto":"Arroio Francisco Alves"},{"texto":"Arroio Garupa"},{"texto":"Arroio Grande"},{"texto":"Arroio Ibacuru"},{"texto":"Arroio Ibirocai"},{"texto":"Arroio Jacaré"},{"texto":"Arroio Jaguarão-Chico"},{"texto":"Arroio João Dias"},{"texto":"Arroio Não Sabia"},{"texto":"Arroio Pelotas"},{"texto":"Arroio Pequiri"},{"texto":"Arroio Petim"},{"texto":"Arroio Pinhal"},{"texto":"Arroio Pirai"},{"texto":"Arroio Portão"},{"texto":"Arroio Ribeiro"},{"texto":"Arroio Ribeiro Pequeno"},{"texto":"Arroio Saicã"},{"texto":"Arroio São Lourenço"},{"texto":"Arroio Sutil"},{"texto":"Arroio Taquara"},{"texto":"Arroio Taquarembozinho"},{"texto":"Arroio Telho"},{"texto":"Arroio Vacaquá"},{"texto":"Arroio Velhaco"},{"texto":"Arroio Vira Carreta"},{"texto":"Lagoa dos Barros"},{"texto":"Rio Carreiro"}]

The BIG difference is you are returning an array of objects and mine is returning an object that has a property containing an array of strings...

So in the def.then of my code I am doing

array.map(resp.suggestions, lang.hitch(this, function(val){

iterating through the resp.suggestions (where resp is an object and suggestions is a property of that object and is an array). In your case it would be more like:

array.map(resp, lang.hitch(this, function(val){
  var item = new MenuItem({
    label: val.texto,
    onClick: lang.hitch(this, function (evt) {
...
GilbertoMatos
Occasional Contributor II

Perfect Robert!

It worked correctly. Thanks for the help once again.

Hug

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

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