3

I have a Coveo facet By City is configured based on a computed field citystate, I have some doctors that are virtual care only, to make sure the facet will show their allowed states I added "virtual care, state" into the citystate computed field, the results are shown as follows:

enter image description here

!!! There is some requirement changes !!!

Business does not like the "virtual care, state" into the citystate computed field, but I do have 2 other computed field for virtual care only doctors: isvirtualonly (bool) and state (array of string) which contains all states this doctor is allowed to provide virtual care service.

I need to capture the event that when user click on the city in the facet, for example, Luverne, Minnesota, I need to modify the query to include all virtual care doctors that meet other search criteria not limited to city matches citystate computed field, but also include those virtual only doctors that their states contains Minnesota.

Thanks Sumit Bhatia suggestion I was able to capture the unique states selected by the By City facet as shown in the following code snippet:

if (document.getElementById('doctors-facet-by-city') !== null) {
    citystateFacet = Coveo.get(document.getElementById('doctors-facet-by-city')).getSelectedValues();
    if (citystateFacet.length > 0) {
        let states = getDistinctStates(citystateFacet);
        for (var i = 0; i < states.length; i++) {
            console.log('state: ' + states[i]);
        }
    }
}

When I selected 2 cities, I do see the aq has this value:

(@fcitystate16243==("Fargo, North Dakota","Luverne, Minnesota")) ((((@fz95xpath16243=5410849302FA49E39DD6C42DBE11367C @fz95xid16243<>5410849302FA49E39DD6C42DBE11367C) @fz95xtemplate16243==48A5EFB48E8B44E7B2579921FB3F79E2) NOT @fz95xtemplate16243==(ADB6CA4F03EF4F47B9AC9CE2BA53FF97,FE5DD82648C6436DB87A7C4210C7413B))) ($qre(expression:@fprimaryspeciality16243 == "aaron ", modifier:'100'))

How do I modify the query in a way to make sure all other conditions are met, not just those doctors with (@fcitystate16243==("Fargo, North Dakota","Luverne, Minnesota")) but include state matches selected states and isvirtualcare is true?

3 Answers 3

1

To achieve the functionality You can track when users click on facet values in Coveo and add custom logic for virtual care doctors. To do this, use Coveo's JavaScript API by following these steps:

Step 1: Listen for Facet Value Click Events : Add a way to detect when someone clicks on one of the filter options. You can do this using Coveo's built-in click detection tool.

Coveo.$('#yourFacetId').on('click', '.CoveoFacetValue', function(event) {
    const selectedCity = $(this).data('value'); // Get the selected city value
    const state = extractStateFromCity(selectedCity); // Implement this function to extract the state
    handleFacetSelection(state);
});

Step 2: Implement Logic to Include Virtual Care Doctors :

Create a function that updates both the selected city and its associated state-level virtual care services when a user clicks a city.

function handleFacetSelection(state) {
    const virtualCareValue = `virtual care, ${state}`;

    // Create an array to store the values to select
    const valuesToSelect = [state, virtualCareValue];

    // Use the Coveo API to select the additional facet values
    valuesToSelect.forEach(value => {
        Coveo.getFacet('yourFacetId').selectValue(value);
    });

    // Trigger a new search with the updated facet selections
    Coveo.getQueryController().executeQuery();
}

Step 3: Extract State from the City Value : You need to implement a function to extract the state from the selected city. This can depend on how your city values are structured. Here’s a simple example assuming the value is in the format "City, State".

function extractStateFromCity(cityValue) {
    const parts = cityValue.split(', ');
    return parts.length > 1 ? parts[1].trim() : ''; // Return the state part
}

After that Run the query again to update the results after you choose the virtual care option.

Hope this help!!

1

You can use this logic to first get the search interface and then find your coveo facet like below.

    document.addEventListener("DOMContentLoaded", function () {
 
    var root = document.querySelector("#SearchInterface");
 
    //Register a buildingQuery event handler on the root HTML element of your search interface
    Coveo.$$(root).on('buildingQuery', function (e, args) {
 
       // Get the facet value
        var selectedFacet = Coveo.state(Coveo.$$(document).find("#SearchInterface"), "f:FacetId");
 
        if (selectedFacet !== null && selectedFacet !== undefined && selectedFacet.length > 0) {
 
            //Build your logic
           
        }
    });
});

Refer to these documents for more details.

https://sitecorecorner.wordpress.com/2021/05/01/update-the-advanced-query-expression-of-coveo-based-on-the-selected-facet/

https://aldrichdev.wordpress.com/2018/01/29/handling-a-facet-option-selection-event-in-coveo/

https://www.getfishtank.com/insights/different-ways-to-interact-with-coveo-facets

Hope this helps.

2
  • Thank you so much Sumit! I was able to use your code to get all unique states user selected, my requirement changed a little bit, business does not like my idea to add 'virtualcare, state' into the City facet, for those virtual care doctors, I do have a isvirtualcare field = 1 and the state field has all states this doctor has license. How do I modify the query and add something " OR (isvirtualcare == 1 and states in selectedStates)?
    – John Lee
    Commented Nov 5 at 5:37
  • @JohnLee Check out my blog and it will give you all the context to extend your query. sbhatiablogs.wordpress.com/2020/10/01/… Commented Nov 5 at 6:18
1

For those who are facing the same issue, here are the solution:

  1. Find the facet selected values
  2. Get distinct state array from the selected values
  3. Find the query from the advancedExpression that represents the By City facet
  4. Append OR condition isvirtualonly=1 AND state=selected state to original facet query, the state for virtual care doctors are comma separated state like South Dakota,Minnesota, = means partial match
  5. Replace the original part with new constructed query
if (document.getElementById('doctors-facet-by-city') !== null) {
    citystateFacetSelectedValues = Coveo.get(document.getElementById('doctors-facet-by-city')).getSelectedValues();
    if (citystateFacetSelectedValues.length > 0) {
        let selectedStates = getDistinctStates(citystateFacetSelectedValues);

        const parts = args.queryBuilder.advancedExpression.getParts();
        const citystatePartIndex = parts.findIndex(element => element.includes('fcitystate'));
        if (citystatePartIndex >= 0) {

            const orginalCitystatePart = parts[citystatePartIndex];

            const virtualCareCondition = buildVirtualCareConditions(selectedStates);
            if (virtualCareCondition) {
                const newPart0 = `((${orginalCitystatePart}) OR ${virtualCareCondition})`;
                args.queryBuilder.advancedExpression.parts[citystatePartIndex] = newPart0;
            }
        }
    }
}

function buildVirtualCareConditions(selectedStates) {
    if (selectedStates.length === 0) return '';

    const stateFieldName = '@' + Coveo.coveoFieldName('state');
    const isVirtualOnlyFieldName = '@' + Coveo.coveoFieldName('isvirtualonly');

    const stateConditions = [];

    for (let i = 0; i < selectedStates.length; i++) {
        const state = selectedStates[i];
        stateConditions.push(`(${stateFieldName}="${state}")`);
    }

    const conditionsString = stateConditions.join(' OR ');

    return `(${isVirtualOnlyFieldName}=="1" AND (${conditionsString}))`;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.