Example Card or Result List Custom Widget#

This article describes the process for customizing the Cards widget but this same example could apply to the Result List widget.

A common request in Squirro is the ability to display additional information in the Cards and Result List widgets, we can do this quite easily with a custom template and by modifying the collection request so that the facets are returned with the items in the item list request.

If you are not familiar with custom widgets then please follow the basic custom widget tutorial first.

Start by Extending the Cards widget#

return Widgets.Cards.extend({
    ... // Other code goes inside the class here
});

Include a Custom Template for Rendering the Additional Data#

In the afterInitialise function, we can reference our custom template and attach it to the itemTemplate pointer. This HTML file will now be used for each item in our list.

afterInitialize: function () {
    this.itemTemplate = this.customResources['itemTemplate.html'];
},

Modify the Collection Request to Include All Facets#

By harnessing getCustomCollectionParams the returned object will be added to the collection request, we need to pass keywords: true to fetch the additional facets.

getCustomCollectionParams: function() {
    return {
        keywords: true,
    };
},

Create the itemTemplate.html File#

The content of this file will replace each item. We can use a debugger to see what fields are available for display by using the following code and then typing item into the console. Item is automatically passed into the template so we can reference it directly in the console during this breakpoint.

<div>
Hello World
<% debugger %>
</div>

Below you can see the output of item, notice the keywords object which contains all of that item’s facet values.

image1#

Implement the Custom HTML#

Here is an example of the custom HTML used to generate the following image, showing the additional facet fields in the view.

<%
    function getKeywordValue (item, kw) {
        var keywords = item.get('keywords') || {},
          value = keywords[kw] || [];
        if (!_.isEmpty(value)) {
            return value[0];
        } else {
            return '';
        }
    }
%>
<div class="item card show_more" data="<%- item['id'] %>">
    <div class="row">
        <div id="icon_row" class="col s2 l2">
            <div class="source">
                <div class="source-bubble js-bubble left" style="background:#ff9600">
                    <i><%- getKeywordValue(item, 'recommendation_score') %></i>

                </div>
            </div>
        </div>
        <div class="col s12 m12 l10">
            <div>
                <h4 class="title no-margin" title="See related items">
                    <b><%= item.escape('title') || $.t('item:untitled') %></b>
                </h4>
            </div>
            <h5 id="sub_header">
                <span class="date refreshable custom_spacer" data-item="<%- item.id %>"><%- displayTime %></span>
                <span class="additional-title">
                </span>
            </h5>
            <div id="category">
            <% if (getKeywordValue(item, 'market_share') !== '') { %>
                <span class="chip"> <%- getKeywordValue(item, 'market_share') %></span>
            <% }; %>
            </div>
        </div>
    </div>
</div>

image2

The Complete Widget.js File#

Below is a complete example of the widget.js file, here you can see all the pieces above coming together to have a complete piece of code.

return Widgets.Cards.extend({
    afterInitialize: function() {
        this.itemTemplate = this.customResources['itemTemplate.html'];
    },
    getCustomCollectionParams: function() {
        return {
            keywords: true,
        };
    },
});

The Complete Widget.css File#

Below is a complete example of the widget.css file.

.custom-custom_recommendations .vItemListCards .vItemCards .detail {
    width: 100%;
    float: none !important;
}
.custom-custom_recommendations .vItemListCards .vItemCards .source {
    width: 60px !important;
}
.custom-custom_recommendations .vItemListCards .vItemCards .item .detail {
    height: 50px !important;
}
.custom_spacer::after {
    content: "   ·   ";
}
@media only screen and (max-width: 992px) {
    #icon_row {
        display: none;
    }
}
@media only screen and (min-width: 1200px) {
    .custom-custom_recommendations .row .col.l10 {
        width: 90%;
    }
    .custom-custom_recommendations .row .col.l2 {
        width: 10%;
    }
}
.custom-custom_recommendations .widget-header {
    margin: .5rem 0 1rem 0;
    background-color: #fff;
    transition: box-shadow .25s;
    border-radius: 2px;
    box-shadow: 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12), 0 3px 1px -2px rgba(0,0,0,0.2);
}
.custom-custom_recommendations .total {
    padding-left: 24px;
}
.custom-custom_recommendations .toggle_preference {
    padding-right: 24px;
    line-height: 64px;
}
.switch label input[type=checkbox]:checked+.lever:after {
    background-color: #009e91 !important;
}
.switch label input[type=checkbox]:checked+.lever {
    background-color: #009e91 !important;
}

The Complete Widget.css File#

Below is a complete example of the config.js file. We did not modify the config in this example, we simply return the original Squirro Cards Widget Config object.

return Pages.Cards;

Simple Small Modifications#

If you just want to make a small modification to the existing view, then you should contact a member of the frontend team at Squirro to get the most up to date HTML for the current itemTemplate.