Gists

6 months ago
<?
/**
 * disables map filtering if enabled when other
 * filters are used instead
 **/
add_action( 'facetwp_scripts', function() {
 ?>
  <script>
    (function($) {
    document.addEventListener('facetwp-refresh', function() {
        if ( null !== FWP.active_facet &&
                '' !== $(FWP.active_facet.nodes[0]).attr('data-name' ) &&
                /** change 'my_map_facet' to name of your map facet */
                'my_map_facet' !== $(FWP.active_facet.nodes[0]).attr( 'data-name' ) ) {
            var $button = $('.facetwp-map-filtering');
            $button.text(FWP_JSON['map']['filterText']);
            FWP_MAP.is_filtering = false;
            $button.toggleClass('enabled');
            FWP.facets.map = [];
        } 
    });
    })(fUtil);
  </script>
  <?php
}, 100 );
6 months ago
<?php
add_action( 'facetwp_scripts', function() {
  ?>
  <script>
    (function($) {
      // Store original alert
      var originalAlert = window.alert;

      // Override window.alert
      window.alert = function(msg) {
        // Catch all FacetWP geolocation alerts
        if (
          msg === "User denied the request for Geolocation." ||
          msg === "Location information is unavailable." ||
          msg === "The request to get user location timed out." ||
          msg === "An unknown error occurred."
        ) {
          // Suppress FacetWP's original alert, do nothing here
          return;
        }
        // Otherwise, let other alerts work as normal
        originalAlert(msg);
      };

      // Now show custom messages via the FacetWP error hook
      FWP.hooks.addAction('facetwp/geolocation/error', function(obj) {
        let error = obj.error;
        let customMessage = "We couldn’t detect your location. Please allow location access.";

        switch (error.code) {
          case error.PERMISSION_DENIED:
            customMessage = "⚠️ You blocked location sharing. Please enable it in your browser.";
            break;
          case error.POSITION_UNAVAILABLE:
            customMessage = "📡 Location info is not available right now.";
            break;
          case error.TIMEOUT:
            customMessage = "⏳ The request took too long. Please try again.";
            break;
          case error.UNKNOWN_ERROR:
            customMessage = "❌ An unknown error occurred while getting your location.";
            break;
        }

        originalAlert(customMessage); // Show thecustom alert
      });
    })(fUtil);

  </script>
  <?php
}, 100 );
10 months ago
<?php

// Example template for a Listing Builder listing in Dev mode.
// The listing shows therapists. The query must be ordering by the last name.
// We insert a full width banner with the letter of the alphabet when a new letter starts.
// Screenshot: https://d.pr/i/pEhwFf
// The classes used replicate what would be the classes in visual mode.
// This listing could be combined with an A-Z facet. 
// If you do, add the script below the template part to your functions.php to remove the letter headings when the A-Z facet is in use.

if ( have_posts() ) :

  echo '<style>
    .fwpl-layout.therapist-listing {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-gap: 40px;
    }    
    .fwpl-item.age-group,
    .fwpl-item.modality {
        padding-top: 10px;
    }
	.letter-heading {
	  width: 100%;
	  display: block;
	  grid-column: 1 / -1;
	  font-size: 20px;
	  font-weight: bold;
	  color: #fff;
	  padding: 0 20px;
	  line-height: 2.4em;
	  background-color: #015c65;
	  border-radius: 5px 5px 25px 5px;    
	}
	
    @media (max-width: 780px) {
      body .facetwp-template .fwpl-layout,
      body .facetwp-template-static .fwpl-layout {
        grid-template-columns: repeat(2, 1fr); /* 2 columns */
      }
    }
  
    @media (max-width: 544px) {
      body .facetwp-template .fwpl-layout,
      body .facetwp-template-static .fwpl-layout {
        grid-template-columns: repeat(1, 1fr); /* 1 columns */
      }
    }

  </style>';

  $current_letter = '';
  
  echo '<div class="fwpl-layout therapist-listing">';

  while ( have_posts() ): the_post();

    // Add a letter heading for each letter in the alphabet
    // We are using the last name here, as the query is ordered by the last_name field
    $last_name = get_field('last_name');
    $first_letter = strtoupper(substr($last_name, 0, 1));

    if ($first_letter !== $current_letter) :
      echo '<div class="letter-heading">' . esc_html($first_letter) . '</div>';
      $current_letter = $first_letter;
    endif;

    echo '<div class="fwpl-row therapist border-top card">';

    $post_id = get_the_ID();
    $post_title = get_the_title();

    echo '<div class="fwpl-item therapist-title entry-title">';
    $website = get_field( 'website', $post_id );
    if ( $website ) {
      echo '<a href="' . $website . '" target="_blank">' . $post_title . '</a>';
    } else {
      echo $post_title;
    }
    echo '</div>';


    echo '<div class="fwpl-item address">';
    echo do_shortcode( '[work_address]' );
    echo '</div>';

    echo '<div class="fwpl-item phone">';
    echo do_shortcode( '[work_phone]' );
    echo '</div>';

    $agegroup = get_field('age_group');
    $modality = get_field('modality');
    if ($agegroup) {
      echo '<div class="fwpl-item age-group">';
      echo '<hr style="width:30%; background-color:white; margin-bottom:10px;">';
      $labels = [];
      foreach ($agegroup as $item) {
        if ( isset( $item['label'] ) ) {
          $labels[] = $item['label'];
        }
      }
      $agegroups = implode(', ', $labels);
      echo '<div class="field-label">Age Group</div>';
      echo '<div style="font-size:15px;">'. $agegroups .'</div>';
      echo '</div>';
    }
    if ($modality) {
      echo '<div class="fwpl-item modality">';
      $labels = [];
      foreach ($modality as $item) {
        if ( isset( $item['label'] ) ) {
          $labels[] = $item['label'];
        }
      }
      $modalities = implode(', ', $labels);
      echo '<div class="field-label">Modality</div>';
      echo '<div style="font-size:15px;">'. $modalities .'</div>';
      echo '</div>';
    }

    echo '</div>';

  endwhile;

  echo '</div>';

  ?>
<?php else : ?>
  <p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
<?php endif; ?>

<?php
// Add this to your functions.php to remove the letter headings when the A-Z facet is in use

add_action( 'facetwp_scripts', function() {
    ?>
    <script>
        (function($) {
            document.addEventListener('facetwp-loaded', function() {
                let selected = FWP.facets['therapist_alphabetical']; // Your A-Z facet name
                if ( selected.length ) { // If any choice in this facet is selected
                    $('.letter-heading').addClass( 'facetwp-hidden' );
                }
            });
        })(fUtil);
    </script>
    <?php
}, 100 );
9 months ago
<?php
// See: 
// https://facetwp.com/help-center/facets/facet-types/checkboxes/#add-show-more-less-toggle-links-for-child-levels-in-a-hierarchical-checkboxes-facet

add_action('facetwp_scripts', function () {
  // Change "4" in both style (3x) and script (1x) to customize from what number of choices they are hidden.
  // "4" means only the first 3 choices show, then a 'show more' link.
  ?>
  <style>
    .facetwp-depth.visible > div:nth-child(n+4 of .facetwp-checkbox),
    .facetwp-depth.visible:not(.showmore) > div:nth-child(n+4 of .facetwp-checkbox) + .facetwp-depth.visible {
      display: none; /* Hide from the 4th choice */
    }
    .facetwp-depth.visible.showmore > div:nth-child(n+4 of .facetwp-checkbox) {
      display: block; /* Show from the 4th choice */
    }
    .facetwp-type-checkboxes a.show-more-link {
      display: block;
      margin-bottom: 4px;
    }
  </style>
 
  <script>
    (function($) {
      document.addEventListener('facetwp-loaded', function() {
        document.querySelectorAll('.facetwp-depth').forEach((node) => {
 
          // Filter out children that have the 'facetwp-depth' class
          const relevantChildren = Array.from(node.children).filter(
            (child) => !child.classList.contains('facetwp-depth')
          );
 
          // Set the label texts
          let showmore_label_more = 'Show more';
          let showmore_label_less = 'Show less';
 
          let showmore_class = 'showmore';
 
          if (relevantChildren.length >= 4) {
 
            // Add show more/less links
            let show = document.createElement('a');
            show.href = 'javascript:;';
            show.textContent = showmore_label_more;
            show.classList.add('show-more-link');
            node.append(show);
 
            // Show hide on click of more/less links
            show.addEventListener('click', function(e) {
              let showmore = e.target;
              let depth = e.target.parentNode;
              if (depth.classList.contains(showmore_class)) {
                depth.classList.remove(showmore_class);
                showmore.textContent = showmore_label_more;
              } else {
                depth.classList.add(showmore_class);
                showmore.textContent = showmore_label_less;
              }
            });
          }
        });
      });
    })(fUtil);
  </script>
  <?php
}, 100);
1 year ago
<?php
add_action( 'facetwp_scripts', function() {
  ?>
  <script>
    document.addEventListener('facetwp-loaded', function() {
      FWP.hooks.addFilter('facetwp/selections/hierarchy_select', function(output, params) {

        var selected_values = [];
        params.el.find('.facetwp-hierarchy_select option:checked').each(function() {
          var value = $(this).attr('value');
          if (value.length) {
            selected_values.push({value: value, label: $(this).text()});
          }
        });

        if (selected_values.length === 3) {
          console.log(selected_values[2]['label']); // get the label of the 3rd level choice and do something with it
        }
        return output;
      });

    });
    })(fUtil);
  </script>
  <?php
}, 100 );
1 year ago
<?php
add_action('facetwp_scripts', function () { ?>
  <script>
    (function($) {
      $().on('facetwp-loaded', function() {
        var has_posts = ( 0 <  FWP.settings.pager.total_rows);
        var method = has_posts ? 'removeClass' : 'addClass';
        $('h1.listing-title')[method]('facetwp-hidden');
      });
    })(fUtil);
  </script>
<?php }, 100);
1 year ago
<?php

// See: https://facetwp.com/help-center/developers/javascript-reference/facetwp-refresh/#reset-all-other-facets-on-change-of-any-facet
// Or, to reset on change of a specific facet:
// https://facetwp.com/help-center/developers/javascript-reference/facetwp-refresh/#reset-all-other-facets-on-change-of-a-specific-facet

add_action( 'facetwp_scripts', function() { ?>
  <script>
    document.addEventListener('facetwp-refresh', function() {
      if ( null !== FWP.active_facet ) {
        let current_facet = fUtil(FWP.active_facet.nodes[0]).attr('data-name' );
        let others = FWP.facets;
        Object.keys(others).forEach(function (key) {
          if ( current_facet != key ) {
            FWP.facets[key] = [];
          }
        });
      }
    });
  </script>
<?php }, 100 );
1 year ago
<?php
/** allows magnifying glass search icon 
 ** to trigger a submit even when auto_refresh
 ** is disabled
 **/
add_action('facetwp_scripts', function () {
    ?>
    <script>
        (function($) {
            $().on('click', '.facetwp-type-search .facetwp-icon', function() {
                if (! FWP.is_refresh) {
                    FWP.refresh();
                }
            });
        })(fUtil);
    </script>
<?php
});
2 years ago
<?php
// If you are using the Submit Button add-on and want the redirect not to happen when your facet is empty, 
// use the following script and de-activate the add-on. This is basically the same as facetwp-submit.js, but with an 
// extra check in L13-14 to check if a specific facet is empty when the Submit button is clicked. If it is, the redirect does not happen.
// This can be useful to prevent 'empty' redirects for facet types that refresh themselves, like an Autocomplete facet that submits on Enter or clicking a selection.

add_action( 'facetwp_scripts', function() {
  ?>
  <script>
    (function($) {
      $().on('click', '.fwp-submit', function() {
        FWP.parseFacets();
        
        // Do nothing if this facet is empty
        if ( ! FWP.facets['my_facet_name'].length ) { // Replace 'my_facet_name' with the name of your facet
          return;
        }

        var href = $(this).attr('data-href');
        var query_string = FWP.buildQueryString();

        if (query_string.length) {
          var prefix = (-1 < href.indexOf('?')) ? '&' : '?';
          href += prefix + query_string;
        }

        window.location.href = href;
      });
    })(fUtil);
  </script>
  <?php
}, 100 );
2 years ago
<?php
// Syncs the selected values of two facets with different types when using one of the facets.
// The facets need to use the same Data Source.
// Change 'categories_radio' and 'categories_dropdown' to the names of your facets.
// Caveat: both facets will ghost each other's choices. This may not be optimal/desired.
// This can be fixed with the second snippet. Until a Dropdown facet has ghosts, this is not (yet) possible for Dropdowns.
add_action( 'facetwp_scripts', function() {
  ?>
  <script>
    document.addEventListener('facetwp-refresh', function() {
      if (null !== FWP.active_facet) {
        if ( 'categories_radio' == fUtil(FWP.active_facet.nodes[0]).attr('data-name' ) ) {
          FWP.facets['categories_dropdown'] = FWP.facets['categories_radio'];
        } else if ( 'categories_dropdown' == fUtil(FWP.active_facet.nodes[0]).attr('data-name' ) ) {
          FWP.facets['categories_radio'] = FWP.facets['categories_dropdown'];
        }
      }
    });
  </script>
  <?php
}, 100 );

// Optional: remove unclickable ghosts from the Radio facet
add_filter( 'facetwp_facet_html', function( $output, $params ) {
    if ( 'categories_radio' == $params['facet']['name'] ) { 
        $output = str_replace ( 'disabled' , '' , $output );
    }
    return $output;
}, 10, 2 );