Feature Layer Query Autocomplete

602
0
08-05-2020 01:44 PM
JaredPilbeam2
MVP Regular Contributor

How do I set up autocomplete on a query? My app is already set up to query a feature layer. I'd just like to know how to incorporate an autocomplete on the feature layer query so that the feature's attributes from the Category field will be listed as the user types.

These help docs are similar, but I don't need another text box:
-Auto complete a textbox from a map service in a widget 

-https://community.esri.com/people/mlewis22/blog/2014/10/21/autocomplete-search-box-using-arcgis-serv... 

<script>
        // JavaScript source code
        require([
            "esri/Map",
            "esri/views/MapView",
            "esri/layers/FeatureLayer",
            "esri/layers/GraphicsLayer",
            "esri/widgets/Home",

        ], function (
            Map,
            MapView,
            FeatureLayer,
            GraphicsLayer,
            Home
        ) {
            var catTypeSelect = document.getElementById("category");
            var keyTypeSelect = document.getElementById("keyword");
            var filterButton = document.getElementById("filterBtn");
            var resRb = document.getElementById("ResidentialRB");

           
            // Recycle
            var recycleLayer = new FeatureLayer({
                portalItem: {
                    // autocasts as new PortalItem()
                    id: "b5665da3feab4b6091914cbfe4ab028f"
                },
            });

            // GraphicsLayer for displaying results
            var resultsLayer = new GraphicsLayer();
            //Set map view
            var map = new Map({
                basemap: "dark-gray",
                layers: [recycleLayer, resultsLayer]
            });

            var view = new MapView({
                container: "viewDiv",
                map: map,
                center: [-87.95, 41.47],
                zoom: 9
            });

            // query all features from the recycle layer
            view
                .when(function () {
                    return recycleLayer.when(function () {
                        var query = recycleLayer.createQuery();
                        return recycleLayer.queryFeatures(query);
                    });
                })
                .then(getValues)
                .then(getUniqueValues)
                .then(addToSelect)
            // re-query the layer based on the selected Category and re-populate the keyword select
            catTypeSelect.addEventListener("change", function () {
                var sqlExp = "";
                if (catTypeSelect.selectedIndex > 0) {
                    sqlExp += "Category LIKE '%" + catTypeSelect.options[catTypeSelect.selectedIndex].value + "%'";
                }
                var query = recycleLayer.createQuery();
                query.where = sqlExp;
                recycleLayer.queryFeatures(query)
                    .then(getValues2)
                    .then(getUniqueValues2)
                    .then(addToSelect2)
            });

            // return an array of all the values in the
            // Category and item_keyword fields of the Recycle layer
            function getValues(response) {
                var features = response.features;
                var values = features.map(function (feature) {
                    return {
                        Category: feature.attributes.Category,
                        item_keyword: feature.attributes.item_keyword
                    }
                });
                return values;
            }
            // re-query the layer based on the selected Category and re-populate the keyword select
            function getValues2(response) {
                var features = response.features;
                var values = features.map(function (feature) {
                    return feature.attributes.item_keyword
                });
                return values;
            }

            // return an array of unique values in
            // the item_keyword and Category fields of the Recycle layer
            function getUniqueValues(values) {
                var uniqueKeyValues = [];
                var uniqueCatValues = [];

                values.forEach(function (item, i) {
                    var keyVal = item.item_keyword.split(";");
                    var catVal = item.Category.split(";");
                    catVal.map(function (val1) {
                        if (
                            (uniqueCatValues.length < 1 || uniqueCatValues.indexOf(val1) === -1) &&
                            val1 !== ""
                        ) {
                            uniqueCatValues.push(val1);
                        }
                    });
                    keyVal.map(function (val2) {
                        if (
                            (uniqueKeyValues.length < 1 || uniqueKeyValues.indexOf(val2) === -1) &&
                            val2 !== ""
                        ) {
                            uniqueKeyValues.push(val2);
                        }
                    });
                });
                return {
                    uKeyVals: uniqueKeyValues,
                    uCatVals: uniqueCatValues
                };
            }
            // re-query the layer based on the selected Category and re-populate the keyword select
            function getUniqueValues2(values) {
                var uniqueKeyValues = [];

                values.forEach(function (item, i) {
                    var keyVal = item.split(";");
                    keyVal.map(function (val2) {
                        if (
                            (uniqueKeyValues.length < 1 || uniqueKeyValues.indexOf(val2) === -1) &&
                            val2 !== ""
                        ) {
                            uniqueKeyValues.push(val2);
                        }
                    });
                });
                return uniqueKeyValues;
            }

            // Add the unique values to the recycle type
            // select element. This will allow the user
            // to filter categories by type.
            function addToSelect(values) {
                var dOpt = document.createElement("option");
                dOpt.value = "";

                dOpt.selected = true;
                dOpt.text = "Select one";
                catTypeSelect.add(dOpt);
                values.uCatVals.sort();
                values.uCatVals.forEach(function (value) {
                    var option = document.createElement("option");
                    option.text = value;
                    catTypeSelect.add(option);
                });

                var dOpt2 = document.createElement("option");
                dOpt2.value = "";

                dOpt2.selected = true;
                dOpt2.text = "Select one";
                keyTypeSelect.add(dOpt2);
                values.uKeyVals.sort();
                values.uKeyVals.forEach(function (value) {
                    var option = document.createElement("option");
                    option.text = value;
                    keyTypeSelect.add(option);
                });

                return setDefinitionExpression();
            }
            // re-query the layer based on the selected Category and re-populate the keyword select
            function addToSelect2(values) {
                while (keyTypeSelect.options.length > 0) {
                    keyTypeSelect.remove(0);
                }
                var dOpt2 = document.createElement("option");
                dOpt2.value = "";
                dOpt2.disabled = true;
                dOpt2.selected = true;
                dOpt2.text = "Select one";
                keyTypeSelect.add(dOpt2);
                values.sort();
                values.forEach(function (value) {
                    var option = document.createElement("option");
                    option.text = value;
                    keyTypeSelect.add(option);
                });
                return true
            }

            // set the definition expression on the recycle
            // layer to reflect the selection of the user
            function setDefinitionExpression() {
                var sqlExp = "";
                if (catTypeSelect.selectedIndex > 0) {
                    sqlExp += "Category LIKE '%" + catTypeSelect.options[catTypeSelect.selectedIndex].value + "%'";
                }
                if (keyTypeSelect.selectedIndex > 0) {
                    if (sqlExp === "") {
                        sqlExp += "item_keyword LIKE '%" + keyTypeSelect.options[keyTypeSelect.selectedIndex].value + "%'";
                    } else {
                        sqlExp += " AND item_keyword LIKE '%" + keyTypeSelect.options[keyTypeSelect.selectedIndex].value + "%'";
                    }
                }
                if (resRb.checked) {
                    if (sqlExp !== "") {
                        sqlExp += " AND USER_IsRes = 'TRUE'";
                    }

                } else {
                    if (sqlExp !== "") {
                        sqlExp += " AND USER_IsBus = 'TRUE'";
                    }
                }
                console.info(sqlExp);
                recycleLayer.definitionExpression = sqlExp;

                if (!recycleLayer.visible) {
                    recycleLayer.visible = true;
                }

                return queryForGeometries();
            }

            // Get all the geometries of the recycle layer
            // the createQuery() method creates a query
            // object that respects the definitionExpression
            // of the layer
            function queryForGeometries() {
                var rQuery = recycleLayer.createQuery();

                return recycleLayer.queryFeatures(rQuery).then(function (response) {
                    rGeometries = response.features.map(function (feature) {
                        return feature.geometry;
                    });

                    return rGeometries;
                });
            }

            filterButton.addEventListener("click", function () {
                setDefinitionExpression();
            });

        });
    </script>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Here's the whole app on Codepen.

0 Kudos
0 Replies