(function( $ ) { 'use strict'; /** * Variables used by the AJAX call */ var xhr; var active = false; var timer; /** * Old-timer function used by select2 to match by characters in their order of appearance (or whatever). */ function matchStart (term, text) { if (text.toUpperCase().indexOf(term.toUpperCase()) === 0) { return true; } return false; } /** * Lets select2 all night long */ function create_select2_dropdown( select_el ){ var args = { allowClear: btf_localization.allow_clear, syncCssClasses: true, minimumResultsForSearch: parseInt(btf_localization.min_search) }; if( btf_localization.show_description == '1' ){ args.templateResult = formatResult; args.templateSelection = formatSelection; } /** * Support language */ if( btf_localization.language !== '' ) { args.language = btf_localization.language; } /** * Support RTL */ if( btf_localization.rtl == '1' ) { args.dir = 'rtl'; } var select2; if ( btf_localization.disable_fuzzy == '1' ) { $.fn.select2.amd.require(['select2/compat/matcher'], function (oldMatcher) { args.matcher = oldMatcher(matchStart); if ( typeof select_el !== 'undefined' ) { select2 = select_el.select2(args); }else{ select2 = $('.beautiful-taxonomy-filters-select').select2(args); } }); } else { if ( typeof select_el !== 'undefined' ) { select2 = select_el.select2(args); }else{ select2 = $('.beautiful-taxonomy-filters-select').select2(args); } } } /** * Format the results of select2 * */ function formatResult (term) { if (!term.id ){ return term.text; } var new_term = term.text; if( term.text.indexOf(":.:") !== -1) { new_term = new_term.replace(':.:', '
'); new_term = new_term.replace(':-:', ''); } var $term = $( '' + new_term + '' ); return $term; } /** * Format the selection of select2 * */ function formatSelection (term) { if (!term.id || term.text.indexOf(":.:") === -1) { return term.text; } //run a regexp on the text to find :.:' + new_term + '' ); return $term; } /** * Run the AJAX update function to make terms conditional. * * @param el jQuery object of the select that changed. */ function conditional_terms_ajax_new( el ){ /** * If there's already an active AJAX request kill it. */ if( active ) { xhr.abort(); } /** * Show loaders and disable selects if the response takes more than 1 second. */ if( timer ){ clearTimeout(timer); } timer = setTimeout(function(){ form.find('.beautiful-taxonomy-filters-loader').addClass('active'); form.find('select.beautiful-taxonomy-filters-select').prop('disabled', true); form.find('.beautiful-taxonomy-filters-button').prop('disabled', true); }, 800); /** * Get general options */ var form = el.closest('#beautiful-taxonomy-filters-form'), nonce = el.data('nonce'), posttype = $('input[name="post_type"]').val(), selects = [], taxonomies = []; /** * Get values from all selects */ var filtered_taxonomies = []; form.find('select.beautiful-taxonomy-filters-select').each(function(index){ var sel = $(this), taxonomy = sel.data('taxonomy'), val = sel.val(); if( val === '' ){ val = 0; } selects.push({ taxonomy: sel.data('taxonomy'), term: val, }); taxonomies.push( sel.data('taxonomy') ); if ( val) { filtered_taxonomies.push( sel.data('taxonomy') ); } }); /** * Run our AJAX */ active = true; xhr = $.ajax({ type: 'post', dataType: 'json', url: btf_localization.ajaxurl, data: { action: 'update_filters_callback', selects: selects, posttype: posttype, nonce: nonce, taxonomies: taxonomies }, success: function( response ){ /** * Make sure all dropdowns are enabled and loaders are hidden */ if( timer ){ clearTimeout(timer); } form.find('select.beautiful-taxonomy-filters-select').prop( 'disabled', false ); form.find('.beautiful-taxonomy-filters-loader').removeClass('active'); form.find('.beautiful-taxonomy-filters-button').prop('disabled', false); /** * Lets get cracking on hiding options */ if( Object.keys(response).length > 0 ){ $.each(response, function(taxonomy, terms) { var select_element = form.find('select.beautiful-taxonomy-filters-select[data-taxonomy="' + taxonomy + '"]'); // Let's first check if we've only filtered one select. If so, we should not disabled any of that's dropdowns so it's easier to switch. if ( 1 === filtered_taxonomies.length && taxonomy === filtered_taxonomies[0] ) { return; } // First we disable all options. var options = select_element.find('option').prop('disabled', true); // Not for the default value.. that dude wants to live. select_element.find('option[value="0"], option[value=""]').prop('disabled', false); // Then we loop through all fetched terms and enable them. for ( var i = 0; i < terms.length; i++ ) { var term = terms[i]; var text = terms[i].term_name; if ( btf_localization.show_count == 1 ) { text += ' (' + terms[i].term_count + ')'; } var option = select_element.find('option[value="' + terms[i].term_id + '"]').prop('disabled', false).text( text ); } // If select2 is being used we need to destroy the instance and run a new one. if( btf_localization.disable_select2 != '1' ){ select_element.select2('destroy'); create_select2_dropdown(select_element); } }); } }, error: function(){ /** * Make sure all dropdowns are enabled and loaders are hidden */ if( timer ){ clearTimeout(timer); } form.find('select.beautiful-taxonomy-filters-select').prop( 'disabled', false ); form.find('.beautiful-taxonomy-filters-loader').removeClass('active'); form.find('.beautiful-taxonomy-filters-button').prop('disabled', false); }, complete: function(){ /** * Regardless of success/error we are done. Set active to false. */ active = false; } }); } /** * Run the AJAX update function to make terms conditional. * * @param el jQuery object of the select that changed. */ function conditional_terms_ajax( el ){ /** * If there's already an active AJAX request kill it. */ if( active ) { xhr.abort(); } /** * Show loaders and disable selects if the response takes more than 1 second. */ if( timer ){ clearTimeout(timer); } timer = setTimeout(function(){ form.find('.beautiful-taxonomy-filters-loader').addClass('active'); form.find('select.beautiful-taxonomy-filters-select').prop('disabled', true); form.find('.beautiful-taxonomy-filters-button').prop('disabled', true); }, 800); /** * Get general options */ var form = el.closest('#beautiful-taxonomy-filters-form'), nonce = el.data('nonce'), posttype = $('input[name="post_type"]').val(), current_taxonomy = el.data('taxonomy'), selects = []; /** * Get values from all selects */ form.find('select.beautiful-taxonomy-filters-select').each(function(index){ var sel = $(this), taxonomy = sel.data('taxonomy'), val = sel.val(); if( val === '' ){ val = 0; } selects.push({ taxonomy: sel.data('taxonomy'), term: val, }); }); /** * Run our AJAX */ active = true; xhr = $.ajax({ type: 'post', dataType: 'json', url: btf_localization.ajaxurl, data: { action: 'update_filters_callback', selects: selects, posttype: posttype, current_taxonomy: current_taxonomy, nonce: nonce, }, success: function( response ){ /** * Make sure all dropdowns are enabled and loaders are hidden */ if( timer ){ clearTimeout(timer); } form.find('select.beautiful-taxonomy-filters-select').prop( 'disabled', false ); form.find('.beautiful-taxonomy-filters-loader').removeClass('active'); form.find('.beautiful-taxonomy-filters-button').prop('disabled', false); /** * Lets get cracking on hiding options */ if( Object.keys(response.taxonomies).length > 0 ){ $.each(response.taxonomies, function(taxonomy, terms){ var select_element = form.find('select.beautiful-taxonomy-filters-select[data-taxonomy="' + taxonomy + '"]'); select_element.find('option').each(function(){ var option = $(this), val = option.val(), option_text = option.text(); /** * empty or 0 is probably an "all" option and we should leave these alone! * also.. leave britney alone! */ if( val === '' || val === 0 || val == '0' ){ return true; } if( $.inArray( val, terms ) === -1 ){ option.prop('disabled', true); } else { option.prop('disabled', false); } }); /** * If select2 is being used we need to destroy the instance and run a new one. */ if( btf_localization.disable_select2 != '1' ){ var select_el = form.find('select.beautiful-taxonomy-filters-select[data-taxonomy="' + taxonomy + '"]'); select_el.select2('destroy'); create_select2_dropdown(select_el); } /** * These do not work consistently.. select2 has some work to do. * form.find('select.beautiful-taxonomy-filters-select[data-taxonomy="' + taxonomy + '"]').trigger('change.select2'); */ }); } }, error: function(){ /** * Make sure all dropdowns are enabled and loaders are hidden */ if( timer ){ clearTimeout(timer); } form.find('select.beautiful-taxonomy-filters-select').prop( 'disabled', false ); form.find('.beautiful-taxonomy-filters-loader').removeClass('active'); form.find('.beautiful-taxonomy-filters-button').prop('disabled', false); }, complete: function(){ /** * Regardless of success/error we are done. Set active to false. */ active = false; } }); } //Document is ready for some JS magic! $(document).ready(function(){ /** * Trigger select2 * */ if( btf_localization.disable_select2 != 1 ){ create_select2_dropdown(); } /** * Update the terms of each taxonomy on the fly * This allows us to only show relevant terms whenever a selection has been made. * */ if( btf_localization.conditional_dropdowns == 1 ){ /** * Trigger on the first select with a value on page load. * This will find all forms and look in each of them. By doing this we make sure all forms that should be updated will be. */ var forms = $('.beautiful-taxonomy-filters form, .beautiful-taxonomy-filters-widget form'); for( var i = 0; i < forms.length; i++ ){ var selects = $(forms[i]).find('.beautiful-taxonomy-filters-select'); for( var j = 0; j < selects.length; j++ ){ if( $(selects[j]).val() !== 0 ){ conditional_terms_ajax_new( $(selects[j]) ); break; } } } /** * Trigger whenever select is changed */ $('.beautiful-taxonomy-filters, .beautiful-taxonomy-filters-widget').on('change', '.beautiful-taxonomy-filters-select', function(){ var el = $(this); conditional_terms_ajax_new( el ); }); } }); })( jQuery );