JavaScript Hooks
The JavaScript hooks are mostly used for theme compatibility, though some customisation is possible. The settings object embedded in the page HTML can be changed before initialisation of the filters, so JavaScript or PHP can be used for some tasks.
Hook Mechanism
JavaScript doesn’t provide a standard mechanism for hooks like WordPress. Therefore the hooks are implemented using the jQuery functionality of triggerHandler. This can take a parameter, and a value is returned. Therefore it’s possible to implement a hook which can take a default value, modify it, and return a result.
However, the standard WordPress mechanism allows for priorities to be set for handlers. This isn’t possible with triggerHandler. It simply calls each registered handler in turn with no sequence. Therefore it’s not possible to guarantee that a particular handler will be the last one called.
Therefore an automatic mechanism is used to trigger hooks with two different names. The first one is an internal hook, used by any theme handler provided by the plugin. Then a different trigger is fired with the work “internal” removed. This allows an externally supplied handler to override the result returned from the internal handler. This makes it much easier when modifying behaviour for a theme.
The relevant code is:
/**
* Trigger a jQuery handler
*
* If the trigger starts with acsell_pf_internal, then a second external trigger
* with the word “internal_” removed is also triggered. This allows external code
* to change the value returned from the internal handler.
*
* It’s done this way so the trigger name can be searched for in all internal code.
*
* Handle the trigger using:
*
* jQuery(document).on( ‘acsell_pf_internal_my_trigger’, function( event, oData ) {
* … // modify oData
* return oData;
* }
*
* @param sTrigger string name of trigger
* @param oData mixed data to send to event handler
*
* @returns mixed updated data
*/
_triggerHandler: function( sTrigger, oData ) {
oData = jQuery( document ).triggerHandler( sTrigger, oData ) || oData;
if ( sTrigger.indexOf( ‘acsell_pf_internal’ ) === 0 ) {
oData = jQuery( document ).triggerHandler( sTrigger.replace( ‘acsell_pf_internal_’, ‘acsell_pf_’, ), oData ) || oData;
}
return oData;
}
Initialisation
Pre initialisation – acsell_pf_internal_pre_initialise, acsell_pf_pre_initialise
This hook allows modification of the global filter object which is a global JS variable called acsell_filter_params.
/**
* acsell_pf_internal_pre_initialise
* – allows changing of the global acsell_filter_params object prior to initialisation
*
* No parameters or return value.
*/
thisFilterObj._triggerHandler( ‘acsell_pf_internal_pre_initialise’ );
Get products per row – acsell_pf_internal_get_product_per_row, acsell_pf_get_product_per_row
Some themes store the number of products per row in a cookie. This hook allows a different value from the default to be set, based on local browser information.
thisFilterObj.m_productPerRow = thisFilterObj._triggerHandler(‘acsell_pf_internal_get_product_per_row’, nProductPerRow);
Theme compatibility – acsell_pf_internal_run_theme_compatibility, acsell_pf_ run_theme_compatibility
This hook is an appropriate place to introduce any click handlers etc relevant for the theme.
thisFilterObj._triggerHandler( “acsell_pf_internal_run_theme_compatibility” )
Change pagination template – acsell_pf_internal_get_pagination_templates, acsell_pf_get_pagination_templates
Acsell Product Filters overrides the pagination controls in the page. This is necessary as it is a Single Page Application. Therefore it has to create the pagination controls appropriately, highlighting the selected page etc.
This hook allows the default template for each part of the pagination controls to be changed.
let defaultTemplate = {};
defaultTemplate.parentClassSelector = ‘.shop-content-area’;
defaultTemplate.paginationContainer = ‘<div class=”products-footer”><nav class=”woocommerce-pagination”></nav></div>’;
defaultTemplate.list = ‘<ul class=”page-numbers acsell_page_numbers”>%pages%</ul>’;
defaultTemplate.prev = ‘<li><a class=”page-numbers prev” href=”javascript:void(0)”>←</a></li>’;
defaultTemplate.number = ‘<li><a class=”page-numbers” title=”%page%” href=”javascript:void(0)”>%page%</a></li>’;
defaultTemplate.current = ‘<li><span class=”page-numbers current” title=”%page%” aria-current=”page” >%page%</span></li>’;
defaultTemplate.ellipsis = ‘<li><span class=”page-numbers dots”>…</span></li>’;
defaultTemplate.next = ‘<li><a class=”page-numbers next” href=”javascript:void(0)”>→</a></li>’;
defaultTemplate.pageSelector = ‘.woocommerce-pagination’;
this.m_pageTemplate = AcsellProductFilters._triggerHandler( “acsell_pf_internal_get_pagination_templates”, defaultTemplate );
Pagination element – acsell_pf_internal_get_pagination_element, acsell_pf_get_pagination_element
This hook is used when the page element does not have the standard class.
thisObj.m_oPageElmnt = thisObj._triggerHandler( “acsell_pf_internal_get_pagination_element”, jQuery( ‘.woocommerce-pagination’ ) );
Selector for sub-category HTML – acsell_pf_internal_get_sub_category_selector, acsell_pf_get_sub_category_selector
When a category page displays sub-categories, the sub-categories have to be preserved when filtering. This hook can be used to modify the selector used to obtain those sub-categories.
let sCategoryElement = this._triggerHandler( ‘acsell_pf_internal_get_sub_category_selector’, ‘.product-category’ );
Products
Product Placeholder Class – acsell_pf_internal_get_product_placeholder_class, acsell_pf_get_product_placeholder_class
This hook is used to add another class to the product placeholder element. It would also be possible to do this by using appropriate PHP hooks.
var viewClass = this._triggerHandler( ‘acsell_pf_internal_get_product_placeholder_class’, ” );
Product Behaviours – acsell_pf_internal_add_product_behaviours, acsell_pf_add_product_behaviours
As the browser JS inserts product HTML dynamically into the page, this may mean that product behaviours – i.e. JavaScript listeners or special classes – are not created properly for the products.
This trigger is passed the list of products that have been added (an array of jQuery elements). Appropriate initialisation of the DOM elements needs to be carried out e.g. to add click handlers. Normally it’s necessary to call the theme JS to do this.
this._triggerHandler( “acsell_pf_internal_add_product_behaviours”, aAddedProduct );
Set product grid size – acsell_pf_internal_set_product_grid_size, acsell_pf_set_product_grid_size
Some themes set the product grid using a class on each element. In that case it’s necessary to update all the elements when the grid size changes, or when new elements are added.
/**
* Set the product grid size based on number of records per row
*
* @param elements jQuery or DOM array of elements to update
*/
setProductGridSize: function ( elements ) {
this._triggerHandler( ‘acsell_pf_internal_set_product_grid_size’, [elements, this.m_productPerRow] );
}
Global Object Interface – AcsellProductFilters
There is a global object that implements the browser JS – AcsellProductFilters.
This has a number of functions that are available for general usage from themes.
Hide the Filters – hideFilters
This is called to hide the filter area, normally as controlled by any theme show/hide buttons or the mobile Show Filters button.
/**
* Hide the filters.
*
* Called from theme compatibility files when theme UI is clicked.
*/
hideFilters: function()
Show filters – showFilters
This is called to hide the filter area, normally as controlled by any theme show/hide buttons or the mobile close filters button.
/**
* Show the filters.
*
* Called from theme compatibility files when theme UI is clicked.
*/
showFilters: function( )
Get number of products per row – getProductPerRow
This is used to get the current setting for the number of products per row. Used when initialising any theme-dependent grid controls.
/**
* Get the products per row
*
* Called from theme compatibility files
*
* @returns productPerRow number of products per row
*/
getProductPerRow: function( ) {
return this.m_productPerRow;
},
Update the number of products per row – updateProductPerRow
This is used to update the products per row. It’s up to the caller to appropriately change the products if needed.
/**
* Change the products per row
*
* Doesn’t trigger a change message
*
* Called from theme compatibility files when theme UI is clicked.
*
* @param productPerRow new value for products per row
*/
updateProductPerRow: function( productPerRow )
Set the product grid size – setProductGridSize
Used to set a grid size for the given products. A handler is required to match this, setting classes as appropriate on each product.
/**
* Set the product grid size based on number of records per row
*
* @param elements jQuery or DOM array of elements to update
*/
setProductGridSize: function ( elements )
Set a cookie – setCookie
This can be used to set a cookie. Can be used to override theme cookies.
/**
* Set the cookie value – external interface
*
* @param cookie_name name of cookie
* @param cookie_value value to store
* @param expiry_time optional expiry time of cookie
*/
setCookie: function( cookie_name, cookie_value, expiry_time )
Get a cookie – getCookie
This can be used to get a cookie value.
/**
* Get the cookie value – external interface
*
* @param cookie_name name of cookie
*
* @returns string cookie value
*/
getCookie: function( cookie_name )
Manipulate the query string – getUpdatedURLQueryString
When changing sort orders, filter selections have to be preserved so the query string sent to the server should include the filter selections. This function is used to manipulate the query string appropriately.
/**
* Get an updated URL query string based on parameter that is changing
*
* Used for different sort by fields in themes
*
* @param urlParams object param->value to change
*
* @returns string new search string
*/
getUpdatedURLQueryString: function( urlParams)
Update products – updateProductRowView
Some themes provide functionality that changes the view of products. This may require the product HTML to be re-requested from the server. This function is used to reload the product HTML.
/**
* Product view has changed
*
* Used from a theme when something changes which affects product display.
* Product HTML is reloaded from server with changed URL parameters
*
* @param view_arg string URL parameter that is changing
* @param view_val string new value for parameter
*
* @returns string new search string
*/
updateProductRowView: function( view_arg, view_val )