/* Minification failed. Returning unminified contents. (357,18-26): run-time error JS1006: Expected ')': function (357,29): run-time error JS1004: Expected ';' (375,6-7): run-time error JS1195: Expected expression: ) (831,6): run-time error JS1004: Expected ';' (881,27): run-time error JS1004: Expected ';' (913,6): run-time error JS1004: Expected ';' (916,25): run-time error JS1004: Expected ';' (935,38): run-time error JS1004: Expected ';' (964,17): run-time error JS1004: Expected ';' (977,6): run-time error JS1004: Expected ';' (978,35): run-time error JS1004: Expected ';' (988,33-36): run-time error JS1009: Expected '}': ... (988,32): run-time error JS1004: Expected ';' (988,67): run-time error JS1004: Expected ';' (988,67-68): run-time error JS1195: Expected expression: : (990,35): run-time error JS1004: Expected ';' (1017,1-2): run-time error JS1002: Syntax error: } (1295,6): run-time error JS1004: Expected ';' (1299,40): run-time error JS1004: Expected ';' (1322,33): run-time error JS1004: Expected ';' (1329,34): run-time error JS1004: Expected ';' (1500,13-16): run-time error JS1009: Expected '}': ... (1501,25): run-time error JS1004: Expected ';' (1501,25-26): run-time error JS1195: Expected expression: : (1502,24): run-time error JS1004: Expected ';' (1502,24-25): run-time error JS1195: Expected expression: : (1503,10-11): run-time error JS1006: Expected ')': ; (1504,6-7): run-time error JS1195: Expected expression: ) (1511,1-2): run-time error JS1002: Syntax error: } (1557,17-20): run-time error JS1009: Expected '}': ... (1557,17-20): run-time error JS1006: Expected ')': ... (1556,39): run-time error JS1004: Expected ';' (1558,22): run-time error JS1004: Expected ';' (1558,22-23): run-time error JS1195: Expected expression: : (1559,14-15): run-time error JS1195: Expected expression: ) (1578,1-2): run-time error JS1002: Syntax error: } (1577,5-38): run-time error JS1018: 'return' statement outside of function: return alternatemediatypesDisplay (1000,5,1016,6): run-time error JS1018: 'return' statement outside of function: return { totalCount: directResponseBody["@odata.count"], offset: aiSearchRequestBody.top, searchMode: aiSearchRequestBody.searchMode, results: directResponseBody.value, productTypes: [], categories: [], military: [], coordinator: [], liveEventDates: [], certCreditTypes: [], certifications: [], closedCaptioned: [], speakers: [], languages: [], fallback: true } */ class CreditTypeFilter { constructor({ label, checked }) { this.label = label; this.count = ko.observable(0); this.checked = ko.observable(checked); this.isPageLoad = false; this.checked.subscribe(() => { if (!this.isPageLoad) { startAcs({skipScrollTop: true}); } }); } silentlySetChecked(value) { this.isPageLoad = true; this.checked(value); this.isPageLoad = false; } } function CreditTypeFilterViewModel() { const self = this; self.creditTypeSearch = ko.observable(""); self.clearCreditTypeSearch = () => self.creditTypeSearch(""); self.creditTypes = ko.observableArray(); self.displayedCreditTypes = ko.pureComputed(() => { const searchQuery = self.creditTypeSearch().toLowerCase(); if (!searchQuery) { return self.creditTypes(); } else { return self.creditTypes() .filter(creditType => creditType.label.toLowerCase().includes(searchQuery) || creditType.checked()) } }); /** * add a credit type to the model */ self.add = (label) => { for (const item of self.creditTypes()) { if (item.label === label) { return item; } } const newItem = new CreditTypeFilter({ label: label, checked: false }); self.creditTypes.push(newItem); return newItem; } /** * parse the acs search facet data */ self.parseAcsCertCreditTypeFacetJson = (data) => { let facetResponse = data.certCreditTypes; facetResponse = facetResponse.sort(function (a, b) { if (a.value.toUpperCase() > b.value.toUpperCase()) { return 1; } if (a.value.toUpperCase() < b.value.toUpperCase()) { return -1; } return 0; }); //hide entire box if empty if (facetResponse.length === 0) { $("#CreditTypesFilterBox").addClass("hidden"); } else { $("#CreditTypesFilterBox").removeClass("hidden"); } for (const creditType of self.creditTypes()) { creditType.count(0); } facetResponse.forEach((certCreditType) => { const value = certCreditType["value"]; const count = certCreditType["count"]; const item = self.add(value); item.count(count); }); self.creditTypes( self.creditTypes() .filter(creditType => creditType.count() !== 0 || creditType.checked())); } };; function FacetViewModel(options) { const self = this self.name = options.name; self.key = options.key; self.marker = options.marker; self.count = options.count; self.isPageLoad = false; self.retainOptions = false; self.optionSearch = ko.observable(""); self.clearOptionSearch = () => self.optionSearch(""); self.options = ko.observableArray([]).extend({ deferred: true }); self.selectedOptions = ko.observableArray([]); /** * get the currently available options filtered by search */ self.displayedOptions = ko.pureComputed(() => { const searchQuery = self.optionSearch().toLowerCase(); let options = null; if (!searchQuery) { options = self.options(); } else { options = self.options() .filter(option => option.value.toLowerCase().includes(searchQuery) || self.selectedOptions.indexOf(option.value) > -1) } return options.sort((left, right) => { return left.value.toLowerCase().trim() > right.value.toLowerCase().trim() ? 1 : -1 }) }); /** * get the ACS formatted filter string */ self.filterString = () => { const selectedOptions = self.selectedOptions(); if (selectedOptions.length) { return options.filterString(selectedOptions) } }; /** * refresh currently available options */ self.refresh = function (data) { if (self.retainOptions) { self.retainOptions = false; } else { //get options that no longer exist const options = data[self.key] ko.utils .arrayFilter( self.selectedOptions(), (selectedOption) => options.map((option) => option.value).indexOf(selectedOption) == -1 ) .forEach((option) => { options.push({ count: 0, value: option }) }); //set options self.options(options); } }; /** * run search when an option is selected */ self.selectedOptions.subscribe(() => { if (!self.isPageLoad) { self.retainOptions = true; startAcs({ skipScrollTop: true }); } }); }; function ProductTypeFilter(value, parent) { const self = this; self.value = value; self.checked = ko.observable(false); self.isPageLoad = false; self.count = ko.computed(function () { const filter = ko.utils.arrayFirst( parent.productTypeFilters(), (item) => { return item.value === self.value; } ); return filter == null ? 0 : filter.count; }); self.checked.subscribe(() => { if (!self.isPageLoad) { startAcs({ skipScrollTop: true }); } }); self.silentlySetChecked = (value) => { this.isPageLoad = true; this.checked(value); this.isPageLoad = false; } } function ProductTypeFilterViewModel() { const self = this; self.productTypeFilters = ko.observableArray([]); var productTypeFilters = acsProductTypes.map(p => new ProductTypeFilter(p, self)); self.productTypes = ko.observableArray(productTypeFilters); self.visibleProductTypes = ko.pureComputed(() => self.productTypes().filter(type => type.count() > 0 || type.checked())); self.anyVisibleProductTypes = ko.pureComputed(() => self.visibleProductTypes().length > 0); self.productTypeFilters.subscribe(newTypeFilters => { const existingTypes = self.productTypes().map(type => type.value); for (const newTypeFilter of newTypeFilters) { if (existingTypes.indexOf(newTypeFilter.value) === -1) { self.productTypes.push(new ProductTypeFilter(newTypeFilter.value, self)); } } }); /** * check a filter by value */ self.setChecked = (value, checked) => { var type = ko.utils.arrayFirst(self.productTypes(), (type) => type.value == value); if (type != null) { type.silentlySetChecked(checked); } } /** * clear all filters */ self.removeAll = () => { self.productTypes().forEach((type) => type.silentlySetChecked(false)); } /** * refresh the product type facets, if they have changed */ self.refresh = (data) => { self.productTypeFilters(data.productTypes); if (data.totalCount === 0) { $("#media-types").addClass("hidden"); } else { $("#media-types").removeClass("hidden"); } } } ; function SearchViewModel() { const self = this; self.facets = [ new FacetViewModel({ name: "Speakers/Authors", key: "speakers", marker: "speaker", count: 1000, filterString: (selectedOptions) => { return `speakerinformation/any(s: search.in(s/fullname, '${delimitedString(selectedOptions)}', '|'))`; } }), new FacetViewModel({ name: "Languages", key: "languages", marker: "language", count: 1000, filterString: (selectedOptions) => { return `languages/any(l: search.in(l/languages, '${delimitedString(selectedOptions)}', '|'))`; } }) ]; /** * get data for the filter badge panel */ self.filterBadges = () => { const badges = []; self.facets.forEach((facet) => facet.selectedOptions().forEach((option) => badges.push(new FilterBadge(option, () => facet.selectedOptions.remove(option))) ) ); return badges; }; /** * returns the selected facet options as a URI encoded string array */ self.queryStringParams = () => { const params = []; self.facets.forEach((facet) => facet.selectedOptions().forEach((option) => params.push(`${facet.marker}=${encodeURIComponent(option)}`) ) ); return params; }; /** * refresh all options based on response from cloud function */ self.refresh = (data) => { for (let i = 0; i < self.facets.length; i++) { const facet = self.facets[i]; facet.refresh(data); } }; /** * unselect all facet options */ self.clearAllFacets = () => { ko.utils.arrayForEach(self.facets, (facet) => { facet.isPageLoad = true; facet.selectedOptions([]); facet.isPageLoad = false; } ); }; /** * select facet options based on query string */ self.readQueryString = (params) => { ko.utils.arrayForEach(self.facets, (facet) => { facet.isPageLoad = true; facet.selectedOptions(params.getAll(facet.marker)); facet.isPageLoad = false; } ); }; } ; const productTypeModel = new ProductTypeFilterViewModel(); const creditTypeModel = new CreditTypeFilterViewModel(); const searchViewModel = new SearchViewModel(); const acsTop = 25; const testMessages = ko.observableArray(); function getParameter(name) { let params = new URL(document.location).searchParams; return params.get(name); } $(document) .ready(async function () { ko.applyBindings({ acsCurrentPageItems }, document.getElementById("acsCurrentPage")); ko.applyBindings({ acsPages }, document.getElementById("paginationNav")); ko.applyBindings({ acsPaginationMessage, testMessages }, document.getElementById("acsPaginationMessageParent")); ko.applyBindings({ filterBadges }, document.getElementById("acsFilterBadgeParent")); ko.applyBindings(productTypeModel, document.getElementById("media-types")); ko.applyBindings({ creditTypeModel }, document.getElementById("CreditTypes")); ko.applyBindings(searchViewModel, document.getElementById("facets")); // When $(document).ready finishes, #divProgress is hidden (Custom.js) // Run the query after this happens so it's shown setTimeout(() => { $("#divProgress").show(); initializeAcs(); const { page } = readQueryString(); startAcs({ page, skipScrollTop: true }); }, 100); }); class Filter { constructor(className, value, count) { this.className = className; this.value = value; this.count = count; } } let registrantTypes = [ new Filter("MilitaryAvailable", "military"), new Filter("CoordinatorAvailable", "coordinator"), ]; function initializeAcs() { let { form, input } = window.getKeywordSearchElements(); $("#btnProductSearch").off("click"); $("#btnProductSearchOutside").off("click"); $("#btnProductSearch").on("click", restartSearch); $("#btnProductSearchOutside").on("click", restartSearch); $("#clearAllFilters").on("click", () => { $("#txtProductSearchOutside").val(""); $(input).val(""); restartSearch(); }); //keep textbox values consistent between mobile and desktop $("#txtProductSearchOutside").on("keyup change", function () { $(input).val($(this).val()); }); $(input).on("keyup change", function () { $("#txtProductSearchOutside").val($(this).val()); }); $(form).on("submit", e => { e.preventDefault(); restartSearch(); }); $("#frmHeaderSearchOutside").on("submit", e => { e.preventDefault(); restartSearch(); }); $(".chkTopicAreasAcs").on("change", () => startAcs({ skipScrollTop: true })); $("#ulShowtimeMonthAndYear input[type=checkbox]").change(() => startAcs({ skipScrollTop: true })); $(".chkRegistrantTypeAcs").on("change", () => startAcs({ skipScrollTop: true })); $(".chkOtherFiltersAcs").on("change", () => startAcs({ skipScrollTop: true })); //back button behavior $(window).on("popstate", (event) => { const { page } = readQueryString(); startAcs({ page }); }); $("#selOrderBy").on("change", startAcs); } function restartSearch() { clearFilters(); startAcs(); } function clearFilters() { //remove badges filterBadges.removeAll(); //clear filters searchViewModel.clearAllFacets(); creditTypeModel.clearCreditTypeSearch(); creditTypeModel.creditTypes.removeAll(); productTypeModel.removeAll(); $(".chkFilter").prop("checked", false); //hide panels $(".defaultMinimizedFilters").collapse('hide'); } function filterSearchFieldsByLanguage(searchFields, currentLanguage) { const langaugeSearchFields = { "en": ["entitle", "ensubtitle"], "fr-ca": ["frcatitle", "frcasubtitle"], "it": ["ittitle", "itsubtitle"] } if (currentLanguage == null || !(currentLanguage in langaugeSearchFields)) { return searchFields; } const acsSearchFieldsList = searchFields.split(","); let excludedFields = []; for (const language in langaugeSearchFields) { if (language !== currentLanguage) { excludedFields = excludedFields.concat(langaugeSearchFields[language]); } } const filteredFields = acsSearchFieldsList.filter( (field) => !excludedFields.includes(field) ); return filteredFields.join(","); } function getSearchFields() { let returnValue = ''; if (acsSearchFields) { returnValue = acsSearchFields; if (typeof Weglot === 'undefined') { return returnValue; } const currentLanguage = Weglot.getCurrentLang(); returnValue = filterSearchFieldsByLanguage(acsSearchFields, currentLanguage); } return returnValue; } function getFilters() { return { TenantId: tenantId, Categories: $(".chkTopicAreasAcs:checked").get().map(element => element.value), ProductTypes: productTypeModel.productTypes() .filter(item => item.checked()) .map(item => item.value), LiveEventDates: $("#ulShowtimeMonthAndYear input[type=checkbox]:checked").get().map(element => element.value), Coordinator: $(".chkRegistrantTypeAcs[value=coordinatoravailable]").is(":checked"), Military: $(".chkRegistrantTypeAcs[value=militaryavailable]").is(":checked"), CertCreditTypes: creditTypeModel.creditTypes() .filter(item => item.checked()) .map(item => item.label), Speakers: searchViewModel.facets .filter(item => item.marker == "speaker")[0] .selectedOptions(), Languages: searchViewModel.facets .filter(item => item.marker == "language")[0] .selectedOptions(), Certifications: $("input[name=SelectedchkCertifications]").is(":checked"), ClosedCaptioned: $("input[name=SelectedchkClosedCaptioning]").is(":checked"), FilterPastLiveDates: true }; } class FilterBadge { constructor(displayName, onRemove) { this.displayName = displayName; let { form, input } = window.getKeywordSearchElements(); this.onRemove = function () { onRemove(); //make sure the mobile search txt value is the same as desktop search value after clearing fitler $("#txtProductSearchOutside").val($(input).val()); }; } } function getFilterBadges() { const badges = []; function uncheck_and_refresh(e) { e.checked = false; startAcs(); } productTypeModel.productTypes() .forEach(item => { if (item.checked()) { badges.push(new FilterBadge(item.value, () => item.checked(false))); } }); $(".chkTopicAreasAcs").each((_, e) => { if (e.checked) { badges.push(new FilterBadge(e.value, () => uncheck_and_refresh(e))); } }); $("#ulShowtimeMonthAndYear input[type=checkbox]").each((_, e) => { if (e.checked) { const label = e.labels[0] || {}; badges.push(new FilterBadge(label.title || e.value, () => uncheck_and_refresh(e))); } }); $(".chkRegistrantTypeAcs").each((_, e) => { if (e.checked) { badges.push(new FilterBadge(e.value, () => uncheck_and_refresh(e))); } }); creditTypeModel.creditTypes().forEach(item => { if (item.checked()) { badges.push(new FilterBadge(item.label, () => item.checked(false))); } }); searchViewModel.filterBadges().forEach(badge => { badges.push(badge); }); $("input[name=SelectedchkCertifications]").each((_, e) => { if (e.checked) { badges.push(new FilterBadge(`Certifications`, () => uncheck_and_refresh(e))); } }); $("input[name=SelectedchkClosedCaptioning]").each((_, e) => { if (e.checked) { badges.push(new FilterBadge(`Closed Captioned`, () => uncheck_and_refresh(e))); } }); let { form, input } = window.getKeywordSearchElements(); $(input).each((_, e) => { if (e.value) { badges.push(new FilterBadge(e.value, () => { e.value = ""; startAcs(); })); } }); // Category page filter badge var categoryName = $("#categoryName").val(); if (categoryName && categoryName.length > 0) { badges.push(new FilterBadge(categoryName, () => { const currentDomain = window.location.origin; const newPagePath = '/find'; window.location.href = currentDomain + newPagePath; })); } return badges; } function readQueryString() { if (!("URLSearchParams" in window)) { return; } const params = new URLSearchParams(window.location.search); function updateCheckboxes(name, selector, panel) { let filtered = false; $(selector).each((_, e) => { e.checked = params.has(name, e.value); if (e.checked) { filtered = true; } }); if (panel) { $(panel).toggleClass("collapse", !filtered); } } //product type filters productTypeModel.removeAll(); for (const typeLabel of params.getAll("type")) { productTypeModel.setChecked(typeLabel, true); } updateCheckboxes("category", ".chkTopicAreasAcs"); updateCheckboxes("month", "#ulShowtimeMonthAndYear input[type=checkbox]", "#ShowtimeMonthAndYear"); updateCheckboxes("registrantType", ".chkRegistrantTypeAcs", "#RegistrantTypes"); //credit type filters creditTypeModel.creditTypes.removeAll(); for (const creditTypeLabel of params.getAll("creditType")) { const item = creditTypeModel.add(creditTypeLabel); item.silentlySetChecked(true); } $("#CreditTypes") .toggleClass("collapse", !params.has("creditType")); searchViewModel.readQueryString(params); //other filters $('input[name=SelectedchkCertifications]')[0].checked = params.has("certifications"); $('input[name=SelectedchkClosedCaptioning]')[0].checked = params.has("closedCaptioning"); const hasOtherFilters = params.has("certifications") || params.has("closedCaptioning"); $("#OtherFilters") .toggleClass("collapse", !hasOtherFilters); //sort by var orderBy = params.get("orderBy"); if (orderBy && orderBy !== "relevance") { $(`#selOrderBy option[value=${orderBy}]`).attr('selected', 'selected'); } let { form, input } = window.getKeywordSearchElements(); var searchValue = ""; //Check for legacy search params if q is unavailable; if (params.has("q")) { searchValue = params.get("q") } else if (params.has("search")) { searchValue = params.get("search"); } else if (params.has("keyword")) { searchValue = params.get("keyword"); } if (searchValue) { $(input).val(searchValue); $("#txtProductSearchOutside").val(searchValue); } const options = {}; if (params.has("page")) { options.page = +params.get("page"); } return options; } function buildNewUrl({ page }) { const qs = []; let { form, input } = window.getKeywordSearchElements(); const q = $(input).val(); if (q) { qs.push(`q=${encodeURIComponent(q)}`); } //Retain scoring profile when replacing query string const scoringProfile = getParameter('sp'); if (scoringProfile) { qs.push(`sp=${encodeURIComponent(scoringProfile)}`); } if (page > 1) { qs.push(`page=${encodeURIComponent(page)}`); } function addParametersForCheckboxValues(name, selector) { for (const input of $(selector).get()) { if (input.checked) { qs.push(`${encodeURIComponent(name)}=${encodeURIComponent(input.value)}`); } } } //product type filters for (const type of productTypeModel.productTypes()) { if (type.checked() === true) { qs.push(`type=${encodeURIComponent(type.value)}`); } } addParametersForCheckboxValues("category", ".chkTopicAreasAcs"); addParametersForCheckboxValues("month", "#ulShowtimeMonthAndYear input[type=checkbox]"); addParametersForCheckboxValues("registrantType", ".chkRegistrantTypeAcs"); for (const creditType of creditTypeModel.creditTypes()) { if (creditType.checked() === true) { qs.push(`creditType=${encodeURIComponent(creditType.label)}`); } } for (const qsParam of searchViewModel.queryStringParams()) { qs.push(qsParam); } if ($('input[name=SelectedchkCertifications]').is(":checked")) { qs.push(`certifications`); } if ($('input[name=SelectedchkClosedCaptioning]').is(":checked")) { qs.push(`closedCaptioning`); } var orderBy = $("#selOrderBy").val() if (orderBy && orderBy !== "Default") { qs.push("orderBy=" + $("#selOrderBy").val()); } maintainNonSearchParameters(qs); const query = qs.length > 0 ? `?${qs.join("&")}` : ""; const newUrl = `${window.location.protocol}//${window.location.host}${window.location.pathname}${query}`; return newUrl; } function maintainNonSearchParameters(qs) { const searchParameters = ["q", "sp", "page", "type", "creditType", "category", "registrantType", "certifications", "closedCaptioning", "orderBy", "month", "speaker", "language"]; const oldUrlParams = new URLSearchParams(window.location.search); for (const [key, value] of oldUrlParams.entries()) { if (!searchParameters.includes(key)) { qs.push(`${key}=${value}`); } } } function updateUrl(newurl) { if (history.pushState) { if (location.href != newurl) { console.log(`Updating URL to ${newurl}`); window.history.pushState({ path: newurl }, "", newurl); } } } const filterBadges = ko.observableArray([]); function isFreeProductSearch(searchString) { if (!searchString) return false; var words = searchString.toLowerCase().split(/\s+/); return words[0] === "free"; } function checkForRedirectToSearch(oldUrl, newUrl) { if (oldUrl !== newUrl && (window.location.pathname === '/' || window.location.pathname.startsWith("/category"))) { const currentDomain = window.location.origin; // Includes the protocol (http/https) and domain const urlObject = new URL(newUrl); // Includes the query parameters const currentQueryParams = urlObject.search; const newPagePath = '/find'; // Remove UTM parameters in new URL const urlParams = new URLSearchParams(currentQueryParams); for (const [key] of urlParams) { if (key.toLowerCase().startsWith('utm_')) { // case-insensitive urlParams.delete(key); } } if (window.location.pathname.startsWith("/category")) { urlParams.append("q", $("#categoryName").val()); } const newQueryString = urlParams.toString() ? '?' + urlParams.toString() : ''; window.location.href = currentDomain + newPagePath + newQueryString; return true; } return false; } function fixUiInputsToFixBackButton() { document.querySelectorAll('input[type="checkbox"]').forEach(cb => { cb.checked = false; }); let { form, input } = window.getKeywordSearchElements(); $(input).val(""); } async function startAcs(options) { let { form, input } = window.getKeywordSearchElements(); var search = $(input).val(); var page = (options ? options.page : null) || 1; var skip = (page - 1) * acsTop; var skipScrollTop = (options ? options.skipScrollTop : null) || false; var scoringProfile = (options ? options.scoringProfile : "default") || "default"; var orderBy = $("#selOrderBy").val(); //Override scoring profile if parameter is declared on URL const scoringProfileParameter = getParameter('sp'); if (scoringProfileParameter) { scoringProfile = scoringProfileParameter; } if (isFreeProductSearch(search)) { scoringProfile = "free"; search = "free"; } const oldUrl = window.location.href.toString(); const newUrl = buildNewUrl({ page }); // Don't push history if we're on a page that is about to be redirected var redirect = checkForRedirectToSearch(oldUrl, newUrl) if (redirect) { return; } updateUrl(newUrl); // Check if we're on the category page with AIS enabled if (search === "" && window.location.pathname.startsWith("/category")) { var categoryName = $("#categoryName").val(); if (categoryName.length > 0) { search = categoryName; } } try { var requestBody = { "Search": search, "SearchFields": getSearchFields(), "Filters": getFilters(), "OrderBy": orderBy, "ScoringProfile": scoringProfile, "Top": acsTop, "Skip": skip }; const data = await makeRequest(requestBody); if (data.totalCount > 0 && data.offset >= data.totalCount) { //Requested offset greater than results, kick user back to page 1 options.page = 1; startAcs(options); return; } if (!skipScrollTop) { window.scrollTo({ top: 0, behavior: 'smooth' }); } testMessages([`Search mode: ${data.searchMode}`, `Source: ${data.fallback ? "Fallback (function app not available; filters not supported)" : "Function App"}`]); searchViewModel.refresh(data); parseAcsDataJson(data, page); productTypeModel.refresh(data); parseAcsProductCategoryFacetJson(data); parseAcsShowtimeMonthAndYearJson(data); parseAcsRegistrantTypeFacetJson(data); parseAcsOtherFiltersFacetJson(data); creditTypeModel.parseAcsCertCreditTypeFacetJson(data); filterBadges(getFilterBadges()); } catch (e) { console.log("ERROR: ", e); } } async function makeRequest(requestBody) { if (acsApiFunctionAppUrl) { try { return await $.ajax({ type: "POST", contentType: "application/json", url: acsApiFunctionAppUrl, data: JSON.stringify(requestBody), dataType: 'json', headers: acsApiFunctionAppKey ? { "Ocp-Apim-Subscription-Key": acsApiFunctionAppKey } : {} }); } catch (ex) { console.warn("Function app call #1 resulted in error", ex); } } if (location.search !== "") { console.log("Attempting function app call without any special parameters to see if function app is running"); try { const checkResult = await $.ajax({ type: "POST", contentType: "application/json", url: acsApiFunctionAppUrl, data: JSON.stringify({ "Search": "", "Filters": { TenantId: tenantId }, "Top": 1, "Skip": 0 }), dataType: 'json', headers: acsApiFunctionAppKey ? { "Ocp-Apim-Subscription-Key": acsApiFunctionAppKey } : {} }); if (checkResult.results.length > 0) { location.search = ""; return; } } catch (ex) { console.warn("Function app call #2 resulted in error", ex); } } console.log("Proceeding to fallback"); return await makeFallbackRequest({ search: requestBody.Search, filter: `tenantid eq '${tenantId}' and hiddenbyonlinecourse eq 0 and hiddenbydigitalseminar eq 0 and startdatetime gt ${new Date().toISOString()}`, queryType: "simple", searchMode: "all", count: true, top: requestBody.Top, skip: requestBody.Skip, searchFields: getSearchFields() }); } async function makeFallbackRequest(aiSearchRequestBody) { let directResponseBody = await $.ajax({ type: "POST", contentType: "application/json", url: acsApiUrl, data: JSON.stringify(aiSearchRequestBody), dataType: 'json', headers: { "api-key": acsApiKey } }); if (directResponseBody["@odata.count"] == 0) { aiSearchRequestBody = { ...aiSearchRequestBody, searchMode: "any" } directResponseBody = await $.ajax({ type: "POST", contentType: "application/json", url: acsApiUrl, data: JSON.stringify(aiSearchRequestBody), dataType: 'json', headers: { "api-key": acsApiKey } }); } return { totalCount: directResponseBody["@odata.count"], offset: aiSearchRequestBody.top, searchMode: aiSearchRequestBody.searchMode, results: directResponseBody.value, productTypes: [], categories: [], military: [], coordinator: [], liveEventDates: [], certCreditTypes: [], certifications: [], closedCaptioned: [], speakers: [], languages: [], fallback: true }; } function parseAcsProductCategoryFacetJson(data) { $(".productCategoryCount").text(""); $(".productCategoryLi").addClass("hidden"); let hasResults = false; categories.forEach(function (category) { let facetResponse = data.categories.find(function (facetResponse) { return facetResponse["value"] === category.value; }); if (!facetResponse) { return; } hasResults = true; $("#productCategoryCount" + category.className).text(facetResponse["count"]); $("#productCategory" + category.className).removeClass("hidden"); }); //hide completely if there are no filter options available if (hasResults) { $("#CategoriesFilterBox").removeClass("hidden"); } else { $("#CategoriesFilterBox").addClass("hidden"); } } function parseAcsRegistrantTypeFacetJson(data) { $(".registrantTypeCount").text(""); $(".registrantTypeLi").addClass("hidden"); let hasResults = false; registrantTypes.forEach(function (registrantType) { let facetResponse = data[registrantType.value].find(function (facetResponse) { return facetResponse["value"] === true; }); if (!facetResponse) { return; } hasResults = true; $("#registrantTypeCount" + registrantType.className).text(facetResponse["count"]); $("#registrantType" + registrantType.className).removeClass("hidden"); }); //hide completely if there are no filter options available if (hasResults) { $("#RegistrationTypesFilterBox").removeClass("hidden"); } else { $("#RegistrationTypesFilterBox").addClass("hidden"); } } function parseAcsCertifications(data) { let certificationsCount = data.certifications.reduce(function (sum, facet) { return facet.value === true ? sum + facet.count : sum }, 0); let hasCertifications = certificationsCount !== 0; if (hasCertifications) { $("#certificationCount").text(certificationsCount); $("#certificationFilterLi").removeClass("hidden"); } else { $("#certificationFilterLi").addClass("hidden"); } return hasCertifications; } function parseAcsClosedCaptioned(data) { let closedCaptionedCount = data.closedCaptioned.reduce(function (sum, facet) { return facet.value === true ? sum + facet.count : sum }, 0); let hasClosedCaptioned = closedCaptionedCount !== 0; if (hasClosedCaptioned) { $("#closedCaptioningCount").text(closedCaptionedCount); $("#closedCaptioningFilterLi").removeClass("hidden"); } else { $("#closedCaptioningFilterLi").addClass("hidden"); } return hasClosedCaptioned; } function parseAcsOtherFiltersFacetJson(data){ let hasClosedCaptioned = parseAcsClosedCaptioned(data); let hasCertifications = parseAcsCertifications(data); if (hasClosedCaptioned || hasCertifications) { $("#OtherFiltersFilterBox").removeClass("hidden"); } else { $("#OtherFiltersFilterBox").addClass("hidden"); } } function parseAcsShowtimeMonthAndYearJson(data) { let hasResults = false; $("#ulShowtimeMonthAndYear > li").each(function (index, li) { $(".badge", li).text(""); $(li).addClass("hidden"); let facetResponse = data.liveEventDates.find(function (facetResponse) { return facetResponse["value"].substr(0, 7) === $("input[type=checkbox]", li).val(); }); if (!facetResponse) { return; } hasResults = true; $(".badge", li).text(facetResponse["count"]); $(li).removeClass("hidden"); }); //hide completely if there are no filter options available if (hasResults) { $("#LiveEventDatesFilterBox").removeClass("hidden"); } else { $("#LiveEventDatesFilterBox").addClass("hidden"); } } const acsResultsLoaded = ko.observable(false); const acsCurrentPageItems = ko.observableArray(); const acsPages = ko.observableArray(); const acsTotal = ko.observable(0); const acsPaginationMessage = ko.pureComputed(() => { let first = null; for (const page of acsPages()) { if (page.active) { first = ((page.page - 1) * acsTop) + 1; break; } } if (first == null) { return null; } const last = first + acsCurrentPageItems().length - 1; const total = acsTotal(); const pluralSuffix = total == 1 ? "" : "s"; return `Showing ${first} to ${last} of ${total} result${pluralSuffix}`; }); function reapplyPagination(totalCount, page) { acsPages([]); let maxPage = Math.ceil(totalCount / acsTop); for (let delta = -9; delta <= 9; delta++) { const pageNumber = page + delta; if (pageNumber >= 1 && pageNumber <= maxPage) { const isActive = delta == 0; acsPages.push({ page: pageNumber, active: isActive, distance: Math.abs(delta), label: `${pageNumber}`, description: `Page ${pageNumber}`, load: () => { if (!isActive) { window.scrollTo({ top: 0, behavior: 'smooth' }); startAcs({ page: pageNumber, skipScrollTop: true }); } } }); } } while (acsPages().length > 9) { // Remove pages that are farthest from the current page to get it down to 9 pages displayed const toRemove = acsPages().slice().sort((a, b) => b.distance - a.distance)[0]; acsPages.remove(toRemove); } var containsFirstPage = ko.utils.arrayFirst(acsPages(), function (item) { return item.page === 1; }); var containsLastPage = ko.utils.arrayFirst(acsPages(), function (item) { return item.label === maxPage.toString(); }); if (page > 1 && !containsFirstPage) { acsPages.splice(0, 0, { active: false, label: `...` }); } if (page > 1) { acsPages.splice(0, 0, { page: page - 1, active: false, label: `«`, description: `Previous page`, load: () => { window.scrollTo({ top: 0, behavior: 'smooth' }); startAcs({ page: page - 1, skipScrollTop: true }); } }); acsPages.splice(0, 0, { page: 1, active: false, label: `««`, description: `First page`, load: () => { window.scrollTo({ top: 0, behavior: 'smooth' }); startAcs({ page: 1, skipScrollTop: true }); } }); } if (page < maxPage && !containsLastPage) { acsPages.push({ active: false, label: `...` }); } if (page < maxPage) { acsPages.push({ page: page + 1, active: false, label: `»`, description: `Next page`, load: () => { window.scrollTo({ top: 0, behavior: 'smooth' }); startAcs({ page: page + 1, skipScrollTop: true }); } }); acsPages.push({ page: maxPage, active: false, label: `»»`, description: `Last page`, load: () => { window.scrollTo({ top: 0, behavior: 'smooth' }); startAcs({ page: maxPage, skipScrollTop: true }); } }); } } function parseAcsDataJson(data, page) { acsTotal(data.totalCount); reapplyPagination(data.totalCount, page); const productTypes = []; $(".chkProductTypeAcs:checked").each(function () { productTypes.push($(this).val()); }); acsCurrentPageItems([]); data.results.forEach((element) => { modifyAcsResultData(element); acsCurrentPageItems.push(element); }); acsResultsLoaded(true); } async function acsAddToCart(pageItem, event) { event.preventDefault(); var addToCartChecksResponse = await $.ajax({ type: "GET", contentType: "application/json", url: `/items/addtocartchecks?productId=${pageItem.id}`, dataType: 'json', }); if (addToCartChecksResponse.showAddToCartModal) { openAddToCartPopupModal(`/items/addtocart?ProductId=${pageItem.id}&type=singlecolumn`); return; } var continuePurchase = true; var purchaseAlert = addToCartChecksResponse.purchaseAlert; if (purchaseAlert) { var purchaseAlertModal = new DialogModal({ title: purchaseAlert.title, body: purchaseAlert.message }); continuePurchase = await purchaseAlertModal.show(); } if (!continuePurchase) { return; } var addToCartResponse = await $.ajax({ type: "POST", url: `/items/addsingleproducttocart`, data: { productId: pageItem.id }, }); // Google Analytics Facebook Tracking if (addToCartResponse && addToCartResponse.addToCartItemDetails) { var addToCartData = JSON.parse(addToCartResponse.addToCartItemDetails); googleAnalytics.addToCartEvent(addToCartData); facebookMetaPixel.addToCartEvent(addToCartData); } if (addToCartResponse.isSendCustomerToCart) { window.location.href = "/shoppingcart"; } } function formatCatalogDate(datetime) { var date = new Date(datetime); // Assuming yourDateTimeString holds the ISO 8601 string var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; var day = date.getDate(); var monthIndex = date.getMonth(); var year = date.getFullYear(); return monthNames[monthIndex] + " " + day.toString().padStart(2, '0') + ", " + year; } function formatBookCopyrightDate(datetime) { var date = new Date(datetime); // Assuming yourDateTimeString holds the ISO 8601 string return date.getFullYear(); } function getVenueString(venuename, city, state) { const locationString = [city, state].filter(str => str).join(", "); return [venuename, locationString].filter(str => str).join(" - "); } function getDateString(publishDate, durationinminutes, timezoneid) { const startDate = new Date(publishDate); const endDate = new Date(startDate.valueOf() + 60000 * durationinminutes); timezoneid = timezoneid || window.timeZoneId; const timeZoneMap = { // US and Canada "Atlantic Standard Time": "America/Halifax", "SA Western Standard Time": "America/Puerto_Rico", "Eastern Standard Time": "America/New_York", "US Eastern Standard Time": "America/Indiana/Indianapolis", "Central Standard Time": "America/Chicago", "Canada Central Standard Time": "America/Regina", "Mountain Standard Time": "America/Denver", "US Mountain Standard Time": "America/Phoenix", "Pacific Standard Time": "America/Los_Angeles", "Alaskan Standard Time": "America/Anchorage", "Hawaiian Standard Time": "Pacific/Honolulu", // Australia "E. Australia Standard Time": "Australia/Brisbane", "AUS Eastern Standard Time": "Australia/Sydney", "Cen. Australia Standard Time": "Australia/Adelaide", "AUS Central Standard Time": "Australia/Darwin", "W. Australia Standard Time": "Australia/Perth", // UK and Europe "GMT Standard Time": "Europe/London", "W. Europe Standard Time": "Europe/Berlin", }; const timezone = timezoneid in timeZoneMap ? timeZoneMap[timezoneid] : "UTC"; const dateFormat = new Intl.DateTimeFormat([], { weekday: "short", year: "numeric", month: "short", day: "numeric", timeZone: timezone }); const timeFormat = new Intl.DateTimeFormat([], { hour: "numeric", minute: "2-digit", timeZone: timezone }); const endTimeFormat = new Intl.DateTimeFormat([], { hour: "numeric", minute: "2-digit", timeZoneName: "short", timeZone: timezone }); const startDateStr = dateFormat.format(startDate); const endDateStr = dateFormat.format(endDate); return [ startDateStr, "-", timeFormat.format(startDate), "to", ...startDateStr === endDateStr ? [] : [endDateStr, "-"], endTimeFormat.format(endDate) ].join(" "); } function wrapForLoggedInUser(urlString) { try { if (urlString.indexOf("/sales/") >= 0 && uniqueMembershipPricingParameterValue) { const url = new URL(urlString, location.href); url.searchParams.append("mbrprc", uniqueMembershipPricingParameterValue); return url.href; } } catch (e) { console.warn(e); } return urlString; } function modifyAcsResultData(value) { value.producturl = wrapForLoggedInUser(value.producturl); value.publishDateDisplay = formatCatalogDate(value.publishDate); value.widgetmessageDisplay = formatWidgetMessageDisplay(value.widgetmessage); value.priceDisplay = formatPriceDisplay(value.calculatedprice, value.price, value.discountname, value.producttype); value.copyrightYearBookDisplay = formatBookCopyrightDate(value.publishDate); const productTypeDisplayDiv = $("
").text(value.producttype); value.alternatemediatypesDisplay = formatAlternateMediaTypeDisplay(productTypeDisplayDiv.html(), value.siblingproducts); for (const speaker of value.speakerinformation) { speaker.fullnameandcredential = [speaker.fullname, speaker.credential] .filter(str => str) .join(", "); } value.displayAllSpeakers = ko.observable(value.speakerinformation.length <= 3); value.speakerinformationDisplay = ko.pureComputed(() => { return value.displayAllSpeakers() ? value.speakerinformation : value.speakerinformation.slice(0, 3); }); value.venueDisplay = getVenueString(value.venuename, value.city, value.state); let shouldDisplayDates = false; const currentDate = new Date(); switch (value.producttype) { case "In-Person Seminar": case "Live Webcast": case "Live Webinar": shouldDisplayDates = true; break; case "Online Course": if ((value.productcode || "").substring(0, 3) != 'CRS') { if (value.showtimemonthandyear && new Date(value.publishDate) >= currentDate) { shouldDisplayDates = true; } } break; } value.shouldDisplayDates = shouldDisplayDates; value.dateDisplay = getDateString(value.publishDate, value.seminarduration, value.timezoneid); value.alternatedatesDisplay = value.alternatedates.map(alternate => { return { ...alternate, venueDisplay: getVenueString(alternate.venuename, alternate.city, alternate.state), dateDisplay: getDateString(alternate.showtime, alternate.seminarduration, alternate.timezoneid) }; }); let certCreditLinkMessage = "Click here for more CE information"; if (value.certcredittypes.length === 1 && value.certcredittypes[0] === "CE Information Coming Soon") { certCreditLinkMessage = "CE Information Coming Soon"; } value.certCreditLinkDisplay = certCreditLinkMessage; } function formatWidgetMessageDisplay(widgetmessage) { return widgetmessage ? "
" + widgetmessage + "
" : ""; } function formatPriceDisplay(calculatedprice, price, discountname, producttype) { calculatedprice = calculatedprice.toFixed(2); price = price.toFixed(2); let priceDescription = "Standard"; if (producttype === "In-Person Seminar") { priceDescription = "Single Registration"; } if (price === calculatedprice) { priceDisplay = "" + acsCurrencySymbol + calculatedprice + " - " + priceDescription + ""; } else { let saleSuffix = ""; if (discountname) { const div = document.createElement("div"); div.innerText = discountname; saleSuffix = " - " + div.innerHTML; } priceDisplay = "" + acsCurrencySymbol + calculatedprice + saleSuffix + " " + priceDescription + " - " + acsCurrencySymbol + price + ""; } return priceDisplay; } function formatAlternateMediaTypeDisplay(producttype, siblingproductsjson) { const siblingproducts = JSON.parse(siblingproductsjson || "[]"); const alternatemediatypes = []; for (const product of siblingproducts) { const existingProducts = alternatemediatypes .filter(existing => existing.ProductType === product.ProductType); if (existingProducts.length > 0) { existingProducts[0].Count++; } else { alternatemediatypes.push({ ...product, Count: 1 }); } } let alternatemediatypesDisplay = producttype; alternatemediatypes.forEach((element, index) => { if (index === 0) { alternatemediatypesDisplay += " - Also Available: "; } else { alternatemediatypesDisplay += " | "; } const url = wrapForLoggedInUser(element.ProductUrl || `/item/${element.ProductId}`); alternatemediatypesDisplay += "" + element.ProductType + ""; if (element.Count > 1) { alternatemediatypesDisplay += " " + element.Count + ""; } }); return alternatemediatypesDisplay; } ;