PageSourceSearch

https://popcouncil.org/wp-content/themes/Avada-Child-Theme/js/views/views-filters.js?ver=7.1.2

js popcouncil.org collected 2026-09-24 08:45:28 UTC 8,769 bytes, 278 lines download raw bytes

1/*
2 * View pages within this site are controled by the
3 * Content Views Pro plugin, this file adjusts submit
4 * buttons text for different view pages based on class.
5 */
6(function ($) {
7  // We are listening for the view wrapper
8  const targetView = document.querySelector(".pt-cv-wrapper");
9
10  if (targetView) {
11    // Attach styles for view content, this loads first
12    document.addEventListener(
13      "DOMContentLoaded",
14      function () {
15        document.querySelector(".pt-cv-view").classList.add("view-content");
16      },
17      false
18    );
19
20    // Options for the observer (which mutations to observe)
21    const config = { childList: true, subtree: true };
22
23    // Create an observer instance linked to the callback function
24    const observer = new MutationObserver(updateView);
25
26    // Start observing the page for changes within the views
27    observer.observe(targetView, config);
28
29    // Handle updating filter buttons within views
30    function updateView() {
31      // Disconnect to make changes
32      observer.disconnect();
33
34      // Attach styles to view content if content changed/was updated
35      $(".pt-cv-view").addClass("view-content");
36
37      let visiblePosts = $(".pt-cv-page:not(.no-posts) .pt-cv-content-item");
38      let searchInput = $(".cvp-live-filter input");
39      let searchSelect = $(".cvp-live-filter select option[selected]");
40      let searchString = "";
41      let searchText = "";
42      let optionFilters = "";
43      let options = [];
44      let count = visiblePosts.length ? visiblePosts.length : 0;
45      let resetBtn = $(".cvp-live-reset");
46
47      if (count == 1) {
48        count = count + " result";
49      } else {
50        count = count + " results";
51      }
52
53      // If user selected options
54      if (searchSelect.length > 0) {
55        $.each(searchSelect, (index, value) => {
56          options.push($(value).text());
57        });
58
59        optionFilters = options.join(" , ");
60      }
61      // If user searched text
62      if (searchInput.val().length > 0) {
63        searchString = searchInput.val();
64      }
65
66      // If filters are used, build string
67      if (searchString.length > 0 && optionFilters.length > 0) {
68        searchText = ' for "' + searchString + " , " + optionFilters + '"';
69
70        // Add text to search results
71        count = count + searchText;
72
73        $(resetBtn).addClass("PC-filter-view-active");
74      } else if (searchString.length > 0 || optionFilters.length > 0) {
75        searchText = ' for "' + searchString + optionFilters + '"';
76
77        // Add text to search results
78        count = count + searchText;
79
80        $(resetBtn).addClass("PC-filter-view-active");
81      }
82
83      // If it already exists, update content
84      if ($("#announcements").length > 0) {
85        $("#announcements").text("Showing " + count);
86        wp.a11y.speak( "Showing " + count, 'polite' );
87      } else {
88        // Build inital
89        let $announcement = $(
90          "<h2>",
91          {
92            "aria-live": "polite",
93            class: "visually-hidden",
94            id: "announcements",
95            text: "Showing " + count,
96          },
97          "</h2>"
98        );
99        $($announcement).insertBefore(".pt-cv-view");
100        wp.a11y.speak( "Showing " + count, 'polite' );
101      }
102
103      // Attach aria-labels for filters
104      $('select[name="tx_country"]').attr("aria-label", "Select country");
105      $('select[name="tx_country"]').attr("id", "tx_country");
106      $('select[name="tx_country"]').prev().attr("for", "tx_country");
107
108      $('select[name="tx_post_tag"]').attr("aria-label", "Select media type");
109      $('select[name="tx_post_tag"]').attr("id", "tx_post_tag");
110      $('select[name="tx_post_tag"]').prev().attr("for", "tx_post_tag");
111
112      $('select[name="tx_topic"]').attr("aria-label", "Select topic");
113      $('select[name="tx_topic"]').attr("id", "tx_topic");
114      $('select[name="tx_topic"]').prev().attr("for", "tx_topic");
115
116      // Adjust text for filter buttons
117      var $view = $(".cvp-live-submit");
118      var pageClasses = ($("#content").attr("class") || "").split(" ");
119
120      for (
121        var index = 0, length = pageClasses.length;
122        index < length;
123        index++
124      ) {
125        switch (pageClasses[index]) {
126          case "insights-page":
127            $view.text("Filter Insights");
128            break;
129          case "media-page":
130            $view.text("Filter Media");
131            break;
132          case "people-page":
133            $view.text("Search Staff");
134            break;
135          case "projects-page":
136            $view.text("Filter Projects");
137            // Replace default images
138            defaultImages();
139            break;
140          default:
141            break;
142        }
143      }
144
145      // Wrap .pt-cv-ctf-value content inside <p> for semantics
146      $(".pt-cv-ctf-value").each(function () {
147        const $el = $(this);
148        if ($el.children("p").length === 0) {
149          $el.html("<p>" + $el.html().trim() + "</p>");
150        }
151      });
152
153      // Transform cards into <article> for Projects page
154      enhanceProjectsGrid();
155
156      // Listen for when new changes happen
157      observer.observe(targetView, config);
158    }
159
160    // Content Views Pro pulls from inline content when no featured image
161    // override the pulled content with the correct default
162    // NOTE: This only applied to the projects view
163    function defaultImages() {
164      const needReplacement = $(".pt-cv-content-item .img-none.cvp-substitute");
165      const base_url = window.location.origin;
166      const default_image = document.createElement("img");
167
168      // Build default image
169      default_image.setAttribute(
170        "src",
171        base_url +
172        "/wp-content/themes/Avada-Child-Theme/assets/images/placeholder.svg"
173      );
174      default_image.setAttribute("height", "1024");
175      default_image.setAttribute("width", "1024");
176      default_image.setAttribute("alt", "");
177
178      // Replace inline content with default
179      needReplacement.each((element) => {
180        needReplacement[element].replaceWith(default_image);
181      });
182    }
183  }
184
185  function enhanceProjectsGrid() {
186    // Only run if the #content wrapper has .projects-page
187    if (!document.querySelector("#content.projects-page")) return;
188
189    $(".pt-cv-content-item").each(function (index) {
190      const $item = $(this);
191
192      // Skip if already an <article>
193      if ($item.is("article")) return;
194
195      const $article = $("<article>", { role: "article" });
196
197      const $heading = $item.find("h3").first();
198      if ($heading.length) {
199        const headingId = $heading.attr("id") || `project-card-title-${index}`;
200        $heading.attr("id", headingId);
201        $article.attr("aria-labelledby", headingId);
202      }
203
204      $article.append($item.contents());
205      $item.replaceWith($article);
206    });
207  }
208})(jQuery);
209
210// Adjust text on search button for search landing page
211(function ($) {
212  const searchButton = $(
213    ".fusion-search-element-3 .fusion-search-form-content .search-button input"
214  );
215  if (searchButton) {
216    // Adjust input text
217    searchButton.attr("value", "Search");
218  }
219})(jQuery);
220
221// Remove wrapper around images within views/archives
222// Also remove incorrect aria
223(function ($) {
224  $(".fusion-image-wrapper").removeAttr("aria-haspopup");
225  $(".fusion-image-wrapper a > img").unwrap();
226})(jQuery);
227
228// Remove odd title field being set on views
229(function ($) {
230  $(".pt-cv-meta-fields a").each(function () {
231    if ($(this).attr("title")) {
232      $(this).removeAttr("title");
233    }
234  });
235})(jQuery);
236
237// Fix search results headings for accessibility
238(function ($) {
239  $(document).ready(function () {
240    // Only run if the body wrapper has .search-results
241    if (!document.querySelector("body.search-results")) return;
242
243    const $resultsHeading = $(".fusion-text-2 p");
244    const $resultsQuery = $(".fusion-text-3 p");
245
246    if ($resultsQuery.length) {
247
248      $resultsQuery.prepend(" ").detach().appendTo($resultsHeading);
249    }
250
251    if ($resultsHeading.length && $resultsHeading.prop("tagName") !== "H2") {
252      $resultsHeading.replaceWith(function () {
253        return $("<h2>", { text: $(this).text(), class: "results-count" });
254      });
255    }
256
257    $("h2.blog-shortcode-post-title").each(function () {
258      $(this).convertElement('h3');
259    });
260  });
261})(jQuery);
262
263// Converting a DOM element into a specified new type of element
264jQuery.fn.convertElement = function (newType) {
265  if (!jQuery(this[0]) || jQuery(this[0]) == undefined || !jQuery(this[0]).length) {
266    return;
267  } else {
268    var atts = {};
269
270    jQuery.each(this[0].attributes, function (idx, attr) {
271      atts[attr.nodeName] = attr.nodeValue;
272    });
273
274    this.replaceWith(function () {
275      return jQuery("<" + newType + "/>", atts).append(jQuery(this).contents());
276    });
277  }
278}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.