Created
December 4, 2017 13:27
-
-
Save ffoodd/82e066ea2a99fb2f524020950d04f17a to your computer and use it in GitHub Desktop.
FacetWP accessibility improvements
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 = { | |
'&': '&', | |
'<': '<', | |
'>': '>', | |
'"': '"', | |
"'": ''' | |
}; | |
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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.