Skip to content

Instantly share code, notes, and snippets.

@ffoodd
Created December 4, 2017 13:27
Show Gist options
  • Save ffoodd/82e066ea2a99fb2f524020950d04f17a to your computer and use it in GitHub Desktop.
Save ffoodd/82e066ea2a99fb2f524020950d04f17a to your computer and use it in GitHub Desktop.
FacetWP accessibility improvements
var FWP = FWP || {};
(function($) {
var defaults = {
'facets': {},
'template': null,
'settings': {},
'is_reset': false,
'is_refresh': false,
'is_bfcache': false,
'auto_refresh': true,
'soft_refresh': false,
'static_facet': null,
'used_facets': {},
'facet_type': {},
'loaded': false,
'jqXHR': false,
'extras': {},
'helper': {},
'paged': 1
};
for (var prop in defaults) {
if ('undefined' === typeof FWP[prop]) {
FWP[prop] = defaults[prop];
}
}
// Safari popstate fix
$(window).on('load', function() {
setTimeout(function() {
$(window).on('popstate', function() {
// Detect browser "back-foward" cache
if (FWP.is_bfcache) {
FWP.loaded = false;
}
if ((FWP.loaded || FWP.is_bfcache) && ! FWP.is_refresh) {
FWP.is_popstate = true;
FWP.refresh();
FWP.is_popstate = false;
}
});
}, 0);
});
FWP.helper.get_url_var = function(name) {
var name = FWP_JSON.prefix + name;
var query_string = FWP.build_query_string();
var url_vars = query_string.split('&');
for (var i = 0; i < url_vars.length; i++) {
var item = url_vars[i].split('=');
if (item[0] === name) {
return item[1];
}
}
return false;
}
FWP.helper.serialize = function(obj, prefix) {
var str = [];
var prefix = ('undefined' !== typeof prefix) ? prefix : '';
for (var p in obj) {
if ('' != obj[p]) { // This must be "!=" instead of "!=="
str.push(prefix + encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
}
}
return str.join('&');
}
FWP.helper.escape_html = function(text) {
var map = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;'
};
return text.replace(/[&<>"']/g, function(m) { return map[m]; }).trim();
}
FWP.helper.detect_loop = function(node) {
var iterator = document.createNodeIterator(node, NodeFilter.SHOW_COMMENT, FWP.helper.node_filter, false);
while (curNode = iterator.nextNode()) {
if (8 === curNode.nodeType && 'fwp-loop' === curNode.nodeValue) {
return curNode.parentNode;
}
}
return false;
}
FWP.helper.node_filter = function() {
return NodeFilter.FILTER_ACCEPT;
}
// Refresh on each facet interaction?
FWP.autoload = function() {
if (FWP.auto_refresh && ! FWP.is_refresh) {
FWP.refresh();
}
}
FWP.refresh = function() {
FWP.is_refresh = true;
// Load facet DOM values
if (! FWP.is_reset) {
FWP.parse_facets();
}
// Check the URL on pageload
if (! FWP.loaded) {
FWP.load_from_hash();
}
// Fire a notification event
$(document).trigger('facetwp-refresh');
// Trigger window.onpopstate
if (FWP.loaded && ! FWP.is_popstate) {
FWP.set_hash();
}
// Preload?
if (! FWP.loaded && ! FWP.is_bfcache && 'undefined' !== typeof FWP_JSON.preload_data) {
FWP.render(FWP_JSON.preload_data);
}
else {
FWP.fetch_data();
}
// Cleanup
FWP.paged = 1;
FWP.static_facet = null;
FWP.soft_refresh = false;
FWP.is_refresh = false;
FWP.is_reset = false;
}
FWP.parse_facets = function() {
FWP.facets = {};
$('.facetwp-facet').each(function() {
var $this = $(this);
var facet_name = $this.attr('data-name');
var facet_type = $this.attr('data-type');
// Store the facet type
FWP.facet_type[facet_name] = facet_type;
// Plugin hook
wp.hooks.doAction('facetwp/refresh/' + facet_type, $this, facet_name);
// Support custom loader
var do_loader = true;
if (FWP.loaded) {
if (FWP.soft_refresh || facet_name === FWP.static_facet || 'undefined' !== typeof FWP.used_facets[facet_name]) {
do_loader = false;
}
}
if (do_loader) {
FWP.loading_handler({
'element': $this,
'facet_name': facet_name,
'facet_type': facet_type
});
}
});
// Add pagination to the URL hash
if (1 < FWP.paged) {
FWP.facets['paged'] = FWP.paged;
}
// Add "per page" to the URL hash
if (FWP.extras.per_page && 'default' !== FWP.extras.per_page) {
FWP.facets['per_page'] = FWP.extras.per_page;
}
// Add sorting to the URL hash
if (FWP.extras.sort && 'default' !== FWP.extras.sort) {
FWP.facets['sort'] = FWP.extras.sort;
}
}
FWP.loading_handler = function(args) {
if ('fade' == FWP_JSON.loading_animation) {
if (! FWP.loaded) {
var $el = args.element;
$(document).on('facetwp-refresh', function() {
$el.prepend('<div class="facetwp-overlay">');
$el.find('.facetwp-overlay').css({
width: $el.width(),
height: $el.height()
});
});
$(document).on('facetwp-loaded', function() {
$el.find('.facetwp-overlay').remove();
});
}
}
else if ('' == FWP_JSON.loading_animation) {
args.element.html('<div class="facetwp-loading"></div>');
}
}
FWP.build_query_string = function() {
var query_string = '';
// Non-FacetWP URL variables
var hash = [];
var get_str = window.location.search.replace('?', '').split('&');
$.each(get_str, function(idx, val) {
var param_name = val.split('=')[0];
if (0 !== param_name.indexOf(FWP_JSON.prefix)) {
hash.push(val);
}
});
hash = hash.join('&');
// FacetWP URL variables
var fwp_vars = FWP.helper.serialize(FWP.facets, FWP_JSON.prefix);
if ('' !== hash) {
query_string += hash;
}
if ('' !== fwp_vars) {
query_string += ('' !== hash ? '&' : '') + fwp_vars;
}
return query_string;
}
FWP.set_hash = function() {
var query_string = FWP.build_query_string();
if ('' !== query_string) {
query_string = '?' + query_string;
}
if (history.pushState) {
history.pushState(null, null, window.location.pathname + query_string);
}
// Update FWP_HTTP.get
FWP_HTTP.get = {};
window.location.search.replace('?', '').split('&').forEach(function(el) {
var item = el.split('=');
FWP_HTTP.get[item[0]] = item[1];
});
}
FWP.load_from_hash = function() {
var hash = [];
var get_str = window.location.search.replace('?', '').split('&');
$.each(get_str, function(idx, val) {
var param_name = val.split('=')[0];
if (0 === param_name.indexOf(FWP_JSON.prefix)) {
hash.push(val.replace(FWP_JSON.prefix, ''));
}
});
hash = hash.join('&');
// Reset facet values
$.each(FWP.facets, function(f) {
FWP.facets[f] = [];
});
FWP.paged = 1;
FWP.extras.sort = 'default';
if ('' !== hash) {
hash = hash.split('&');
$.each(hash, function(idx, chunk) {
var obj = chunk.split('=')[0];
var val = chunk.split('=')[1];
if ('paged' === obj) {
FWP.paged = val;
}
else if ('per_page' === obj) {
FWP.extras.per_page = val;
}
else if ('sort' === obj) {
FWP.extras.sort = val;
}
else if ('' !== val) {
var type = ('undefined' !== typeof FWP.facet_type[obj]) ? FWP.facet_type[obj] : '';
if ('search' === type || 'autocomplete' === type) {
FWP.facets[obj] = decodeURIComponent(val);
}
else {
FWP.facets[obj] = decodeURIComponent(val).split(',');
}
}
});
}
}
FWP.fetch_data = function() {
// Abort pending requests
if (FWP.jqXHR && FWP.jqXHR.readyState !== 4) {
FWP.jqXHR.abort();
}
var endpoint = ('wp' === FWP.template) ? document.URL : FWP_JSON.ajaxurl;
// dataType is "text" for better JSON error handling
FWP.jqXHR = $.ajax(endpoint, {
type: 'POST',
dataType: 'text',
data: {
action: 'facetwp_refresh',
data: {
'facets': JSON.stringify(FWP.facets),
'static_facet': FWP.static_facet,
'used_facets': FWP.used_facets,
'http_params': FWP_HTTP,
'template': FWP.template,
'extras': FWP.extras,
'soft_refresh': FWP.soft_refresh ? 1 : 0,
'is_bfcache': FWP.is_bfcache ? 1 : 0,
'first_load': FWP.loaded ? 0 : 1,
'paged': FWP.paged
}
},
success: function(response) {
try {
var json_object = $.parseJSON(response);
FWP.render(json_object);
}
catch(e) {
var pos = response.indexOf('{"facets');
if (-1 < pos) {
var error = response.substr(0, pos);
var json_object = $.parseJSON(response.substr(pos));
FWP.render(json_object);
// Log the error
console.log(error);
}
else {
$('.facetwp-template').text('FacetWP was unable to auto-detect the post listing');
// Log the error
console.log(response);
}
}
}
});
}
FWP.render = function(response) {
// Don't render CSS-based (or empty) templates on pageload
// The template has already been pre-loaded
if (('wp' === FWP.template || '' === response.template) && ! FWP.loaded && ! FWP.is_bfcache) {
var inject = false;
}
else {
var inject = response.template;
if ('wp' === FWP.template) {
var $tpl = $(response.template).find('.facetwp-template');
if (1 > $tpl.length) {
var wrap = document.createElement('div');
wrap.innerHTML = response.template;
var loop = FWP.helper.detect_loop(wrap);
if (loop) {
$tpl = $(loop).addClass('facetwp-template');
}
}
if (0 < $tpl.length) {
var inject = $tpl.html();
}
else {
// Fallback until "loop_no_results" action is added to WP core
var inject = FWP_JSON['no_results_text'];
}
}
}
if (false !== inject) {
if (! wp.hooks.applyFilters('facetwp/template_html', false, { 'response': response, 'html': inject })) {
$('.facetwp-template').html(inject);
}
}
// Populate each facet box
$.each(response.facets, function(name, val) {
$('.facetwp-facet-' + name).html(val);
});
// Populate the counts
if ('undefined' !== typeof response.counts) {
$('.facetwp-counts').html(response.counts);
wp.a11y.speak(response.counts);
}
// Populate the pager
if ('undefined' !== typeof response.pager) {
$('.facetwp-pager').html(response.pager);
}
// Populate the "per page" box
if ('undefined' !== typeof response.per_page) {
$('.facetwp-per-page').html(response.per_page);
if ('default' !== FWP.extras.per_page) {
$('.facetwp-per-page-select').val(FWP.extras.per_page);
}
}
// Populate the sort box
if ('undefined' !== typeof response.sort) {
$('.facetwp-sort').html(response.sort);
$('.facetwp-sort-select').val(FWP.extras.sort);
}
// Populate the settings object (iterate to preserve static facet settings)
$.each(response.settings, function(key, val) {
FWP.settings[key] = val;
});
// WP Playlist support
if ('function' === typeof WPPlaylistView) {
$('.facetwp-template .wp-playlist').each(function() {
return new WPPlaylistView({ el: this });
});
}
// Fire a notification event
$(document).trigger('facetwp-loaded');
// Allow final actions
wp.hooks.doAction('facetwp/loaded');
// Detect "back-forward" cache
FWP.is_bfcache = true;
// Done loading?
FWP.loaded = true;
}
FWP.reset = function(facet_name) {
FWP.parse_facets();
if ('undefined' !== typeof facet_name) {
FWP.facets[facet_name] = [];
if ('undefined' !== typeof FWP.used_facets) {
delete FWP.used_facets[facet_name];
}
}
else {
$.each(FWP.facets, function(f) {
FWP.facets[f] = [];
});
FWP.extras.sort = 'default';
FWP.used_facets = {};
}
FWP.is_reset = true;
FWP.refresh();
}
FWP.init = function() {
if (0 < $('.facetwp-sort').length) {
FWP.extras.sort = 'default';
}
if (0 < $('.facetwp-pager').length) {
FWP.extras.pager = true;
}
if (0 < $('.facetwp-per-page').length) {
FWP.extras.per_page = 'default';
}
if (0 < $('.facetwp-counts').length) {
FWP.extras.counts = true;
}
if (0 < $('.facetwp-selections').length) {
FWP.extras.selections = true;
}
// Make sure there's a template
var has_template = $('.facetwp-template').length > 0;
if (! has_template) {
var has_loop = FWP.helper.detect_loop(document.body);
if (has_loop) {
$(has_loop).addClass('facetwp-template');
}
else {
return;
}
}
var $div = $('.facetwp-template:first');
FWP.template = $div.is('[data-name]') ? $div.attr('data-name') : 'wp';
// Facets inside the template?
if (0 < $div.find('.facetwp-facet').length) {
console.error('Facets should not be inside the "facetwp-template" container');
}
wp.hooks.doAction('facetwp/ready');
// Generate the user selections
if (FWP.extras.selections) {
wp.hooks.addAction('facetwp/loaded', function() {
var selections = '';
$.each(FWP.facets, function(key, val) {
if (val.length < 1 || 'undefined' === typeof FWP.settings.labels[key]) {
return true; // skip this facet
}
var choices = val;
var facet_type = $('.facetwp-facet-' + key).attr('data-type');
choices = wp.hooks.applyFilters('facetwp/selections/' + facet_type, choices, {
'el': $('.facetwp-facet-' + key),
'selected_values': choices
});
if ('string' === typeof choices) {
choices = [{ value: '', label: choices }];
}
else if ('undefined' === typeof choices[0].label) {
choices = [{ value: '', label: choices[0] }];
}
var values = '';
$.each(choices, function(idx, choice) {
values += '<span class="facetwp-selection-value" data-value="' + choice.value + '">' + FWP.helper.escape_html(choice.label) + '</span>';
});
selections += '<li data-facet="' + key + '"><span class="facetwp-selection-label">' + FWP.settings.labels[key] + ':</span> ' + values + '</li>';
});
if ('' !== selections) {
selections = '<ul>' + selections + '</ul>';
}
$('.facetwp-selections').html(selections);
});
}
// Click on a user selection
$(document).on('click', '.facetwp-selections .facetwp-selection-value', function() {
if (FWP.is_refresh) {
return;
}
var facet_name = $(this).closest('li').attr('data-facet');
var facet_value = $(this).attr('data-value');
FWP.parse_facets();
FWP.is_reset = true;
if ('' != facet_value) {
var arr = FWP.facets[facet_name];
var arr_idx = arr.indexOf(facet_value);
if (-1 < arr_idx) {
arr.splice(arr_idx, 1);
FWP.facets[facet_name] = arr;
}
}
else {
FWP.facets[facet_name] = [];
}
if ('undefined' !== typeof FWP.used_facets) {
delete FWP.used_facets[facet_name]; // slider support
}
delete FWP.facets['paged']; // remove "paged" from URL
FWP.refresh();
});
// Pagination
$(document).on('click', '.facetwp-page', function(e) {
e.preventDefault();
$('.facetwp-page').removeClass('active');
$(this).addClass('active');
FWP.paged = $(this).attr('data-page');
FWP.soft_refresh = true;
FWP.refresh();
});
// Per page
$(document).on('change', '.facetwp-per-page-select', function() {
FWP.extras.per_page = $(this).val();
FWP.soft_refresh = true;
FWP.autoload();
});
// Sorting
$(document).on('change', '.facetwp-sort-select', function() {
FWP.extras.sort = $(this).val();
FWP.soft_refresh = true;
FWP.autoload();
});
$(document).on('facetwp-loaded', function() {
var label_id = "";
$('.facetwp-sort-select, .facetwp-dropdown').each(function() {
label_id = $(this).parents(".widget").find(".form-control-label").attr("id");
$(this).attr("aria-labelledby", label_id);
});
});
FWP.refresh();
}
$(function() {
FWP.init();
});
})(jQuery);
<?php
/*
Plugin Name: FacetWP a11y
Description: FacetWP accessibility improvements
Author: Gaël Poupard
Version: 0.1
*/
add_filter('facetwp_assets', function($assets) {
unset($assets['front.js']);
unset($assets['fSelect.js']);
$assets['mu-facetwp-front.js'] = plugins_url('/js/mu-facetwp-front.js', __FILE__);
$assets['mu-facetwp-fselect.js'] = plugins_url('/js/mu-fSelect.js', __FILE__);
return $assets;
});
add_filter('facetwp_pager_html', function($html, $params) {
$html = '<nav aria-label="' . __('Pagination', 'mu-facetwp') . '"><ul class="pagination">';
// first
$classes = 'page-item';
if ($params['page'] === 1) {
$classes .= ' disabled';
$tabindex = ' tabindex="-1"';
}
$html .= '<li class="' . $classes . '">';
$html .= '<a class="facetwp-page page-link" data-page="' . ($params['page'] - 1). '" href="' . get_pagenum_link($params['page'] - 1) . '"' . $tabindex . '>';
$html .= '<span class="screen-reader-text">' . __('Previous page', 'mu-facetwp') . '</span>';
$html .= '</a></li>';
// number
if ($params['total_pages'] > 1) {
for ($i = 1; $i <= $params['total_pages']; $i++) {
// skip far pages
if ($i < $params['page'] - 3 || $i > $params['page'] + 3) {
continue;
}
$aria = '';
$classes = 'page-item';
if ($params['page'] === $i) {
$classes .= ' active';
$aria = ' aria-current="page" tabindex="-1"';
}
$html .= '<li class="' . $classes . '">';
$html .= '<a class="facetwp-page page-link"' . $aria . ' data-page="' . $i . '" href="' . get_pagenum_link($i) . '">' . __('Page ', 'mu-facetwp') . $i . '</a>';
$html .= '</li>';
}
}
// last
$classes = 'page-item';
if ($params['page'] === $params['total_pages']) {
$classes .= ' disabled';
$tabindex = ' tabindex="-1"';
}
$html .= '<li class="' . $classes . '">';
$html .= '<a class="facetwp-page page-link" data-page="' . ($params['page'] + 1). '" href="' . get_pagenum_link($params['page'] + 1) . '"' . $tabindex . '>';
$html .= '<span class="screen-reader-text">' . __('Next page', 'mu-facetwp') . '</span>';
$html .= '</a></li>';
$html .= '</ul></nav>';
return $html;
}, 10, 2);
add_filter('facetwp_result_count', function($output, $params) {
$output = sprintf(
__('Showing results %1$s to %2$s of %3$s.', 'mu-facetwp'),
$params['lower'],
$params['upper'],
$params['total']
);
return $output;
}, 10, 2);
(function($) {
$.fn.fSelect = function(options) {
if ('string' === typeof options) {
var settings = options;
}
else {
var settings = $.extend({
placeholder: 'Select some options',
numDisplayed: 3,
overflowText: '{n} selected',
searchText: 'Search',
showSearch: true,
optionFormatter: false
}, options);
}
/**
* Constructor
*/
function fSelect(select, settings) {
this.$select = $(select);
this.settings = settings;
this.create();
}
/**
* Prototype class
*/
fSelect.prototype = {
create: function() {
this.settings.multiple = this.$select.is('[multiple]');
var multiple = this.settings.multiple ? ' multiple' : '';
this.$select.wrap('<div class="fs-wrap' + multiple + '" tabindex="0" />');
this.$select.before('<div class="fs-label-wrap" role="presentation"><div class="fs-label">' + this.settings.placeholder + '</div><span class="fs-arrow"></span></div>');
var legend = this.$select.parents(".widget").first().find(".form-control-label").attr("id");
this.$select.before('<div class="fs-dropdown hidden"><ul class="fs-options list-unstyled" role="group" aria-labelledby="' + legend + '"></ul></div>');
this.$select.addClass('hidden');
this.$wrap = this.$select.closest('.fs-wrap');
this.$wrap.data('id', window.fSelect.num_items);
window.fSelect.num_items++;
this.reload();
},
reload: function() {
if (this.settings.showSearch) {
var search = '<div class="fs-search"><input type="search" aria-label="' + this.settings.searchText + '" placeholder="' + this.settings.searchText + '"/></div>';
this.$wrap.find('.fs-dropdown').prepend(search);
}
this.idx = 0;
this.optgroup = 0;
this.selected = [].concat(this.$select.val()); // force an array
var choices = this.buildOptions(this.$select);
this.$wrap.find('.fs-options').html(choices);
this.reloadDropdownLabel();
},
destroy: function() {
this.$wrap.find('.fs-label-wrap').remove();
this.$wrap.find('.fs-dropdown').remove();
this.$select.unwrap().removeClass('hidden');
},
buildOptions: function($element) {
var $this = this;
var choices = '';
$element.children().each(function(i, el) {
var $el = $(el);
if ('optgroup' == $el.prop('nodeName').toLowerCase()) {
choices += '<div class="fs-optgroup-label" data-group="' + $this.optgroup + '">' + $el.prop('label') + '</div>';
choices += $this.buildOptions($el);
$this.optgroup++;
}
else {
var val = $el.prop('value');
// exclude the first option in multi-select mode
if (0 < $this.idx || '' != val || ! $this.settings.multiple) {
var disabled = $el.is(':disabled') ? ' disabled' : '';
var selected = -1 < $.inArray(val, $this.selected) ? ' selected' : '';
var checked = -1 < $.inArray(val, $this.selected) ? 'true' : 'false';
var group = ' g' + $this.optgroup;
var row = '<li class="fs-option' + selected + disabled + group + '" data-value="' + val + '" data-index="' + $this.idx + '"><span class="fs-checkbox" aria-hidden="true"><i aria-hidden="true"></i></span><span class="fs-option-label" role="checkbox" aria-checked="' + checked + '" tabindex="0">' + $el.html() + '</span></li>';
if ('function' === typeof $this.settings.optionFormatter) {
row = $this.settings.optionFormatter(row);
}
choices += row;
$this.idx++;
}
}
});
return choices;
},
reloadDropdownLabel: function() {
var settings = this.settings;
var labelText = [];
this.$wrap.find('.fs-option.selected').each(function(i, el) {
labelText.push($(el).find('.fs-option-label').text());
$(el).find(".fs-option-label").attr("aria-checked", "true");
});
if (labelText.length < 1) {
labelText = settings.placeholder;
}
else if (labelText.length > settings.numDisplayed) {
labelText = settings.overflowText.replace('{n}', labelText.length);
}
else {
labelText = labelText.join(', ');
}
this.$wrap.find('.fs-label').html(labelText);
this.$wrap.toggleClass('fs-default', labelText === settings.placeholder);
this.$select.change();
}
}
/**
* Loop through each matching element
*/
return this.each(function() {
var data = $(this).data('fSelect');
if (!data) {
data = new fSelect(this, settings);
$(this).data('fSelect', data);
}
if ('string' === typeof settings) {
data[settings]();
}
});
}
/**
* Events
*/
window.fSelect = {
'num_items': 0,
'active_id': null,
'active_el': null,
'last_choice': null,
'idx': -1
};
$(document).on('click', '.fs-option:not(.hidden, .disabled)', function(e) {
var $wrap = $(this).closest('.fs-wrap');
var do_close = false;
if ($wrap.hasClass('multiple')) {
var selected = [];
// shift + click support
if (e.shiftKey && null != window.fSelect.last_choice) {
var current_choice = parseInt($(this).attr('data-index'));
var addOrRemove = ! $(this).hasClass('selected');
var min = Math.min(window.fSelect.last_choice, current_choice);
var max = Math.max(window.fSelect.last_choice, current_choice);
for (i = min; i <= max; i++) {
$wrap.find('.fs-option[data-index='+ i +']')
.not('.hidden, .disabled')
.each(function() {
$(this).toggleClass('selected', addOrRemove);
$(this).find(".fs-option-label").attr("aria-checked", addOrRemove);
});
}
}
else {
window.fSelect.last_choice = parseInt($(this).attr('data-index'));
$(this).toggleClass('selected');
$(this).find(".fs-option-label").attr("aria-checked", ! $(this).find(".fs-option-label").attr("aria-checked"));
}
$wrap.find('.fs-option.selected').each(function(i, el) {
selected.push($(el).attr('data-value'));
});
}
else {
var selected = $(this).attr('data-value');
$wrap.find('.fs-option').removeClass('selected');
$(this).addClass('selected');
do_close = true;
}
$wrap.find('select').val(selected);
$wrap.find('select').fSelect('reloadDropdownLabel');
// fire an event
$(document).trigger('fs:changed', $wrap);
if (do_close) {
closeDropdown($wrap);
}
});
$(document).on('keyup', '.fs-search input', function(e) {
if (40 == e.which) { // down
$(this).blur();
return;
}
var $wrap = $(this).closest('.fs-wrap');
var matchOperators = /[|\\{}()[\]^$+*?.]/g;
var keywords = $(this).val().replace(matchOperators, '\\$&');
$wrap.find('.fs-option, .fs-optgroup-label').removeClass('hidden');
if ('' != keywords) {
$wrap.find('.fs-option').each(function() {
var regex = new RegExp(keywords, 'gi');
if (null === $(this).find('.fs-option-label').text().match(regex)) {
$(this).addClass('hidden');
}
});
$wrap.find('.fs-optgroup-label').each(function() {
var group = $(this).attr('data-group');
var num_visible = $(this).closest('.fs-options').find('.fs-option.g' + group + ':not(.hidden)').length;
if (num_visible < 1) {
$(this).addClass('hidden');
}
});
}
setIndexes($wrap);
});
$(document).on('click', function(e) {
var $el = $(e.target);
var $wrap = $el.closest('.fs-wrap');
if (0 < $wrap.length) {
// user clicked another fSelect box
if ($wrap.data('id') !== window.fSelect.active_id) {
closeDropdown();
}
// fSelect box was toggled
if ($el.hasClass('fs-label') || $el.hasClass('fs-arrow')) {
var is_hidden = $wrap.find('.fs-dropdown').hasClass('hidden');
if (is_hidden) {
openDropdown($wrap);
}
else {
closeDropdown($wrap);
}
}
}
// clicked outside, close all fSelect boxes
else {
closeDropdown();
}
});
$(document).on('keydown', function(e) {
var $wrap = window.fSelect.active_el;
var $target = $(e.target);
// toggle the dropdown on space
if ($target.hasClass('fs-wrap')) {
if (32 == e.which) {
$target.find('.fs-label').trigger('click');
return;
}
}
// preserve spaces during search
else if (0 < $target.closest('.fs-search').length) {
if (32 == e.which) {
return;
}
}
else if (null === $wrap) {
return;
}
if (38 == e.which) { // up
e.preventDefault();
$wrap.find('.fs-option.hl').removeClass('hl');
var $current = $wrap.find('.fs-option[data-index=' + window.fSelect.idx + ']');
var $prev = $current.prevAll('.fs-option:not(.hidden, .disabled)');
if ($prev.length > 0) {
window.fSelect.idx = parseInt($prev.attr('data-index'));
$wrap.find('.fs-option[data-index=' + window.fSelect.idx + ']').addClass('hl');
setScroll($wrap);
}
else {
window.fSelect.idx = -1;
$wrap.find('.fs-search input').focus();
}
}
else if (40 == e.which) { // down
e.preventDefault();
var $current = $wrap.find('.fs-option[data-index=' + window.fSelect.idx + ']');
if ($current.length < 1) {
var $next = $wrap.find('.fs-option:not(.hidden, .disabled):first');
}
else {
var $next = $current.nextAll('.fs-option:not(.hidden, .disabled)');
}
if ($next.length > 0) {
window.fSelect.idx = parseInt($next.attr('data-index'));
$wrap.find('.fs-option.hl').removeClass('hl');
$wrap.find('.fs-option[data-index=' + window.fSelect.idx + ']').addClass('hl');
setScroll($wrap);
}
}
else if (32 == e.which || 13 == e.which) { // space, enter
e.preventDefault();
$wrap.find('.fs-option.hl').click();
}
else if (27 == e.which) { // esc
closeDropdown($wrap);
}
});
function setIndexes($wrap) {
$wrap.find('.fs-option.hl').removeClass('hl');
$wrap.find('.fs-search input').focus();
window.fSelect.idx = -1;
}
function setScroll($wrap) {
var $container = $wrap.find('.fs-options');
var $selected = $wrap.find('.fs-option.hl');
var itemMin = $selected.offset().top + $container.scrollTop();
var itemMax = itemMin + $selected.outerHeight();
var containerMin = $container.offset().top + $container.scrollTop();
var containerMax = containerMin + $container.outerHeight();
if (itemMax > containerMax) { // scroll down
var to = $container.scrollTop() + itemMax - containerMax;
$container.scrollTop(to);
}
else if (itemMin < containerMin) { // scroll up
var to = $container.scrollTop() - containerMin - itemMin;
$container.scrollTop(to);
}
}
function openDropdown($wrap) {
window.fSelect.active_el = $wrap;
window.fSelect.active_id = $wrap.data('id');
window.fSelect.initial_values = $wrap.find('select').val();
$wrap.find('.fs-dropdown').removeClass('hidden');
$wrap.addClass('fs-open');
setIndexes($wrap);
}
function closeDropdown($wrap) {
if ('undefined' == typeof $wrap && null != window.fSelect.active_el) {
$wrap = window.fSelect.active_el;
}
if ('undefined' !== typeof $wrap) {
// only trigger if the values have changed
var initial_values = window.fSelect.initial_values;
var current_values = $wrap.find('select').val();
if (JSON.stringify(initial_values) != JSON.stringify(current_values)) {
$(document).trigger('fs:closed', $wrap);
}
}
$('.fs-wrap').removeClass('fs-open');
$('.fs-dropdown').addClass('hidden');
window.fSelect.active_el = null;
window.fSelect.active_id = null;
window.fSelect.last_choice = null;
}
})(jQuery);
@a4jp-com
Copy link

a4jp-com commented Jul 4, 2021

Is there a way to echo out page numbers in PHP from FacetWP in templates? I can see <?php echo facetwp_display( 'pager' ); ?> creates the pagination but I just wanna get the page number after clicking the pagination numbers, next or last. I want to add post numbers like 1/12, 2/12, 3/12, etc. to each post.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment