Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest possible way in jQuery to filter "Radios + Select + Checkbox" together simultaneously

What is the fastest strategy (in terms of Performance) to filter a combination of different type filters in jQuery?

In this example, I use "Radios + Select + Checkbox" and need them to operate together simultaneously.

JS Bin Link: https://jsbin.com/wegopom/3/edit?js,output

I am targeting <img> markers in a Leaflet map based on the:

  • image's "src" e.g. img[src$="marker-icon.png"] (ends with file name)
  • image's "class" e.g. img.variation

Speed on the filter is central as this map will be displaying hundreds and eventually thousands of marker images.


For the Radios, ("variation" class)... I have a change function:

jQuery(document).on("change", ".variation", function() {

For the Select, ("filterbottler" ID)... I have a second change function:

jQuery('#filterbottler').change(function(){

For the checkbox, ("outages" ID)... I have a third change function:

jQuery('#outages').change(function(){

It was simple to make two of these change functions work in tandem using a bunch of IF statements and adjoined/chained classes (like img.variation.bottler which would be very slow)... but now that I've added a third filter, it seems like overload and it has now become very hard for me to wrap my brain around every single filtering scenario.

The JS Bin @ https://jsbin.com/wegopom/3/edit?js,output features each of these three filters working independently...

The goal is to get the first three filters (Variation, Bottler, & Outages) to simultaneously work together in the quickest and most efficient way possible. How can I resolve this?


jQuery(document).ready(function($){

    // Filter 1) by Variation
    jQuery(document).on("change", ".variation", function() {
        var bottlerValue = jQuery("#filterbottler").find("option:selected").val();
        var bottlerClass = '.field-ccb-cached__'+bottlerValue;

        // marker groups to be used in exclusionary :not() statements so they aren't affected by the filters... e.g. marker-icon.png & marker-icon-2x.png are "My Location" markers
        var mainMarkers = '[src$="bottler_22px.png"],[src$="marker-icon.png"],[src$="marker-icon-2x.png"]';
        var includeOutageMarkers = '[src$="bottler_22px.png"],[src$="marker-icon.png"],[src$="marker-icon-2x.png"],[src$="cross_22px.png"]';

        if (this.id == "map-filters-show-all") {
            jQuery('.leaflet-marker-pane img:not('+mainMarkers+')').show(500);
        }
        else if (this.id == "map-filters-16oz-cans") {
            jQuery('.leaflet-marker-pane img:not('+includeOutageMarkers+',.field-report-variation__16oz-cans)').hide(500);
            jQuery('.leaflet-marker-pane img.field-report-variation__16oz-cans').show(500);
        } else if (this.id == "map-filters-12oz-cans") {
            jQuery('.leaflet-marker-pane img:not('+includeOutageMarkers+',.field-report-variation__12oz-cans)').hide(500);
            jQuery('.leaflet-marker-pane img.field-report-variation__12oz-cans').show(500);
        } else if (this.id == "map-filters-fountain-surge") {
            jQuery('.leaflet-marker-pane img:not('+includeOutageMarkers+',.field-report-variation__fountain-surge)').hide(500);
            jQuery('.leaflet-marker-pane img.field-report-variation__fountain-surge').show(500);
        } else if (this.id == "map-filters-fountain-surge-red-berry-blast") {
            jQuery('.leaflet-marker-pane img:not('+includeOutageMarkers+',.field-report-variation__fountain-surge-red-berry-blast)').hide(500);
            jQuery('.leaflet-marker-pane img.field-report-variation__fountain-surge-red-berry-blast').show(500);
        }
    });

    // Filter 2) by Bottling Company (select box)
    jQuery('#filterbottler').change(function(){
        var bottlerValue = jQuery("#filterbottler").find("option:selected").val();
        var bottlerClass = '.field-ccb-cached__'+bottlerValue;

        if (bottlerClass != '.field-ccb-cached___none') {
            jQuery('.leaflet-marker-pane img:not([src$="bottler_22px.png"],[src$="marker-icon.png"],[src$="marker-icon-2x.png"],[src$="cross_22px.png"],'+bottlerClass+')').hide(500);
            jQuery('.leaflet-marker-pane img'+bottlerClass).show(500);
        }
        if (bottlerClass === '.field-ccb-cached___none') {
            jQuery('.leaflet-marker-pane img:not([src$="bottler_22px.png"],[src$="marker-icon.png"],[src$="marker-icon-2x.png"])').show(500);
        }

    });

    // Filter 3) Show Outage Reports (checkbox on/off)
    jQuery('#outages').change(function(){
        if(this.checked){
            jQuery('.leaflet-marker-pane img[src$="cross_22px.png"],[src$="exclamation_22px.png"]').fadeToggle(500);
            jQuery.cookie('outagemarkers', true);
        }
        else {
            jQuery('.leaflet-marker-pane img[src$="cross_22px.png"],[src$="exclamation_22px.png"]').fadeToggle(500);
            jQuery.cookie('outagemarkers', false);
        }
    });
like image 923
WebMW Avatar asked Apr 23 '21 19:04

WebMW


1 Answers

UPDATE

  1. I have updated both my jQuery and pure JS solutions to move all constant variables outside of the event handler to improve performance.
  2. I improved the way in which I build the selectors and filters for both. For jQuery, this means using '*' as a fallback vaklue when a filter is not active (set to show-all or none). In pure JS, I use a boolean false to "turn off" the filter and then when using filter() later, if a filter is set to false, I manually set the filter condition to true to bypass it.
  3. Some selectors we were querying were able to be simplified. For example, rather than querying all select options and then using find() or filter() to find the one that is selected only to get that option's value, I simply get the value of the <select> element itself. In jQuery: bottlerSelect.val(), and in pure JS: bottlerSelect.value.

To maximize the performance of your program, it's best to keep all your filters together in one blocks and then filter for all of them. Once we've defined all our desired filters, we can filter all our markers by the filter selectors and save them into a matchedMarkers variables. We can then take those that didn't match and save them into a separate unmatchedMarkers with this one line: unmatchedMarkers = allMarkers.not(matchedMarkers);

All put together, it's actually a very simple and lightweight program, and it could be even more efficient in vanilla JS which I hope to revisit in the next day or two.

jQuery Solution

CodePen link: https://cdpn.io/e/943560466fc36d61871d01b57739137d

jQuery(document).ready(function($){
  var allMarkers = $('.leaflet-marker-icon'),
      variationPrefix = 'field-report-variation__',
      bottlerPrefix = 'field-ccb-cached__',
      outagesSelector = ':not([src$="cross_22px.png"],[src$="exclamation_22px.png"])',
      variationInputs = $('input.variation'),
      bottlerSelect = $('#filterbottler'),
      outagesCheckbox = $('#outages');
  $(document).on('change', '.variation, #filterbottler, #outages', function() {
    var variationSelector = '.'+variationPrefix+variationInputs.filter(':checked').attr('id').split('-').slice(2).join('-').toLowerCase().replace(/ /g,'-'),
      variationFilter = variationSelector.endsWith('__show-all') ? '*' : variationSelector + ',:not([class*="'+variationPrefix+'"])',
      bottlerSelector = '.'+bottlerPrefix+bottlerSelect.val(),
      bottlerFilter = bottlerSelector.endsWith('___none') ? '*' : bottlerSelector + ',:not([class*="'+bottlerPrefix+'"])',
      outagesFilter = outagesCheckbox.is(':checked') ? '*' : outagesSelector,
      matchedMarkers = allMarkers.filter(variationFilter).filter(bottlerFilter).filter(outagesFilter),
      unmatchedMarkers = allMarkers.not(matchedMarkers);
    matchedMarkers.fadeIn(500);
    unmatchedMarkers.fadeOut(500);
  });
});
.leaflet-marker-pane{width:100%;border:1px solid #000}table td{min-width:25px;height:30px;border:1px solid gray;padding:10px}
<div class="form-item" id="map-filter-content"> <label style="font-size:18px;">Filter Reports by Variation <i>(must either "Show All" or be a specific variation):</i></label><div class="form-checkboxes"> <input type="radio" value="Show All" name="variation" class="variation" id="map-filters-show-all" checked=""> <label>Show All</label><br> <input type="radio" value="16oz Cans" name="variation" class="variation" id="map-filters-16oz-cans"> <label>16oz Cans</label><br> <input type="radio" value="12oz Cans" name="variation" class="variation" id="map-filters-12oz-cans"> <label>12oz Cans</label><br> <input type="radio" value="Fountain SURGE" name="variation" class="variation" id="map-filters-fountain-surge"> <label>Fountain SURGE</label><br> <input type="radio" value="Fountain SURGE Red Berry Blast" name="variation" class="variation" id="map-filters-fountain-surge-red-berry-blast"> <label>Fountain SURGE Red Berry Blast</label></div><hr style="margin:15px 0 10px 0;"><div class="field-widget-options-select form-wrapper"><div class="control-group form-type-select form-item"> <label style="font-size:18px;">Filter by Bottling Company <i>(must either "Show All" or be a specific bottler):</i></label><div class="controls"> <select id="filterbottler" class="form-select"><option value="_none">- Select All Coca-Cola Bottlers -</option><option value="190">ABARTA</option><option value="191">Aberdeen Coca-Cola</option><option value="192">Ada Coca-Cola</option><option value="193">Atlantic Coca-Cola</option><option value="194">Bemidji Coca-Cola</option><option value="195">Binks Coca-Cola</option><option value="196">Canyon City Coca-Cola</option><option value="197">Cedar City Coca-Cola</option><option value="198">Chesterman Coca-Cola</option><option value="199">Clark</option><option value="200">Coca-Cola Consolidated</option><option value="186">Coca-Cola High Country</option><option value="187">Coca-Cola Southwest</option><option value="177">Coca-Cola UNITED</option><option value="201">Columbus Coca-Cola</option><option value="202">Corinth</option><option value="203">Decatur</option><option value="204">Deming Coca-Cola</option><option value="205">Dickinson Coca-Cola</option><option value="206">Durango Coca-Cola</option><option value="207">Durham Coca-Cola</option><option value="183">Emporia Coca-Cola</option><option value="208">Florida Coca-Cola</option><option value="209">Fort Smith Coca-Cola</option><option value="244">Glasgow Coca-Cola</option><option value="210">Glendive Coca-Cola</option><option value="211">Great Lakes Coca-Cola</option><option value="212">Hancock</option><option value="213">Heartland Coca-Cola</option><option value="214">Hot Springs Coca-Cola</option><option value="215">Huntsville</option><option value="216">Idabel Coca-Cola</option><option value="217">Internation Falls</option><option value="218">Jefferson Coca-Cola</option><option value="219">Ketchikan</option><option value="220">Kokomo Coca-Cola</option><option value="178">Lehrkinds</option><option value="184">Liberty Coca-Cola</option><option value="221">Love Coca-Cola</option><option value="222">Lufkin Coca-Cola</option><option value="223">Macon</option><option value="224">Magnolia Coca-Cola</option><option value="225">Maui</option><option value="226">Meridian</option><option value="227">MiddlesBoro</option><option value="179">Mile High</option><option value="228">Minden Coca-Cola</option><option value="182">Nashville Coca-Cola</option><option value="229">Northern New England</option><option value="230">ODOM</option><option value="231">Orangeburg Coca-Cola</option><option value="232">Ozarks Coca-Cola</option><option value="233">Pulaski Coca-Cola</option><option value="176">Reyes Coca-Cola</option><option value="234">Rock Hill Coca-Cola</option><option value="235">Santa Fe Coca-Cola</option><option value="236">Sitka</option><option value="237">Sooner Coca-Cola</option><option value="185">Swire Coca-Cola</option><option value="181">Timber Country</option><option value="238">Trenton Coca-Cola</option><option value="180">Tullahoma Coca-Cola</option><option value="239">Union City</option><option value="174">Viking Coca-Cola</option><option value="240">Washington Coca-Cola</option><option value="241">Williston Coca-Cola</option><option value="188">Winfield Coca-Cola</option><option value="242">Winona Coca-Cola</option><option value="243">Yakima Coca-Cola</option> </select></div></div></div><hr style="margin:15px 0 10px 0;"><div class="mwcheck"> <input type="checkbox" id="outages" checked> <label>Show Outage Reports <i>(must turn these icons on/off with other filters intact: <img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png"> & <img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/cross_22px.png">)</i></label></div></div><hr><div class="leaflet-marker-pane"><table><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__16oz-cans field-ccb-cached__190"></td><td> < Has Class "field-report-variation__16oz-cans" <b>(16oz Cans)</b><br> < Has Class "field-ccb-cached__190" <b>("ABARTA" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__12oz-cans field-ccb-cached__190"></td><td> < Has Class "field-report-variation__12oz-cans" <b>(12oz Cans)</b><br> < Has Class "field-ccb-cached__190" <b>("ABARTA" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__12oz-cans field-ccb-cached__191"></td><td> < Has Class "field-report-variation__12oz-cans" <b>(12oz Cans)</b><br> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__16oz-cans field-ccb-cached__190"></td><td> < Has Class "field-report-variation__16oz-cans" <b>(16oz Cans)</b><br> < Has Class "field-ccb-cached__190" <b>("ABARTA Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__16oz-cans field-ccb-cached__191"></td><td> < Has Class "field-report-variation__16oz-cans" <b>(16oz Cans)</b><br> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__12oz-cans field-ccb-cached__191"></td><td> < Has Class "field-report-variation__12oz-cans" <b>(12oz Cans)</b><br> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/cross_22px.png" class="leaflet-marker-icon tag-inside-marker field-ccb-cached__191"></td><td> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b> <br><br>This always shows unless:<br>1) "Show Outage Reports" is deselected... or <br>2) Another bottling company (e.g. ABARTA is selected)<br></td></tr></table></div>
<script src="https://code.jquery.com/jquery-1.8.3.js"></script>

Pure JavaScript Solution

CodePen link: https://cdpn.io/e/d9e89a278a7bb190841c19f53c376033

This pure vanilla JavaScript solution is even simpler than the jQuery solution, and it will increase performance quite a bit if you can exclude jQuery from this project altogether and stick to pure JS. No need to wait for the page to be fully loaded. Just run your JavaScript right after the HTML content and everything will work as expected. This also allows for greater flexibility in our filtering methods. Rather than running three filter functions back-to-back, we can run all our conditions in one single filter method and immediately either fade in or out the associated marker element. Also to improve performance, instead of relying on JavaScript to animate the fading transition, I created two simple states in the CSS, the default state (opacity: 1), and a filtered state denoted by the class .filtered. All the fading in and out takes place completed in the CSS with a simple CSS transition determined by whether or not the .filtered class is applied.

Here it is in pure JavaScript:

const allMarkers = Array.from(document.querySelectorAll('.leaflet-marker-icon')),
      variationPrefix = 'field-report-variation__',
      bottlerPrefix = 'field-ccb-cached__',
      outagesSelector = ':not([src$="cross_22px.png"],[src$="exclamation_22px.png"])',
      variationInputs = Array.from(document.querySelectorAll('input.variation')),
      bottlerSelect = document.getElementById('filterbottler'),
      outagesCheckbox = document.getElementById('outages');
document.addEventListener('change', e => {
  if (e.target?.matches('.variation, #filterbottler, #outages')) {
    const variationSelector = '.'+variationPrefix+variationInputs.filter(input => input.checked)[0].id.split('-').slice(2).join('-').toLowerCase().replace(/ /g,'-'),
          variationFilter = variationSelector.endsWith('__show-all') ? false : variationSelector + ',:not([class*="'+variationPrefix+'"])',
          bottlerSelector = '.'+bottlerPrefix+bottlerSelect.value,
          bottlerFilter = bottlerSelector.endsWith('___none') ? false : bottlerSelector + ',:not([class*="'+bottlerPrefix+'"])',
          outagesFilter = outagesCheckbox.checked ? false : outagesSelector;
    allMarkers.forEach(marker => ((variationFilter ? marker.matches(variationFilter) : true) && (bottlerFilter ? marker.matches(bottlerFilter) : true) && (outagesFilter ? marker.matches(outagesFilter) : true)) ? marker.classList.remove('filtered') : marker.classList.add('filtered'));
  }
});
.leaflet-marker-pane{width:100%;border:1px solid #000}table td{min-width:25px;height:30px;border:1px solid gray;padding:10px}

.leaflet-marker-icon {
  opacity: 1;
  transition: opacity 500ms ease-out;
}
.leaflet-marker-icon.filtered {
  opacity: 0;
}
<div class="form-item" id="map-filter-content"> <label style="font-size:18px;">Filter Reports by Variation <i>(must either "Show All" or be a specific variation):</i></label><div class="form-checkboxes"> <input type="radio" value="Show All" name="variation" class="variation" id="map-filters-show-all" checked=""> <label>Show All</label><br> <input type="radio" value="16oz Cans" name="variation" class="variation" id="map-filters-16oz-cans"> <label>16oz Cans</label><br> <input type="radio" value="12oz Cans" name="variation" class="variation" id="map-filters-12oz-cans"> <label>12oz Cans</label><br> <input type="radio" value="Fountain SURGE" name="variation" class="variation" id="map-filters-fountain-surge"> <label>Fountain SURGE</label><br> <input type="radio" value="Fountain SURGE Red Berry Blast" name="variation" class="variation" id="map-filters-fountain-surge-red-berry-blast"> <label>Fountain SURGE Red Berry Blast</label></div><hr style="margin:15px 0 10px 0;"><div class="field-widget-options-select form-wrapper"><div class="control-group form-type-select form-item"> <label style="font-size:18px;">Filter by Bottling Company <i>(must either "Show All" or be a specific bottler):</i></label><div class="controls"> <select id="filterbottler" class="form-select"><option value="_none">- Select All Coca-Cola Bottlers -</option><option value="190">ABARTA</option><option value="191">Aberdeen Coca-Cola</option><option value="192">Ada Coca-Cola</option><option value="193">Atlantic Coca-Cola</option><option value="194">Bemidji Coca-Cola</option><option value="195">Binks Coca-Cola</option><option value="196">Canyon City Coca-Cola</option><option value="197">Cedar City Coca-Cola</option><option value="198">Chesterman Coca-Cola</option><option value="199">Clark</option><option value="200">Coca-Cola Consolidated</option><option value="186">Coca-Cola High Country</option><option value="187">Coca-Cola Southwest</option><option value="177">Coca-Cola UNITED</option><option value="201">Columbus Coca-Cola</option><option value="202">Corinth</option><option value="203">Decatur</option><option value="204">Deming Coca-Cola</option><option value="205">Dickinson Coca-Cola</option><option value="206">Durango Coca-Cola</option><option value="207">Durham Coca-Cola</option><option value="183">Emporia Coca-Cola</option><option value="208">Florida Coca-Cola</option><option value="209">Fort Smith Coca-Cola</option><option value="244">Glasgow Coca-Cola</option><option value="210">Glendive Coca-Cola</option><option value="211">Great Lakes Coca-Cola</option><option value="212">Hancock</option><option value="213">Heartland Coca-Cola</option><option value="214">Hot Springs Coca-Cola</option><option value="215">Huntsville</option><option value="216">Idabel Coca-Cola</option><option value="217">Internation Falls</option><option value="218">Jefferson Coca-Cola</option><option value="219">Ketchikan</option><option value="220">Kokomo Coca-Cola</option><option value="178">Lehrkinds</option><option value="184">Liberty Coca-Cola</option><option value="221">Love Coca-Cola</option><option value="222">Lufkin Coca-Cola</option><option value="223">Macon</option><option value="224">Magnolia Coca-Cola</option><option value="225">Maui</option><option value="226">Meridian</option><option value="227">MiddlesBoro</option><option value="179">Mile High</option><option value="228">Minden Coca-Cola</option><option value="182">Nashville Coca-Cola</option><option value="229">Northern New England</option><option value="230">ODOM</option><option value="231">Orangeburg Coca-Cola</option><option value="232">Ozarks Coca-Cola</option><option value="233">Pulaski Coca-Cola</option><option value="176">Reyes Coca-Cola</option><option value="234">Rock Hill Coca-Cola</option><option value="235">Santa Fe Coca-Cola</option><option value="236">Sitka</option><option value="237">Sooner Coca-Cola</option><option value="185">Swire Coca-Cola</option><option value="181">Timber Country</option><option value="238">Trenton Coca-Cola</option><option value="180">Tullahoma Coca-Cola</option><option value="239">Union City</option><option value="174">Viking Coca-Cola</option><option value="240">Washington Coca-Cola</option><option value="241">Williston Coca-Cola</option><option value="188">Winfield Coca-Cola</option><option value="242">Winona Coca-Cola</option><option value="243">Yakima Coca-Cola</option> </select></div></div></div><hr style="margin:15px 0 10px 0;"><div class="mwcheck"> <input type="checkbox" id="outages" checked> <label>Show Outage Reports <i>(must turn these icons on/off with other filters intact: <img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png"> & <img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/cross_22px.png">)</i></label></div></div><hr><div class="leaflet-marker-pane"><table><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__16oz-cans field-ccb-cached__190"></td><td> < Has Class "field-report-variation__16oz-cans" <b>(16oz Cans)</b><br> < Has Class "field-ccb-cached__190" <b>("ABARTA" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__12oz-cans field-ccb-cached__190"></td><td> < Has Class "field-report-variation__12oz-cans" <b>(12oz Cans)</b><br> < Has Class "field-ccb-cached__190" <b>("ABARTA" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__12oz-cans field-ccb-cached__191"></td><td> < Has Class "field-report-variation__12oz-cans" <b>(12oz Cans)</b><br> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__16oz-cans field-ccb-cached__190"></td><td> < Has Class "field-report-variation__16oz-cans" <b>(16oz Cans)</b><br> < Has Class "field-ccb-cached__190" <b>("ABARTA Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__16oz-cans field-ccb-cached__191"></td><td> < Has Class "field-report-variation__16oz-cans" <b>(16oz Cans)</b><br> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__12oz-cans field-ccb-cached__191"></td><td> < Has Class "field-report-variation__12oz-cans" <b>(12oz Cans)</b><br> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/cross_22px.png" class="leaflet-marker-icon tag-inside-marker field-ccb-cached__191"></td><td> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b> <br><br>This always shows unless:<br>1) "Show Outage Reports" is deselected... or <br>2) Another bottling company (e.g. ABARTA is selected)<br></td></tr></table></div>
like image 53
Brandon McConnell Avatar answered Sep 24 '22 08:09

Brandon McConnell