PageSourceSearch

https://www.janushendersoncharitable.org/wp-content/plugins/janush…/product-search/view.js?ver=1791231069

js janushendersoncharitable.org collected 2026-10-06 05:22:43 UTC 17,760 bytes, 1 lines download raw bytes

1!function(){"use strict";function e(){if("undefined"==typeof jhProductSearch)return void console.error("jhProductSearch is not defined. Make sure the script is enqueued properly.");const e=document.querySelectorAll(".product-search");0!==e.length?e.forEach(e=>{try{new t(e)}catch(e){console.error("Error initializing ProductSearchBlock:",e)}}):console.log("No product search blocks found on this page.")}console.log("Product Search view.js loaded!"),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e();class t{constructor(e){this.element=e,this.contentName=e.dataset.contentName||"";try{this.filters=JSON.parse(e.dataset.filters||"[]"),this.manualFilters=JSON.parse(e.dataset.manualFilters||"[]"),console.log("Parsed filters:",this.filters),console.log("Parsed manual filters:",this.manualFilters)}catch(e){console.error("Error parsing filter data:",e),this.filters=[],this.manualFilters=[]}this.selectMenu=e.querySelector(".select-menu"),this.selectDropdown=e.querySelector(".select-menu__dropdown"),this.searchInput=e.querySelector(".search-container__search-input"),this.resultsDropdown=e.querySelector(".results-dropdown"),this.searchTimeout=null,this.filterOptionsCache={},this.allProducts=[],this.searchProducts=[],this.productsLoaded=!1,this.init()}showLoadingOverlay(){const e=this.element.querySelector(".loading-overlay-filter");if(e){const t=e.querySelector("img");if(t&&!t.src){const e=t.getAttribute("data-spinner-path");e&&void 0!==window.jhProductSearch&&window.jhProductSearch.pluginBaseUrl&&(t.src=window.jhProductSearch.pluginBaseUrl+e)}e.style.display="flex"}}hideLoadingOverlay(){const e=this.element.querySelector(".loading-overlay-filter");e&&(e.style.display="none")}
1async init(){try{this.showLoadingOverlay(),this.setupSelectMenu(),await this.loadAllProducts(),this.hideLoadingOverlay(),this.setupSearch(),this.renderFilters().catch(e=>{console.error("Failed to render filters:",e)})}catch(e){this.hideLoadingOverlay(),console.error("Error during ProductSearchBlock initialization:",e)}}async loadAllProducts(){const e=this.contentName;if(e){const t=`${jhProductSearch.ajaxUrl.replace("jhi-blocks/v1/","")}jhenderson/v1/product_filters/get_tab_data?content_name=${encodeURIComponent(e)}`;try{const s={Accept:"application/json, text/plain, */*","X-Requested-With":"XMLHttpRequest"},r={headers:s};let o=await fetch(t,r);if(!o.ok&&403===o.status&&window.jhProductSearch&&jhProductSearch.isUserLoggedIn&&(console.log("[ProductSearchBlock] 403 error detected for logged-in user, retrying with WordPress authentication..."),s["X-WP-Nonce"]=jhProductSearch.nonce,o=await fetch(t,{headers:s,credentials:"same-origin"})),o.ok){const t=await o.json();if(t&&t.products&&t.products.length>0)return this.allProducts=t.products,this.searchProducts=[...this.allProducts],"filterEMEAPerformance"===e&&this.loadEmeaTabulaSearchProducts(),this.productsLoaded=!0,void console.log("[ProductSearchBlock] Loaded products:",Number(this.allProducts.length));console.warn("[ProductSearchBlock] No products found in API response.")}else console.error("[ProductSearchBlock] API response not OK:",Number(o.status))}catch(e){console.error("Error loading all products for search:",e)}}this.allProducts=[],this.searchProducts=[],this.productsLoaded=!0,console.warn("[ProductSearchBlock] No products loaded.")}async loadEmeaTabulaSearchProducts(){const e=`${jhProductSearch.ajaxUrl.replace("jhi-blocks/v1/","")}jhenderson/v1/product_filters/get_tab_data?content_name=filterEMEAetfs`,t={Accept:"application/json, text/plain, */*","X-Requested-With":"XMLHttpRequest"};try{let s=await fetch(e,{headers:t});if(!s.ok&&403===s.status&&window.jhProductSearch&&jhProductSearch.isUserLoggedIn&&(t["X-WP-Nonce"]=jhProductSearch.nonce,s=await fetch(e,{headers:t,credentials:"same-origin"})),!s.ok)return void console.warn("[ProductSearchBlock] Tabula search products request failed:",Number(s.status));const r=await s.json();if(r&&Array.isArray(r.products)){this.searchProducts.push(...r.products);const e=this.searchInput?this.searchInput.value.trim().toLowerCase():"";e.length>=2&&this.performClientSearch(e)}}catch(e){console.warn("[ProductSearchBlock] Could not load Tabula search products:",e)}}async renderFilters(){if(!this.selectDropdown||0===this.filters.length)return void console.log("No filters configured or dropdown element not found");let e="";for(const t of this.filters){const s=`product-search-filter-${String(t.filterMetaKey
1).replace(/[^A-Za-z0-9_-]/g,"-")}`;e+='<div class="select-menu__dropdown__section">',e+=`<h3 id="${s}" class="product-search__dropdown-header">${this.escapeHtml(t.filterWidgetLabel||t.filterMetaKey)}</h3>`,e+=`<ul role="group" aria-labelledby="${s}">`;try{const s=await this.loadFilterOptions(t.filterMetaKey);if(s.length>0){const r="filters_radio"===t.inputType?"radio":"checkbox",o="radio"===r?this.escapeHtml(t.filterMetaKey):`${this.escapeHtml(t.filterMetaKey)}[]`;s.forEach(t=>{const s=this.escapeHtml(t.value).replace(/\s+/g,"-");e+=`\n\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t<label>\n\t\t\t\t\t\t\t\t\t\t<div class="jh-checkbox"><span></span><input type="${r}" id="${s}" name="${o}" value="${this.escapeHtml(t.value)}"></div>\n\t\t\t\t\t\t\t\t\t\t${this.escapeHtml(t.label)}\n\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t`})}else e+="<li><em>No options available</em></li>"}catch(s){console.error(`Error loading options for ${t.filterMetaKey}:`,s),e+="<li><em>Error loading options</em></li>"}e+="</ul>",e+="</div>"}this.manualFilters.length>0&&this.manualFilters.forEach((t,s)=>{if(!t.options||0===t.options.length)return;const r=`product-search-manual-filter-${s}`;e+='<div class="select-menu__dropdown__section">',e+=`<h3 id="${r}" class="product-search__dropdown-header">${this.escapeHtml(t.headerLabel)}</h3>`,e+=`<ul aria-labelledby="${r}">`,t.options.forEach(t=>{const s=t.link.replace("[site_url]",window.location.origin);e+=`\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href="${this.escapeHtml(s)}">${this.escapeHtml(t.label)}</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t`}),e+="</ul>",e+="</div>"});const t=this.selectDropdown.querySelector(".select-menu__dropdown__footer");t?t.insertAdjacentHTML("beforebegin",e):this.selectDropdown.innerHTML=e,this.setupFilterActions(),this.attachCheckboxListeners(),console.log("Filters rendered successfully"),this.hideLoadingOverlay()}attachCheckboxListeners(){const e=this.selectDropdown;e&&(e.addEventListener("change",t=>{if("checkbox"===t.target.type||"radio"===t.target.type){const s=t.target.closest(".jh-checkbox");if(s){if("radio"===t.target.type){const s=t.target.name;e.querySelectorAll(`input[type="radio"][name="${s}"]`).forEach(e=>{const t=e.closest(".jh-checkbox");t&&t.classList.remove("jh-checkbox--checked")})}t.target.checked?s.classList.add("jh-checkbox--checked"):s.classList.remove("jh-checkbox--checked")}}}),e.addEventListener("submit",t=>{t.preventDefault(),t.stopImmediatePropagation();const s=e.querySelectorAll('input[type="checkbox"]:checked'),r=new URLSearchParams,o={};s.forEach(e=>{const t=e.name.replace("[]","");o[t]||(o[t]=[]),o[t].push(e.value)});const a={investment_type:"vehicle",vehicle:"vehicle",asset_class:"assetClasses",assetClasses:"assetClasses",product_type:"productType"};Object.keys(o).forEach(e=>{const t=a[e]||e;o[e].forEach(e=>{r.append(t,e)})});const n=new URL(this.getProductUrl(),window.location.origin);r.forEach((e,t)=>{n.searchParams.append(t,e)});let c=n.pathname+this.encodeSearchParams(n.search);window.location.pathname.includes("/en-us/")&&(c+=(c.includes("?")?"&":"?")+"loadCode=@NAV");const i=this.sanitizeUrl(c);i&&(window.location.href=i)}))}async loadFilterOptions(e){if(this.filterOptionsCache[e])return this.filterOptionsCache[e];if(this.allProducts&&this.allProducts.length>0)return this.extractOptionsFromSpokeProducts(this.allProducts,e);try{console.log(`Loading filter options for: ${e}`);const t=this.contentName;if(t){console.log(`Using content_name: ${t}`);const s=`${jhProductSearch.ajaxUrl.replace("jhi-blocks/v1/","")}jhenderson/v1/product_filters/get_tab_data?content_name=${encodeURIComponent(t)}`;console.log("Fetching from filter API:",s);const r={Accept:"application/json, text/plain, */*","X-Requested-With":"XMLHttpRequest"};let o=await fetch(s,{headers:r});if(!o.ok&&403===o.status&&window.jhProductSearch&&jhProductSearch.isUserLoggedIn&&(console.log("[ProductSearchBlock] Filter API 403 error, retrying with WordPress authentication..."),r["X-WP-Nonce"]=jhProductSearch.nonce,o=await fetch(s,{headers:r,credentials:"same-origin"})),o.ok){const t=await o.json();if(t&&t.products&&t.products.length>0)return console.log("Successfully fetched products:",Number(t.products.length),"products"),this.extractOptionsFromSpokeProducts(t.products,e)}}return[]}catch(t){return console.error(`Error loading filter options for ${e}:`,t),[]}}getProductUrl(){const e=window.location.pathname.split("/").filter(
1Boolean);return 0===e.length?"/product/":e[0].includes("-")&&e.length>=2?`/${e[0]}/${e[1]}/product/`:`/${e[0]}/product/`}extractOptionsFromSpokeProducts(e,t){if(!e||!Array.isArray(e))return console.warn("No products array provided"),[];console.log(`Processing ${Number(e.length)} products for ${String(t).replace(/[\r\n]/g,"")}...`);const s=new Map;e.forEach(e=>{let r=null;switch(t){case"vehicle":case"investment_type":r=e.vehicle;break;case"asset_class":case"assetClasses":r=e.assetClasses;break;case"product_type":r=e.product_type;break;default:r=e[t]}r&&(Array.isArray(r)?r.forEach(e=>{e&&s.set(e,this.getVehicleLabel(e)||e)}):s.set(r,this.getVehicleLabel(r)||r))});const r=Array.from(s,([e,t])=>({value:e,label:t})).sort((e,t)=>e.label.localeCompare(t.label));return console.log(`Loaded ${Number(r.length)} options for ${String(t).replace(/[\r\n]/g,"")}`),r}extractOptionsFromProducts(e,t){if(!e||!Array.isArray(e))return console.warn("No products array provided"),[];const s=new Map;console.log(`Processing ${Number(e.length)} products for ${String(t).replace(/[\r\n]/g,"")}...`),e.forEach((e,r)=>{const o=e[t];if(o)if(Array.isArray(o))o.forEach(e=>{if(e){const t=this.getVehicleLabel(e)||e;s.set(e,t)}});else{const e=this.getVehicleLabel(o)||o;s.set(o,e)}r<3&&console.log(`Product ${r} ${t}:`,o)});const r=Array.from(s,([e,t])=>({value:e,label:t}));return console.log(`Loaded ${Number(r.length)} options for ${String(t).replace(/[\r\n]/g,"")}`),this.filterOptionsCache[t]=r,r}getVehicleLabel(e){return{JIF:"Mutual Funds",MF:"Mutual Funds",ETF:"ETFs",CIT:"Collective Investment Trusts",SMA:"Separately Managed Accounts",MA:"Managed Accounts",JAS:"Annuity Subaccounts",USPRIVC:"Private Funds",SEP:"SEP Accounts",ISEP:"ISEP Accounts",IIC:"Irish Investment Company",OEIC:"OEIC",SICV:"SICAV",UNTR:"Unit Trust",IVTR:"Investment Trust",EXOEIC:"OEIC",IUT:"Irish Unit Trust",ICAV:"ICAV ETFs",AUSMIS:"Australian Managed Investment Scheme",AUSMI:"Australian Managed Investment",HGFD:"Hedge Fund",SGUT:"Singapore Unit Trust",USMF:"US Mutual Fund",SICAVHDG:"SICAV - Hedge",INCO:"Investment Company",Equities:"Equities","Fixed Income":"Fixed Income","Multi-Asset":"Multi-Asset","Money Market":"Money Market",Alternatives:"Alternatives"}[e]}setupFilterActions(){const e=this.selectDropdown.querySelector(".apply-filters-btn");e&&e.addEventListener("click",()=>{const e={};this.selectDropdown.querySelectorAll('input[type="checkbox"]:checked').forEach(t=>{const s=t.name;e[s]||(e[s]=[]),e[s].push(t.value)});const t=new URL(this.getProductUrl(),window.location.origin);Object.keys(e).forEach(s=>{e[s].forEach(e=>{t.searchParams.append(s,e)})});const s=this.sanitizeUrl(t.pathname+this.encodeSearchParams(t.search));s&&(window.location.href=s)})}setupSelectMenu(){console.log("setupSelectMenu called"),console.log("selectMenu:",this.selectMenu),console.log("selectDropdown:",this.selectDropdown),this.selectMenu&&this.selectDropdown?(this.selectMenu.addEventListener("click",e=>{e.stopPropagation(),e.preventDefault(),this.selectDropdown.classList.contains("visible")?(this.selectDropdown.classList.remove("visible"),this.selectMenu.classList.remove("has-open-menu"),this.selectMenu.setAttribute("aria-expanded","false")):(this.selectDropdown.classList.add("visible"),this.selectMenu.classList.add("has-open-menu"),this.selectMenu.setAttribute("aria-expanded","true"))},!0),this.selectDropdown.addEventListener("click",e=>{e.stopPropagation()}),document.addEventListener("click",e=>{const t=this.selectMenu.contains(e.target),s=this.selectDropdown.contains(e.target),r=this.selectDropdown.classList.contains("visible");t||s||!r||(this.selectDropdown.classList.remove("visible"),this.selectMenu.classList.remove("has-open-menu"),this.selectMenu.setAttribute("aria-expanded","false")),setTimeout(()=>{const e=this.selectDropdown.classList.contains("visible"),t=this.selectMenu.classList.contains("has-open-menu");!e&&t&&(this.selectMenu.classList.remove("has-open-menu"),this.selectMenu.setAttribute("aria-expanded","false"))},10)}),this.selectMenu.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.selectMenu.click())}),console.log("setupSelectMenu completed")):console.error("Missing required elements for dropdown")}setupSearch(){this.searchInput&&(this.searchInput.addEventListener("input",e=>{clearTimeout(this.searchTimeout);const t=e.target.value.trim().toLowerCase();this.productsLoaded?t.length<2?this.hideSearchResults():this.searchTimeout=setTimeout(()=>{this.performClientSearch(t)},300):this.resultsDropdown.innerHTML='<div class="search-loading">Loading products...</div>'}),this.searchInput.addEventListener("focus",()=>{this.searchInput.value.trim().length>=2&&this.resultsDropdown.classList.add("visible")}),document.addEventListener("click",e=>{const t=this.element.querySelector(".product-search__content__search");t&&!t.contains(e.target)&&this.hideSearchResults()}))}performClientSearch(e){console.log("[ProductSearchBlock] Searching for:",e.replace(/[\r\n]/g,"")),console.log("[ProductSearchBlock] Products available:",Number(this.searchProducts.length));const t={};
1this.searchProducts.forEach(e=>{if(!e.productNameFinal)return;const s=e.productNameFinal.toLowerCase();if(!t[s]){let r=e.permalink||e.shareClasses&&e.shareClasses[0]&&e.shareClasses[0].permalink||"";r=r.split("?")[0],t[s]={...e,permalink:r}}});const s=Object.values(t).filter(t=>{const s=(t.productNameFinal||"").toLowerCase(),r=(t.ticker||"").toLowerCase(),o=(t.isin||"").toLowerCase(),a=Array.isArray(t.assetClasses)?t.assetClasses.join(" ").toLowerCase():(t.assetClasses||"").toLowerCase(),n=Array.isArray(t.shareClasses)?t.shareClasses.flatMap(e=>[e.ticker,e.isin]).filter(Boolean).join(" ").toLowerCase():"";return s.includes(e)||r.includes(e)||o.includes(e)||a.includes(e)||n.includes(e)});console.log("[ProductSearchBlock] Search results:",Number(s.length)),this.renderSearchResults(s,e)}async performSearch(e){try{const t={Accept:"application/json, text/plain, */*","X-Requested-With":"XMLHttpRequest"};window.jhProductSearch&&jhProductSearch.nonce&&(t["X-WP-Nonce"]=jhProductSearch.nonce);const s=await fetch(`${jhProductSearch.ajaxUrl}product-search?search=${encodeURIComponent(e)}`,{headers:t});if(!s.ok)throw new Error("Search failed");const r=await s.json();this.renderSearchResults(r,e)}catch(t){console.error("Search error:",t),this.renderSearchResults([],e)}}renderSearchResults(e,t){const s=e.length,r=Math.min(5,s),o=e.slice(0,5),a=document.createDocumentFragment(),n=document.createElement("div");n.className="product-search__dropdown-header",n.setAttribute("role","status"),a.appendChild(n);const c=document.createElement("span");n.appendChild(c);let i=null;s>5&&(i=document.createElement("a"),i.setAttribute("aria-label","View all search results"),n.appendChild(document.createTextNode(" ")),n.appendChild(i));const l=[];if(o.length>0){const e=document.createElement("ul");e.className="results-dropdown__list",e.setAttribute("role","listbox"),a.appendChild(e),o.forEach(()=>{const t=document.createElement("li");t.className="results-dropdown__list__item",t.setAttribute("role","option");const s=document.createElement("a");s.className="results-dropdown__list__item__link",t.appendChild(s),e.appendChild(t),l.push(s)})}if(s>0){if(c.appendChild(document.createTextNode(`Showing ${r} of ${s} results`)),i){const e=this.sanitizeUrl(this.getProductUrl());if(e){const s=new URL(e,window.location.origin);s.searchParams.set("search",t),i.href=s.pathname+this.encodeSearchParams(s.search),i.appendChild(document.createTextNode("View all"))}}}else c.appendChild(document.createTextNode("No results found. Please try again."));o.forEach((e,t)=>{const s=l[t];try{const t=new URL(e.permalink,window.location.origin);if(t.origin===window.location.origin){let r="";if(window.location.pathname.includes("/en-us/")){let t=null;e.shareClasses&&e.shareClasses.length>0&&(t=e.shareClasses[0].shareClassCode||e.shareClasses[0].shareClass),"A"===t?r="loadCode=@NAV":"C"===t&&(r="loadCode=@CDSC")}const o=t.pathname+t.search,a=r?o+(o.includes("?")?"&":"?")+r:o;(/^\/[^/]/.test(a)||"/"===a)&&s.setAttribute("href",a)}}catch(e){}s.appendChild(document.createTextNode(String(e.productNameFinal)))}),this.resultsDropdown.replaceChildren(a),this.resultsDropdown.style.display="block",this.resultsDropdown.classList.add("visible"),this.searchInput.setAttribute("aria-expanded","true")}hideSearchResults(){this.resultsDropdown&&(this.resultsDropdown.style.display="none",this.resultsDropdown.classList.remove("visible"),this.searchInput.setAttribute("aria-expanded","false"))}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}encodeSearchParams(e){return e.replace(/\+/g,"%20")}sanitizeUrl(e){if(!e||"string"!=typeof e)return"";const t=e.trim();return/^https?:\/\//i.test(t)||/^\/[^/]/.test(t)||"/"===t?t:""}}}();

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.