Creating a Custom Facet in Coveo Hive – Part Three

This is the 3rd (and most likely final) blog post in the Creating a Custom Facet in Coveo Hive series. If you’ve completed parts one and two, you’ve got a working custom facet that can be interacted with and can modify the current query and state, and update the search results that appear on the page. The last big piece of functionality, in my opinion, is setting up the facet breadcrumbs. This step is totally optional, and you should check with project management to make sure it falls within scope and the client requested to implement.

I struggled on this piece greatly because I wasn’t able to find any documentation on how to do this for a custom (Hive) facet. I had to contact Coveo Support, who then referred me to a Typescript file in their GitHub repositories which had the code for setting up breadcrumbs (albeit in a language I wasn’t too familiar with). I didn’t quite understand how the code worked, even after getting past the language barriers, and I wasn’t sure which parts I actually needed in my code. Thus, I created this blog post to answer some of those questions, for those that are in my same shoes at some point in the future.

What Functionality Do We Need?

Before thinking about exactly what code is required to implement breadcrumbs, it may help to think about what our goals are, on a high level. If you are unfamiliar with Coveo breadcrumbs, they are pieces of markup that are generated and added to the DOM when a Coveo facet value changes (an option is checked, a value is submitted, etc). By default they appear above the search results. This is often termed the “breadcrumb bar”.

breadcrumb bar

Continue reading “Creating a Custom Facet in Coveo Hive – Part Three”

Advertisements

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:

$('#gridItemTemplate').render(data.nextItems).appendTo('div#subItemGrid');

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.