Loading icon on query

799
9
Jump to solution
10-30-2020 08:01 AM
JaredPilbeam2
MVP Regular Contributor

I'm having trouble adding a loading icon to this app. I want it to appear when the user makes a query. In the map, the points change to whatever category or item_keyword the user selects from the two drop-downs. As it stands, after making a selection the user can't tell when the process completes.

I'm able to display a loading icon for the map view as this example demonstrates, but I'm not sure how to do it on a query.

Here's the section of my app dealing with queries:

// 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);
        setDefinitionExpression();
    });

    keyTypeSelect.addEventListener("change", setDefinitionExpression);

    // 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() {
        console.log("Running query");
        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();
    });
});
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Esteemed Contributor

No there isn't. Just simply add the 

domClass.add('loadingDiv', 'visible');

before 

        recycleLayer
            .queryFeatures(query)
...

and remove it in the addToSelect2 method as I mentioned before.

View solution in original post

9 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Jared,

   You show the div when you right before you execute the query.

domClass.add('loadingDiv', 'visible'); and then in your results function (the last one addToSelect2) you hide it. 

JaredPilbeam2
MVP Regular Contributor

Thanks Robert,

It's apparently a pretty simple operation, but where exactly to put this stuff is not really popping out at me. Is there not an example somewhere?

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

No there isn't. Just simply add the 

domClass.add('loadingDiv', 'visible');

before 

        recycleLayer
            .queryFeatures(query)
...

and remove it in the addToSelect2 method as I mentioned before.

JaredPilbeam2
MVP Regular Contributor

Thanks!

For posterity:

        var query = recycleLayer.createQuery();
        query.where = sqlExp;
        domClass.add('loadingDiv', 'visible'); //add loadingDiv here
        recycleLayer
            .queryFeatures(query)
            .then(getValues2)
            .then(getUniqueValues2)
            .then(addToSelect2);
select
    function addToSelect2(values) {
        while (keyTypeSelect.options.length > 0) {
            keyTypeSelect.remove(0);
            domClass.remove('loadingDiv', 'visible'); //remove loadingDiv here
        }‍‍‍‍‍‍
0 Kudos
JaredPilbeam2
MVP Regular Contributor

Robert,

Sorry to drag you back into this one. I was wondering how to get the loading div to show when you query both the Category and item_keyword? Right now, the div shows for the Category only.

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Jared,

   Can you post your full code so I can see what you have done?

0 Kudos
JaredPilbeam2
MVP Regular Contributor
// 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;
        domClass.add('loadingDiv', 'visible'); //add loadingDiv
        recycleLayer
            .queryFeatures(query)
            .then(getValues2)
            .then(getUniqueValues2)
            .then(addToSelect2);

        setDefinitionExpression();
    });

    keyTypeSelect.addEventListener("change", setDefinitionExpression);

    // 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 item_keyword 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);
            
        }
        domClass.remove('loadingDiv', 'visible'); //remove loadingDiv
        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() {
        console.log("Running query");
        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();
    });
});
0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor
function setDefinitionExpression() {‍
  domClass.add('loadingDiv', 'visible'); //add loadingDiv
...

‍‍‍‍    function queryForGeometries() {
        console.log("Running query");
        var rQuery = recycleLayer.createQuery();

        return recycleLayer.queryFeatures(rQuery).then(function (response) {
            rGeometries = response.features.map(function (feature) {
                return feature.geometry;
            });
            domClass.remove('loadingDiv', 'visible'); //remove loadingDiv
            return rGeometries;
        });
    }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
JaredPilbeam2
MVP Regular Contributor

Perfect. Thanks a lot.

0 Kudos