3

I have my own query in search, How can i disable the default search function in ArcGIS search widget and apply mine?

my current code

const location = () => {
   const map = new Map({
        basemap: 'arcgis-light-gray',
       
      });
      const view = new MapView({
        center: [123.5504, 12.3574], // Longitude, latitude
        container: mapDiv.current,
        map: map,
        zoom: 2, // Zoom level
        ui: {
          components: ["attribution"] // removes default widgets except for attribution
       }
      });
      var zoom = new Zoom({
        view: view,
        layout: "vertical"
     });
     view.ui.add(zoom, "bottom-right");
     
      view
        .when((r) => {})
        .then(() => {
          mapDiv.current = view;
          search();
        }); 
    }
const search = () => {
      const searchWidget = new Search();

      mapDiv.current.ui.add(searchWidget, { position: "top-left", index: 2 });

}

this is the sample search widget in arcGIS, I want to override the search function, that the only thing that can be searched is the data in my query and it will appear just like in the picture

enter image description here

resource

https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Search.html

  • what is the default search behavior and what behavior you want in place of it? – K450 Dec 16 '21 at 06:44
  • in arcGIS search widget there is already have a search function that if you tried to type there is a suggestion appearing, and i want to override that. I want to override the search function using my query, but i dont know how to override it –  Dec 16 '21 at 06:54
  • @K450 I just updated the question –  Dec 16 '21 at 07:02
  • have you tried providing an array to `suggestions` property? – K450 Dec 16 '21 at 07:03
  • @K450, no. I dont know how. I dont know how to override the suggestions –  Dec 16 '21 at 07:04
  • wait so you want to override the source for your search. Like user should only be able to search from the data you provide? – K450 Dec 16 '21 at 07:11
  • Yes exactly !!! @K450 –  Dec 16 '21 at 07:11
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/240193/discussion-between-k450-and-kaito). – K450 Dec 16 '21 at 07:12

2 Answers2

1

You need to create a custom SearchSource that pulls suggestions and results from your data, and set it as a source for your searchWidget.

Things you need to implement:

  • SearchSource - search source that uses your data.
    • getSuggestions [returns promise] - Proivdes list of suggestions from your source
    • getResults [returns promise] - Provides list of search results from your source.

Implementation:

I modified this sample code for search widget with custom source provided with official docs

As you can see that getSuggestions and getResults both returns a promise as it is designed to access remote data with api's. But as your data is stored locally, you need to create a promise object that resolves to your data.

Test Data you provided me:

const test_data = {
    allIBLocations: {
      data: [
        {
          id: 'e53be02e-4cdb-11ec-81d3-0242ac130003',
          status: 'Incomplete',
          name: 'Revere - 2',
          externalId: '547e2f43-b950-4b5e-ada4-7fcc110a3785',
          ownerId: '494bd1c4-6d28-4a42-9d98-515129fde2b9',
          owner: {
            id: '494bd1c4-6d28-4a42-9d98-515129fde2b9',
          },
          orgId: 'd7d931d4-289d-49b1-bd88-29d0317b6987',
          deletedBy: null,
          deletedAt: null,
          updatedBy: null,
          updatedAt: '2021-12-15T03:43:00.787Z',
          ibLocationType: {
            name: 'Shared Office',
          },
          ibLocationTypeId: 'e53bca08-4cdb-11ec-81d3-0242ac130003',
          capacity: null,
          phoneNumber: null,
          address: {
            street1: 'Nitzsche Burg',
            street2: 'Emiliano Camp',
            city: 'Rowlandtown',
            state: 'Kentucky',
            zipCode: '41738',
            country: 'Kuwait',
          },
          geoCode:{
            latitude:-23.0633,
            longitude:15.0875
          }
          // geoCode: null,
        },
        {
          id: 'e53be45c-4cdb-11ec-81d3-0242ac130003',
          status: 'Incomplete',
          name: 'Jersey City - 4',
          externalId: '1fb7c170-f794-4c85-9a3b-57b8013a2821',
          ownerId: '494bd1c4-6d28-4a42-9d98-515129fde2b9',
          owner: {
            id: '494bd1c4-6d28-4a42-9d98-515129fde2b9',
          },
          orgId: 'd7d931d4-289d-49b1-bd88-29d0317b6987',
          deletedBy: null,
          deletedAt: null,
          updatedBy: null,
          updatedAt: '2021-12-15T03:43:00.788Z',
          ibLocationType: {
            name: 'Warm Site',
          },
          ibLocationTypeId: 'e53bcf80-4cdb-11ec-81d3-0242ac130003',
          capacity: null,
          phoneNumber: null,
          address: {
            street1: 'Madisen Club',
            street2: 'Cyrus Courts',
            city: 'East Breanamouth',
            state: 'Kentucky',
            zipCode: '05565-8531',
            country: 'Solomon Islands',
          },
          geoCode:{
            latitude:51.6617,
            longitude:-4.5789
          }
          // geoCode: null,
        },
        {
          id: 'e53be510-4cdb-11ec-81d3-0242ac130003',
          status: 'Incomplete',
          name: 'Wellington - 5',
          externalId: '479e2dc0-b55d-42fd-978b-9d9086216a5f',
          ownerId: '494bd1c4-6d28-4a42-9d98-515129fde2b9',
          owner: {
            id: '494bd1c4-6d28-4a42-9d98-515129fde2b9',
          },
          orgId: 'd7d931d4-289d-49b1-bd88-29d0317b6987',
          deletedBy: null,
          deletedAt: null,
          updatedBy: null,
          updatedAt: '2021-12-15T03:43:00.788Z',
          ibLocationType: {
            name: 'Hospital',
          },
          ibLocationTypeId: 'e53bbf40-4cdb-11ec-81d3-0242ac130003',
          capacity: null,
          phoneNumber: null,
          address: {
            street1: 'Carter Pass',
            street2: 'Gutmann Brooks',
            city: 'Paterson',
            state: 'New Jersey',
            zipCode: '79928-2470',
            country: 'Cyprus',
          },
          geoCode: {
            latitude: 51.0899,
            longitude: 67.9272,
          },
        },
        {
          id: 'e53be7e0-4cdb-11ec-81d3-0242ac130003',
          status: 'Incomplete',
          name: 'Doral - 9',
          externalId: 'b096ed12-fed2-4a9b-8e61-5c2639b7b7d8',
          ownerId: '494bd1c4-6d28-4a42-9d98-515129fde2b9',
          owner: {
            id: '494bd1c4-6d28-4a42-9d98-515129fde2b9',
          },
          orgId: 'd7d931d4-289d-49b1-bd88-29d0317b6987',
          deletedBy: null,
          deletedAt: null,
          updatedBy: null,
          updatedAt: '2021-12-15T03:43:00.789Z',
          ibLocationType: {
            name: 'Warehouse',
          },
          ibLocationTypeId: 'e53bcc24-4cdb-11ec-81d3-0242ac130003',
          capacity: null,
          phoneNumber: null,
          address: {
            street1: 'Koelpin Lodge',
            street2: 'Ana Tunnel',
            city: 'Carsonside',
            state: 'Maine',
            zipCode: '44431',
            country: 'Guatemala',
          },
          geoCode: {
            latitude: 0.181,
            longitude: 47.7937,
          },
          //  "geoCode": null
        },
        {
          id: 'e53bec7c-4cdb-11ec-81d3-0242ac130003',
          status: 'Incomplete',
          name: 'Bossier City - 13',
          externalId: '486d4838-bb19-4b29-b4d0-1b492762ebe8',
          ownerId: '494bd1c4-6d28-4a42-9d98-515129fde2b9',
          owner: {
            id: '494bd1c4-6d28-4a42-9d98-515129fde2b9',
          },
          orgId: 'd7d931d4-289d-49b1-bd88-29d0317b6987',
          deletedBy: null,
          deletedAt: null,
          updatedBy: null,
          updatedAt: '2021-12-15T03:43:00.790Z',
          ibLocationType: {
            name: 'Hospital',
          },
          ibLocationTypeId: 'e53bbf40-4cdb-11ec-81d3-0242ac130003',
          capacity: null,
          phoneNumber: null,
          address: {
            street1: 'Lakin Throughway',
            street2: 'Zulauf Island',
            city: 'Casa Grande',
            state: 'Illinois',
            zipCode: '68798',
            country: 'Mayotte',
          },
          geoCode:{
            latitude:84.2091,
            longitude:147.886
          }
          // geoCode: null,
        },
        {
          id: 'f14e81b4-e932-4d8e-900e-bfbff065aa0e',
          status: 'Incomplete',
          name: 'loc3',
          externalId: 'locId3',
          ownerId: 'db1a73a2-498b-43c8-9185-424cda7ea272',
          owner: {
            id: 'db1a73a2-498b-43c8-9185-424cda7ea272',
          },
          orgId: 'd7d931d4-289d-49b1-bd88-29d0317b6987',
          deletedBy: null,
          deletedAt: null,
          updatedBy: null,
          updatedAt: '2021-12-15T03:48:14.815Z',
          ibLocationType: null,
          ibLocationTypeId: null,
          capacity: 0,
          phoneNumber: 0,
          address: {
            street1: 'add1',
            street2: '',
            city: '',
            state: '',
            zipCode: '',
            country: 'Anguilla',
          },
          geoCode: null,
        },
        {
          id: '9ceb84ec-aaeb-43af-9b26-11d8ae360625',
          status: 'Incomplete',
          name: 'loc2',
          externalId: 'locId2',
          ownerId: 'db1a73a2-498b-43c8-9185-424cda7ea272',
          owner: {
            id: 'db1a73a2-498b-43c8-9185-424cda7ea272',
          },
          orgId: 'd7d931d4-289d-49b1-bd88-29d0317b6987',
          deletedBy: null,
          deletedAt: null,
          updatedBy: null,
          updatedAt: '2021-12-15T03:45:12.722Z',
          ibLocationType: null,
          ibLocationTypeId: null,
          capacity: 0,
          phoneNumber: 0,
          address: {
            street1: 'add1',
            street2: '',
            city: '',
            state: '',
            zipCode: '',
            country: 'Albania',
          },
          geoCode: null,
        },
        {
          id: '74b322b3-525f-4e76-b002-2997e9a9a8e1',
          status: 'Incomplete',
          name: 'loc5',
          externalId: 'locId5',
          ownerId: 'db1a73a2-498b-43c8-9185-424cda7ea272',
          owner: {
            id: 'db1a73a2-498b-43c8-9185-424cda7ea272',
          },
          orgId: 'd7d931d4-289d-49b1-bd88-29d0317b6987',
          deletedBy: null,
          deletedAt: null,
          updatedBy: null,
          updatedAt: '2021-12-15T03:57:41.612Z',
          ibLocationType: null,
          ibLocationTypeId: null,
          capacity: 0,
          phoneNumber: 0,
          address: {
            street1: 'add',
            street2: '',
            city: '',
            state: '',
            zipCode: '',
            country: 'Anguilla',
          },
          geoCode: null,
        },
        {
          id: '125b0fc8-b91a-42b2-90b3-c37b9afdfa36',
          status: 'Incomplete',
          name: 'loc1',
          externalId: 'locId1',
          ownerId: 'db1a73a2-498b-43c8-9185-424cda7ea272',
          owner: {
            id: 'db1a73a2-498b-43c8-9185-424cda7ea272',
          },
          orgId: 'd7d931d4-289d-49b1-bd88-29d0317b6987',
          deletedBy: null,
          deletedAt: null,
          updatedBy: null,
          updatedAt: '2021-12-15T03:43:34.697Z',
          ibLocationType: null,
          ibLocationTypeId: null,
          capacity: 0,
          phoneNumber: 0,
          address: {
            street1: 'add1',
            street2: '',
            city: '',
            state: '',
            zipCode: '',
            country: 'Albania',
          },
          geoCode: null,
        },
        {
          id: '3375b2d3-13cd-401c-b79b-21cbdb956b15',
          status: 'Incomplete',
          name: 'loc7',
          externalId: 'locId7',
          ownerId: 'db1a73a2-498b-43c8-9185-424cda7ea272',
          owner: {
            id: 'db1a73a2-498b-43c8-9185-424cda7ea272',
          },
          orgId: 'd7d931d4-289d-49b1-bd88-29d0317b6987',
          deletedBy: null,
          deletedAt: null,
          updatedBy: null,
          updatedAt: '2021-12-15T04:02:11.694Z',
          ibLocationType: null,
          ibLocationTypeId: null,
          capacity: 0,
          phoneNumber: 0,
          address: {
            street1: 'add',
            street2: '',
            city: '',
            state: '',
            zipCode: '',
            country: 'Albania',
          },
          geoCode: null,
        },
        {
          id: '76af916a-d42c-43a8-a945-3832bb9a4047',
          status: 'Incomplete',
          name: 'loc6',
          externalId: 'locId6',
          ownerId: 'b9e7b94f-d3a7-460d-afb7-34e277df3aec',
          owner: {
            id: 'b9e7b94f-d3a7-460d-afb7-34e277df3aec',
          },
          orgId: 'd7d931d4-289d-49b1-bd88-29d0317b6987',
          deletedBy: null,
          deletedAt: null,
          updatedBy: null,
          updatedAt: '2021-12-15T04:00:02.946Z',
          ibLocationType: null,
          ibLocationTypeId: null,
          capacity: 0,
          phoneNumber: 0,
          address: {
            street1: 'add',
            street2: '',
            city: '',
            state: '',
            zipCode: '',
            country: 'Albania',
          },
          geoCode: null,
        },
        {
          id: 'cf688233-f48d-4566-a4e9-5f208d6afb71',
          status: 'Incomplete',
          name: 'loc4',
          externalId: 'locId4',
          ownerId: 'db1a73a2-498b-43c8-9185-424cda7ea272',
          owner: {
            id: 'db1a73a2-498b-43c8-9185-424cda7ea272',
          },
          orgId: 'd7d931d4-289d-49b1-bd88-29d0317b6987',
          deletedBy: null,
          deletedAt: null,
          updatedBy: null,
          updatedAt: '2021-12-15T03:53:28.203Z',
          ibLocationType: null,
          ibLocationTypeId: null,
          capacity: 0,
          phoneNumber: 0,
          address: {
            street1: 'add1',
            street2: '',
            city: '',
            state: '',
            zipCode: '',
            country: 'Albania',
          },
          geoCode: null,
        },
      ],
    },
  };
const testData = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(test_data); //test_data = Your data.
  }, 1000);
});

Now that you have a promise that resolves to your data, you can use it to get suggestions and results from.

const customSearchSource = new SearchSource({
  placeholder: 'Search',
  getSuggestions: (params) => {
    return testData.then((data) => {
      var results = [];
      var toSearch = params.suggestTerm;
      data = data["allIBLocations"]["data"];

      for(var i=0; i<data.length; i++) {
        if(data[i]["name"].indexOf(toSearch)!=-1) {
          results.push(data[i]);
        }
      }
      return results.map((feature) => {
        return {
          key: "name",
          text: feature.name,
          sourceIndex: params.sourceIndex
        };
      })
    });
  },
  getResults: (params) => {
    return testData.then((data) => {
      var results = [];
      var toSearch = params.suggestResult.text;
      data = data["allIBLocations"]["data"];
      for(var i=0; i<data.length; i++) {
        if(data[i]["name"].indexOf(toSearch)!=-1) {
          results.push(data[i]);
        }}
      
      const searchResults = results.map((feature) => {
        console.log(feature)
        const graphic = new Graphic({
          geometry: new Point({
            latitude: feature.geoCode.latitude,
            longitude: feature.geoCode.longitude
          }),
          attributes: feature.address
        });
        const buffer = geometryEngine.geodesicBuffer(
          graphic.geometry,
          100,
          "meters"
        );
        const searchResult = {
          extent: buffer.extent,
          feature: graphic,
          name: feature["name"]
        };
        return searchResult;
      });
      return searchResults;
    });
  }
});

And finally set the customSearchSource as a source in your searchWidget, also disable default source to force searchWidget to use the source that you provide.

const searchWidget = new Search({
  view: view,
  sources: [customSearchSource],
  includeDefaultSources: false
});

Live Demo

K450
  • 691
  • 5
  • 17
0

You have to create a custom source with the ArcGIS JS API and add that as the source and also set the flag to includeDefaultSources to false so it only uses yours.

https://developers.arcgis.com/javascript/latest/sample-code/widgets-search-customsource/

With a codepen example here: https://codepen.io/pen?editors=1000

Notice here how they add the custom source made, and add it as a source to the search widget when it is instantiated.

        // Create Search widget using custom SearchSource
        const searchWidget = new Search({
          view: view,
          sources: [ customSearchSource ],
          includeDefaultSources: false
        });

You can find the documentation on how to make a customSource here https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Search-SearchSource.html

Carson
  • 1,147
  • 5
  • 19
  • 41