For Dev - Callbacks after rendering products on collection/search page


1. Overview

We have some functions to support rendering extra elements, binding extra events,... after filtering or rendering product list on collection/search pages

Because the DOM is rebuilt, these functions will be called every time product list is rendered, to bind events again.


2. Callback after rendering Product List

2.1. What this is used for

  • Bind events/modify elements in product items, for example:
    • Product swatches events
    • Product image slider
    • Match product image's height
    • ...
  • Re-call some functions for 3rd party integration like reviews, wish list, multi-currency

2.2. When this is called

  • Called when rendering product list
  • This won't be called on page's first load, when product list is rendered from liquid
  • Except in some cases: See 1.2 of Product List Component

2.3. Commonly used fields

ProductList.prototype.afterRender = function() { 
	// The product list data returned from API
	var data = this.data; 
	// Your code here 
}

You can access the product list's data, settings, DOM element,... by this

  • this.$element
  • this.data
  • this.settings
  • this.children: these are the individual product items

You can console.log or check your debugger for all attributes in this

2.4. Example usage

Integrate with Shopify reviews:

ProductList.prototype.afterRender = function() { 
	// Intergrate Review Shopify
	if (window.SPR && boostPFSThemeConfig.custom.show_product_review) {
		window.SPR.initDomEls();
		window.SPR.loadBadges();
	}
}

Another example: Integrate with BEST currency converter


3. Callback after filtering

3.1. What this is used for

  • Rendering extra element related to filter tree, that needs to be updated when the filter tree update for example:
    • Text for total number of products
    • Text for number of selected filter
    • Add extra clear all button anywhere on the page
    • Add extra apply all button anywhere on the page
    • ...

3.2. When this is called

  • When filter tree is rendered
  • Filter tree is rendered on first load
  • Filter tree is rendered when filtering
  • Filter tree is not rendered again when changing sorting/pagination

3.3. Commonly used fields

Filter.prototype.afterRender = function() { 
	// The product list data returned from API
	var data = this.data; 
	// Your code here 
}

You can access the product list's data, settings, DOM element,... by this

  • this.$element
  • this.data
  • this.settings
  • this.children: these are the individual product items

You can console.log or check your debugger for all attributes in this

3.4. Example usage

Add a span to show total products text

Filter.prototype.afterRender = function() { 
	var totalProduct = data.total_product + '<span> ' + boostPFSThemeConfig.label.items_with_count_other + '</span>';
	if (data.total_product == 1) {
		totalProduct = data.total_product + '<span> ' + boostPFSThemeConfig.label.items_with_count_one + '</span>';
	}
	jQ('.boost-pfs-filter-total-product').html(totalProduct);
}

Add a text to show number of selected filters

Filter.prototype.afterRender = function() {
	var count = 0;

	this.filterTrees[0].filterOptions.forEach(function(filterOption) {
		// FilterOption has numberAppliedFilterItems field. We add those up.
		count += filterOption.numberAppliedFilterItems;
	})

	// Prepend the count number above the filter tree
	jQ('').prepend('<div> Selected filters: ' + count + '</div>');
}

Add a clear all button outside of filter tree on mobile view

Filter.prototype.afterRender = function() {
	jQ('.clear-all-button-container').append(this.filterTrees[0].clearAllButton.$element);
}