Score:-1

Taxonomy term relationships

cn flag

I have 3 taxonomy terms that I would like to expose as filters but I would like to use JavaScript to disable filters as you make selections in the other related exposed filters. For example:

Styles Makes Models
Cars BMW 750i
Trucks Ford F-150

If you select "Cars" then the "Makes - Ford" and "Models - F-150" would be disabled. I currently have each item assigned a proper CSS class for hooks but I am needing to find a way to add a CSS class to each "Makes" item and "Models" item that would be available if the user selected "Styles - Cars".

I need to do this on form field change and without refreshing the page. Is this possible?

Much thanks in advanced.

beltouche avatar
cn flag
You might want to consider one of these modules: https://www.drupal.org/project/cshs or https://www.drupal.org/project/shs
Score:0
cn flag

@beltouche, thanks for the module ideas. I ended up going another route because I needed the filters to update as each one changed. Basically, just like a facet but without reloading the page. I'm sure there are a few ways to go about this and probably in a more efficient way but for the amount of items and the functionality I needed this seems to be working pretty good.

For anyone else that is looking to try and accomplish the same, here are the steps I took to accomplish what I needed.

  1. I have a content type called "inventory" that hold about 700 entries
  2. There are 3 fields in "inventory" that I would like to use to filter by
  3. I created a view showing content of type "inventory"
  4. Name the view "Custom Quick Search"
  5. Check to "create a block"
  6. Set the view to "show Fields"
  7. Add the 3 fields, style, make, model
  8. Set items per page to "all"
  9. Create custom view templates:
  10. views-view-unformatted--custom-quick-search
  11. views-view-fields--custom-quick-search
  12. views-view-field--field-style
  13. views-view-field--field-make
  14. views-view-field--field-model

The code for each are as follows: views-view-unformatted--custom-quick-search

{% for row in rows %}
  {% if row|render|trim is not empty %}
    {{ row.content }}
  {% endif %}
{% endfor %}

views-view-fields--custom-quick-search

{% set category_name = fields.field_category.content|striptags %}
{% set category_id = fields.field_category.content|preg_replace('(<a href="/taxonomy/term/)','$1') %}
{% set category_id = category_id|preg_replace('(" hreflang="en">.*)','$1') %}

{% set make_name = fields.field_make.content|striptags %}
{% set make_id = fields.field_make.content|preg_replace('(<a href="/taxonomy/term/)','$1') %}
{% set make_id = make_id|preg_replace('(" hreflang="en">.*)','$1') %}

{% set model_name = fields.field_model.content|striptags %}
{% set model_id = fields.field_model.content|preg_replace('(<a href="/taxonomy/term/)','$1') %}
{% set model_id = model_id|preg_replace('(" hreflang="en">.*)','$1') %}

<div class="item" style="display: none;" data-category="{{ category_name|clean_class }}" data-make="{{ make_name|clean_class }}" data-model="{{ model_name|clean_class }}">

  <div class="-styles" data-category="{{ category_name|clean_class }}">
    <label for="{{ category_name|clean_class }}" data-category="{{ category_name|clean_class }}" data-make="{{ make_name|clean_class }}" data-model="{{ model_name|clean_class }}">
      <input type="checkbox" name="{{ category_name|trim }}" value="{{ category_id|trim }}" class="{{ category_name|trim|clean_class }}" id="{{ category_name|trim|clean_class }}" />
    {{ category_name|trim }}</label>
  </div>

  <div class="-makes" data-category="{{ category_name|clean_class }}" data-make="{{ make_name|clean_class }}">
    <label for="{{ make_name|clean_class }}" data-category="{{ category_name|clean_class }}" data-make="{{ make_name|clean_class }}" data-model="{{ model_name|clean_class }}">
      <input type="checkbox" name="{{ make_name|trim }}" value="{{ make_id|trim }}" class="{{ make_name|trim|clean_class }}" id="{{ make_name|trim|clean_class }}" />
    {{ make_name|trim }}</label>
  </div>

  <div class="-models" data-category="{{ category_name|clean_class }}" data-make="{{ make_name|clean_class }}" data-model="{{ model_name|clean_class }}">
    <label for="{{ model_name|clean_class }}" data-category="{{ category_name|clean_class }}" data-make="{{ make_name|clean_class }}" data-model="{{ model_name|clean_class }}">
      <input type="checkbox" name="{{ model_name|trim }}" value="{{ model_id|trim }}" class="{{ model_name|trim|clean_class }}" id="{{ model_name|trim|clean_class }}" />
    {{ model_name|trim }}</label>
  </div>

</div>

views-view-field--field-style views-view-field--field-make views-view-field--field-model

{{ output }}

Place the block on a page wrapped in the following:

<div class="quickSearch hidden">
    <div class="quickSearch__content">
        <div class="quickSearch__filters">
            <div class="filters-widget -styles">
                <div class="filters-widget__items">
                    <div class="filters-widget__item">
                    <div class="filters-widget__header">
                        <h4>Styles</h4>
                        <i class="fas fa-expand-alt"></i>
                        <i class="far fa-compress-alt"></i>
                    </div>
                    <div class="filters-widget__copy">
                    </div>
                    </div>
                </div>
            </div>

            <div class="filters-widget -makes">
                <div class="filters-widget__items">
                    <div class="filters-widget__item">
                    <div class="filters-widget__header">
                        <h4>Makes</h4>
                        <i class="fas fa-expand-alt"></i>
                        <i class="far fa-compress-alt"></i>
                    </div>
                    <div class="filters-widget__copy">
                    </div>
                    </div>
                </div>
            </div>

            <div class="filters-widget -models">
                <div class="filters-widget__items">
                    <div class="filters-widget__item">
                    <div class="filters-widget__header">
                        <h4>Models</h4>
                        <i class="fas fa-expand-alt"></i>
                        <i class="far fa-compress-alt"></i>
                    </div>
                    <div class="filters-widget__copy">
                    </div>
                    </div>
                </div>
            </div>

            <div class="unsorted__styles" style="display: none;"></div>
            <div class="unsorted__makes" style="display: none;"></div>
            <div class="unsorted__models" style="display: none;"></div>

            <div data-drupal-selector="edit-actions" class="form-actions js-form-wrapper form-wrapper" id="edit-actions">
            <input data-drupal-selector="edit-submit-custom-search-inventory" type="submit" id="edit-submit-custom-search-inventory" value="Search" class="button js-form-submit form-submit -brand-01">
            </div>
            {{ drupal_entity('block', 'views_block__custom_quick_search_block_quick_search', check_access=false) }}
        </div>
        <div class="quickSearch__links">
            {{ drupal_entity('block_content', '8') }}
        </div>
    </div>
</div>

The rest of the code is the JavaScript that swaps out the fields

/**
     * Clear disabled from makes and models on front page
     * Clone makes into unsorted
     * Remove duplicate entries
     * Reorder into alpha desc and move into dropdown
     */
 function loadMakes(show_styles){
  console.log(show_styles);
  if( show_styles == 'all' ){
    jQuery('.quickSearch .item .-makes').clone().prependTo('.quickSearch .unsorted__makes');
  }
  else{
    jQuery('.quickSearch .item .-makes[data-category="'+show_styles+'"]').clone().prependTo('.quickSearch .unsorted__makes');
  }
  //
  // Remove duplicates from makes dropdown.
  var makes = {};
  jQuery('.unsorted__makes .-makes').each(function() {
    var make = jQuery(this).attr('data-make');
    if (makes[make])
      jQuery(this).remove();
    else
      makes[make] = true;
  });
  // Reorder alpha and move to drop downs.
  jQuery(function(){
    jQuery('.unsorted__makes .-makes').sort(sort_makes).clone().prependTo('.filters-widget.-makes .filters-widget__copy');
    function sort_makes(a, b){
      return(jQuery(b).data('make')) < (jQuery(a).data('make')) ? 1 : -1;
    }
  });
}

/**
 *
 * Clone models into unsorted
 * Remove duplicate entries
 * Reorder into alpha desc and move into dropdown
 */
function loadModels(show_styles,show_makes){
  if( show_makes == 'all' ){
    jQuery('.quickSearch .item .-models').clone().prependTo('.quickSearch .unsorted__models');
  }
  else{
    jQuery('.quickSearch .item .-models[data-category="'+show_styles+'"][data-make="'+show_makes+'"]').clone().prependTo('.quickSearch .unsorted__models');
  }
  //
  // Remove duplicates from models dropdown.
  var models = {};
  jQuery('.unsorted__models .-models').each(function() {
    var model = jQuery(this).attr('data-model');
    if (models[model])
      jQuery(this).remove();
    else
      models[model] = true;
  });
  // Reorder alpha and move to drop downs.
  jQuery(function(){
    jQuery('.unsorted__models .-models').sort(sort_models).clone().prependTo('.filters-widget.-models .filters-widget__copy');
    function sort_models(a, b){
      return(jQuery(b).data('model')) < (jQuery(a).data('model')) ? 1 : -1;
    }
  });
}

/**
         * Move styles into unsorted
         * Remove empty entries
         * Remove duplicate entries
         * Reorder into alpha desc and move into dropdown
         */
        // Remove empty entries
        jQuery('.quickSearch .item').each(function(){
            if( jQuery(this).data('make') == undefined || jQuery(this).data('make') == null || jQuery(this).data('make') == ''){
                jQuery(this).remove();
            }
        });
        jQuery('.quickSearch .item .-styles').prependTo('.quickSearch .unsorted__styles');
        // Remove duplicates from styles dropdown.
        var styles = {};
        jQuery('.unsorted__styles .-styles').each(function() {
            var style = jQuery(this).attr('data-category');
            if (styles[style])
                jQuery(this).remove();
            else
                styles[style] = true;
        });
        // Reorder alpha and move to drop downs.
        jQuery(function(){
            jQuery('.unsorted__styles .-styles').sort(sort_styles).prependTo('.filters-widget.-styles .filters-widget__copy');
            function sort_styles(a, b){
                return(jQuery(b).data('category')) < (jQuery(a).data('category')) ? 1 : -1;
            }
        });

        // Show and hide makes and models based on selected style
        var show_styles = '';
        jQuery('.-styles input[type=checkbox]').change(function(){
            jQuery('.-styles input[type=checkbox]').not(this).prop('checked', false);
            jQuery('.-makes .filters-widget__copy, .-models .filters-widget__copy').html('');
            jQuery('.unsorted__makes, .unsorted__models').html('');
            show_styles = jQuery(this).parent().data('category');
            loadMakes(show_styles);
            loadModels(show_styles,show_styles);
        });

        // Show and hide makes and models based on selected style
        var show_makes = '';
        jQuery('.-makes').on('change', 'input[type=checkbox]', function(){
            jQuery('.-makes input[type=checkbox]').not(this).prop('checked', false);
            jQuery('.-models .filters-widget__copy').html('');
            jQuery('.unsorted__models').html('');
            show_styles = jQuery(this).parent().data('category');
            show_makes = jQuery(this).parent().data('make');
            loadModels(show_styles,show_makes);
        });

        // Quick Search submit button
        jQuery('.quickSearch .form-submit').on('click', function(){
            styles = jQuery('.-styles input:checked').val();
            makes = jQuery('.-makes input:checked').val();
            models = jQuery('.-models input:checked').val();
            var quick_search_url = '';
            if( styles && !makes && !models ){
                quick_search_url = 'category/'+styles;
            }
            else if( styles && makes && !models ){
                quick_search_url = 'category/'+styles;
                quick_search_url += '/make/'+makes;
            }
            else if( styles && !makes && models ){
                quick_search_url = 'category/'+styles;
                quick_search_url += '/model/'+models;
            }
            else if( styles && makes && models ){
                quick_search_url = 'category/'+styles;
                quick_search_url += '/make/'+makes;
                quick_search_url += '/model/'+models;
            }
            else if( !styles && makes && !models ){
                quick_search_url += '/make/'+makes;
            }
            else if( !styles && makes && models ){
                quick_search_url += '/make/'+makes;
                quick_search_url += '/model/'+models;
            }
            else if( !styles && !makes && models ){
                quick_search_url += '/model/'+models;
            }

            window.location.href = '/inventory-search/'+quick_search_url;
        });

        loadMakes('all');
        loadModels('all','all');

    }
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.