0

I have an events content type, and from it, I have a view that lists events. We're using a bootstrap theme, and the format of the display I'm concerned with is Bootstrap List Group. This allows us to use a field as a grouping header.

Since we want the end user to see events grouped by month, we have the display of the grouping field set to Year Month. So for example, one header would be "July 2018".

We also have the view paged, so that it shows 15 events per page. We've added a "Show More" button at the bottom.

However a problem arises when the next page of events start in the same month as the previous set ended in. So for example, the user might see this:

 August 2018
  - Labor Day Holiday
  - a cookout
  - a meeting 

[ Load More ]

Then when they hit "Load More", they see this:

 August 2018
  - Labor Day Holiday
  - a cookout
  - a meeting

 August 2018
  - Ice Cream Social
  - a party
  - ...

[ Load More ]

How can I prevent the Grouping header from repeating on loading more?

1

Your description makes it sound like you have ajax views enabled which is probably going to be very challenging to get working correctly.

There may be a better backend way to do this, but one way that occurs to me is to fix this on the client side with javascript, by merging lists after ajax finishes loading.

  1. Copy the Bootstrap List Group view display template into your theme's templates folder.

  2. Add a custom data attribute to mimic the text value of the grouping's row title, and attach a custom javascript behavior to do the work on the client side.

    {{ attach_library('yourtheme/prevent_duplicate_list_group') }}
    <ul id="{{ id }}" {{ attributes.addClass(classes) }}>
      {% for key, row in rows %}
        <li class="list-group-item">
          {% if row.title %}
            <h4 class="list-group-item-heading" data-grouping="{{ row.title }}">{{ row.title }}</h4>
          {% endif %}
          <p class="list-group-item-text">{{ row.content }}</p>
        </li>
      {% endfor %}
    </ul>
    
  3. Create a library in yourtheme.libraries.yml to add a JS behavior.

    prevent_duplicate_list_group:
      js:
         js/prevent_duplicate_list_group.js
    
  4. Write some custom javascript logic to look for all instances of the duplicate grouping and move the values from the second list into the first.

    I've not used bootstrap views thus don't know the exact dom structure you'll need to work with, but here is something completely untested to get you started.

    /**
     * @file
     * Behavior to merge duplicate List Group titles loaded from ajax-enabled views.
     */
    
    (function ($) {
      'use strict';
    
      Drupal.behaviors.prevent_duplicate_list_group = {
        attach: function (context, settings) {
          $('.list-group-item-heading', context)
            .each(function (idx, element) {
              var title = $(element).attr('data-grouping'),
                duplicates = $('[data-grouping="'+ title + '"]');
              if (duplicates.length == 2) {
                var first = duplicates.eq(0).closest('ul');
                var second = duplicates.eq(1).closest('ul');
                // snagged from https://stackoverflow.com/a/28487699/413538
                // you may need to overhaul this to only walk through
                // list items from the second list up until it gets to a list item that contains an h4 and hide each individual li
                var i=1;
                $('li', first).each(function(){
                  $(first).append($('li:nth-child('+i+')', second).clone());
                  i++;
                });
                second.remove();
              }
            }
          );
        }
      };
    })(jQuery);
    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.