Handling a facet option selection event in Coveo

While I was able to find some other notable results on this topic, none of them quite helped me achieve this completely, so I thought I’d provide my own solution for this. In Coveo if you ever need to handle a click or select event on one of your facets, you can do so using code similar to the following:

    Coveo.$('.CoveoSearchInterface').on('state:change:f:@aopasitename', function (e, data)  {
        console.log('Facet State has changed, the new value is: ' + data.value);

Prior to writing this blog post, I found a very similar solution here. Except I was confused by the $('#search') part, as I didn’t have any element with that id, and I couldn’t figure out what element this was supposed to be pointing to (until I Google-searched that specific selector and found a page explaining what it was). Let’s break this code down:

  1. Coveo.$('.CoveoSearchInterface') is a selector to my current search interface. This is a div which encompasses the entire search interface (makes sense) – so, including the search box, facets, results section and other sections.  Your search interface might be a div with id “search”. For me, it is a div containing a class, “CoveoSearchInterface” . I believe the naming of this class is specific to Coveo Hive.
  2. Calling .on() latches onto the search interface div. The first parameter is the name of the event. So because we want to handle when a facet option is selected, we really want to hook into the state change event (because Coveo state changes when a facet is selected or deselected). For more information on state check out this detailed document.
  3. Finally, you need to provide the name of a field. This field would be hooked up to the facet you are trying to handle changes for (Hint: You can get this from the URL query string after selecting an option in your facet.) If it is a custom/external (non-Sitecore) field, then you can use @ followed by the field name. Otherwise, you will need to convert the field name to a Coveo for Sitecore field name using one of the following helper functions:
    1. If using Coveo Hive, use coveoFieldName("myFieldName").
    2. Otherwise, use ToCoveoFieldName("myFieldName").

Lastly, the f: is included because we are referencing a state attribute name. So your actual state attribute name would be f:[yourFieldName].


Razor Template Scripting with jQuery

Recently I discovered template scripting in Razor (not sure what the actual name for it is) and it’s really saved me in some recent projects.  It’s basically a markup template/placeholder inside of a script tag, with dynamic references to model attributes. This lets you render new content onto your page using jQuery’s .render() and .appendTo() functions by targeting the ID of the template.

It starts with a controller action or method. You’ll need to return an instance of the model you’re using or a generic list of instances, depending on your situation. In my case, I made my controller action return a list of items to be added to a grid, if the user clicked a button indicating they wanted to see more items.

Some very basic code:

public ActionResult GetItems(type param1, type param2)
    var itemList = new List<MyModel>();
    itemList = GetNewContent(param1, param2);
    if (itemList.Count < 1)
       return Json(new { success = false }, JsonRequestBehavior.AllowGet);
    return Json(new { success = true, nextItems = itemList }, JsonRequestBehavior.AllowGet);

 The markup looks a little like this:

2016-03-16 14_19_27-SubZero - Microsoft Visual Studio (Administrator).png

Notice the dynamic variables in purple – those are your model attributes, which should exist in the model objects you returned in the controller action.

The JS call:


Because the type of data.nextItems is a list of those model objects, this code knows what those attributes are and how to get them. This will then append the new data based on the template provided, to the element you specify – in my case, a div.

This is a very useful method for rendering markup on the fly using jQuery.