12

Going by the examples out of the box in Coveo, I always see this bit to construct the query:

Coveo.$(function() {
    Coveo.$('#search')
        .on(Coveo.QueryEvents.buildingQuery,
            function(e, args) {

I want to add essentially my own faceting system to this, but not using OOTB facets necessarily, mostly due to design. I have "tabs" that are dropdowns essentially, with checkboxes, and after the user selects whatever series of boxes they'll go with, they click an "apply" button.

When the button is clicked, I know using Coveo.$("search").coveo("executeQeury") will kick off a new query, but I'm confused as to how to access the query builder for either refining my starting point, or just generating a new query based on the "facets" involved.

I feel like I'm missing something obvious, but any help would be appreciated. Thanks.

10

If you want to get the building query and attach filters to the search you can do something like this:

Coveo.$('#search').on("buildingQuery", function(e, args) {
    args.queryBuilder.advancedExpression.add('@Model.ToCoveoFieldName("templatename") == "MyTemplate"');
}).coveoForSitecore('init', CoveoForSitecore.componentsOptions);

in this case you can change the advanced expression with what you need.

If you want to monitor the state of your custom facet and perform custom actions based on the state change you can do something like this:

$('.CoveoFacetDropdown').on('state:change', function() {
    //execute new query
    $('#search').coveo('executeQuery');
});
  • 1
    I think I need something more concrete. I saw .build() in the Coveo docs, but the brief example they give isn't useful for how do I get the QueryBuilder object out, check it, change it, etc. If there was a way to just reinitialize the query and run it again, that'd work just as well. – Ken McAndrew Sep 19 '16 at 23:42
  • I went back to accept this as the answer in the end. By turning things off/on like I had, I also killed paging, etc. Redoing the query through my original function and then calling executeQuery got me what I needed. – Ken McAndrew Jan 7 '17 at 20:34
10

You can modify the expression that gets passed in as a parameter to the event function. This happens at query time and the modified query gets passed to the Coveo REST API.

You'd wind up with something like this to filter items after a specific start date:

Coveo.$(function() { Coveo.$('#search')
    .on(Coveo.QueryEvents.buildingQuery, function(e, args) {
        args.queryBuilder.expression.add("@sysdate>=" + startDate)
    });
});
  • Thanks for the edit - sorry, did the original answer on my phone. – George Chang Sep 20 '16 at 14:38
  • Is this applicable after the initial page load as well? What I ended up doing - because I was in a crunch and it worked - was to use .off to dislodge the buildingQuery, then .on to reattach so my re-query would happen, then hit executeQuery to make it fire. It's probably a hammer approach that needs a scalpel, but it got me past for now. – Ken McAndrew Sep 27 '16 at 13:01
3

A bit late for this party, but here is what I would suggest.

First of all, you need to create your custom component which will inherit from the Coveo search component.

Then you will add the methods needed for that component.

Then you will bind a click event to it.

So my component look like this:

Coveo.$(function() {  
               //I bind to my parent in my constructor, I also assign the underscore template 
                var CustomFacet = (function(_super) {
                  function CustomFacet(element, options, bindings) {
                    this.type = 'CustomFacet';
                    Coveo.Component.bindComponentToElement(element, this);
                    this.element = element;
                    this.options = options;
                    this.bindings = bindings;
                    this.templateToLoad = Coveo.$(".custom-facet-values-template").html();
                    var _this = this;
                    //I populate my facet with a GroupByRequest
                    Coveo.$(this.bindings.searchInterface.element)
                    .on(Coveo.QueryEvents.buildingQuery, function(e, args){
                        args.queryBuilder.groupByRequests.push({"field" : "@syssource", "maximumNumberOfValues":6,"sortCriteria":"occurrences","injectionDepth":1000})
                    })

                       //Then I load the results to my underscore template
                    .on(Coveo.QueryEvents.querySuccess, function(e, args){
                        var facetTitle = "Sources"
                        var facetValues = [];
                        _.each(args.results.groupByResults, function(groupByResult){
                            if(groupByResult.field == "syssource"){
                                facetValues.push(groupByResult.values);
                            }         
                        })
                        var customFacetValues = Coveo.UnderscoreTemplate.fromString(_this.templateToLoad).template;
                        var templateData = {
                            facetTitle: facetTitle,
                            facetValues: facetValues
                            };
                            Coveo.$(".CoveoCustomFacet").html(customFacetValues(templateData));
                        })
                    }

                    //Then my list of custom methods.
                    // First a click event which will select the source field
                    CustomFacet.prototype.customFacetClick = function() {
                        Coveo.$(this.bindings.searchInterface.element)
                        .on(Coveo.QueryEvents.buildingQuery, function(e, args){
                            args.queryBuilder.advancedExpression.add('@syssource=="John West Blog"');
                        })

                        this.bindings.usageAnalytics.logSearchEvent({
                           //Code to log the name of the event and the metadata
                        });
                        //Then also code to update the state and the URL

                        //Then I execute my query 
                        this.bindings.queryController.executeQuery();
                    }

                    //Add more method, such as facet clear, facet deselect...

                    // Then I register my component
                    CustomFacet.ID = 'CustomFacet';
                    Coveo.CoveoJQuery.registerAutoCreateComponent(CustomFacet);

                }(Coveo.Component));

Now my underscore template (very simple for now):

<div class="CoveoCustomFacet">
                    <script class="custom-facet-values-template" type="text/underscore">
                        <div class="customFacetTitle">{{= facetTitle}}</div>
                        {{ _.each(facetValues[0], function(value){ }}
                            <div class="customFacetValue">{{= value.Value}} {{=value.NumberOfResults}}</div>
                        {{ }); }}
                        <div class=""></div>
                    </script>
                </div>

And finally my click event:

Coveo.$('.CoveoCustomFacet').click(function(ev){
          Coveo.$(ev.currentTarget).coveo('customFacetClick');
       });

As you can see, I am playing with a Coveo object, so I use the Coveo jQuery plugin to call my click method, but I could also use the 'get' method of the Coveo Search Interface: developers.coveo.com/display/JsSearchV1/Step+2+-+Interacting+with+the+search+interface+or+components+instance#Step2-Interactingwiththesearchinterfaceorcomponentsinstance-Getacomponentinstance

Sorry I didn't finish all the methods but this might be for another post.

  • The get would be used to return a jQuery object instead... forgot to mention it :P – Simon Langevin Oct 20 '16 at 21:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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