$(document).ready(function(){ var $nonModalTabs = $('div.tabs:not(.list-search-tabs)'); haas.tabs.tabSetup($nonModalTabs); }); (function () { 'use strict'; var haas = window.haas || {}; haas.tabs = { tabSetup: function ($tabs) { $tabs.each(function(){ var $thisTab = $(this); var $tabGroup = $thisTab.find('.tabgroup'); var $tabHeader = $thisTab.find('ul.tabs'); var $tabLinks = $tabHeader.find('li a'); var $firstTabLink = $thisTab.find('ul.tabs li:first-of-type a'); var $tabContainers = $thisTab.find('div.tab'); var $firstTabContainer = $tabGroup.find('div.tab:first-of-type'); console.log('TAB LINKS!', $tabLinks); var submenuurl = window.location.pathname.split('/'); // breaks url into parts between / var urlslice = window.location.hash.substr(1); // delivers everything after # var tabreference; if (urlslice.indexOf(".") >= 0) { tabreference = window.location.hash.substr(1, (urlslice.indexOf('.'))); } else if (urlslice.indexOf("0") >= 0) { tabreference = window.location.hash.substr(1, (urlslice.indexOf('0'))); } else { tabreference = window.location.hash.substr(1); } $tabLinks.each(function(index, $tab){ $($tab).css('background-color', $($tab).attr('data-bgcolor')); $($tab).css('color', $($tab).attr('data-color')); }); // hide all tabcontainers, initially $tabContainers.hide(); // if there's a tab reference in the url, select that tab var tabcheck = tabreference.substr(0, 3); if (tabcheck === "tab") { var $this = $('ul.tabs a').filter('[href*="' + tabreference + '"]'), target = $this.attr('href'); $this.addClass('active'); $(target).addClass('activetab').show(); } else { // otherwise, just select the first tab $firstTabLink.addClass('active'); $firstTabContainer.addClass('activetab').show(); } //counts tabs and adds class to create css centering controls var tabnum = $tabLinks.length; if (tabnum === 1) { $tabHeader.addClass('one'); $thisTab.find('.tabs .button').addClass('one'); } if (tabnum === 2) { $tabHeader.addClass('two'); $thisTab.find('.tabs .button').addClass('two'); } if (tabnum === 3) { $tabHeader.addClass('three'); $thisTab.find('.tabs .button').addClass('three'); } if (tabnum === 4) { $tabHeader.addClass('four'); $thisTab.find('.tabs .button').addClass('four'); } if (tabnum === 5) { $tabHeader.addClass('five'); $thisTab.find('.tabs .button').addClass('five'); } $tabLinks.click(function (e) { e.preventDefault(); var $thisLink = $(this); var target = $thisLink.attr('href').replace('#',''); $tabLinks.removeClass('active'); $tabContainers.removeClass('activetab').hide(); $thisLink.addClass('active'); $tabContainers.each(function(){ // targeted this way so it can be used with tabs inside modals var $this = $(this); if($this.attr('id') === target){ $this.addClass('activetab').show(); } }); var pageurl = window.location.pathname; var linkref = $thisLink.attr('href'); if (linkref.indexOf(pageurl) > -1) { location.reload(); } }); }); } } })(); $(function() { const initGrids = () => { $('.grid .row').each(function(ndx, row) { var maxHeight = 0; $(row).children().each(function(ndx, val) { // find max height for all section headers in grid var $sectionHeader = $(val).find('.sectionHeader h2'); var currentHeight = $sectionHeader.height(); if (currentHeight) { maxHeight = currentHeight > maxHeight ? currentHeight : maxHeight; } }); // set margins for section headers so the height is equal $(row).children().each(function(ndx, val) { var $sectionHeaderParent = $($(val).find('.sectionHeader')[0]); var $sectionHeaderChild = $($(val).find('.sectionHeader')[1]); var extraMargin = maxHeight - $(val).find('.sectionHeader h2').height(); $sectionHeaderParent.addClass('grid-sh-parent-edit'); $sectionHeaderChild.addClass('grid-sh-child-edit'); $(val).find('.sectionHeader h2').css('margin-top', extraMargin); }); }); // set non-responsive grid lengths Array.from(document.querySelectorAll('.grid')).forEach(gridComponent => { let isResponsive = gridComponent.querySelector('.gridpad').dataset.nresponsive; if (isResponsive && isResponsive === 'true') { let columns = Array.from(gridComponent.querySelectorAll('.row > div')); columns.forEach(column => { // if 5 equal columns, class name is just "col" if (column.className === 'col-md-5') { column.style.width = '20%'; } else { // for other split types, take the number from the column class and adjust width accordingly let columnSplit = column.className.slice(column.className.lastIndexOf('-') + 1); column.style.width = ((100 / 12) * columnSplit) + '%'; } }); } }); Array.from(document.querySelectorAll('.grid')).forEach(gridComponent => { let gridLink = gridComponent.querySelector('.gridpad').dataset.gridLink; if (gridLink && gridLink.length) { gridLink = gridLink.includes('.html') ? gridLink : gridLink+'.html'; gridComponent.style.cursor = 'pointer'; gridComponent.onclick = () => window.location = gridLink; } }); } initGrids(); if (window.ContextHub) { window.ContextHub.eventing.on(ContextHub.SegmentEngine.PageInteraction.Teaser.prototype.info.loadEvent, function() { initGrids(); }); } }); //video thumb component - javascript// $(window).bind("load", function() { var tallest = 0; $(".video_thumb-wrapper").each(function(){ if($(this).height() > tallest) tallest = $(this).height(); }); $(".video_thumb-wrapper").height(tallest); }); $(function() { // Prepend an overlay div for popup videos ( not in markup to accomodate Mobile App ) const videoOverlayElement = document.createElement('div'); videoOverlayElement.classList.add('popup-video-overlay'); document.querySelectorAll('.video-popup-container .videoWrapper').forEach(elem => { elem.prepend(videoOverlayElement.cloneNode()); }); $('.video-popup-container').on('click', function(e) { var $dataContainer = $(e.target).is('.video-popup-container') ? $(e.target) : $(e.target).parents('.video-popup-container'); var videoSrc = $dataContainer.attr('data-vid-src'); if (videoSrc.includes('youtube')) videoSrc = videoSrc + '&autoplay=1' haas.components.Modal.open('
'); }); // For videos with thumbnail overrides, onclick remove thumbnail & autoplay video Array.from(document.querySelectorAll('.thumbnail-override-container')).forEach(thumbnail => { thumbnail.onclick = (e) => { const parentVideo = e.currentTarget.parentElement.querySelector('iframe'); e.currentTarget.remove(); parentVideo.src = parentVideo.src + '&autoplay=1'; } }); if (!OnetrustActiveGroups || !OnetrustActiveGroups.includes('C0004')) { const acceptCookiesVideoTemplate = _.template(document.querySelector('#acceptCookiesVideoTemplate').innerHTML); Array.from(document.querySelectorAll('.video_small')).forEach(videoElem => { // Wistia videos are not currently blocked, so don't add message to wistia videos if (videoElem.querySelector('.wistia-default')) return; const acceptCookieTextTl = videoElem.querySelector('.video-container') ? videoElem.querySelector('.video-container').dataset.acceptCookieTextTl : videoElem.querySelector('.video-popup-container') ? videoElem.querySelector('.video-popup-container').dataset.acceptCookieTextTl : 'Please accept targeting cookies to view videos'; const acceptCookiesButtonTl = videoElem.querySelector('.video-container') ? videoElem.querySelector('.video-container').dataset.acceptCookiesBtnTl : videoElem.querySelector('.video-popup-container') ? videoElem.querySelector('.video-popup-container').dataset.acceptCookiesBtnTl : 'Cookie Settings'; videoElem.querySelector('.videoWrapper').innerHTML = videoElem.querySelector('.videoWrapper').innerHTML + acceptCookiesVideoTemplate({ acceptCookieText: acceptCookieTextTl, cookieButtonText: acceptCookiesButtonTl }); videoElem.querySelector('.vid-ot-btn-img').onclick = () => videoElem.querySelector('#ot-sdk-btn').click(); }); // TO-DO: Use addEventListenerFunction to see if user has accepted cookies & remove if they did window.addEventListener('OneTrustGroupsUpdated', (e) => { let newPermissions = e.detail; if (newPermissions.includes('C0004')) { Array.from(document.querySelectorAll('.accept-cookies-video-container')).forEach(elem => { elem.remove(); }); } }); } }); // now relying on flexbox to set height of video containers $(function(){ var self = this; var hiddenFiltersList = $('#video-search-data-container').attr('data-hidden-filters') ? $('#video-search-data-container').attr('data-hidden-filters').split(',') : []; var preselectedFiltersList = $('#video-search-data-container').attr('data-preselected-filters') ? $('#video-search-data-container').attr('data-preselected-filters').split(',') : []; var displayFiltersList = $('#video-search-data-container').attr('data-display-filters') ? $('#video-search-data-container').attr('data-display-filters').split(',') : []; var initFancybox = function($parent) { $parent.find('.fancybox-media').fancybox({ type : "iframe", maxWidth : 960, maxHeight : 720, fitToView : false, width : '70%', height : '70%', autoSize : false, closeClick : false, openEffect : 'none', closeEffect : 'none', afterShow : function() { var vidId = haas.region.props.region === 'CN' ? '#' + this.href.slice(this.href.indexOf('/iframe/') + 8, this.href.indexOf('?videoFoam')) : '#' + this.href.slice(this.href.indexOf('/embed/') + 7, this.href.indexOf('?rel')); var $vidContainer = $('#videoResultsColumn ' + vidId).find('a'); if ($vidContainer.data('description')) { $('.fancybox-outer').append("

" + $vidContainer.data('description') + "

"); } } }); }; var addHyphenatedTerms = function(list) { var newList = list.slice(); list.forEach(function(keyword) { if (keyword.indexOf('-') > -1) { newList.push.apply(newList, keyword.split('-')); } }); return newList; }; var openSearch = function(videoResults, searchTerms) { var searchResults = []; // For all search results, make sure that ALL of them exist in either the video's title, description, or popularTopics tags searchResults = videoResults.filter(function(video){ return searchTerms.every(function(term) { var popularTopics = ''; var vidTitle = video.title.replace(/[,.]/g, ' ').toLowerCase().split(' '); var vidDesc = ''; video.tags.forEach(function(tag) { if (tag.name === 'videoDescription') { vidDesc = tag.content.replace(/[,.]/g, ' ').toLowerCase().split(' '); } if (tag.name === 'popularTopics') { popularTopics = tag.content.toLowerCase().split(','); } }); // Add dehypenated versions of terms, in addition to the hyphenated ones vidTitle = vidTitle.length ? addHyphenatedTerms(vidTitle) : vidTitle; vidDesc = vidDesc.length ? addHyphenatedTerms(vidDesc) : vidDesc; popularTopics = popularTopics.length ? addHyphenatedTerms(popularTopics) : popularTopics; return vidTitle.includes(term.toLowerCase()) || vidDesc.includes(term.toLowerCase()) || popularTopics.includes(term.toLowerCase()); }); }); return searchResults; }; var buildQueryString = function(mode) { var baseURI = '/bin/haascnc/search.json?type=diy&q='; var queryKeyword = ''; var queryFilters = ''; var contentType = '[search.contentType: "Videos"]'; // static content type for videos var lang = '&setLang=' + $('html').attr('lang'); // dynamic language get var offset = '&offset=0'; // TO-DO: add pagination if needed var count = '&count=2000'; var videoTagBase = '[search.videoTags:+'; var hasVideoTags = false; var videoTagSelector = ".videoSearch input[type='checkbox']:not(.hidden-filter)"; if (mode && mode === 'mobile') { videoTagSelector = "#videoSearchFormMobile input[type='checkbox']:not(.hidden-filter)"; } // only pull videos that are selectable $(videoTagSelector).each(function(ndx, val) { if (hasVideoTags) { var tagValue = val.value.replace(/\s/g, '+'); videoTagBase = videoTagBase + '+||+' + '"' + tagValue + '"'; } else { var tagValue = val.value.replace(/\s/g, '+'); videoTagBase = videoTagBase + '"'+ tagValue + '"'; hasVideoTags = true; } }); $(videoTagSelector).each(function(ndx, val) { // filters are strict now too if (val.checked && !$(val).hasClass('preselected')) { if (hasVideoTags) { var tagValue = val.value.replace(/\s/g, '+'); videoTagBase = videoTagBase + '+&&+' + '"' + tagValue + '"'; } else { var tagValue = val.value.replace(/\s/g, '+'); videoTagBase = videoTagBase + '"'+ tagValue + '"'; hasVideoTags = true; } } }); preselectedFiltersList.forEach(function(filter) { try { var val = $('input[name="' + filter + '"]')[0]; // Preselected Filters are Strict if (hasVideoTags) { var tagValue = val.value.replace(/\s/g, '+'); videoTagBase = videoTagBase + '+&&+' + '"' + tagValue + '"'; } else { var tagValue = val.value.replace(/\s/g, '+'); videoTagBase = videoTagBase + '"'+ tagValue + '"'; hasVideoTags = true; } } catch (e) { return; } }); if (hasVideoTags) { videoTagBase = videoTagBase + ']+&&+'; queryFilters = videoTagBase; } haas.LOGGER.debug('videoSearch Query String: ', baseURI + queryFilters + contentType + lang + offset + count); return baseURI + encodeURIComponent(queryFilters + contentType) + lang + offset + count; }; var filterVideos = function(allVideos) { // skip the video if it doesnt have videoTags (parent pages) // and is not an alarm video (alarm vids might not have videoTag) return allVideos.filter(function(video) { return video.tags.some(function(tag) { return tag.name === 'videoTags' || tag.name === 'alarms'; }); }); }; var getPageOffset = function() { var $CURRENT_PAGE = $('.video-results-pagination-list a.video-results-current-page'); var currentPage = parseInt($CURRENT_PAGE.html()); // If pagination is rendered, then return the offset, if not rendered, init to 0 return currentPage ? ((currentPage - 1) * 9) : 0; }; var renderVideoResults = function(searchResult, region) { var $videoContainer = $('#videoResultsContainer'); var videoTemplate = _.template($('#videoSearchResults').html()); var paginationTemplate = _.template($('#videoResultsPagination').html()); haas.LOGGER.debug('videoSearch Results: ', searchResult); if(searchResult.length > 0) { var videoData = ''; _.each(searchResult, function (video, index) { if (region === 'CN' && index >= 9) { return; } var title = video.title; var id = ''; var cnid = ''; var tags = ''; var description = ''; var tagTitle = ''; _.each(video.tags, function (tag, index) { if (tag.name === 'videoID') { id = tag.content; } else if (tag.name === 'videoCNID') { cnid = tag.content; } else if (tag.name === 'videoTags') { tags = tag.content; } else if (tag.name === 'videoDescription') { description = tag.content; } else if (tag.name === 'videoTitle') { tagTitle = tag.content; } }); videoData += videoTemplate({ 'title': tagTitle.length ? tagTitle : title, 'id': id, 'cnid': cnid, 'tags': tags, 'description': description, 'region': region }); }); videoData += paginationTemplate(); $videoContainer.html(videoData); bindPaginationClick(); initFancybox($('.video-search-container')); } else { var noResultsTemplate = _.template($('#noSearchResults').html()); haas.LOGGER.warn("No videos found."); $videoContainer.html(noResultsTemplate({ 'errLine1': $('#videoResultsColumn').data('errorline1'), 'errLine2': $('#videoResultsColumn').data('errorline2') })); } }; var initAllVideos = function() { var queryString = buildQueryString(); haas.LOGGER.debug('Initializing All Videos: ', queryString); haas.search.fetchResults(queryString).then(function(payload) { if(payload.success === true) { var allPages = payload.result.webPages; allPages = filterVideos(allPages); if (haas.region.props.region === 'CN') { allPages = allPages.slice(0, 9); $('.video-results-pagination-container').css('display', 'block'); } renderVideoResults(allPages, haas.region.props.region); } else { haas.LOGGER.warn(payload.error.message); } }); }; var updateSearchTerms = function() { var searchTermTemplate = _.template($('#searchTermTemplate').html()); if ($('#videoSearchFormMobile').is(':visible')) { $('#videoSearchFormMobile #search-terms').append(searchTermTemplate({ 'searchTerm': $('#videoSearchFormMobile #video-search-query').val().trim() })); // Clear the search field after appending $('#videoSearchFormMobile #video-search-query').val(''); } else { $('.videoSearch #search-terms').append(searchTermTemplate({ 'searchTerm': $('.videoSearch #video-search-query').val().trim() })); // Clear the search field after appending $('.videoSearch #video-search-query').val(''); } // Add event handler for removing the terms each time terms are updated $('.filter-button-container i').on('click', function(e) { $(e.target).parents('.filter-button-container').remove(); handleQueryChange(); }); }; var handleQueryChange = function(e) { var queryString = ''; var mode = ''; var isSearchPopulated; var SUBMIT_BTN_SELECTOR = '#video-search-submit-btn'; var OPEN_SEARCH_SELECTOR = '#video-search-query'; var FILTER_CHECKBOX_SELECTOR = ".filter-container input[type='checkbox']"; if ($('#videoSearchFormMobile').is(':visible')) { mode = 'mobile'; } // before handling change, check if any search fields are populated isSearchPopulated = (mode === 'mobile' && $('#videoSearchFormMobile #video-search-query').val().trim()) || (!mode && $('.videoSearch #video-search-query').val().trim()); // if the event was a button click or an enter key, append search keyword if (e && $(e.target).is(SUBMIT_BTN_SELECTOR)) { if (isSearchPopulated) { updateSearchTerms(); } else { return; } } if (e && $(e.target).is(OPEN_SEARCH_SELECTOR)) { if (e.keyCode === 13 && isSearchPopulated) { updateSearchTerms(); } else { return; } } if (mode === 'mobile') { queryString = buildQueryString(mode); } else { queryString = buildQueryString(); } haas.LOGGER.debug('videoSearch URI: ', queryString); haas.search.fetchResults(queryString).then(function(payload) { if(payload.success === true) { var searchTerms = $('.videoSearch #search-terms .filter-button-container .filter-button').toArray().map(function(btn) { return $(btn).data('value'); }) var openSearchResults = openSearch(payload.result.webPages, searchTerms); openSearchResults = filterVideos(openSearchResults); if (haas.region.props.region === 'CN') { var pageOffset = getPageOffset(); if (e && ($(e.target).is(SUBMIT_BTN_SELECTOR) || $(e.target).is(OPEN_SEARCH_SELECTOR) || $(e.target).is(FILTER_CHECKBOX_SELECTOR))) { $('a.video-results-current-page').html('1'); pageOffset = 0; } openSearchResults = openSearchResults.slice(pageOffset, pageOffset + 9); } renderVideoResults(openSearchResults, haas.region.props.region); } else { haas.LOGGER.warn(payload.error.message); } }); }; var handleNavbarClick = function(e) { var elementValue = $(e.target).data('value'); var videoFilterSelector = ".videoSearch .filter-container input[value='" + elementValue + "']"; $('.videoSearch .filter-container input').prop('checked', false); $(videoFilterSelector).click(); }; var handleClearFilters = function(){ if ($('#videoSearchFormMobile').is(':visible')) { $('#videoSearchFormMobile .filter-container input:not(".preselected")').prop('checked', false); $('#videoSearchFormMobile #search-terms').empty(); } else { $('.videoSearch .filter-container input:not(".preselected")').prop('checked', false); $('.videoSearch #search-terms').empty(); } handleQueryChange(); }; var handlePaginationClick = function(e) { var $VIDEO_PAGE_ACTIVE_ITEM = $('a.video-results-current-page'); var $VIDEO_RESULTS = $('#videoResultsContainer a'); var btnClick = $(e.target).html(); var currentPage = parseInt($VIDEO_PAGE_ACTIVE_ITEM.html()); var prevPage = '<'; var nextPage = '>'; if (btnClick === prevPage && currentPage !== 1) { $VIDEO_PAGE_ACTIVE_ITEM.html(currentPage - 1); } if (btnClick === nextPage && $VIDEO_RESULTS.length === 9) { $VIDEO_PAGE_ACTIVE_ITEM.html(currentPage + 1); } handleQueryChange(); }; var mobileFormShow = function(e) { $('#videoSearchFormMobile').css('display', 'block'); }; var mobileFormHide = function(e) { if ($(e.target).is('#videoSearchFormMobile') || $(e.target).hasClass('modal-close-btn')) { $('#videoSearchFormMobile').css('display', 'none'); } }; var mobileSearchFormInit = function() { // initialize a modal for mobile var searchForm = $("
").append($('.search-filter-column').html()); $(searchForm).insertBefore('.haas-modal'); $("#videoSearchFormMobile input[type='checkbox']").on('click', handleQueryChange); $('#videoSearchFormMobile #video-search-submit-btn').on('click', handleQueryChange); $('#videoSearchFormMobile').on('click', mobileFormHide); $('#videoSearchFormMobile .reset-filters-btn').on('click', handleClearFilters); }; var bindPaginationClick = function() { $('.video-results-pagination-list li a:not(.video-results-current-page)').off('click').on('click', handlePaginationClick); }; var bindEvents = function() { $(".videoSearch input.preselected").off('click'); $(".videoSearch input[type='checkbox']").on('click', handleQueryChange); $('.videoSearch #video-search-submit-btn').on('click', handleQueryChange); $('#video-search-query').on('keypress', handleQueryChange); $('.search-filter-btn-mobile').on('click', mobileFormShow); $('#videoSearchNav li').on('click', handleNavbarClick); $('.videoSearch .reset-filters-btn').on('click', handleClearFilters); }; var videoSearchInit = function () { hiddenFiltersList.forEach(function(filter) { $('input[name="' + filter + '"]').addClass('hidden-filter'); }); // if hide all is checked if ($('#video-search-data-container').attr('data-hide-all-filters') === 'true') { $('.filter-container input').addClass('hidden-filter'); } displayFiltersList.forEach(function(filter) { $('input[name="' + filter + '"]').removeClass('hidden-filter'); }); preselectedFiltersList.forEach(function(filter) { $('input[name="' + filter + '"]').prop('checked', true).prop('disabled', true).addClass('preselected'); }); mobileSearchFormInit(); initAllVideos(); bindEvents(); }; // only run js if videosearch component is on page // initialize after price group promise finishes, so we can use region freely. if ($('.videoSearch').length) { $.when(haas.region.priceGroupPromise).then(function() { videoSearchInit(); }); } }); /* global $, haas */ (function () { 'use strict'; var VIDEOWRAPPER = '.video-wrapper'; $(document).ready(function() { /*var region = haas.cookies.getCookie('pldata.2'); if (!region) { $.when(haas.region.priceGroupPromise).then(function() { region = haas.cookies.getCookie('pldata.2'); }); }*/ $(VIDEOWRAPPER).each(function(){ var $thisList = $(this); var $videoContainer = $thisList.find('.videoList-container'); if($thisList.hasClass('non-legacy')){ var SEARCHURI = $thisList.attr('data-search-uri'); haas.search.fetchResults(SEARCHURI).then(function(data){ if(data.success === true){ var videoTemplate = _.template($('#videoSearchList').html()); var videos = data.result.webPages; if(videos.length > 0) { var videoData = ''; _.each(videos, function (video, index) { var title = video.title; var path = haas.search.insertAlarmSelectorInHTMLURI(video.path); var id = ''; var cnid = ''; var tags = ''; var tagTitle = ''; _.each(video.tags, function (tag, index) { if (tag.name === 'videoID') { id = tag.content; } else if (tag.name === 'videoCNID') { cnid = tag.content; } else if (tag.name === 'videoTags') { tags = tag.content; } else if (tag.name === 'videoTitle') { tagTitle = tag.content; } }); videoData += videoTemplate({ 'title': tagTitle.length ? tagTitle : title, 'path': path, 'id': id, 'cnid': cnid, 'tags': tags }); }); $videoContainer.html(videoData); $thisList.removeClass('hidden'); initFancybox($thisList); } else { haas.LOGGER.warn("No videos found."); } } else{ haas.LOGGER.warn(data.error.message); } }); } else { initFancybox($thisList); } }); }); function initFancybox($parent) { $parent.find('.fancybox-media').fancybox({ type : "iframe", maxWidth : 960, maxHeight : 720, fitToView : false, width : '70%', height : '70%', autoSize : false, closeClick : false, openEffect : 'none', closeEffect : 'none' }); } })(); (function(){ })(); function replaceContentInContainer(target, source) { document.getElementById(target).innerHTML = document.getElementById(source).innerHTML; } $(window).bind("load", function() { var tallest = 0; $(".title-wrapper").each(function(){ if($(this).height() > tallest) tallest = $(this).height(); }); $(".title-wrapper").height(tallest); }); $(document).ready(function() { $(".expand-button").click(function() { $.fancybox.open([ {href : getOriginalRendition() } ]); }); }); function getOriginalRendition() { var curStr = document.getElementById("text-image-image").src; var cutoff = curStr.indexOf("/_jcr_content"); if (cutoff !== -1) { return curStr.substring(0, cutoff); } else { return curStr; } } /*global $ */ $(function() { // Callable init function, in case text is in modal haas.utils.initTextComponents = function() { 'use strict'; $('.text-data-container').each(function(ndx, elem) { var fontFamily = $(elem).attr('data-fontFamily'); var h1FontSize = parseInt($(elem).attr('data-h1FontSize')); var h2FontSize = parseInt($(elem).attr('data-h2FontSize')); var h3FontSize = parseInt($(elem).attr('data-h3FontSize')); var pFontSize = parseInt($(elem).attr('data-pFontSize')); var h1MobileFontSize = parseInt($(elem).attr('data-h1MobileFontSize')); var h2MobileFontSize = parseInt($(elem).attr('data-h2MobileFontSize')); var h3MobileFontSize = parseInt($(elem).attr('data-h3MobileFontSize')); var pMobileFontSize = parseInt($(elem).attr('data-pMobileFontSize')); var hasOverrides = fontFamily || h1FontSize || h2FontSize || h3FontSize || pFontSize || h1MobileFontSize || h2MobileFontSize || h3MobileFontSize || pMobileFontSize; // if override is checked, add inline styling to all text elements in body if (hasOverrides) { var textBody = $(elem).parent().find('.text-body'); var customClass = 'customText-' + ndx; var h1Selector = $(textBody).find('h1'); var h2Selector = $(textBody).find('h2'); var h3Selector = $(textBody).find('h3'); var pSelector = $(textBody).find('p'); $(textBody).addClass(customClass); if (fontFamily) { $(h1Selector) .add($(h2Selector)) .add($(h3Selector)) .add($(pSelector)) .css('font-family', fontFamily); } if(screen.width > 800) { if (h1FontSize) { $(h1Selector).css('font-size', h1FontSize + 'px'); } if (h2FontSize) { $(h2Selector).css('font-size', h2FontSize + 'px'); } if (h3FontSize) { $(h3Selector).css('font-size', h3FontSize + 'px'); } if (pFontSize) { $(pSelector).css('font-size', pFontSize + 'px'); } } else { if (h1MobileFontSize) { $(h1Selector).css('font-size', h1MobileFontSize + 'px'); } if (h2MobileFontSize) { $(h2Selector).css('font-size', h2MobileFontSize + 'px'); } if (h3MobileFontSize) { $(h3Selector).css('font-size', h3MobileFontSize + 'px'); } if (pMobileFontSize) { $(pSelector).css('font-size', pMobileFontSize + 'px'); } } } }); } //call for text that lives on page haas.utils.initTextComponents(); if (window.ContextHub) { window.ContextHub.eventing.on(ContextHub.SegmentEngine.PageInteraction.Teaser.prototype.info.loadEvent, function() { haas.utils.initTextComponents(); }); } }); (function() { haas.components.StandardFeatures = haas.Component.create({ initialize: function() { }, render: function() { this.$element.find('.disclaimer').hide(); this.cleanData(); this.renderAvailableOptions(); if (screen.width < 800) { this.bindEventsMobile(); } else { this.bindEvents(); } this.setColors(); }, cleanData: function() { let chararray = this.$element.find(".char h2").toArray(); $(chararray).each(function(index, element) { $(element).text($(element).text().replace('_', ' ')); }); //script to remove "Char Name:" from the beginning of the Char Short Text let optarray = this.$element.find("#standard-features .char ul li").toArray(); $(optarray).each(function(index, element) { let lilist = $(element).html(); let optionlist = lilist.slice(lilist.indexOf(":") + 7); $(element).html(optionlist); }); }, bindEventsMobile: function() { var self = this; self.$element.find('#standard-features').click(function() { self.$element.find('.char-group').slideToggle(); self.$element.find('#standard-features > i').toggleClass('fa-chevron-circle-right fa-chevron-circle-down'); if (screen.width < 800) { if ($(this).hasClass('openFeature')) { window.scrollTo({ top: (this.$element.offset().top - 200), behavior: "smooth", }); $(this).toggleClass('openFeature'); } else { self.$element.find('.openFeature').trigger("click"); self.$element.find('#standard-features').addClass('openFeature'); } } }); self.$element.find('#available-features').click(function() { self.$element.find('.avail-char-group').slideToggle(); self.$element.find('.disclaimer').slideToggle(); self.$element.find('#available-features>i').toggleClass('fa-chevron-circle-right fa-chevron-circle-down'); if (screen.width < 800) { if ($(this).hasClass('openFeature')) { window.scrollTo({ top: (this.$element.offset().top - 200), behavior: "smooth", }); $(this).toggleClass('openFeature'); } else { self.$element.find('.openFeature').trigger("click"); self.$element.find('#available-features').addClass('openFeature'); } } }); self.$element.find('#automation-features').click(function() { self.$element.find('.auto-char-group').slideToggle(); self.$element.find('#automation-features>i').toggleClass('fa-chevron-circle-right fa-chevron-circle-down'); if (screen.width < 800) { if ($(this).hasClass('openFeature')) { window.scrollTo({ top: (this.$element.offset().top - 200), behavior: "smooth", }); $(this).toggleClass('openFeature'); } else { self.$element.find('.openFeature').trigger("click"); self.$element.find('#automation-features').addClass('openFeature'); } } }); }, bindEvents: function() { let self = this; self.$element.find('#standard-features').click(function() { self.$element.find('.char-group').slideToggle(); self.$element.find('#standard-features > i').toggleClass('fa-chevron-circle-right fa-chevron-circle-down'); }); self.$element.find('#available-features').click(function() { self.$element.find('.avail-char-group').slideToggle(); self.$element.find('.disclaimer').slideToggle(); self.$element.find('#available-features>i').toggleClass('fa-chevron-circle-right fa-chevron-circle-down'); }); self.$element.find('#automation-features').click(function() { self.$element.find('.auto-char-group').slideToggle(); self.$element.find('#automation-features>i').toggleClass('fa-chevron-circle-right fa-chevron-circle-down'); }); }, setColors: function() { let self = this; self.$element.find('#standard-features').css('background-color', self.$element.find('.standard-options').attr('data-standardBgColor')); self.$element.find('#standard-features').css('color', self.$element.find('.standard-options').attr('data-standardColor')); self.$element.find('#available-features').css('background-color', self.$element.find('.available-options').attr('data-availableBgColor')); self.$element.find('#available-features').css('color', self.$element.find('.available-options').attr('data-availableColor')); }, renderAvailableOptions: function() { let Modal = haas.components.Modal; let self = this; let lang = $('html').attr('lang'); let $availableOptionsElement = this.$element.find('.available-options'); let $automationOptionsElement = this.$element.find('.automation-options'); let machineModel = $('.model-view > .row').attr('data-sap-id'); machineModel = machineModel.replaceAll('/', '%252F'); let optionsEndpoint = '/bin/haascnc/model/detail.lang=' + lang + '.model=' + machineModel + '.json'; $.get({ url: optionsEndpoint, cache: false }).then(function(optionsResult) { optionsResult.categories.forEach(function(catEl){ catEl.options.forEach(function(opt) { opt.availRegions = ''; opt.regions.forEach(function(region){ opt.availRegions = opt.availRegions + region.name + '|'; }); opt.availRegions = opt.availRegions.slice(0, -1); opt.description_long = opt.description_long.replaceAll("'", ""); opt.json = JSON.stringify(opt).replaceAll("\"", "'"); opt.id = opt.id.replaceAll('.', '-'); opt.id = opt.id.replaceAll(' ', '-'); opt.id = opt.id.replaceAll('/', '-'); opt.id = opt.id.replaceAll('"', ''); }); let availableOptionsContent = self.templates.availableOptionsTemplate({ catName: catEl.name, catOptions: catEl.options, catRegions: catEl.availRegions }); $availableOptionsElement.append(availableOptionsContent); }); optionsResult.standard_categories.forEach(function(standCat){ standCat.options.forEach(function(stndOpt){ stndOpt.id = stndOpt.id.replaceAll('.', '-'); stndOpt.id = stndOpt.id.replaceAll(' ', '-'); stndOpt.id = stndOpt.id.replaceAll('/', '-'); stndOpt.id = stndOpt.id.replaceAll('"', ''); let currentRegion = haas.region.props.region; let currentCurrency = haas.region.props.currency; let optionRegionData = stndOpt.regions.find(region => region.name === currentRegion); // If the option doesnt have pricing in region or is standard in user's region, then remove from available options if (!optionRegionData || !optionRegionData.prices) { $('#' + stndOpt.id).remove(); return; } let optionRegionPriceData = optionRegionData.prices.find(price => price.currency === currentCurrency); if (!optionRegionPriceData || optionRegionPriceData.is_standard) { if (self.$element.find(".char-group > ul > li[data-name*='" + stndOpt.name + "']")) { console.log('Standard Features Component: hid a region-data item', stndOpt.id); $('#' + stndOpt.id).remove(); } } }); }); self.$element.find('.avail-region-data').click(function() { let option = JSON.parse($(this).attr('data-option').replaceAll("'", "\"")); Modal.open(self.templates.optionDetailsTemplate({option: option})); }); self.$element.find('.region-data').click(function() { Modal.open(self.templates.standardOptionDetailsTemplate({ option : { name: $(this).data('name'), image: { path: $(this).data('img') }, product_detail_page: $(this).data('path'), description_long: $(this).data('description') } })); }); $.when(haas.region.priceGroupPromise).then(function(priceGroup) { self.$element.find('.avail-region-data').each(function() { let $regionData = $(this); let delimiter = $regionData.data('delimiter'); let regions = $regionData.data('regions') ? $regionData.data('regions').split(delimiter) : null; if (!_.includes(regions, priceGroup.region)) { console.log('Standard Features Component: hid a region-data item', $regionData[0].innerHTML); $regionData.remove(); } }); self.$element.find('.avail-char-group').each(function(o) { if (!$(this).find('.avail-region-data').length) { $(this).remove(); } }); }) let automation = optionsResult.associations.filter(autoElement => autoElement.model.type_string === 'barfeeder'); automation.forEach(function(automationEl){ automationEl.model.availRegions = '' automationEl.model.regions.forEach(function(aRegion) { automationEl.model.availRegions = automationEl.model.availRegions + aRegion.name + '|'; }); automationEl.model.json = JSON.stringify(automationEl.model).replaceAll("\"", "'"); let automationOptionsContent = self.templates.automationOptionsTemplate({ automationOption: automationEl.model, automationRegions: automationEl.model.availRegions }); $automationOptionsElement.append(automationOptionsContent); }); if (automation.length) { self.$element.find('.automation-options').css('visibility', 'visible'); } self.$element.find('.auto-region-data').click(function() { let option = JSON.parse($(this).attr('data-option').replaceAll("'", "\"")); Modal.open(self.templates.automationDetailsTemplate({option: option})); }); if (self.elementNode.querySelector('.automation-options > .auto-char-group')) { self.$element.find('.automation-options').show(); self.$element.find('#automation-features').show(); } }); } }); })(); $(document).ready(function() { var vw_to_px; $('.iframe-container').each(function(){ vw_to_px = window.innerHeight * ($(this).attr('data-height') * .01); $(this).height(vw_to_px); }); // Remove the Social Media Instagram section from homepage in China regions // Notes: If the layout here ever changes, it could cause problems, could look into alternative solutions. $.when(haas.region.priceGroupPromise).then(function(priceGroup) { if (priceGroup.region === 'CN') { // this will remove the instagram iframe, and the two components before it (header and reference components) var igContainer = $("iframe[src='https://data.haascnc.com/test/social2.html']").parents('.simple_iframe'); igContainer.prev().prev().remove(); igContainer.prev().remove(); igContainer.remove(); } }); }); /* global haas, _, $, priceGroupPromise */ //similarMachine js// (function () { haas.components.SimilarMachines = haas.Component.create({ tallestsimilarmachinecard: 0, elementObserver: null, observerConfig: { childList: true, subtree: true }, initialize: function () { let self = this; self.setCardHeights(); // must wait for PGP to complete before getting region data, otherwise prices can be blank $.when(haas.region.priceGroupPromise).then(function (price_group) { // Only show CNY prices for V Models if in CN region if (price_group.region === 'CN') { if (price_group.currency === 'USD') self.vModelHideUSD(); $(window).on('haas-currency-changed', function(event, currency) { if (currency === 'USD') self.vModelHideUSD(); if (currency === 'CNY') self.vModelShowCNY(); }); } }); }, setCardHeights: function() { let self = this; const similarMachinesElement = self.elementNode; const horizontalSelector = '.horizontal-details:not(.accordionContainer .horizontal-details):not(.tab .horizontal-details)'; if (Array.from(self.elementNode.querySelectorAll('.details')).length) { self.elementObserver = new MutationObserver((mutationList, observer) => { mutationList.forEach(mutation => { switch(mutation.type) { case 'childList': Array.from(self.elementNode.querySelectorAll('.details')).forEach(detailCard => { let currentHeight = detailCard.getBoundingClientRect().height; self.tallestsimilarmachinecard = self.tallestsimilarmachinecard > currentHeight ? tallestsimilarmachinecard : currentHeight; }); Array.from(self.elementNode.querySelectorAll('.details')).forEach(detailCard => { detailCard.style.height = self.tallestsimilarmachinecard; }); break; default: break; } }); }); self.elementObserver.observe(similarMachinesElement, self.observerConfig); } else if (Array.from(self.elementNode.querySelectorAll(horizontalSelector)).length) { self.elementObserver = new MutationObserver((mutationList, observer) => { mutationList.forEach(mutation => { switch(mutation.type) { case 'childList': Array.from(self.elementNode.querySelectorAll(horizontalSelector)).forEach(detailCard => { let currentHeight = detailCard.getBoundingClientRect().height; self.tallestsimilarmachinecard = self.tallestsimilarmachinecard > currentHeight ? tallestsimilarmachinecard : currentHeight; }); Array.from(self.elementNode.querySelectorAll(horizontalSelector)).forEach(detailCard => { detailCard.style.height = self.tallestsimilarmachinecard; }); break; default: break; } }); }); self.elementObserver.observe(similarMachinesElement, self.observerConfig); } }, vModelShowCNY: function() { $('.similar-models a').each(function(ndx, element) { if (_.endsWith($(element).attr('href'), '-v.html')) { var price_container = $(element).find('.pricecontainer'); var default_price = $(price_container).find('.current-price-container'); var promotion_price = $(price_container).find('.promotion-container'); promotion_price.removeClass('hidden'); default_price.find('.price_prefix').removeClass('hidden'); default_price.find('.current_price').removeClass('hidden'); default_price.find('.v-model-cny-label').addClass('hidden'); } }); }, vModelHideUSD: function() { $('.similar-models a').each(function(ndx, element) { if (_.endsWith($(element).attr('href'), '-v.html')) { var price_container = $(element).find('.pricecontainer'); var default_price = $(price_container).find('.current-price-container'); var promotion_price = $(price_container).find('.promotion-container'); promotion_price.addClass('hidden'); default_price.find('.price_prefix').addClass('hidden'); default_price.find('.current_price').addClass('hidden'); default_price.find('.v-model-cny-label').removeClass('hidden'); } }); } }); })(); (function() { haas.components.ServiceTagPage = haas.Component.create({ serviceTags: [], serviceTagTitles: [], keywords: [], tabDataJSON: null, searchEndpoint: haas.constants.api.search, diySearchBaseQuery: '', queryBase: '[search.contentType: "Service Update" || "How-To Procedure" || "Videos" || "Troubleshooting Guide" || "Instruction Manual" || "Reference"]', queryBaseVideosOnly: '[search.contentType: "Videos"]', videoOnlyMode: false, videoPopupMode: false, singlePageContentMode: false, initialize: function() { let self = this; let serviceTagData = self.elementNode.querySelector('#service-tag-page-content').dataset.serviceTags; let serviceTagTitleData = self.elementNode.querySelector('#service-tag-page-content').dataset.tagTitles; let keywordData = self.elementNode.querySelector('#service-tag-page-content').dataset.keywords; self.serviceTags = (serviceTagData && serviceTagData.length) ? serviceTagData.split(',') : []; self.serviceTagTitles = (serviceTagTitleData && serviceTagTitleData.length) ? serviceTagTitleData.split(',') : []; self.keywords = (keywordData && keywordData.length) ? keywordData.split(',') : []; self.tabDataJSON = JSON.parse(self.elementNode.querySelector('#service-tag-page-content').dataset.tabDataJson); self.videoOnlyMode = self.elementNode.querySelector('#data-container').dataset.videosOnlyMode ? true : false; self.videoPopupMode = self.elementNode.querySelector('#data-container').dataset.videoPopupMode ? true : false; self.singlePageContentMode = self.elementNode.querySelector('#data-container').dataset.singlePageContentMode ? true : false; console.log(self.tabDataJSON); if (self.singlePageContentMode) { self.elementNode.parentElement.classList.add('single-page-content-mode'); } else { self.elementNode.parentElement.classList.add('nav-mode'); self.highlightActivePage(); } if (self.videoOnlyMode) { self.populateContent(); } else { self.populateTabs(); self.populateContent(); } }, clearActiveTab: function() { Array.from(this.elementNode.querySelectorAll('button')).forEach(button => { button.classList.remove('active'); }); }, clearTopicContent: function() { this.elementNode.querySelector('#tag-page-container').innerHTML = ''; }, highlightActivePage: function() { let self = this; let serviceTagLinkContainer = self.elementNode.querySelector('.service-tag-link-container'); let linkElements = Array.from(serviceTagLinkContainer.querySelectorAll('li')); linkElements.forEach(listElem => { let anchorElem = listElem.querySelector('a'); let currentPath = window.location.pathname.slice(window.location.pathname.lastIndexOf('/')); if (anchorElem.href.includes(currentPath)) anchorElem.style.color = '#cb2c31'; }); }, videoClickHandler: function(e) { let self = this; haas.components.Modal.open(self.templates.videoModal({ videoId: e.currentTarget.dataset.videoId, wistiaId: e.currentTarget.dataset.videoCnId })); }, tabClickHandler: function(e) { let self = this; self.clearActiveTab(); self.clearTopicContent(); e.target.classList.add('active'); self.populateContent(); }, headerClickHandler: function(e) { let accordionContentElement = e.currentTarget.parentElement.querySelector('.stp-accordion-content'); let iconElement = e.currentTarget.querySelector('i'); if (iconElement.classList.contains('fa-plus-square')) { iconElement.classList.remove('fa-plus-square'); iconElement.classList.add('fa-minus-square'); } else { iconElement.classList.remove('fa-minus-square'); iconElement.classList.add('fa-plus-square'); } $(accordionContentElement).slideToggle(); }, createTab: function(innerTextVal, queryData, tabNdx) { let self = this; let tabElement = document.createElement('button'); tabElement.innerText = innerTextVal; tabElement.id = innerTextVal.replaceAll(' ', '-'); tabElement.dataset.tabQueryData = JSON.stringify(queryData); tabElement.onclick = self.tabClickHandler.bind(self); if (tabNdx === 0) tabElement.classList.add('active'); return tabElement; }, populateTabs: function() { let self = this; let tabsMade = 0; for (let tabKey in self.tabDataJSON) { let tabElement = self.createTab(tabKey, self.tabDataJSON[tabKey], tabsMade); self.elementNode.querySelector('#tag-tab-container').append(tabElement); tabsMade++; } }, populateContent: function() { let self = this; let queries = []; if (self.videoOnlyMode) { queries = self.buildQueriesVideosOnly(self.tabDataJSON, 0, 800); } else { let activeTopicQueryData = JSON.parse(self.elementNode.querySelector('#tag-tab-container button.active').dataset.tabQueryData); queries = self.buildQueries(activeTopicQueryData, 0, 800); } // Add loading image while query is fetched self.elementNode.querySelector('#tag-page-container').innerHTML = haas.constants.loadingTmpl; Promise.all(queries.map(query => fetch(query))) .then(results => Promise.all(results.map(result => result.json()))) .then(payloads => { console.log(payloads); let pages = payloads.reduce((prev, current) => prev.concat(current.result.webPages), []); let tsGuidePages = [], videoPages = [], htProcedurePages = [], serviceUpdatePages = [], instrManPages = [], referencePages = []; pages.forEach(page => { if (page.tags.some(tag => tag.content === 'Service Update')) serviceUpdatePages.push(page); if (page.tags.some(tag => tag.content === 'Troubleshooting Guide')) tsGuidePages.push(page); if (page.tags.some(tag => tag.content === 'Videos')) videoPages.push(page); if (page.tags.some(tag => tag.content === 'How-To Procedure')) htProcedurePages.push(page); if (page.tags.some(tag => tag.content === 'Instruction Manual')) instrManPages.push(page); if (page.tags.some(tag => tag.content === 'Reference')) referencePages.push(page); }); // Clear out loading image self.elementNode.querySelector('#tag-page-container').innerHTML = ''; if (serviceUpdatePages.length) self.elementNode.querySelector('#tag-page-container').append(self.buildContentHTML('service-update', serviceUpdatePages, 'fa-file-text-o')); if (tsGuidePages.length) self.elementNode.querySelector('#tag-page-container').append(self.buildContentHTML('troubleshooting-guide', tsGuidePages, 'fa-file-text-o')); if (videoPages.length) self.elementNode.querySelector('#tag-page-container').append(self.buildContentHTML('videos', videoPages, 'fa-film')); if (htProcedurePages.length) self.elementNode.querySelector('#tag-page-container').append(self.buildContentHTML('how-to-procedure', htProcedurePages, 'fa-file-text-o')); if (referencePages.length) self.elementNode.querySelector('#tag-page-container').append(self.buildContentHTML('reference', referencePages, 'fa-file-text-o')); if (instrManPages.length) self.elementNode.querySelector('#tag-page-container').append(self.buildContentHTML('instruction-manual', instrManPages, 'fa-file-text-o')); }); }, buildContentHTML: function(documentType, pages, faClass) { let self = this; let contentContainer = document.createElement('div'); contentContainer.classList.add('service-tag-page-accordion'); contentContainer.id = documentType+'-accordion'; let header = document.createElement('h2'); header.innerHTML = '' + ''+pages[0].tags.find(tag => tag.name === 'localizedContentType').content + ''; contentContainer.append(header); let accordionContent = document.createElement('div'); accordionContent.classList.add('stp-accordion-content'); pages.sort((a, b) => (a.title < b.title) ? -1 : 1).forEach(page => { // TO-DO: create a different flow for videos, need to load videos. See Video List Component let pageContentElement = document.createElement('div'); let pageLinkElement = document.createElement('a'); let faIcon = document.createElement('i'); let textSpan = document.createElement('span'); pageLinkElement.classList.add('navigation_link'); pageLinkElement.href = page.path; textSpan = page.title; faIcon.classList.add('fa'); faIcon.classList.add(faClass); faIcon.ariaHidden = true; pageLinkElement.append(faIcon); pageLinkElement.append(textSpan); if (documentType === 'videos' && self.videoPopupMode) { let videoID = page.tags.find(tag => tag.name === 'videoID'); let videoCNID = page.tags.find(tag => tag.name === 'videoCNID'); if (videoID && videoID.content) pageLinkElement.dataset.videoId = videoID.content; if (videoCNID && videoCNID.content) pageLinkElement.dataset.videoCnId = videoCNID.content; pageLinkElement.style.cursor = 'pointer'; pageLinkElement.removeAttribute('href'); pageLinkElement.onclick = self.videoClickHandler.bind(self); } pageContentElement.append(pageLinkElement); accordionContent.append(pageContentElement); }); contentContainer.append(accordionContent); header.onclick = self.headerClickHandler; return contentContainer; }, buildPopularTopicsString: function(tabQueryData) { let queryStrings = []; for (let key in tabQueryData) { if (key === 'keywords') continue; console.log(tabQueryData[key].queryString); queryStrings.push(tabQueryData[key].queryString); } console.log(queryStrings); if (queryStrings.length === 1) return '[search.popularTopics: ' + queryStrings[0].replace(/[\(\)]*/g,'') + ']'; return '[search.popularTopics: ' + queryStrings.join(' || ') + ']'; }, buildKeywordQuery: function(tabQueryData) { // TO-DO: Finish Keywords let keywords = tabQueryData['keywords']; let keywordQueryString = ''; if (keywords && keywords.length) { for (let keyword of keywords.split(',')) { keywordQueryString = '"' + keyword + '"' + ' or ' + keywordQueryString; } } keywordQueryString = keywordQueryString.slice(0, keywordQueryString.lastIndexOf(' or ')) console.log(keywords, keywordQueryString); return keywordQueryString; }, buildQueries: function(tabQueryData, offset, count) { let self = this; let queryType = 'type=diy'; let queryLang = 'setLang=' + document.documentElement.lang; let queryOffset = 'offset=' + offset; let queryCount = 'count=' + count; // Keyword and Popular Topics have to be queried separately let keywordQuery = ''; let popularTopicTagQuery = ''; let builtQueries = []; // Build and add keyword query if keywords available if (tabQueryData['keywords'] && tabQueryData['keywords'].length) { keywordQuery = self.buildKeywordQuery(tabQueryData) + ' && ' + self.queryBase; console.log('Keyword Query : ' + keywordQuery) keywordQuery = 'q=' + encodeURIComponent(keywordQuery); keywordQuery = self.searchEndpoint + '?' + queryType + '&' + keywordQuery + '&' + queryLang + '&' + queryOffset + '&' + queryCount; builtQueries.push(keywordQuery); } // Build and add popular topics tag query if tags available if (Object.keys(tabQueryData).some(key => key !== 'keywords')) { popularTopicTagQuery = self.queryBase + ' && ' + self.buildPopularTopicsString(tabQueryData); console.log('Popular Topics Tag Query : ' + popularTopicTagQuery) popularTopicTagQuery = 'q=' + encodeURIComponent(popularTopicTagQuery); popularTopicTagQuery = self.searchEndpoint + '?' + queryType + '&' + popularTopicTagQuery + '&' + queryLang + '&' + queryOffset + '&' + queryCount; builtQueries.push(popularTopicTagQuery); } return builtQueries; }, buildQueriesVideosOnly: function(totalQueryData, offset, count) { let self = this; let queryType = 'type=diy'; let queryLang = 'setLang=' + document.documentElement.lang; let queryOffset = 'offset=' + offset; let queryCount = 'count=' + count; // Keyword and Popular Topics have to be queried separately let keywordQuery = ''; let popularTopicTagQuery = ''; let builtQueries = []; // Build and add keyword query if keywords available for (let key in totalQueryData) { let tabQueryData = totalQueryData[key]; if (tabQueryData['keywords'] && tabQueryData['keywords'].length) { keywordQuery = self.buildKeywordQuery(tabQueryData) + ' && ' + self.queryBaseVideosOnly; console.log('Keyword Query : ' + keywordQuery) keywordQuery = 'q=' + encodeURIComponent(keywordQuery); keywordQuery = self.searchEndpoint + '?' + queryType + '&' + keywordQuery + '&' + queryLang + '&' + queryOffset + '&' + queryCount; builtQueries.push(keywordQuery); } // Build and add popular topics tag query if tags available if (Object.keys(tabQueryData).some(key => key !== 'keywords')) { popularTopicTagQuery = self.queryBaseVideosOnly + ' && ' + self.buildPopularTopicsString(tabQueryData); console.log('Popular Topics Tag Query : ' + popularTopicTagQuery) popularTopicTagQuery = 'q=' + encodeURIComponent(popularTopicTagQuery); popularTopicTagQuery = self.searchEndpoint + '?' + queryType + '&' + popularTopicTagQuery + '&' + queryLang + '&' + queryOffset + '&' + queryCount; builtQueries.push(popularTopicTagQuery); } } return builtQueries; } }); })(); $(document).ready(function() { $(".sectionHeader").each(function() { var $this = $(this); var $tag = $this.find(".recently-updated-tag"); // if not authored to show the tag, then no need to compare timestamps if ($tag.length === 0) { return; } var compareDate = new Date(); // now compareDate.setDate(compareDate.getDate() - $tag.data("recentness-duration")); // 30 days ago if (parseInt($("meta[name='search.lastUpdatedTimestamp']").attr("content")) > compareDate.getTime()) { $tag.removeClass("hidden"); } }) }); $(function() { var search_box_container = $('.search_box_top_wrapper'); var search_nav_item = $('.nav-item-search, .nav-item-search *'); var currencyToggle = $('.currencyToggle'); var currencyUSD = $('.currency-usd'); var currencyCNY = $('.currency-cny'); var body = $('body'); var bindSearchBarEvents = function() { // if under the haas-tooling path, disable bing search, just scroll to top if (window.location.pathname.includes('haas-tooling')) { document.querySelector('.nav-item-search').classList.add('bing-disabled'); search_nav_item.on('click', function(e){ window.scrollTo(0, 0); }); } else { // Toggle Search Bar Show with Search Nav Item Click search_nav_item.on('click', function(e){ search_box_container.slideToggle(); e.stopPropagation(); }); // If clicked outside search box, hide search box. body.mouseup(function(e) { if (!search_box_container.is(e.target) && !search_nav_item.is(e.target) && search_box_container.has(e.target).length === 0) { search_box_container.slideUp(); } }); } }; var renderCNCurrencyToggle = function() { var currency = haas.cookies.getCookie('pldata1.2'); currencyToggle.css('display', 'flex'); if (currency === 'USD') { currencyUSD.addClass('active-currency'); body.addClass('active-currency-usd'); // Check if the price container is empty before adding asterisk $('.current_price').each(function(){ if ($(this).html() !== ' ') { $(this).addClass('usd-asterisk'); } }); } else if (currency === 'CNY') { currencyCNY.addClass('active-currency'); body.addClass('active-currency-cny'); // Remove asterisk class $('.current_price').each(function(){ $(this).removeClass('usd-asterisk'); }); } // if not on the Compare Machines Page and on a V Model Page / Build and Price if (window.location.pathname.indexOf('/compare-machines.') < 0 && (_.endsWith(window.location.pathname, '-v.html') || _.endsWith(window.location.pathname, '-V.html') || _.endsWith(window.location.pathname, '/v-series.html'))) { $('.currency-cny').addClass('active-currency'); $('.currency-usd').removeClass('active-currency'); $('.currency-usd').css('display', 'none'); $('body').removeClass('active-currency-usd'); $('body').addClass('active-currency-cny'); if (currency === 'USD') { haas.region.setCurrentCurrency('CNY', false, true); } // this case will only occur on product pages if ($('.current_price').length) { $($('.current_price')[0]).addClass('usd-asterisk'); $('.vModel-warning-message').css('display', 'block'); } } else { haas.region.setCurrentCurrency('USD', false, true); } }; var bindCNCurrencyToggleEvents = function() { // event handler for USD Icon click currencyUSD.click(function(e) { var currency = haas.cookies.getCookie('pldata1.2'); if (!currencyUSD.hasClass('active-currency')) { // switch to USD currencyCNY.removeClass('active-currency'); currencyUSD.addClass('active-currency'); body.removeClass('active-currency-cny'); body.addClass('active-currency-usd'); haas.region.setCurrentCurrency('USD', false, true); $('.current_price').each(function(){ // Check if the price container is empty before adding asterisk if ($(this).html() !== ' ') { $(this).addClass('usd-asterisk'); } }); } }); // event handler for CNY Icon click currencyCNY.click(function(e) { var currency = haas.cookies.getCookie('pldata1.2'); if (!currencyCNY.hasClass('active-currency')) { // switch to CNY currencyUSD.removeClass('active-currency'); currencyCNY.addClass('active-currency'); body.removeClass('active-currency-usd'); body.addClass('active-currency-cny'); haas.region.setCurrentCurrency('CNY', false, true); // Remove asterisk class $('.current_price').each(function(){ $(this).removeClass('usd-asterisk'); }); } }); }; var initSecondaryNav = function() { bindSearchBarEvents(); // Wait for price group promise before rendering location-specific features $.when(haas.region.priceGroupPromise).then(function(payload){ var region = payload.region; var country = payload.country; var hfoid = payload.hfoid; // Add currency toggle buttons to header if (region === 'CN') { renderCNCurrencyToggle(); bindCNCurrencyToggleEvents(); } }); if (localStorage.showEcommerce) { if (localStorage.guid && localStorage.needCartUpdate && localStorage.needCartUpdate === "true") { haas.LOGGER.debug('UPDATING CART: ', localStorage.guid); $.when(haas.ecommUtils.updateCartQuantity(localStorage.guid)) .then(function() { haas.ecommUtils.renderCartQuantity(); }) .fail(function(payload) { var error = payload.responseJSON.errors[0]; var eatCookiesEndpoint = haas.constants.api.eatcookies(localStorage.storedSiteLang); haas.LOGGER.debug(error); if (error.type === 'CartError' && error.reason === 'notFound') { localStorage.guid = ''; haas.cookies.setCookie('ecommparts-cart', ''); localStorage.cartQuantity = 0; haas.ecommUtils.renderCartQuantity(); } return $.get(eatCookiesEndpoint).then(function(payload) { return payload; }); }); } else { if(localStorage.access_token) { $.when(haas.ecommUtils.updateCartQuantity(localStorage.access_token)).then(function(){ haas.ecommUtils.renderCartQuantity(); }); } haas.ecommUtils.renderCartQuantity(); } haas.ecommUtils.bindMiniCartOnClick(); } }; /** * Init Secondary Navigation */ initSecondaryNav(); }); (function () { haas.components.RotaryFit = haas.Component.create({ pdpType: null, element: null, initialize: function() { this.pdpType = document.querySelector('.model-title').dataset.type; this.hideIrrelevantColumns(); if (this.pdpType === 'rotary') this.hideRegionSpecificModels(); this.bindAltFitClickEvent(); }, bindAltFitClickEvent: function() { let _self = this; _self.elementNode.querySelectorAll('.alt-fit-td').forEach((element) => { element.onclick = _self.altFitClickHandler.bind(_self); }); }, altFitClickHandler: function(e) { let Modal = haas.components.Modal; let altFitMsg = document.createElement('p'); let altFitTxt = this.elementNode.dataset.cautionMsg; altFitMsg.innerHTML = altFitTxt; altFitMsg.classList.add('alt-fit-warning'); Modal.open(altFitMsg.outerHTML); }, hideRegionSpecificModels: function() { let _self = this; let machineTds = _self.elementNode.querySelectorAll('.model-for-rotary'); machineTds.forEach((elem) => { if (elem.innerHTML.endsWith('-V') || elem.innerHTML.endsWith('-SE') || elem.innerHTML.endsWith('-I') || elem.innerHTML.endsWith('-EU') || elem.innerHTML.endsWith('-UK')) { elem.parentElement.remove(); } }) }, hideIrrelevantColumns: function() { switch (this.pdpType) { case 'mill': this.elementNode.querySelectorAll('.rotary').forEach((element) => { element.style.display = 'none'; }); break; case 'lathe': this.elementNode.querySelectorAll('.rotary').forEach((element) => { element.style.display = 'none'; }); break; case 'rotary': this.elementNode.querySelectorAll('.haas-machine').forEach((element) => { element.style.display = 'none'; }); break; default: break; } } }) })(); (function() { /* * Redirect Component Usage * 1. If there’s a url query param present and it matches the key (region, hfo, keyword, etc.) in the one of the redirect-components on the page, then continue to step 2; * 2. If the user doesn't have that cookie already set, then redirect based on url parameter, else continue to step 3; * 3. Check if the user has cookies accepted, if so, continue to step 4, else redirect to default link; * 4. Iterate through redirect components in page order, and check relevant cookies for a key match, if found redirect based on key, else redirect to default link; */ var REDIRECT_DATA_SELECTOR = '.redirect-data-container'; // If not on redirect page, skip if (!$(REDIRECT_DATA_SELECTOR).length) { return; } // Dont perform redirects in authoring (NOTE: This will enable redirects in ONLY published sites: aemdev, aemqas, live site) var defaultRedirectLink = $($(REDIRECT_DATA_SELECTOR)[0]).data('defaultlink'); if (!wcmmode.edit) { var redirectLink = ''; // If there is a cookie, prioritize its key & value // NOTE: Expects only one url query param, not multiple if (window.location.search && (window.location.search.indexOf('hfo=') !== -1 || window.location.search.indexOf('region=') !== -1 || window.location.search.indexOf('keyword=') !== -1)) { // remove the '?' from the url params and split params by '&&' var queryParams = window.location.search.slice(1).split('&&'); // get the param and split the key and value by '=' var redirectParam = _.filter(queryParams, function(param) { return param.indexOf('hfo=') !== -1 || param.indexOf('region=') !== -1 || param.indexOf('keyword=') !== -1; })[0].split('='); var paramType = redirectParam[0]; var paramKey = redirectParam[1]; var cookieExists = false; haas.LOGGER.debug('url redirect param:', redirectParam); // Check if user has relevant cookie already set if (paramType === 'hfo') { cookieExists = !haas.region.props.hfoid ? false : true; } if (paramType === 'region') { cookieExists = !haas.region.props.region ? false : true; } // get the redirect object with the correct key & make sure it is present on page // also make sure relevant cookie isnt already set var matchedRedirectObject = $(REDIRECT_DATA_SELECTOR + "[data-key='" + paramType + "']"); if (matchedRedirectObject.length && !cookieExists) { matchedRedirectObject = matchedRedirectObject[0]; if ($(matchedRedirectObject).data('redirects').hasOwnProperty(paramKey)) { var redirectURL = $(matchedRedirectObject).data('redirects')[paramKey]; redirectLink = redirectURL; } } } // If redirect Link updated via url param, redirect and skip cookie check. // Else if cookies not accepted, cannot check cookies, so redirect to default link // Else, iterate through redirect components in page order and try to match user's cookies with a key if (redirectLink.length) { window.location = redirectLink; } else { $.when(haas.region.priceGroupPromise).then(function(price_group){ if (!haas.region.props.cookiesAccepted) { haas.LOGGER.debug('cookies not accepted, reached default redirect'); window.location = defaultRedirectLink; } else { var user_hfo = price_group.hfoid; var user_region = price_group.region; $(REDIRECT_DATA_SELECTOR).each(function(ndx, redirect_element) { var redirectKey = $(redirect_element).data('key'); var redirectList = $(redirect_element).data('redirects'); haas.LOGGER.debug('defaultKey', redirectKey); haas.LOGGER.debug('redirectLinkList', redirectList); // If key is hfo or region, check the redirect list for user's cookie // if found, set redirect link and exit 'each' loop, else continue loop if (redirectKey === 'hfo') { if (redirectList.hasOwnProperty(user_hfo)) { haas.LOGGER.debug('matched hfo: ', user_hfo); redirectLink = redirectList[user_hfo]; return false; } } if (redirectKey === 'region') { if (redirectList.hasOwnProperty(user_region)) { haas.LOGGER.debug('matched region: ', user_region); redirectLink = redirectList[user_region]; return false; } } }); // if redirect link is set, redirect // else if url param and user's cookie fail to match all keys, redirect to default link if (redirectLink.length) { haas.LOGGER.debug('REDIRECTING TO ', redirectLink); window.location = redirectLink; } else { haas.LOGGER.debug('reached default redirect'); window.location = defaultRedirectLink; } } }); } } })(); $(document).ready(function(){ $('.classification-banner').each(function(){ var bannerLength = $(this).find('tr:first td').length; $('.classification-banner').addClass('banner-' + bannerLength); }); }); $(function(){ // Event Handler for Haas Delivered Price Modal Button $.when(haas.region.priceGroupPromise).then(function(payload) { // Populate pdp promo message with model's current message if ($('body').hasClass('product-page')) { let titleFontSize = document.querySelector(".model-title").dataset.titlefontsize; if (titleFontSize) document.querySelector(".model-title").style.fontSize = titleFontSize + "px"; let sapId = $('.model-view > .row').attr('data-sap-id'); haas.services.modelDetail.getModel(sapId).then(function(machine) { let siteLang = $('html').attr('lang'); let promotion = null; let isOrderPromo = false; let productHeroElem = document.querySelector('.productHero'); if (machine.hasPromotion()) { promotion = machine.getMachinePromotion(); } else if (machine.hasOrderPromotion()) { isOrderPromo = true; promotion = machine.getOrderPromotion(); } if (promotion) { let promoPrice = isOrderPromo ? machine.getFormattedOrderDiscountPrice() : machine.getFormattedDiscountPrice(); // Add the correct Promo PDP Message for language if (promotion.localizedPdpMessages[siteLang]) { $('.pdp-promo-message p').html(promotion.localizedPdpMessages[siteLang]); $('.pdp-promo-message').removeClass('hidden'); } else if (promotion.localizedPdpMessages['en'] && promotion.localizedPdpMessages['en'].length) { $('.pdp-promo-message p').html(promotion.localizedPdpMessages['en']); $('.pdp-promo-message').removeClass('hidden'); } // Populate PDP Promo price if its not already populated Array.from(productHeroElem.querySelectorAll('.price')).forEach(priceElem => { if (!priceElem.classList.contains('has-promotion')) { let promotionPriceElem = priceElem.querySelector('.promotion-container .promotion_price') priceElem.classList.add('has-promotion'); promotionPriceElem.innerHTML = promoPrice; promotionPriceElem.style.display = ''; } }); } }); // Price Overrides let productHeroElem = document.querySelector('.productHero'); let priceOverridesElem = productHeroElem.querySelector('#price-overrides'); let priceOverrides = {}; let regionNames = ''; let pricePerRegion = ''; if (priceOverridesElem.dataset.regionNames) regionNames = priceOverridesElem.dataset.regionNames.split(','); if (priceOverridesElem.dataset.formattedPriceValues) pricePerRegion = priceOverridesElem.dataset.formattedPriceValues.split(','); if (regionNames) { regionNames.forEach(function(item, index) { priceOverrides[regionNames[index]] = pricePerRegion[index] }); // Set price overrides if (priceOverrides[haas.cookies.getCookie('pldata.2')]) { let prefix = $('.productHero .price:visible').attr('data-prefix'); Array.from(productHeroElem.querySelectorAll('.current_price')).forEach(priceElem => priceElem.innerHTML = priceOverrides[haas.cookies.getCookie('pldata.2')]); Array.from(productHeroElem.querySelectorAll('.price_prefix')).forEach(pricePrefixElem => pricePrefixElem.innerHTML = prefix); } } //Allows for the promo banner on a PDP page to redirect user to the B&P page of the machine they are currently viewing document.querySelector('.promoBanner').onclick = function(e) { e.preventDefault(); if (sapId.includes("/")) { window.location = '/content/haascnc/' + localStorage.storedSiteLang + '/build-and-price/choose-options.' + sapId.replace('/','%252F') + '.html'; } else { window.location = '/content/haascnc/' + localStorage.storedSiteLang + '/build-and-price/choose-options.' + sapId + '.html'; } } } }); }); (function() { haas.components.ProductHeroV2 = haas.Component.create({ shownNdx: 0, initialize: function() { }, render: function() { let self = this; self.renderGallery(); self.checkPriceExists(); }, checkPriceExists: function() { let self = this; $.when(haas.region.priceGroupPromise).then((priceGroup) => { let availableRegionElements = Array.from(self.elementNode.querySelectorAll('.regions input')); let availableRegions = availableRegionElements.map(elem => ({region: elem.dataset.region, currency: elem.dataset.currency})); // Check if price exists for machine // If it does, show buttons ( unless authored to be hidden ) // If not, hide buttons and show "not available" message if (availableRegions.find(regionObj => regionObj.region === priceGroup.region && regionObj.currency === priceGroup.currency)) { let heroBtnContainerElem = self.elementNode.querySelector('.hero-btn-container'); if (!heroBtnContainerElem.classList.contains('hide-hero-btns')) { heroBtnContainerElem.classList.remove('hidden'); } } else { self.elementNode.querySelector('.no-pricing-msg').classList.remove('hidden'); } }); }, renderGallery: function() { let self = this; let galleryElement = self.elementNode.querySelector('.gallery'); if (galleryElement) { let children = galleryElement.children; if (children.length > 1) { self.unhideLeftRightButtons(); if(self.elementNode.querySelector('.videoWrapper')) { var newDiv = document.createElement('div'); newDiv.classList.add('product-gallery-video'); let icon = self.elementNode.querySelector('.videoWrapper').dataset.icon; newDiv.innerHTML = ''; if(haas.cookies.getCookie('pldata.2') === 'CN') { if(self.elementNode.querySelector('.cn-detail-video-frame')) { galleryElement.insertBefore(newDiv, galleryElement.firstChild); self.elementNode.querySelector('.product-gallery-video > img').classList.add('selected'); self.elementNode.querySelector('#bigBoxImage').classList.add('hidden'); self.elementNode.querySelector('.videoWrapper').classList.remove('hidden'); self.shownNdx = -1; } else { self.elementNode.querySelector('#bigBoxImage').src = galleryElement.querySelector('#gallery-img-0').closest('div').querySelector('img').src; galleryElement.querySelector('#gallery-img-0').closest('div').querySelector('img').classList.add('selected'); } } else { if(self.elementNode.querySelector('.detail-video-frame')){ galleryElement.insertBefore(newDiv, galleryElement.firstChild); self.elementNode.querySelector('.product-gallery-video > img').classList.add('selected'); self.elementNode.querySelector('#bigBoxImage').classList.add('hidden'); self.elementNode.querySelector('.videoWrapper').classList.remove('hidden'); self.shownNdx = -1; if (!OnetrustActiveGroups || !OnetrustActiveGroups.includes('C0004')) { const acceptCookiesVideoTemplate = _.template(document.querySelector('#acceptCookiesVideoTemplate').innerHTML); videoElem = self.elementNode.querySelector('.bigBox'); const acceptCookieTextTl = videoElem.querySelector('.videoWrapper') ? videoElem.querySelector('.videoWrapper').dataset.acceptCookieTextTl : 'Please accept targeting cookies to view videos'; const acceptCookiesButtonTl = videoElem.querySelector('.videoWrapper') ? videoElem.querySelector('.videoWrapper').dataset.acceptCookiesBtnTl : 'Cookie Settings'; videoElem.querySelector('.videoWrapper').innerHTML = videoElem.querySelector('.videoWrapper').innerHTML + acceptCookiesVideoTemplate({ acceptCookieText: acceptCookieTextTl, cookieButtonText: acceptCookiesButtonTl }); videoElem.querySelector('.vid-ot-btn-img').onclick = () => videoElem.querySelector('#ot-sdk-btn').click(); window.addEventListener('OneTrustGroupsUpdated', (e) => { let newPermissions = e.detail; if (newPermissions.includes('C0004')) { Array.from(document.querySelectorAll('.hero-accept-cookies-video-container')).forEach(elem => { elem.remove(); }); } }); } } else { self.elementNode.querySelector('#bigBoxImage').src = galleryElement.querySelector('#gallery-img-0').closest('div').querySelector('img').src; galleryElement.querySelector('#gallery-img-0').closest('div').querySelector('img').classList.add('selected'); } } } else { self.elementNode.querySelector('#bigBoxImage').src = galleryElement.querySelector('#gallery-img-0').closest('div').querySelector('img').src; galleryElement.querySelector('#gallery-img-0').closest('div').querySelector('img').classList.add('selected'); } } } this.bindEvents(); }, unhideLeftRightButtons: function() { let self = this; let bigBoxElement = self.elementNode.querySelector('.bigBox'); bigBoxElement.querySelector('.product-pdp-gallery-left').classList.remove('hidden'); bigBoxElement.querySelector('.product-pdp-gallery-right').classList.remove('hidden'); }, bindEvents: function() { let self = this; self.bindBigBoxClick(); self.bindGalleryClickEvents(); self.bindLeftButtonClick(); self.bindRightButtonClick(); }, bindBigBoxClick: function() { let self = this; let galleryElement = self.elementNode.querySelector('.gallery'); this.elementNode.querySelector('#bigBoxImage').onclick = function() { let imageId = galleryElement.querySelector('#gallery-img-' + self.shownNdx).id; let imageNdx = parseInt(imageId.split('-')[2]); galleryElement.querySelector('#gallery-img-' + self.shownNdx).click(); self.shownNdx = imageNdx; }; }, bindGalleryClickEvents: function() { let self = this; let imageSelector = '.product-gallery-image'; let videoSelector = self.elementNode.querySelector('.product-gallery-video'); Array.from(self.elementNode.querySelectorAll(imageSelector)).forEach(imageElement => { imageElement.onclick = function(e) { let imageElem = e.currentTarget.querySelector('img'); let imageId = e.currentTarget.querySelector('.fancybox-gallery img').id; let imageNdx = parseInt(imageId.split('-')[2]); self.elementNode.querySelector('#bigBoxImage').classList.remove('hidden'); self.elementNode.querySelector('#bigBoxImage').src = imageElem.src; if(self.elementNode.querySelector('.videoWrapper')) { self.elementNode.querySelector('.videoWrapper').classList.add('hidden'); } self.elementNode.querySelector('.selected').classList.remove('selected'); imageElem.classList.add('selected'); self.shownNdx = imageNdx; }; }); if(self.elementNode.querySelector('.product-gallery-video')) { videoSelector.onclick = function(e) { let videoElem = e.currentTarget.querySelector('img'); self.elementNode.querySelector('#bigBoxImage').classList.add('hidden'); self.elementNode.querySelector('.videoWrapper').classList.remove('hidden'); self.elementNode.querySelector('.selected').classList.remove('selected'); videoElem.classList.add('selected'); self.shownNdx = -1; } } }, bindLeftButtonClick: function() { let self = this; self.elementNode.querySelector('.product-pdp-gallery-left').onclick = function () { let currentSelectedNdx = self.shownNdx; let galleryImgArray = Array.from(self.elementNode.querySelectorAll('.gallery .product-gallery-image > img')); let galleryImgCount = galleryImgArray.length; let bigBoxImgElem = self.elementNode.querySelector('#bigBoxImage'); let bigVideoElem = self.elementNode.querySelector('.videoWrapper'); var nextSelectedImage; var nextNdx; if(document.querySelector('.zh-CN')) { if(self.elementNode.querySelector('.cn-detail-video-frame')) { var cnID = $(bigVideoElem).attr('data-cnid'); var video = Wistia.api(cnID); if(currentSelectedNdx === 0) { bigBoxImgElem.classList.add('hidden'); self.elementNode.querySelector('.videoWrapper').classList.remove('hidden'); video.play(); nextSelectedImage = self.elementNode.querySelector('.product-gallery-video > img'); nextNdx = -1; } else if(currentSelectedNdx === -1) { nextNdx = galleryImgCount - 1; nextSelectedImage = galleryImgArray[nextNdx]; bigBoxImgElem.src = nextSelectedImage.src; video.pause(); bigVideoElem.classList.add('hidden'); bigBoxImgElem.classList.remove('hidden'); } else { nextNdx = currentSelectedNdx -1; nextSelectedImage = galleryImgArray[nextNdx]; bigBoxImgElem.src = nextSelectedImage.src; } } else { nextNdx = currentSelectedNdx === 0 ? galleryImgCount - 1 : currentSelectedNdx - 1; nextSelectedImage = galleryImgArray[nextNdx]; bigBoxImgElem.src = nextSelectedImage.src; } } else { if(self.elementNode.querySelector('.videoWrapper')) { if(currentSelectedNdx === 0) { bigBoxImgElem.classList.add('hidden'); self.elementNode.querySelector('.videoWrapper').classList.remove('hidden'); $('.detail-video-frame')[0].contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); nextSelectedImage = self.elementNode.querySelector('.product-gallery-video > img'); nextNdx = -1; } else if(currentSelectedNdx === -1) { nextNdx = galleryImgCount - 1; nextSelectedImage = galleryImgArray[nextNdx]; bigBoxImgElem.src = nextSelectedImage.src; $('.detail-video-frame')[0].contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*'); bigVideoElem.classList.add('hidden'); bigBoxImgElem.classList.remove('hidden'); } else { nextNdx = currentSelectedNdx -1; nextSelectedImage = galleryImgArray[nextNdx]; bigBoxImgElem.src = nextSelectedImage.src; } } else { nextNdx = currentSelectedNdx === 0 ? galleryImgCount - 1 : currentSelectedNdx - 1; nextSelectedImage = galleryImgArray[nextNdx]; bigBoxImgElem.src = nextSelectedImage.src; } } self.elementNode.querySelector('.selected').classList.remove('selected'); nextSelectedImage.classList.add('selected'); self.shownNdx = nextNdx; } }, bindRightButtonClick: function() { let self = this; self.elementNode.querySelector('.product-pdp-gallery-right').onclick = function () { let currentSelectedNdx = self.shownNdx; let galleryImgArray = Array.from(self.elementNode.querySelectorAll('.gallery .product-gallery-image > img')); let galleryImgCount = galleryImgArray.length; let bigBoxImgElem = self.elementNode.querySelector('#bigBoxImage'); let bigVideoElem = self.elementNode.querySelector('.videoWrapper'); var nextSelectedImage; var nextSelectedImage; var nextNdx; if(document.querySelector('.zh-CN')) { if(self.elementNode.querySelector('.cn-detail-video-frame')) { var cnID = $(bigVideoElem).attr('data-cnid'); var video = Wistia.api(cnID); if(currentSelectedNdx === galleryImgCount - 1) { bigBoxImgElem.classList.add('hidden'); bigVideoElem.classList.remove('hidden'); video.play(); nextSelectedImage = self.elementNode.querySelector('.product-gallery-video > img'); nextNdx = -1; } else if(currentSelectedNdx === -1) { nextNdx = 0; nextSelectedImage = galleryImgArray[nextNdx]; bigBoxImgElem.src = nextSelectedImage.src; video.pause(); bigVideoElem.classList.add('hidden'); bigBoxImgElem.classList.remove('hidden'); } else { nextNdx = currentSelectedNdx + 1; nextSelectedImage = galleryImgArray[nextNdx]; bigBoxImgElem.src = nextSelectedImage.src; } } else { nextNdx = currentSelectedNdx === galleryImgCount - 1 ? 0 : currentSelectedNdx + 1; nextSelectedImage = galleryImgArray[nextNdx]; bigBoxImgElem.src = nextSelectedImage.src; } } else { if(self.elementNode.querySelector('.videoWrapper')) { if(currentSelectedNdx === galleryImgCount - 1) { bigBoxImgElem.classList.add('hidden'); bigVideoElem.classList.remove('hidden'); $('.detail-video-frame')[0].contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); nextSelectedImage = self.elementNode.querySelector('.product-gallery-video > img'); nextNdx = -1; } else if(currentSelectedNdx === -1) { nextNdx = 0; nextSelectedImage = galleryImgArray[nextNdx]; bigBoxImgElem.src = nextSelectedImage.src; $('.detail-video-frame')[0].contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*'); bigVideoElem.classList.add('hidden'); bigBoxImgElem.classList.remove('hidden'); } else { nextNdx = currentSelectedNdx + 1; nextSelectedImage = galleryImgArray[nextNdx]; bigBoxImgElem.src = nextSelectedImage.src; } } else { nextNdx = currentSelectedNdx === galleryImgCount - 1 ? 0 : currentSelectedNdx + 1; nextSelectedImage = galleryImgArray[nextNdx]; bigBoxImgElem.src = nextSelectedImage.src; } } self.elementNode.querySelector('.selected').classList.remove('selected'); nextSelectedImage.classList.add('selected'); self.shownNdx = nextNdx; } } }); })(); $(document).ready(function() { //https://developer.mozilla.org/en-US/docs/Web/Guide/Printing#Print_an_external_page_without_opening_it function closePrint () { document.body.removeChild(this.__container__); } function setPrint () { this.contentWindow.__container__ = this; this.contentWindow.onbeforeunload = closePrint; this.contentWindow.onafterprint = closePrint; this.contentWindow.focus(); // Required for IE this.contentWindow.print(); } function printPage (sURL) { var oHiddFrame = document.createElement("iframe"); oHiddFrame.onload = setPrint; oHiddFrame.style.visibility = "hidden"; oHiddFrame.style.position = "fixed"; oHiddFrame.style.right = "0"; oHiddFrame.style.bottom = "0"; oHiddFrame.src = sURL; document.body.appendChild(oHiddFrame); } $('.pdf-link').click(function(e) { e.preventDefault(); printPage($(this).data('url')); }); }); $(document).ready(function(){ var y = $(window).width(); Array.from(document.querySelectorAll('.ecommcat')).forEach ((category) => { if($(category).attr('href').includes("winners")) { if(haas.cookies.getCookie('pldata5.2') !== 'US') { category.classList.add('hidden'); } } }); // If on the priceList page, listen for hash changes in case user clicks primary nav if (document.querySelector('.price-list')) { window.onhashchange = () => { window.location.reload(); } } //remove links from top level menu items with exceptions init(); // set up mobile menu logo links (in both header and flyout menu) $(".logo-mobile-link").attr('href', window.location.protocol + '//' + window.location.host + '/' + haas.utils.getLanguage() + '.html'); function fmainmenu() { if (y > 800) { $("li.level01").mouseenter(function(){ if (($(this).attr("id") !== "owners")&&($(this).attr("id") !== "video")) { $(this).find(".submenu01").stop().slideDown(300); $(this).find(".submenu01").addClass("open"); $('#alarm-quick-search-query-navigation').select2('close'); } }).mouseleave(function(e){ // first check keeps navigation from closing when user interacts with // alarm quick search select box if(e.target.id !== 'quantity-select' && e.target.className.indexOf('alarm') === -1 && e.target.className.indexOf('select2') === -1 && !$('#alarm-quick-search-query-navigation').siblings('.select2').hasClass('select2-container--open')){ if (($(this).attr("id") !== "owners")&&($(this).attr("id") !== "video")) { $(".level01").removeClass( "open" ); $(".submenu01").stop().slideUp(300, function() { $(".submenu01").removeClass( "open" ); }); } } }); function ScrollStart() { $(".submenu01").css("top", 160); } function menuScroll() { $(".submenu01").css("top", 160); } $(document).ready(function() { document.addEventListener("touchmove", ScrollStart, false); document.addEventListener("scroll", menuScroll, false); }); // animation for when navibar is hidden ( on ecommerce pages ) // broken on safari right now, fix later /* if (window.location.pathname.includes('haas-tooling')) { document.querySelector('#topsub').style.overflow = 'hidden'; document.querySelector('.desktop-menu.icon-bar-container').onmouseover = () => { document.querySelector('#topsub').style.overflow = ''; document.querySelector('#topsub').style.maxHeight = '500px'; }; // if mouse leaves the navibar, delay closing for 1s, if user goes back to navibar in that time dont close it document.querySelector('#navibar').onmouseleave = () => { setTimeout(() => { if (!document.querySelector('#navibar:hover')) { document.querySelector('#topsub').style.overflow = 'hidden'; document.querySelector('#topsub').style.maxHeight = '0'; } }, 1000); }; } */ //determine active menu links let category = ''; const currentPath = window.location.pathname; if (currentPath.includes('/machines')) { category = 'machines'; } else if (currentPath.includes('/productivity')) { category = 'productivity'; } else if (currentPath.includes('/whyhaas')) { category = 'whyhaas'; } else if (currentPath.includes('/service')) { category = 'service'; } else if (currentPath.includes('/video')) { category = 'video'; } else if (currentPath.includes('/haas-tooling')) { category = 'haas-tooling'; } else if (currentPath.includes('/haas-service-parts')) { category = 'haas-service-parts'; } try { document.querySelector('#topsub .mainmenu .level01[id="'+category+'"]').classList.add('indicate'); } catch (e) { // just means that user is not on a main category, no error handling needed } } else { // open mobile menu let lim = "0"; let $body = $('body'); let menu = document.getElementById("navibar"); let stickyThreshold = menu.querySelector(".menu-container").offsetTop; // remove winner circle category if not in US $.when(haas.region.priceGroupPromise).then(function(priceData) { if (priceData.country !== 'US') { let winnerCircleCategory = Array.from(document.querySelectorAll('.ecomm-nav-container .mobile-only .level1')).find(category => category.id.includes('winner')); if (winnerCircleCategory) winnerCircleCategory.style.display = 'none'; } }); function openMenu() { $body.addClass('mobile-flyout-open'); $("#mobileMenu").toggleClass('hidden'); }; function closeMenu() { $body.removeClass('mobile-flyout-open'); $("#mobileMenu").toggleClass('hidden'); }; window.onscroll = function() { let toolingSearch = document.querySelector('.toolingSearch'); // if on a haas tooling page, only make nav sticky when past the tooling search if (toolingSearch) { if (window.pageYOffset > toolingSearch.getBoundingClientRect().y + window.scrollY + toolingSearch.offsetHeight) { menu.classList.add('sticky'); } else { menu.classList.remove("sticky"); } } else { if (window.pageYOffset >= stickyThreshold) { menu.classList.add('sticky'); } else { menu.classList.remove("sticky"); } } }; $('ul.mainmenu li').removeClass('indicate'); // open menu $("#mobileMenu").off("click").on("click", function() { openMenu(); lim = "2"; }); // close menu $("#mobile-menu-close").off("click").on("click", function(){ closeMenu(); lim = "0"; }); // close menu when clicking outside of menu $(document).off("click").on("click", function(e){ if (lim === "1") { closeMenu(); lim = "0"; // Prevents menu closing function when mainmenu is clicked. $(".mainmenu").click(function(e){ e.stopPropagation(); lim = "2"; }); } else { // bypasses menu closing on first document click. if (lim === "2") { lim = "1"; } } }); //first level click $("li.level01").off("click").on("click", function(e) { if (($(this).attr("id") === "owners") || ($(this).attr("id") === "video") || ($(this).attr("id") === "service")) { closeMenu(); } else { // check if you are clicking into the category or returning from it let isActive = $(this).hasClass('active'); $(this).toggleClass("active"); if ($(this).hasClass("active")){ $('li.level01').hide(); $("li.level01.active").show(); } else { $('li.level01').show(); } // toggle the submenu of the category that was clicked $(this).find(".submenu01").toggleClass("open"); $(this).parents('.mobile-scroll-container').toggleClass('overflow'); // set submenu height offset to be right below the header ( or the first list item for return animation ) if (isActive) $(this).find(".submenu01").css('top', ($('.mobile-menu-header').offset().top + $('.mobile-menu-header').height()) - $(this).offset().top + 'px'); else $(this).find(".submenu01").css('top', $(this).height() + 1 + 'px'); //if second layer of pages unwrap link. If not, leave link. $(this).find("li.level1").each(function() { if ($(this).find("ul.submenu1 li.level2").length) { if ($(this).closest("#productivity").length) {} else { $(this).find("> a:not(.level2-category-link)").contents().unwrap(); } } else { } }); e.stopPropagation(); } }); // second level click $("li.level1").off("click").on("click", function(e) { if ($(this).closest("#owners").length || $(this).closest("#video").length || $(this).closest("#whyhaas").length || $(this).hasClass("alarm-quick-search-wrapper")) { closeMenu(); e.stopPropagation(); } else if ($(this).closest("#productivity").length) { this.querySelector('a').click(); closeMenu(); e.stopPropagation(); } else { // check if you are clicking into the category or returning from it let isActive = $(this).hasClass('active'); $(this).toggleClass("active"); if ($(this).hasClass("active")){ $('li.level1').hide(); $("div.m1").hide(); $("li.level1.active").show(); } else { $('li.level1').show(); $("div.m1").show(); } // toggle parent category's header, hide mobileArrow, display submenu, display category's link, display back arrow icon in header $("ul.mainmenu li.active span.toplevel").toggle(); $(this).find("span.title:after").css("display","none"); $(this).find(".submenu1").toggleClass("open"); $(this).find('.level2-category-link').toggleClass('hidden'); if ($(this).attr("id") === "vertical-mills" || $(this).attr("id") === "milling" || $(this).attr("id") === "lathe_tooling" || $(this).attr("id") === "holemaking" || $(this).attr("id") === "package_kits" || $(this).attr("id") === "coolant") { $(this).find('.submenu1').toggleClass("overflow"); $(this).parents('.submenu01').toggleClass("overflow"); } if (isActive) { $(this).parents(".submenu01").css('top', $(this).parents('.level01.active').height() + 1 + 'px'); $(this).find(".submenu1").css('top', ($(this).parents('.level01.active').offset().top + $(this).parents('.level01.active').height()) - $(this).offset().top + 'px'); } else { $(this).parents(".submenu01").css('top', 0); $(this).find(".submenu1").css('top', $(this).height() + 1 + 'px'); } $("#shop ul.submenu01 li.level2.categorylink").hide(); e.stopPropagation(); } }); //third level click $("li.level2").off("click").on("click", function(e) { closeMenu(); e.stopPropagation(); }); } }//end fmainmenu fmainmenu(); $(window).bind('resize', function(e){ if (y<800) { if( /Android|MSIE|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) { // prevents rapid reload on mobile devices. } else { var w = $(window).width(); if (w>785) { if (window.RT) clearTimeout(window.RT); window.RT = setTimeout(function() { this.location.reload(false); /* false to get page from cache */ }, 300); } } }//if y<800 else { if( /Android|MSIE|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) { // prevents rapid reload on mobile devices. } else { var w = $(window).width(); if (w<785) { if (window.RT) clearTimeout(window.RT); window.RT = setTimeout(function(){ this.location.reload(false); /* false to get page from cache */ }, 300); } } } }); // remove any extra bindings on language links $('.language-link').off(); function init() { $("li.level01").each(function(index){ var $this = $(this); var thisID = $this.attr('id'); if (thisID === 'whyhaas') $this.find("a[class='menu-link']").contents().unwrap(); }); // prevent ecomm search from redirecting /* $('.ecomm-searchbar').off('click').on('click', function(e) { e.preventDefault(); e.stopPropagation(); }); */ if (window.innerWidth <= 800) { $('.level01#machines').find("a[class='menu-link']").contents().unwrap(); $('.level01#productivity').find("a[class='menu-link']").contents().unwrap(); $('.level01#haas-tooling').find("a[class='menu-link']").contents().unwrap(); $('.level01#haas-service-parts').find("a[class='menu-link']").contents().unwrap(); } // temp redirect for service dropdown btn $('.service-tmp-redirect-btn > a').attr('href', '/content/haascnc/' + $('html').attr('lang') + '/service.html'); $.when(haas.region.priceGroupPromise).then(function(price_group) { var region = price_group.region; var specialSeriesRegions = ['CN', 'SE', 'IN', 'HE', 'CH']; var $specialSeriesSelector = $('#menulink.special-series-btn'); if (specialSeriesRegions.includes(region)) { let currentPath = window.location.pathname; let langRegex = /(\/[a-zA-Z]{2})\/|(\/[a-zA-Z]{2}).html/; let specialSeriesUrlBase = '/machines/Special-Series/'; let euSeriesUrl = '/machines/Special-Series/eu_series_redirect.html'; // if not on english page, extract the language path prefix if (langRegex.test(currentPath)) { // get language id from path, [1] for non-homepage match, [2] for homepage match, then prepend to url base let languageId = langRegex.exec(currentPath)[1] ? langRegex.exec(currentPath)[1] : langRegex.exec(currentPath)[2]; specialSeriesUrlBase = languageId + specialSeriesUrlBase; euSeriesUrl = languageId + euSeriesUrl; } // Show button if in special series regions & add link to button depending on region $specialSeriesSelector.removeClass('hidden'); if (region === 'CN') { $specialSeriesSelector.attr('href', specialSeriesUrlBase + 'v-series.html'); // if in CN region, force button text to 'V-Model系列' in all languages $('#machines .special-series-btn span.desktop-menu, #machines .special-series-btn span.mobile-menu').each(function() { $(this).text('V-Model系列'); }); } if (region === 'SE') { $specialSeriesSelector.attr('href', specialSeriesUrlBase + 'se-series.html'); } if (region === 'IN') { $specialSeriesSelector.attr('href', specialSeriesUrlBase + 'i-series.html'); } if (region === 'HE') { $specialSeriesSelector.attr('href', euSeriesUrl); // if in CN region, force button text to 'V-Model系列' in all languages $('#machines .special-series-btn span.desktop-menu, #machines .special-series-btn span.mobile-menu').each(function() { $(this).text('EU Series'); }); } } }); Array.from(document.querySelectorAll('#haas-tooling .ql-container')).forEach(qlElem => { if (!qlElem.querySelector('a')) qlElem.outerHTML = ''; }); $('.quicklink').each(function() { if(haas.cookies.getCookie('salesOrg') === '1000') { if($(this).attr('data-hideforus')) { $(this).hide(); } else { var temphref = $(this).attr('data-linkus'); $(this).attr("href", temphref + ".html"); } } else if(haas.cookies.getCookie('salesOrg') === '2000') { if($(this).attr('data-hideforeu')) { $(this).hide(); } else { if( $(this).attr('data-linkeu')) { var temphref= $(this).attr('data-linkeu'); $(this).attr("href", temphref + ".html"); } else { var temphref = $(this).attr('data-linkus'); $(this).attr("href", temphref + ".html"); } if($(this).children(".desktop-menu").hasClass('eu')) { $(this).find(".desktop-menu").toggleClass('hidden'); } if($(this).children("img").hasClass('eu')) { $(this).find("img").toggleClass('hidden'); } if($(this).children(".mobile-menu").hasClass('eu')) { $(this).find(".mobile-menu").toggleClass('hidden'); } } } }); $('.ecommcat').each(function() { if($(this).attr('data-hideforeu') && haas.cookies.getCookie('salesOrg') === '2000') { $(this).hide(); } }); } if (window.ContextHub) { window.ContextHub.eventing.on(ContextHub.SegmentEngine.PageInteraction.Teaser.prototype.info.loadEvent, function() { init(); fmainmenu(); }); } }); // Bing Custom Search, adapted from https://ui.customsearch.ai/api/ux/render?customConfig=2567271250&market=en-us&safeSearch=Moderate (function(){ var self = this; var mode = $(window).width() <= 800 ? 'mobile' : 'desktop'; var $BCS_SEARCH_BUTTON = $('.bcs-searchbox-submit'); var $BCS_SEARCH_FIELD = $('.bcs-searchbox'); var $BCS_MODAL_CONTAINER = $('.bcs-modal'); var $BCS_MODAL_CONTENT_CONTAINER = $('.bcs-modal .bcs-modal-body .bcs-results'); var $BCS_MODAL_CLOSE = $('.bcs-modal-close'); var $BCS_MODAL_NOT_CONTENT = $('.bcs-modal'); var $BCS_PAGE_ITEM = $('.bcs-pagination li a:not(.bcs-current-page)'); var $BCS_PAGE_ACTIVE_ITEM = $('.bcs-pagination a.bcs-current-page'); var $BCS_WEBPAGE_SEARCH_BTN = mode === 'desktop' ? $('#search-box-container #bcs-web-search') : $('#mobile-search-box-container #bcs-web-search'); var $BCS_IMAGE_SEARCH_BTN = mode === 'desktop' ? $('#search-box-container #bcs-img-search') : $('#mobile-search-box-container #bcs-img-search'); var EVENT_KEYDOWN = 'keydown'; var EVENT_CLICK = 'click'; // Change targets for mobile if (mode === 'mobile') { $BCS_SEARCH_BUTTON = $('#mobile-search-box-container .bcs-searchbox-submit'); $BCS_SEARCH_FIELD = $('#mobile-search-box-container .bcs-searchbox'); $BCS_MODAL_CONTAINER = $('#mobile-search-box-container .bcs-modal'); $BCS_MODAL_CONTENT_CONTAINER = $('#mobile-search-box-container .bcs-modal .bcs-modal-body .bcs-results'); $BCS_MODAL_CLOSE = $('#mobile-search-box-container .bcs-modal-close'); $BCS_MODAL_NOT_CONTENT = $('#mobile-search-box-container .bcs-modal'); } var handleEnterKey = function(e) { if (e.keyCode === 13) { var searchTerms = $BCS_SEARCH_FIELD.val().trim(); haas.bcsSearch.resetOffset(); document.querySelector('.bcs-modal').classList.remove('bcs-service-search'); displaySearchResults(searchTerms); } }; var handleSearchClick = function(e) { var searchTerms = $BCS_SEARCH_FIELD.val().trim(); haas.bcsSearch.resetOffset(); document.querySelector('.bcs-modal').classList.remove('bcs-service-search'); displaySearchResults(searchTerms); }; var handlePaginationClick = function(e) { var btnClick = $(e.target).html(); var currentPage = parseInt($BCS_PAGE_ACTIVE_ITEM.html()); var prevPage = '<'; var nextPage = '>'; if (btnClick === prevPage && currentPage !== 1) { $BCS_PAGE_ACTIVE_ITEM.html(currentPage - 1); if ($BCS_MODAL_CONTAINER.hasClass('bcs-service-search')) { haas.bcsServiceSearch.prevPage(); displaySearchResults(haas.bcsServiceSearch.bcs_terms); } else if ($BCS_MODAL_CONTAINER.hasClass('bcs-tooling-search')) { haas.bcsToolingSearch.prevPage(); displaySearchResults(haas.bcsToolingSearch.bcs_terms); } else if ($BCS_WEBPAGE_SEARCH_BTN.hasClass('active')) { haas.bcsSearch.prevPage(); displaySearchResults(haas.bcsSearch.bcs_terms); } else { haas.bcsSearch.prevPage(); displayImageResults(haas.bcsSearch.bcs_terms); } } if (btnClick === nextPage) { $BCS_PAGE_ACTIVE_ITEM.html(currentPage + 1); if ($BCS_MODAL_CONTAINER.hasClass('bcs-service-search')) { haas.bcsServiceSearch.nextPage(); displaySearchResults(haas.bcsServiceSearch.bcs_terms); } else if ($BCS_MODAL_CONTAINER.hasClass('bcs-tooling-search')) { haas.bcsToolingSearch.nextPage(); displaySearchResults(haas.bcsToolingSearch.bcs_terms); } else if ($BCS_WEBPAGE_SEARCH_BTN.hasClass('active')) { haas.bcsSearch.nextPage(); displaySearchResults(haas.bcsSearch.bcs_terms); } else { haas.bcsSearch.nextPage(); displayImageResults(haas.bcsSearch.bcs_terms); } } }; var handleResultsClick = function(e) { if (!$(e.target).parents('.bcs-modal-content').length) { hideResultsModal(); } }; var handleWebSearchClick = function(e) { if (!$(e.target).parents('#bcs-web-search').hasClass('active')) { $BCS_IMAGE_SEARCH_BTN.removeClass('active'); $BCS_WEBPAGE_SEARCH_BTN.addClass('active'); $('.bcs-results').removeClass('video-results'); haas.bcsSearch.resetOffset(); $BCS_PAGE_ACTIVE_ITEM.html('1'); displaySearchResults(haas.bcsSearch.bcs_terms); } }; var handleImageSearchClick = function(e) { if (!$(e.target).parents('#bcs-web-search').hasClass('active')) { $BCS_WEBPAGE_SEARCH_BTN.removeClass('active'); $BCS_IMAGE_SEARCH_BTN.addClass('active'); $('.bcs-results').addClass('video-results'); haas.bcsSearch.resetOffset(); $BCS_PAGE_ACTIVE_ITEM.html('1'); displayImageResults(haas.bcsSearch.bcs_terms); } }; var bindEventHandlers = function() { $BCS_SEARCH_FIELD.on(EVENT_KEYDOWN, handleEnterKey); $BCS_SEARCH_BUTTON.on(EVENT_CLICK, handleSearchClick); $BCS_MODAL_CLOSE.on(EVENT_CLICK, hideResultsModal); $BCS_MODAL_NOT_CONTENT.on(EVENT_CLICK, handleResultsClick); $BCS_PAGE_ITEM.on(EVENT_CLICK, handlePaginationClick); $BCS_WEBPAGE_SEARCH_BTN.on(EVENT_CLICK, handleWebSearchClick); $BCS_IMAGE_SEARCH_BTN.on(EVENT_CLICK, handleImageSearchClick); }; var displaySearchResults = function(searchTerms){ var resultTemplate = _.template($('#pageResultTemplate').html()); var resultPromise = null; if (document.querySelector('.bcs-modal').classList.contains('bcs-service-search')) { resultPromise = haas.bcsServiceSearch.performSearch(searchTerms); } else if (document.querySelector('.bcs-modal').classList.contains('bcs-tooling-search')) { resultPromise = haas.bcsToolingSearch.performSearch(searchTerms); } else { resultPromise = haas.bcsSearch.performSearch(searchTerms); } resultPromise.then(function(res) { if (!res.webPages) { console.log('NO RESULTS for ', searchTerms); resultTemplate = _.template($('#pageResultNoResults').html()); $BCS_MODAL_CONTENT_CONTAINER.empty(); $BCS_MODAL_CONTENT_CONTAINER.append( resultTemplate({ result_text: $('#pageResultNoResults').data('text'), search_term: searchTerms }) ); $('.bcs-pagination-container').hide(); } else { var pages = res.webPages.value; // empty container of results $BCS_MODAL_CONTENT_CONTAINER.empty(); // populate container with results pages.forEach(function(page) { $BCS_MODAL_CONTENT_CONTAINER.append(resultTemplate({ page_link: page.url, page_title: page.name, page_caption:page.snippet })); }); $('.bcs-pagination-container').show(); } showResultsModal(); }); }; var displayImageResults = function(searchTerms) { var resultTemplate = _.template($('#imageResultTemplate').html()); haas.bcsSearch.performSearch(searchTerms, 'image').then(function(res) { if (!res.value.length) { console.log('NO RESULTS for ', searchTerms); resultTemplate = _.template($('#pageResultNoResults').html()); $BCS_MODAL_CONTENT_CONTAINER.empty(); $BCS_MODAL_CONTENT_CONTAINER.append( resultTemplate({ result_text: $('#pageResultNoResults').data('text'), search_term: searchTerms }) ); $('.bcs-pagination-container').hide(); } else { var pages = res.value; // empty container of results $BCS_MODAL_CONTENT_CONTAINER.empty(); // populate container with results pages.forEach(function(page) { $BCS_MODAL_CONTENT_CONTAINER.append(resultTemplate({ pageLink: page.hostPageUrl, thumbSrc: page.thumbnailUrl, thumbHeight:page.thumbnail.height, thumbWidth:page.thumbnail.width })); }); $('.bcs-pagination-container').show(); } showResultsModal(); }); }; var showResultsModal = function() { document.querySelector('body').classList.add('bcs-search-open'); $BCS_MODAL_CONTAINER.show(); }; var hideResultsModal = function() { document.querySelector('body').classList.remove('bcs-search-open'); $BCS_MODAL_CONTAINER.hide(); haas.bcsSearch.resetBcsSearch(); $BCS_PAGE_ACTIVE_ITEM.html('1'); if (mode === 'mobile') { if ($BCS_MODAL_CONTAINER.hasClass('bcs-service-search')) { $BCS_MODAL_CONTAINER.removeClass('bcs-service-search'); $('.search_box_top_wrapper').hide(); } } }; var init = function() { bindEventHandlers(); }; init(); })(); (function() { haas.components.PriceList = haas.Component.create({ init: function() { }, render: function() { let self = this; $.when(haas.region.priceGroupPromise).then(function(price_group){ if (price_group.region === 'FR' && !document.querySelector('.haas-delivered-message.pl-msg')) self.renderHaasDelivered(); self.renderPromotionPrices(); }); }, renderHaasDelivered: function() { let templateHtml = $('#pl-hdm-template').html(); let $pageHeader = $($('.sectionHeader')[0]); $(templateHtml).insertAfter($pageHeader); // Event Handler for Haas Delivered Price Modal Button let $haasDeliveredButton = $('.haas-delivered-message.pl-msg button'); let modalHeight = $(window).height() * .80 + 'px'; let modalWidth = Math.min($(window).width() * .90, 1000) + 'px'; let pdfSource = '/content/dam/haascnc/assets/haas-delivered/fr/HaasDeliveredFrance_' + $('html').attr('lang') + '.pdf'; $haasDeliveredButton.on('click', function() { haas.components.Modal.open(' promo.regions.includes(userRegion)); promos.forEach(promo => { let discount = promo.getDiscount(); let filteredModels = promo.models.filter(modelId => self.elementNode.querySelector('[data-model-id="'+modelId+'"]')); filteredModels.forEach(modelId => { try { let modelElem = self.elementNode.querySelector('[data-model-id="'+modelId+'"]'); let priceContainer = modelElem.querySelector('.price'); let priceRegions = priceContainer.querySelector('.regions'); let promoPriceContainer = priceContainer.querySelector('.promotion_price'); let userPriceData = Array.from(priceRegions.children).find(price => price.dataset.region === userRegion); if (userPriceData) { let discountPrice = userPriceData.value; if (discount.type === 'percent') discountPrice = discountPrice * ((100 - discount.value) / 100); if (discount.type === 'flat') discountPrice = discountPrice - discount.value; priceContainer.classList.add('has-promotion'); promoPriceContainer.innerHTML = haas.utils.formatCurrency(Number(discountPrice.toFixed(2))); promoPriceContainer.style.display = ''; } else { console.error('No region price for model: ' + modelId); } } catch (e) { console.error('Could not set promo price for model: ' + modelId); console.error(e); } }); }); } }); })(); (function() { haas.components.PlpFilterButton = haas.Component.create({ dataContainer: null, buttonText: null, initialize: function() { this.dataContainer = this.elementNode.querySelector('#data-container'); this.buttonText = this.elementNode.querySelector('h1'); }, render: function() { this.initializeAuthoredStyling(); this.bindEvents(); }, initializeAuthoredStyling: function() { let textColor = this.dataContainer.dataset.textcolor; let backgroundColor = this.dataContainer.dataset.bgcolor; let fullWidth = this.dataContainer.dataset.fullwidth; let fontSize = parseInt(this.dataContainer.dataset.fontsize); let selector = $(".plp-filter-button").find("h1"); if(fullWidth === "1") this.buttonText.style.width = "100%"; if(fontSize) $(selector).css("font-size", fontSize + "px"); if(textColor) this.buttonText.style.color = textColor; if(backgroundColor) this.buttonText.style.backgroundColor = backgroundColor; }, handleButtonClick: function(e) { if(this.dataContainer.dataset.filtercategory === "Part Category") { var filterCategory = document.getElementsByName(this.dataContainer.dataset.filtercategory + "-" + this.dataContainer.dataset.filtervalue); filterCategory.forEach( function(currentValue) { currentValue.click(); }); } else { var filterCategory = document.getElementsByName(this.dataContainer.dataset.filtercategory); var filterValue = this.dataContainer.dataset.filtervalue; filterCategory.forEach( function(currentValue) { if(currentValue.value === filterValue && currentValue.parentElement?.classList.contains("not-selectable")) { document.querySelector('input:checked').click(); currentValue.click(); } else if(currentValue.value === filterValue) { currentValue.click(); } }); } if(document.querySelector('.partListing')) { window.scrollTo({ top: document.querySelector('.partListing').offsetTop, left: 0, behavior: 'smooth'}); } else if(document.querySelector('.customPartListing')) { window.scrollTo({ top: document.querySelector('.customPartListing').offsetTop, left: 0, behavior: 'smooth'}); } }, bindEvents: function() { this.$element.find('#button').on('click', this.handleButtonClick.bind(this)); } }); })(); (function() { haas.components.PaymentCalculator = haas.Component.create({ initialize: function() { $('#machine-price').val(new Intl.NumberFormat('en-US', { maximumFractionDigits: 0}).format(parseInt($('#machine-price').val()))); $('#down-amount').val(new Intl.NumberFormat('en-US', { maximumFractionDigits: 0}).format(parseInt($('#down-amount').val()))); }, render: function() { var _self = this; $('#term').on('change', function() { var machinePrice = $('#machine-price').val().replace(/[^0-9\.]/g, ''); var mdown = $(this).find('option:selected').attr('data-mdown'); $('#interest').prop('selectedIndex', $(this).prop('selectedIndex')); if (mdown) { mdown = mdown.replace(/[^0-9\.]/g, '') / 100; $('#down-amount').val(new Intl.NumberFormat('en-US', { maximumFractionDigits: 0}).format(parseInt(machinePrice * mdown))); $('#down-amount').prop('disabled', true); } else { $('#down-amount').prop('disabled', false); //$('#down-amount').val(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0}).format(parseInt('0'))); } }); $('#down-amount').on('blur', function() { if (!$('#down-amount').val()){ $('#down-amount').val('0'); } $('#down-amount').val($('#down-amount').val().replace(/[^0-9\.]/g, '')); $('#down-amount').val(new Intl.NumberFormat('en-US', { maximumFractionDigits: 0}).format(parseInt($('#down-amount').val()))); }); $('#calculate-pmnt-btn').on('click', function() { _self.calculate(); }); $('#interest').on('change', function(){ var machinePrice = $('#machine-price').val().replace(/[^0-9\.]/g, ''); var mdown = $(this).find('option:selected').attr('data-mdown'); $('#term').prop('selectedIndex', $(this).prop('selectedIndex')); if (mdown) { mdown = mdown.replace(/[^0-9\.]/g, '') / 100; $('#down-amount').val(new Intl.NumberFormat('en-US', { maximumFractionDigits: 0}).format(parseInt(machinePrice * mdown))); $('#down-amount').prop('disabled', true); } else { $('#down-amount').prop('disabled', false); //$('#down-amount').val(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0}).format(parseInt('0'))); } console.log('MDOWN', mdown); }); this.calculate(); }, calculate: function() { var machinePrice = $('#machine-price').val().replace(/[^0-9\.]/g, ''); console.log('PRICE', machinePrice); var downPayment = $('#down-amount').val().replace(/[^0-9\.]/g, ''); if (!downPayment) { downPayment = 0; $('#down-amount').val(new Intl.NumberFormat('en-US', {maximumFractionDigits: 0}).format(parseInt(downPayment))); } console.log('DPAYMENT', downPayment); var term = parseInt($('#term').val()); console.log('TERM', term); var interest = parseFloat($('#interest').val()); interest = (interest / 100) / 12; var x = Math.pow(1 + interest, term); var loan = machinePrice - downPayment; var monthly = (loan * x * interest)/(x-1); var num = $('#machine-price').val().replace(/[^0-9\.]/g, ''); console.log('FETCHED NUMBER', parseFloat(num)); $('.estimated-result').html(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 2 }).format(monthly)); $('.estimated-loan').html('with ' + (new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0 }).format(downPayment)) + ' down payment'); } }); })(); (function() { haas.components.PaybackCalculator = haas.Component.create({ initialize: function() { }, render: function() { var _self = this; $('#calculate-btn').on('click', function() { _self.calculate(); }); /* $('#interest').on('change', function(){ var machinePrice = $('#machine-price').val().replace(/[^0-9\.]/g, ''); var mdown = $(this).find('option:selected').attr('data-mdown'); $('#term').prop('selectedIndex', $(this).prop('selectedIndex')); if (mdown) { mdown = mdown.replace(/[^0-9\.]/g, '') / 100; $('#down-amount').val(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0}).format(parseInt(machinePrice * mdown))); $('#down-amount').prop('disabled', true); } else { $('#down-amount').prop('disabled', false); //$('#down-amount').val(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0}).format(parseInt('0'))); } console.log('MDOWN', mdown); }); */ this.calculate(); }, calculate: function() { var amountOfTime = $('#amount-of-time').val().replace(/[^0-9\.]/g, ''); var loadsPerHour = $('#loads-per-hour').val().replace(/[^0-9\.]/g, ''); var hoursPerDay = $('#hours-per-day').val().replace(/[^0-9\.]/g, ''); var daysPerYear = $('#days-per-year').val().replace(/[^0-9\.]/g, ''); var shopsHourlyRate = $('#shop-rate').val().replace(/[^0-9\.]/g, ''); if (!shopsHourlyRate) { shopsHourlyRate = 0; $('#shop-rate').val(new Intl.NumberFormat('en-US', { maximumFractionDigits: 0}).format(parseInt(shopsHourlyRate))); } $('#shop-rate').val(new Intl.NumberFormat('en-US', { maximumFractionDigits: 0}).format(parseInt(shopsHourlyRate))); var yearly = shopsHourlyRate * (amountOfTime / 60) * loadsPerHour * hoursPerDay * daysPerYear; var monthly = yearly / 12; $('.estimated-yearly').html(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 2 }).format(yearly)); $('.estimated-monthly').html(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 2 }).format(monthly)); //$('.estimated-loan').html('with ' + (new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0 }).format(downPayment)) + ' down payment'); } }); })(); (function() { // TO-DO: Write Functions to control the modal popup & to build the payload var Modal = haas.components.Modal; var EVENT_CLICK = 'click'; var EVENT_BLUR = 'blur'; var EVENT_CHANGE = 'change'; var EVENT_SUBMIT = 'submit'; var EVENT_FOCUS = 'focus'; var EVENT_KEYDOWN = 'keydown'; var $HAAS_MODAL = $('.haas-modal'); var showValidationState = haas.utils.showValidationState; var validateInput = haas.utils.validateInput; var nonZipCodeCountries = ['SA', 'EG', 'OM', 'QA', 'KW', 'BH', 'LB', 'AE', 'VN', 'CN']; var formModel = { machines: [{ model: '', included: '', options: '', machine_language: '', machine_region: '', machine_currency: '', machine_hfo_id: '', discounts: [{ discount: 'configured', type: 'flat', value: 0, amount: 0 }], tooling_qty: {} }], customer: { company: '', email: '', first_name: '', last_name: '', phone: '' }, address: { city: '', country: '', post_code: '', region: '', street: '', additionalComments:'' }, serial: '', isPackage: true }; var authFormModel = { machines: [{ model: '', included: '', options: '', machine_language: '', machine_region: '', machine_currency: '', machine_hfo_id: '', discounts: [{ discount: 'configured', type: 'flat', value: 0, amount: 0 }], tooling_qty: {} }], customer: { id : '', first_name : '', last_name : '' }, serial: '', isPackage: true }; haas.components.PackageReference = haas.Component.create({ token : {}, successMessage : '', errorMessage : '', forceGLUSD: false, initialize: function() { var self = this; if (self.$element.hasClass('card-reference')) { var count = self.$element.find('.packageCardContainer').length; console.log(count); switch(count) { case 1: self.$element.addClass('one-card'); break; case 2: self.$element.addClass('two-card'); break; default: break; } } $.when(haas.jwToken.jwtPromise).then(function (token) { self.token = token; }); }, showContactForm : function(e) { var self = this; var serial = $(e.target).parents('.pkg-btn-container').find('.package-data').attr('data-serial'); var dataContainer = $(".package-data[data-serial='"+serial+"']"); var model = dataContainer.attr('data-machines'); var modelDetails = haas.services.modelDetail.getModel(model); this.successMessage = this.successMessage ? this.successMessage : $(e.target).parents('.pkg-btn-container').find('.package-data').attr('data-successmessage'); this.errorMessage = this.errorMessage ? this.errorMessage : $(e.target).parents('.pkg-btn-container').find('.package-data').attr('data-errormessage'); this.forceGLUSD = this.forceGLUSD ? this.forceGLUSD : $(e.target).parents('.pkg-btn-container').find('.package-data').attr('data-forceGLUSD'); Modal.open("Loading"); // Populate Machine Options $.when(modelDetails).then(function(details) { if(haas.jwToken.isValid(self.token)){ Modal.open(self.templates.contactFormTemplateAuthenticated({ serialNo: serial })); } else { Modal.open(self.templates.contactFormTemplate({ serialNo: serial })); haas.utils.initAutocomplete(); self.disableAutocomplete(); } self.bindEventHandlers(self); if (dataContainer.is('[data-hidestandardoptions]')) { $('#standard-ops, #std-txt').css('display', 'none'); } // iterate through array and determine if package has spindle / tool-changer, then remove from standard features var packageHasSpindle = false, packageHasTC = false; if (dataContainer.attr('data-options')) { details.options.forEach(function(option) { if (dataContainer.attr('data-options').includes(option.id)) { if (option.categoryId === 'spindles') { packageHasSpindle = true; } if (option.categoryId === 'tool-changers') { packageHasTC = true; } } }); } var standardOptions = details.getStandardOptions(); if (packageHasSpindle) { standardOptions = standardOptions.filter(function(option) { return option.categoryId !== 'spindles'; }) } if (packageHasTC) { standardOptions = standardOptions.filter(function(option) { return option.categoryId !== 'tool-changers'; }) } standardOptions = standardOptions.map(function(option) { return option.name; }); var packageOptions = dataContainer.attr('data-options') ? dataContainer.attr('data-optionnames').split(',,') : []; var packageAssociate = dataContainer.attr('data-assocname') ? dataContainer.attr('data-assocname').split(',,') : []; var packageAssociateOps = dataContainer.attr('data-assocoptionnames') ? dataContainer.attr('data-assocoptionnames').split(',,') : []; var packageAutomation = dataContainer.attr('data-autoname') ? dataContainer.attr('data-autoname').split(',,') : []; var packageAutomationOps = dataContainer.attr('data-autooptionnames') ? dataContainer.attr('data-autooptionnames').split(',,') : []; var toolingOptions = dataContainer.attr('data-toolingoptionnames') ? dataContainer.attr('data-toolingoptionnames').split(',,').filter(function(op) { return op.length; }) : []; $('#standard-ops').append(self.buildListItemHTML(standardOptions)); $('#package-ops').append(self.buildListItemHTML(packageOptions)); $('#package-ops').append(self.buildListItemHTML(packageAssociate)); $('#package-ops').append(self.buildListItemHTML(packageAssociateOps)); $('#package-ops').append(self.buildListItemHTML(packageAutomation)); $('#package-ops').append(self.buildListItemHTML(packageAutomationOps)); if (toolingOptions.length) $('#tooling-ops').append(self.buildToolingListItemHTML(toolingOptions, dataContainer)); else $('#tooling-txt').remove(); }); }, buildToolingListItemHTML: function(opList, dataContainer) { var quantities = dataContainer.attr('data-toolingoptions') ? dataContainer.attr('data-toolingoptions').split(',').map(function(pair) { return pair.split(':')[1]; }) : []; var listItemHTML = ''; console.log(quantities, opList); for (var i = 0; i < opList.length; i++) { listItemHTML += '
  • ' + opList[i] + ' x ' + quantities[i] + '
  • '; } return listItemHTML; }, buildListItemHTML: function(opList) { var listItemHTML = ''; opList.forEach(function(option) { listItemHTML += '
  • ' + option + '
  • '; }); return listItemHTML; }, getInputChangeHandler: function (self) { return function () { return self.validateInput($(this)); }; }, validateInput: function ($input) { var validation = validateInput($input); showValidationState(validation); return validation.isValid; }, validateForm: function () { var form = this; var $inputs = $HAAS_MODAL.find('[data-validators]').filter(':visible'); var validationStates = $inputs.map(function () { return form.validateInput($(this)); }); // blur all address fields to trigger field validations $HAAS_MODAL.find('.bp-input').blur(); return _.every(validationStates); }, showSubmissionLoader: function() { $('.haas-modal-wrapper #submission-loader').removeClass('hidden'); }, hideSubmissionLoader: function() { $('.haas-modal-wrapper #submission-loader').addClass('hidden'); }, showSuccessDialog: function (msg) { Modal.open(_.template('

    {{=msg}}

    ')({msg: msg})); }, showErrorDialog: function (msg) { Modal.open(_.template('

    {{=msg}}

    ')({msg: msg})); }, handleCountryChange: function(self) { return function() { $HAAS_MODAL.find('#Region').parent().find('.error-output').empty(); $HAAS_MODAL.find('#PostCode').parent().find('.error-output').empty(); if ($HAAS_MODAL.find('#Region')[0].hasAttribute('disabled')) { $HAAS_MODAL.find('#Region').data('validators', ''); } else { $HAAS_MODAL.find('#Region').data('validators', 'required'); } // if new country val is ME, dont require post code if (nonZipCodeCountries.indexOf($('#Country').val()) > -1) { $HAAS_MODAL.find('#PostCode').data('validators', ''); } else { $HAAS_MODAL.find('#PostCode').attr('data-validators', 'required'); } }; }, disableAddressAutocomplete: function(e) { $HAAS_MODAL.find('#autocomplete').attr('autocomplete', 'new-password'); }, disableAutocomplete: function() { if (!!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime)) { // for chrome $HAAS_MODAL.find('input.bp-input').attr('autocomplete', 'new-password'); } else { // Non-chorme browsers $HAAS_MODAL.find('input.bp-input').attr('autocomplete', 'off'); } }, submitForm: function(e) { e.preventDefault(); if (!this.validateForm()) { return; } var serial = $HAAS_MODAL.find('#pkg-form').attr('data-serial'); var form = this.serializeInputs(serial); var authenticated = haas.jwToken.isValid(this.token); this.buildMachinePayloadObjAndSubmit(form, serial, authenticated); }, serializeInputs: function (serial) { var form = this; var $inputs = $HAAS_MODAL.find('.bp-input') var tmp = {}; var inputsObj = _.assign({}, formModel); var authInputsObj = _.assign({}, authFormModel); $inputs.each(function () { var $input = $(this); var val = $input.val(); if ($input.is('[type=checkbox]')) { val = $input.prop('checked'); } var key = $input.prop('name'); // Check if the input's val is not empty // NOTE: IE11 specific check for duplicate input fields erasing populated fields if (key && val && val.length > 0) { tmp[key] = val; } }); // check to see if user is logged in; // if so, submit form with information from token if(haas.jwToken.isValid(form.token)){ _.assign(authInputsObj.customer, { id : form.token.customerId, contact_id : form.token.contactId, first_name : form.token.firstName, last_name : form.token.lastName }); return authInputsObj; } else { _.assign(inputsObj.customer, { company: tmp.company, email: tmp.email, first_name: tmp.first_name, last_name: tmp.last_name, phone: tmp.phone }); if(tmp.opt_status) { _.assign(inputsObj.customer, { opt_status: '01' }); } else if(inputsObj.customer.opt_status) { delete inputsObj.customer.opt_status; } _.assign(inputsObj.address, { city: tmp.city, country: tmp.country, post_code: tmp.post_code, region: tmp.region, street: tmp.address2 ? tmp.street + ", " + tmp.address2 : tmp.street + ", ", additionalComments: tmp.additionalComments }); inputsObj.include_specs = tmp.include_specs; return inputsObj; } }, buildMachinePayloadObjAndSubmit: function(payloadObj, serial, authenticated) { var self = this; var dataContainer = $(".package-data[data-serial='"+serial+"']"); var model = dataContainer.attr('data-machines'); var modelDetails = haas.services.modelDetail.getModel(model); var associate = dataContainer.attr('data-associates'); var associateDetails = (associate && associate.length) ? haas.services.modelDetail.getModel(associate) : null; var configuredPrice = Number(dataContainer.find('.current_price').html().replace(/[^0-9]/g, '')); var automation = dataContainer.attr('data-automations'); var automationDetails = (automation && automation.length) ? haas.services.modelDetail.getModel(automation) : null; var overridePrice = Number(dataContainer.attr('data-overrideprice')); var overrideDiscountAmount = Number(dataContainer.attr('data-overrideamount')) || Number(configuredPrice - overridePrice) || null; var toolingOptions = dataContainer.attr('data-toolingoptions') ? dataContainer.attr('data-toolingoptions').split(',') : []; $.when(modelDetails, associateDetails, automationDetails).then(function(details, associateModelDetails, automationModelDetails) { var allOptions = dataContainer.attr('data-options') ? dataContainer.attr('data-options').split(',') : []; var includedOptions = []; var addedOptions = []; allOptions.forEach(function(opId) { var optionObj = details.options.filter(function(option) { return option.id === opId }); if (optionObj[0]) { var isStandard = optionObj[0].isStandard; if (isStandard) { includedOptions.push(opId); } else { addedOptions.push(opId); } } }); _.assign(payloadObj.machines[0], { model: dataContainer.attr('data-machines'), included: includedOptions.join(','), options: addedOptions.join(','), machine_language: haas.utils.getLanguage(), machine_region: self.forceGLUSD ? 'GL' : haas.region.props.region, machine_currency: self.forceGLUSD ? 'USD' : haas.region.props.currency, machine_hfo_id: haas.region.props.hfoid }); // clear out tooling and associates _.assign(payloadObj.machines[0], { tooling_qty: {} }); payloadObj.machines.splice(1); if (toolingOptions && toolingOptions.length) { var toolingOptionsObj = {}; toolingOptions.forEach(function(toolingOpt) { var toolingOptionStr = toolingOpt.split(':'); toolingOptionsObj[toolingOptionStr[0]] = Number(toolingOptionStr[1]); }); _.assign(payloadObj.machines[0], { tooling_qty: toolingOptionsObj }); } else { _.assign(payloadObj.machines[0], { tooling_qty: {} }); } if (!overrideDiscountAmount) { _.assign(payloadObj.machines[0], { discounts: [] }); } else { _.assign(payloadObj.machines[0], { discounts: [{ discount: 'configured', type: 'flat', value: overridePrice, amount: overrideDiscountAmount || configuredPrice - overridePrice }] }); } if (automationModelDetails) { var automationModelObj = { model: '', included: '', options: '', machine_language: haas.utils.getLanguage(), machine_region: self.forceGLUSD ? 'GL' : haas.region.props.region, machine_currency: self.forceGLUSD ? 'USD' : haas.region.props.currency, machine_hfo_id: haas.region.props.hfoid, discounts: [] } var allAutomationOptions = dataContainer.attr('data-automationoptions') ? dataContainer.attr('data-automationoptions').split(',') : []; var includedAutomationOptions = []; var addedAutomationOptions = []; allAutomationOptions.forEach(function(opId) { var optionObj = automationModelDetails.options.filter(function(option) { return option.id === opId }); if (optionObj[0]) { var isStandard = optionObj[0].isStandard; if (isStandard) { includedAutomationOptions.push(opId); } else { addedAutomationOptions.push(opId); } } }); _.assign(automationModelObj, { model: automation, included: includedAutomationOptions.join(','), options: addedAutomationOptions.join(','), machine_language: haas.utils.getLanguage(), machine_region: self.forceGLUSD ? 'GL' : haas.region.props.region, machine_currency: self.forceGLUSD ? 'USD' : haas.region.props.currency, machine_hfo_id: haas.region.props.hfoid, discounts: [] }); haas.LOGGER.debug(automationModelObj); if (payloadObj.machines.length > 1) { payloadObj.machines[1] = automationModelObj; } else { payloadObj.machines.push(automationModelObj); } } if (associateModelDetails) { var associateModelObj = { model: '', included: '', options: '', machine_language: haas.utils.getLanguage(), machine_region: self.forceGLUSD ? 'GL' : haas.region.props.region, machine_currency: self.forceGLUSD ? 'USD' : haas.region.props.currency, machine_hfo_id: haas.region.props.hfoid, discounts: [] } var allAssociateOptions = dataContainer.attr('data-associateoptions') ? dataContainer.attr('data-associateoptions').split(',') : []; var includedAssociateOptions = []; var addedAssociateOptions = []; allAssociateOptions.forEach(function(opId) { var optionObj = associateModelDetails.options.filter(function(option) { return option.id === opId }); if (optionObj[0]) { var isStandard = optionObj[0].isStandard; if (isStandard) { includedAssociateOptions.push(opId); } else { addedAssociateOptions.push(opId); } } }); _.assign(associateModelObj, { model: associate, included: includedAssociateOptions.join(','), options: addedAssociateOptions.join(','), machine_language: haas.utils.getLanguage(), machine_region: self.forceGLUSD ? 'GL' : haas.region.props.region, machine_currency: self.forceGLUSD ? 'USD' : haas.region.props.currency, machine_hfo_id: haas.region.props.hfoid, discounts: [] }); haas.LOGGER.debug(associateModelObj); if (payloadObj.machines.length > 1 && !automationModelDetails) { payloadObj.machines[1] = associateModelObj; } else { payloadObj.machines.push(associateModelObj); } } if (payloadObj.machines.length > 1 && !(associateModelDetails || automationModelDetails)) { payloadObj.machines.splice(1); } payloadObj.serial = serial; haas.LOGGER.debug(payloadObj); self.showSubmissionLoader(); if (authenticated){ haas.services.createQuote.submit(payloadObj, true).then(function(res) { var payload = JSON.parse(res); var resultState = payload.success; self.hideSubmissionLoader(); haas.LOGGER.debug(payloadObj); if (resultState) { self.showSuccessDialog(self.successMessage); } else { self.showErrorDialog(self.errorMessage); } }); } else { haas.services.createQuote.submit(payloadObj, false).then(function(res) { var payload = JSON.parse(res); var resultState = payload.success; self.hideSubmissionLoader(); haas.LOGGER.debug(payload); if (resultState) { self.showSuccessDialog(self.successMessage); } else { self.showErrorDialog(self.errorMessage); } }); } }); }, bindEventHandlers : function(self) { $HAAS_MODAL.find('.bp-input').off(EVENT_BLUR).on(EVENT_BLUR, this.getInputChangeHandler(self)); $HAAS_MODAL.find('#autocomplete').off(EVENT_CHANGE).on(EVENT_CHANGE, this.getInputChangeHandler(self)); $HAAS_MODAL.find('#autocomplete').off(EVENT_FOCUS).on(EVENT_FOCUS, this.disableAddressAutocomplete.bind(self)); $HAAS_MODAL.find('#pkg-form').off(EVENT_SUBMIT).on(EVENT_SUBMIT, this.submitForm.bind(self)); $HAAS_MODAL.find('#Country').off(EVENT_CHANGE).on(EVENT_CHANGE, this.handleCountryChange(self)); $HAAS_MODAL.find('#pkg-form').on('autocompleteFilled', self.handleCountryChange(self)); }, bindPkgBtnHandler : function(self) { this.$element.find('.pkg-btn').off(EVENT_CLICK).on(EVENT_CLICK, this.showContactForm.bind(self)); }, render : function() { this.bindPkgBtnHandler(this); } }); })(); // format prices when document is ready $(function() { $.when(haas.region.priceGroupPromise).then(function(price_group){ $('.packageReference .pkg-price').each(function(ndx, elem) { var price = Number($(elem).html()); console.log(price, haas.utils.formatCurrency(price)); $(elem).text(haas.utils.formatCurrency(price)); }) $('.packageReference .packageListItemContainer, .packageReference .packageCardContainer').each(function(ndx, elem) { var $packageData = $(elem).find('.package-data'); var $savingsContainer = $(elem).find('#pkg-discount'); var $savingsContainerZH = $(elem).find('.hide-non-zh #pkg-discount'); var $percentageContainer = $(elem).find('.pkg-price-container .hide-zh .text-red.text-bold, .savings-container .text-bold'); var $serialNumberContainer = $(elem).find('#sn-container'); var displaySerialNumbers = $serialNumberContainer.attr('data-displayserialnums') ? $serialNumberContainer.attr('data-displayserialnums').split(',') : []; var displaySNHTML = ''; var overridePrice = Number($packageData.attr('data-overrideprice')); var listPrice = Number($(elem).find('#list-price .current_price').text().replace(/[^0-9]/g, '')); var savings = $packageData.attr('data-overrideamount') ? Number($packageData.attr('data-overrideamount')) : listPrice - overridePrice; var percentageSaved = Math.round(100.00 * savings / listPrice); var parentRef = $(elem).parents('.packageReference'); var stockTextCopy = $packageData.attr('data-stock-text-override') === 'true' ? $packageData.attr('data-route-copy') : $packageData.attr('data-stock-copy'); var $stockTextContainer = $(elem).find('#stockCopy'); if (!$savingsContainer.text().length) { $savingsContainer.text(haas.utils.formatCurrency(savings)); } if (!$savingsContainerZH.text().length) { $savingsContainerZH.text(haas.utils.formatCurrency(savings)); } $percentageContainer.text(percentageSaved + $percentageContainer.text()); console.log(stockTextCopy); $stockTextContainer.html(stockTextCopy); displaySerialNumbers.forEach(function(sn) { if (sn[0] === '-') { displaySNHTML += "

    SN# "+sn.substr(1)+"

    " } else { displaySNHTML += "

    SN# "+sn+"

    " } }); $serialNumberContainer.append(displaySNHTML); }); }); }); (function() { 'use strict'; haas.components.ImportedPackageDefinition = haas.Component.create({ packageDefinitionJSON: {}, initialize: function() { this.packageDefinitionJSON = JSON.parse(this.elementNode.dataset.json); }, render: function() { let _self = this; let tempElem = document.createElement('div'); tempElem.innerHTML = _self.templates.importedPackageTemplate({ packageTitle: _self.packageDefinitionJSON.packageTitle, packageNotes: _self.packageDefinitionJSON.notes, packagePrice: _self.packageDefinitionJSON.overridePrice, packageDiscount: _self.packageDefinitionJSON.overrideDiscount, packageMachine: _self.packageDefinitionJSON.parentModel, packageOptions: _self.packageDefinitionJSON.optionNames ? _self.packageDefinitionJSON.optionNames.split('&&').filter((opt) => opt && opt.length) : [], packageToolingIDs: _self.packageDefinitionJSON.toolingIDs ? _self.packageDefinitionJSON.toolingIDs.split(',') : [], packageToolingQtys: _self.packageDefinitionJSON.toolingQuants ? _self.packageDefinitionJSON.toolingQuants.split(',').map((qty) => Number(qty)) : [] }); _self.elementNode.append(tempElem); } }); })(); (function() { // TO-DO: Write Functions to control the modal popup & to build the payload var Modal = haas.components.Modal; var EVENT_CLICK = 'click'; var EVENT_BLUR = 'blur'; var EVENT_CHANGE = 'change'; var EVENT_SUBMIT = 'submit'; var EVENT_FOCUS = 'focus'; var EVENT_KEYDOWN = 'keydown'; var $HAAS_MODAL = $('.haas-modal'); var showValidationState = haas.utils.showValidationState; var validateInput = haas.utils.validateInput; var nonZipCodeCountries = ['SA', 'EG', 'OM', 'QA', 'KW', 'BH', 'LB', 'AE', 'VN', 'CN']; haas.components.PackageCardAuthorable = haas.Component.create({ successMessage : '', errorMessage : '', initialize: function() { var self = this; }, showContactForm : function(e) { var self = this; console.log(this); Modal.open("Loading"); Modal.open(self.templates.contactFormTemplate()); haas.utils.initAutocomplete(); var elem = this.$element.find('.pkg-text-data-container'); var fontFamily = $(elem).attr('data-fontFamily'); var h1FontSize = parseInt($(elem).attr('data-h1FontSize')); var h2FontSize = parseInt($(elem).attr('data-h2FontSize')); var h3FontSize = parseInt($(elem).attr('data-h3FontSize')); var pFontSize = parseInt($(elem).attr('data-pFontSize')); console.log(fontFamily, h1FontSize, h2FontSize, h3FontSize, pFontSize, elem); var hasOverrides = fontFamily || h1FontSize || h2FontSize || h3FontSize || pFontSize; // if override is checked, add inline styling to all text elements in body if (hasOverrides) { var textBody = $('.haas-modal .package-modal-content').find('.text-body'); var customClass = 'customText-modal'; var h1Selector = $(textBody).find('h1'); var h2Selector = $(textBody).find('h2'); var h3Selector = $(textBody).find('h3'); var pSelector = $(textBody).find('p'); console.log(textBody); $(textBody).addClass(customClass); if (fontFamily) { $(h1Selector) .add($(h2Selector)) .add($(h3Selector)) .add($(pSelector)) .css('font-family', fontFamily); } if (h1FontSize) { $(h1Selector).css('font-size', h1FontSize + 'px'); } if (h2FontSize) { $(h2Selector).css('font-size', h2FontSize + 'px'); } if (h3FontSize) { $(h3Selector).css('font-size', h3FontSize + 'px'); } if (pFontSize) { $(pSelector).css('font-size', pFontSize + 'px'); } } self.disableAutocomplete(); self.bindEventHandlers(self); }, /* buildListItemHTML: function(opList) { let listItemHTML = ''; opList.forEach(function(option) { listItemHTML += '
  • ' + option + '
  • '; }); return listItemHTML; }, */ getInputChangeHandler: function (self) { return function () { return self.validateInput($(this)); }; }, validateInput: function ($input) { var validation = validateInput($input); showValidationState(validation); return validation.isValid; }, validateForm: function () { var form = this; var $inputs = $HAAS_MODAL.find('[data-validators]').filter(':visible'); var validationStates = $inputs.map(function () { return form.validateInput($(this)); }); // blur all address fields to trigger field validations $HAAS_MODAL.find('.bp-input').blur(); return _.every(validationStates); }, showErrorDialog: function (err) { Modal.open(_.template('

    {{=err}}

    ')({err: err})); }, showSubmissionLoader: function() { $('#submission-loader').removeClass('hidden'); }, hideSubmissionLoader: function() { $('#submission-loader').addClass('hidden'); }, showSuccessDialog: function () { Modal.open(_.template('

    yeet

    ')({msg: msg})); }, handleCountryChange: function(self) { return function() { $HAAS_MODAL.find('#Region').parent().find('.error-output').empty(); $HAAS_MODAL.find('#PostCode').parent().find('.error-output').empty(); if ($HAAS_MODAL.find('#Region')[0].hasAttribute('disabled')) { $HAAS_MODAL.find('#Region').data('validators', ''); } else { $HAAS_MODAL.find('#Region').data('validators', 'required'); } // if new country val is ME, dont require post code if (nonZipCodeCountries.indexOf($('#Country').val()) > -1) { $HAAS_MODAL.find('#PostCode').data('validators', ''); } else { $HAAS_MODAL.find('#PostCode').attr('data-validators', 'required'); } }; }, disableAddressAutocomplete: function(e) { $HAAS_MODAL.find('#autocomplete').attr('autocomplete', 'new-password'); }, disableAutocomplete: function() { if (!!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime)) { // for chrome $HAAS_MODAL.find('input.bp-input').attr('autocomplete', 'new-password'); } else { // Non-chorme browsers $HAAS_MODAL.find('input.bp-input').attr('autocomplete', 'off'); } }, submitForm: function(e) { e.preventDefault(); if (!this.validateForm()) { return; } }, bindEventHandlers : function(self) { $HAAS_MODAL.find('.bp-input').off(EVENT_BLUR).on(EVENT_BLUR, this.getInputChangeHandler(self)); $HAAS_MODAL.find('#autocomplete').off(EVENT_CHANGE).on(EVENT_CHANGE, this.getInputChangeHandler(self)); $HAAS_MODAL.find('#autocomplete').off(EVENT_FOCUS).on(EVENT_FOCUS, this.disableAddressAutocomplete.bind(self)); $HAAS_MODAL.find('#pkg-form').off(EVENT_SUBMIT).on(EVENT_SUBMIT, this.submitForm.bind(self)); $HAAS_MODAL.find('#Country').off(EVENT_CHANGE).on(EVENT_CHANGE, this.handleCountryChange(self)); $HAAS_MODAL.find('#pkg-form').on('autocompleteFilled', self.handleCountryChange(self)); }, bindPkgBtnHandler : function(self) { this.$element.find('.pkg-btn').off(EVENT_CLICK).on(EVENT_CLICK, this.showContactForm.bind(self)); }, render : function() { this.bindPkgBtnHandler(this); } }); })(); // format prices when document is ready $(function() { $.when(haas.region.priceGroupPromise).then(function(price_group){ $('.packageCardAuthorable .packageListItemContainer, .packageCardAuthorable .packageCardContainer').each(function(ndx, elem) { var $serialNumberContainer = $(elem).find('#sn-container'); var displaySerialNumbers = $serialNumberContainer.attr('data-displayserialnums') ? $serialNumberContainer.attr('data-displayserialnums').split(',') : []; var displaySNHTML = ''; displaySerialNumbers.forEach(function(sn) { if (sn[0] === '-') { displaySNHTML += "

    SN# "+sn.substr(1)+"

    " } else { displaySNHTML += "

    SN# "+sn+"

    " } }); $serialNumberContainer.append(displaySNHTML); }); }); }); (function() { haas.components.OptionMachines = haas.Component.create({ initialize: function() { console.log('AVAILABLE ON THESE MACHINES!'); }, render: function() { var self = this; var localization = 'US'; var lang = $('html').attr('lang'); var optionId = $('.option-details').data('id'); var optionCat = $('.option-details').data('name').toUpperCase(); var eccURL = '/bin/haascnc/optionMachines.json'; var sortedMachines = [{ category: 'Vertical Mills', machines: [{ sub_category: 'VF Series', machines: [] }, { sub_category: 'Universal Machines', machines: [] }, { sub_category: 'VR Series', machines: [] }, { sub_category: 'Pallet-Changing VMCs', machines: [] }, { sub_category: 'Mini Mills', machines: [] }, { sub_category: 'Mold Machines', machines: [] }, { sub_category: 'Drill/Tap/Mill Series', machines: [] }, { sub_category: 'Toolroom Mills', machines: [] }, { sub_category: 'Compact Mills', machines: [] }, { sub_category: 'Gantry Series', machines: [] }, { sub_category: 'Vertical Mill/Turn', machines: [] }, { sub_category: 'Extra-Large VMC', machines: [] }, { sub_category: 'Desktop Mill', machines: [] }, { sub_category: 'Control Simulator', machines: [] }, { sub_category: 'Mill Auto Parts Loader', machines: [] }] }, { category: 'Lathes', machines: [{ sub_category: 'ST Series', machines: [] }, { sub_category: 'Dual Spindle', machines: [] }, { sub_category: 'Toolroom Lathes', machines: [] }, { sub_category: 'Chucker Lathe', machines: [] }, { sub_category: 'Bar Feeder', machines: [] }, { sub_category: 'Lathe Auto Parts Loader', machines: [] }] }, { category: 'Horizontal Mills', machines: [{ sub_category: '50-Taper', machines: [] }, { sub_category: '40-Taper', machines: [] }] }, { category: 'Rotaries & Indexers', machines: [{ sub_category: 'Rotary Tables', machines: [] }, { sub_category: 'Indexers', machines: [] }, { sub_category: 'Rotary Tables', machines: [] }, { sub_category: '5-Axis Rotaries', machines: [] }, { sub_category: 'Extra-Large Rotaries', machines: [] }] }]; $.get({ url: eccURL, data: { 'I_PL_TYPE': localization, 'I_CHAR_NAME': optionCat, 'I_CHAR_VALUE': optionId }, cache: false }).then(function(machines) { var resJson; try { resJson = JSON.parse(machines); } catch (e) { resJson = machines; } var machinesResult = resJson.exp_tab_models; var ungroupedMachines = []; var groupedData = []; var $dataContainer = $('.data-container'); var test = []; machinesResult.forEach(function(result) { console.log('FETCHING MODEL', result.model); var modelObj = self.fetchMachineCat(result.model)[0]; if (modelObj) ungroupedMachines.push(modelObj); console.log('OptiONTYPE', result.option_type); sortedMachines.forEach(function(sMachines){ sMachines.machines.forEach(function(ssMachines){ if(modelObj.subCat == ssMachines.sub_category) { if(result.option_type === 'S') { modelObj.type = 'Standard' } else if (result.option_type === 'R') { modelObj.type = 'Required' } else { modelObj.type = 'Optional' } ssMachines.machines.push(modelObj); } }) }) // if (modelObj) test[modelObj.mainCat][modelObj.subCat].push(modelObj); }); console.log('SORTED MACHINES FINAL', sortedMachines); sortedMachines.forEach(function(row, index) { var optionMachinesContent = self.templates.optionMachinesTemplate({ lang: lang.toLowerCase(), category: row.category, machines: row.machines }); $dataContainer.append(optionMachinesContent); }); $('.subcategories').each(function(){ console.log('CHILDREN', $(this)); if($(this).find('.subcategory').children().length === 1) { $(this).remove(); } }); $('.category').each(function(){ $(this).css('color', $(this).attr('data-color')); $(this).css('background-color', $(this).attr('data-bgcolor')); if(!$(this).next('.cat-content').children().find('li>a').length) { console.log('EMPTY MAIN CAT', $(this)); $(this).remove(); } }); $('.category').click(function(){ $(this).next('.cat-content').slideToggle(); $(this).find('i').toggleClass('fa-chevron-circle-right fa-chevron-circle-down') }); if(!$('.option-machines-main').attr('data-expanded')) { $('.cat-content').hide(); } else { $('.category').each(function(){ $(this).find('i').toggleClass('fa-chevron-circle-right fa-chevron-circle-down') }); } //$('
    ').text('TEST').insertAfter('.category'); console.log('GROUPED', groupedData); console.log('FETCHED MACHINES FOR AN OPTION', ungroupedMachines); }); }, fetchMachineCat: function(machineModel) { var machinesInfo = [ { model: 'VF-1', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2TR', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2SS', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2YT', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2SSYT', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2YT-V', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2SSYT-V', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-5/40-V', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-5SS-V', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'TM-0', subCat: 'Toolroom Mills', mainCat: 'Vertical Mills' }, { model: 'TM-0P', subCat: 'Toolroom Mills', mainCat: 'Vertical Mills' }, { model: 'TM-1', subCat: 'Toolroom Mills', mainCat: 'Vertical Mills' }, { model: 'TM-1P', subCat: 'Toolroom Mills', mainCat: 'Vertical Mills' }, { model: 'TM-2P', subCat: 'Toolroom Mills', mainCat: 'Vertical Mills' }, { model: 'TM-2', subCat: 'Toolroom Mills', mainCat: 'Vertical Mills' }, { model: 'TM-3P', subCat: 'Toolroom Mills', mainCat: 'Vertical Mills' }, { model: 'TM-3', subCat: 'Toolroom Mills', mainCat: 'Vertical Mills' }, { model: 'MINIMILL-EDU', subCat: 'Mini Mills', mainCat: 'Vertical Mills' }, { model: 'MINIMILL', subCat: 'Mini Mills', mainCat: 'Vertical Mills' }, { model: 'MINIMILL2', subCat: 'Mini Mills', mainCat: 'Vertical Mills' }, { model: 'SMINIMILL', subCat: 'Mini Mills', mainCat: 'Vertical Mills' }, { model: 'SMINIMILL2', subCat: 'Mini Mills', mainCat: 'Vertical Mills' }, { model: 'VF-2SS', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2SSYT', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2TR', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-3', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-3SS', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-3YT', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-3SSYT', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-4', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-4SS', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-5/40', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-5/40TR', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-5SS', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-5/40XT', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-3SS', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-3SSYT', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-4SS', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-5SS', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-3YT/50', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-5/50', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-5/50TR', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-5/50XT', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-5/40TR', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-5/50TR', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-6/40', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-6SS', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-6/40TR', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-7/40', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-8/40', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-9/40', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-10/40', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-11/40', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-12/40', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-14/40', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-6SS', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-6/40TR', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-6/50TR', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-6/50', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-7/50', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-8/50', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-9/50', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-10/50', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-11/50', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-12/50', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-14/50', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-1YT-EU', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-1SSYT-EU', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2-I', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2-SE', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2-V', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2SS-V', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2YT-EU', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2SSYT-EU', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-1SSYT-EU', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2SS-V', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-2SSYT-EU', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-4-I', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-4-SE', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-4-V', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-4SS-V', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-5/40-I', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-6SS-V', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'VF-4-I', subCat: 'VF Series', mainCat: 'Vertical Mills' }, { model: 'UMC-350', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-350HD', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-500', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-500SS', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-750', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-750SS', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-1000', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-1000-P', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-1000SS', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-1000SS-P', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-1250', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-1250SS', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-1500-DUO', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-1500SS-DUO', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'UMC-1600-H', subCat: 'Universal Machines', mainCat: 'Vertical Mills' }, { model: 'VR-8', subCat: 'VR Series', mainCat: 'Vertical Mills' }, { model: 'VR-9', subCat: 'VR Series', mainCat: 'Vertical Mills' }, { model: 'VR-11', subCat: 'VR Series', mainCat: 'Vertical Mills' }, { model: 'VR-14', subCat: 'VR Series', mainCat: 'Vertical Mills' }, { model: 'VR-1600-6AX', subCat: 'VR Series', mainCat: 'Vertical Mills' }, { model: 'VC-400', subCat: 'Pallet-Changing VMCs', mainCat: 'Vertical Mills' }, { model: 'VC-400SS', subCat: 'Pallet-Changing VMCs', mainCat: 'Vertical Mills' }, { model: 'VM-2', subCat: 'Mold Machines', mainCat: 'Vertical Mills' }, { model: 'VM-3', subCat: 'Mold Machines', mainCat: 'Vertical Mills' }, { model: 'VM-6', subCat: 'Mold Machines', mainCat: 'Vertical Mills' }, { model: 'DT-1', subCat: 'Drill/Tap/Mill Series', mainCat: 'Vertical Mills' }, { model: 'DT-2', subCat: 'Drill/Tap/Mill Series', mainCat: 'Vertical Mills' }, { model: 'DM-1', subCat: 'Drill/Tap/Mill Series', mainCat: 'Vertical Mills' }, { model: 'DM-2', subCat: 'Drill/Tap/Mill Series', mainCat: 'Vertical Mills' }, { model: 'DT-1-I', subCat: 'Drill/Tap/Mill Series', mainCat: 'Vertical Mills' }, { model: 'DT-2-I', subCat: 'Drill/Tap/Mill Series', mainCat: 'Vertical Mills' }, { model: 'CM-1', subCat: 'Compact Mills', mainCat: 'Vertical Mills' }, { model: 'GR-510', subCat: 'Gantry Series', mainCat: 'Vertical Mills' }, { model: 'GR-712', subCat: 'Gantry Series', mainCat: 'Vertical Mills' }, { model: 'GM-2', subCat: 'Gantry Series', mainCat: 'Vertical Mills' }, { model: 'GM-2-5AX', subCat: 'Gantry Series', mainCat: 'Vertical Mills' }, { model: 'VMT-750', subCat: 'Vertical Mill/Turn', mainCat: 'Vertical Mills' }, { model: 'VS-3', subCat: 'Extra-Large VMC', mainCat: 'Vertical Mills' }, { model: 'VS-1', subCat: 'Extra-Large VMC', mainCat: 'Vertical Mills' }, { model: 'VS-3-5AX', subCat: 'Extra-Large VMC', mainCat: 'Vertical Mills' }, { model: 'Desktop Mill', subCat: 'Desktop Mill', mainCat: 'Vertical Mills' }, { model: 'Control-Simulator', subCat: 'Control Simulator', mainCat: 'Vertical Mills' }, { model: 'ST-10', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-10L', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-10LY', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-15', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-15L', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-15LY', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-20', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-20L', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-20LY', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-20Y', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-25', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-25L', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-25LY', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-25Y', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-28', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-28L', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-28LY', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-28Y', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-30', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-30L', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-30LY', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-30Y', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-35', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-35Y', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-35L', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-10Y', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-15Y', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-20Y', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-25Y', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-30Y', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-30LY', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-35LY', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-40', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-40L', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-45', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-45L', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-50', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-55', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-10-V', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-20-V', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-10Y-V', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'ST-20Y-V', subCat: 'ST Series', mainCat: 'Lathes' }, { model: 'DS-30Y', subCat: 'Dual-Spindle', mainCat: 'Lathes' }, { model: 'TL-1', subCat: 'Toolroom Lathes', mainCat: 'Lathes' }, { model: 'TL-2', subCat: 'Toolroom Lathes', mainCat: 'Lathes' }, { model: 'TL-1-EDU', subCat: 'Toolroom Lathes', mainCat: 'Lathes' }, { model: 'CL-1', subCat: 'Chucker Lathe', mainCat: 'Lathes' }, { model: 'EC-400', subCat: '40-Taper', mainCat: 'Horizontal Mills' }, { model: 'EC-500', subCat: '40-Taper', mainCat: 'Horizontal Mills' }, { model: 'EC-500/50', subCat: '50-Taper', mainCat: 'Horizontal Mills' }, { model: 'EC-1600', subCat: '50-Taper', mainCat: 'Horizontal Mills' }, { model: 'EC-1600ZT', subCat: '50-Taper', mainCat: 'Horizontal Mills' }, { model: 'EC-1600ZT-5AX', subCat: '50-Taper', mainCat: 'Horizontal Mills' }, { model: 'EC-1600-H', subCat: '50-Taper', mainCat: 'Horizontal Mills' }, { model: 'EC-630', subCat: '50-Taper', mainCat: 'Horizontal Mills' }, { model: 'TRT70', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TRT100', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TRT210', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TRT160', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TRT310', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TR160', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TR210', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TR160-2', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TR310', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TR200Y', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TR500SS', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TSC4', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TSC3', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TSC2', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'TSC', subCat: '5-Axis Rotaries', mainCat: 'Rotaries & Indexers' }, { model: 'HRT100', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT160', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT160SS', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT160SP', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT160-2', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRTA5', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT210', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT210HT', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT210M', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT210SP', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT210SS', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT210-2', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRTA6', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT310', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT310SP', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT310SS', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT450', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT630', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT800', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'HRT1000', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'TH240', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' }, { model: 'TH450', subCat: 'Rotary Tables', mainCat: 'Rotaries & Indexers' } ]; var result = machinesInfo.filter(function (machine) { return machine.model.toUpperCase() === machineModel; }); return result; } }); })(); (function() { haas.components.OptionCards = haas.Component.create({ verticals: [], horizontals: [], turning: [], rotaries: [], cardSort: '', initialize: function() { var self = this; if ($('.specific-filter').attr('data-bgcolor')) { $('.specific-filter').css('background-color', $('.specific-filter').attr('data-bgcolor')); } this.cardSort = $('.specific-filter').attr('data-sort'); console.log('REGION COOKIE', haas.cookies.getCookie('pldata.2')); console.log('URL', window.location.pathname.split('/').pop()); var self = this; if ($('.tabs>ul>li>a').attr('data-skip')) { return false; } console.log('OPTION CARDS INITIALIZED!'); var fetchURL = '/bin/haascnc/model/list.json'; $.get({ url: fetchURL, cache: false }).then(function(data) { data.Milling[0].series.forEach(function(verticalCat){ verticalCat.details.forEach(function(vertical){ vertical.prices.forEach(function(price){ if (haas.cookies.getCookie('pldata.2') === price.region) { self.verticals.push({'id': vertical.id}); } }) }); }); data.Milling[1].series.forEach(function(horizontalCat){ horizontalCat.details.forEach(function(horizontal){ self.horizontals.push({'id': horizontal.id}); }); }); data.Turning.find(obj => obj.id === 'lathes').series.forEach(function(turningCat){ turningCat.details.forEach(function(turn){ self.turning.push({'id': turn.id}); }) }); console.log('TURNING', data.Turning); data.Turning.find(obj => obj.id === 'rotaries-indexers').series.forEach(function(rotaryCat){ rotaryCat.details.forEach(function(rotary){ self.rotaries.push({'id': rotary.id}); }); }); self.renderMenu($('.tabs>ul>li>a.active').text().replace(' ', '')); console.log('DATA FECTHED', data); }).fail(function(err){ console.log('ERROR Fetching Data', err); }); $('.tabs>ul>li').on('click', function() { $('#noresults').hide(); $('.cards-sort').val($('.specific-filter').attr('data-sort')); $('.card-container').show(); self.renderMenu($(this).children('a').text().replace(' ', '')); console.log('clicked', $(this).children('a').text().replace(' ', '')); console.log('SORTED BY', this.cardSort); }); $('.machine-select').on('change', function(){ console.log('SAP CHAR FROM ELEMENT', $('.card-container').attr('data-cat')); $('.card-container').hide(); $('.filter-loader').show(); $('#noresults').hide(); console.log('MACHINE SELECTED', $(this).val()); console.log('HTML LANG', $('html').attr('lang')); var fetchMachineDataURL = '/bin/haascnc/model/detail.lang=' + $('html').attr('lang') + '.model=' + $(this).val().replaceAll('/', '%252F') + '.json'; if ($(this).val() === 'all') { $('.card-container').show(); $('.filter-loader').hide(); } else { $.get({ url: fetchMachineDataURL, cache: false }).then(function(data){ $('.filter-loader').hide(); var filteredSpindles = data.categories.find((obj => obj.product_detail_page.split('/').pop() === window.location.pathname.split('/').pop())); if(filteredSpindles) { console.log('Options', filteredSpindles); filteredSpindles.options.forEach(function(spindle){ console.log('Option', spindle.id); console.log('CARD', $('.card-container[data-id="' + spindle.id + '"]').attr('data-id', spindle.id)); $('.card-container[data-id="'+ spindle.id +'"]').show(); }) } else { $('.noresults').show(); } }); } }); if (window.location.pathname.split('/').pop() === 'spindles.html') { $('.cards-sort').on('change', function(){ $('.specific-filter').attr('data-sort', $('.cards-sort').val()); console.log('SORT CHANGED!', $(this).val()); if($(this).val() !== this.cardSort) { this.cardSort = $(this).val(); $('.haas-content-card').each(function(){ var $container = $(this); var $cards = $(this).children('.card-container'); console.log('CARDS', $cards); $container.empty().append($cards.get().reverse()); if ($container.is(':empry')) { console.log('EMPTY!!!!!!!'); } }); } }) } else { $('.option-sort').hide(); } $('.tabs>ul>li>a').attr('data-skip', 1); }, render: function() { }, renderMenu: function(selectedTab) { var self = this; var machinesData; console.log('MACHINES DATA', selectedTab); if (selectedTab.toLowerCase() === 'vertical mills') { machinesData = self.verticals; } else if (selectedTab.toLowerCase() === 'horizontal mills') { machinesData = self.horizontals; } else if (selectedTab.toLowerCase() === 'lathes' || selectedTab.toLowerCase() === 'turning centers') { machinesData = self.turning; } else if (selectedTab.toLowerCase() === 'mills') { machinesData = [...self.verticals, ...self.horizontals]; } else if (selectedTab.toLowerCase() === 'rotaries' || selectedTab.toLowerCase() === 'rotary') { machinesData = self.rotaries; } console.log('APPENDED DATA', machinesData); console.log('Rendering', selectedTab); var $selectElement = $('.machine-select'); $selectElement.empty(); $selectElement.append(''); machinesData.forEach(function(machine) { console.log('MACHIDE ID', machine.id); if(machine.id === 'SIMULATOR' || machine.id === 'HAAS BAR FEEDER V2' || machine.id === 'HAAS BAR FEEDER' || machine.id === 'APL-10-25' || machine.id === 'APL-VMC-SMALL') { return false; } else { var machinesContent = self.templates.machinesDropdownTemplate({ id: machine.id }); $selectElement.append(machinesContent); } }); }, bindEvents: function() { } }); })(); // also affects the Package Reference cards on /shop/industry pages $(document).ready(function() { if ($(".card-wrapper").length > 0) { var $h2s = $(".card-wrapper h2"); haas.utils.eqHeight($h2s); $(window).resize(function() { $h2s.each(function(){ $(this).removeAttr('style'); }); haas.utils.eqHeight($h2s); }); } }); $('#mc-embedded-subscribe').click(function() { setTimeout( function () { if($('#mce-error-response').css('display') == 'block' || $('#mce-success-response').css('display') == 'block') { $('.hide-element ').hide(); $(document).animate({scrollTop:0}, 'slow'); } else { $('.hide-element ').show(); } } , 2000 ); }); $(window).bind("load", function() { var imgarray = $(".fancybox-gallery img").toArray(); $(imgarray).each(function(index, element) { var testimg = $(element); var realimg = new Image(); realimg.src = testimg.attr("src"); var imgheight = realimg.height; var imgwidth = realimg.width; if (imgheight > imgwidth) { $(element).addClass("portrait"); } else if (imgheight < imgwidth) { $(element).addClass("landscape"); } }); }); $(document).ready(function(){ $(".gallery-thumbnail").click(function(){ var chosen = $(this).html(); $(".gallery-main").html(chosen); $(".gallery-thumbnail").removeClass("gallery-active"); $(this).addClass("gallery-active"); $(".gallery-main img").addClass("magnify"); mag(); $('.magnify').loupe(); }); // (c) 2010 jdbartlett, MIT license function mag(){ (function(a){a.fn.loupe=function(b){var c=a.extend({loupe:"loupe",width:400,height:300},b||{});return this.length?this.each(function(){var j=a(this),g,k,f=j.is("img")?j:j.find("img:first"),e,h=function(){k.hide()},i;if(j.data("loupe")!=null){return j.data("loupe",b)}e=function(p){var o=f.offset(),q=f.outerWidth(),m=f.outerHeight(),l=c.width/2,n=c.height/2;if(!j.data("loupe")||p.pageX>q+o.left+10||p.pageXm+o.top+10||p.pageY").addClass(c.loupe).css({width:c.width,height:c.height,position:"absolute",overflow:"hidden"}).append(g=a("").attr("src",j.attr(j.is("img")?"src":"href")).css("position","absolute")).mousemove(e).hide().appendTo("body");j.data("loupe",true).mouseenter(e).mouseout(function(){i=setTimeout(h,10)})}):this}}(jQuery)); }; mag(); $('.magnify').loupe(); }); (function() { haas.components.ModalPageLink = haas.Component.create({ initialize: function() { console.log('MODAL PAGE LINK LOADED.'); this.bindEvents(); }, render: function() { }, bindEvents: function() { var Modal = haas.components.LinkModal; $('.modal-trigger').on('click', function() { var $template = $(this).next('template'); Modal.open($template[0].innerHTML); }); } }); })(); /* global haas, _, $ */ (function () { 'use strict'; // there may be multiple instances of this component on one page, // so we need to iterate through them var $LISTSEARCHES = $('.list-search'); if ($LISTSEARCHES.length === 0) { return; } $LISTSEARCHES.each(function () { var $thisList = $(this); var dataMap = {}; var autocompleteList = []; var dataSourceQueue = []; var $tabContainer = $thisList.find('section.tabgroup'); var tabContentTemplate = _.template($('#tabContents').html()); var tabContents = ''; var explainer = {}; var $popupList = $thisList.find('select.option-list'); var language = haas.utils.getLanguage(); var noResultsText = $thisList.data('noresultstext') || 'No results found'; var pleaseEnterText = $thisList.data('pleaseentertext') || 'Please enter'; var orMoreCharactersText = $thisList.data('ormorecharacterstext') || 'or more characters'; var pleaseDeleteText = $thisList.data('pleasedeletetext') || 'Please delete'; var characterText = $thisList.data('charactertext') || 'character'; var charactersText = $thisList.data('characterstext') || 'characters'; var theResultsCouldNotBeLoadedText = $thisList.data('theresultscouldnotbeloadedtext') || 'The results could not be loaded'; var searchingText = $thisList.data('searchingtext') || 'Searching…'; var loadingMoreResultsText = $thisList.data('loadingmoreresultstext') || 'Loading more results…'; var removeAllItemsText = $thisList.data('removeallitemstext') || 'Remove all items'; var youCanOnlySelectText = $thisList.data('youcanonlyselecttext') || 'You can only select'; var itemText = $thisList.data('itemtext') || 'item'; var itemsText = $thisList.data('itemstext') || 'items'; $thisList.find(".list-search-header").each(function () { var $tabHeader = $(this); var id = $tabHeader.attr("id"); var title = $tabHeader.data("title"); var dataSourceUri = $tabHeader.data("source-uri"); dataSourceQueue.push({ id: id, title: title, uri: dataSourceUri }); }); initDataSource(); function initDataSource() { // we need two separate lists of the same data: // -- an array to check the autocompleter against, which will also be used // by the select2.js to populate the dropdown // -- the contents of the tabs, ordered by type (mill/lathe) if (dataSourceQueue.length === 0) { // if we've processed the entire queue, set up the data // sort by code number autocompleteList = autocompleteList.sort(function(a,b) { return parseInt(a.text.replace(/[^0-9]/g, '')) - parseInt(b.text.replace(/[^0-9]/g, '')); }); // add explainer to top of list explainer = explainer || {'text': '', 'value': ''}; autocompleteList.unshift({ "text": explainer.text, "id": explainer.value }); $popupList.select2({ data: autocompleteList, dropdownCssClass: 'listSearchDropdown', placeholder: $popupList.attr('data-placeholder'), language: { errorLoading: function () { return theResultsCouldNotBeLoadedText + '.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = pleaseDeleteText + ' ' + overChars + ' '; if (overChars != 1) { message += charactersText; } else { message += characterText; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = pleaseEnterText + ' ' + remainingChars + ' ' + orMoreCharactersText; return message; }, loadingMore: function () { return loadingMoreResultsText; }, maximumSelected: function (args) { var message = youCanOnlySelectText + ' ' + args.maximum + ' '; if (args.maximum != 1) { message += itemsText; } else { message += itemText; } return message; }, noResults: function(){ return noResultsText; }, searching: function () { return searchingText; }, removeAllItems: function () { return removeAllItemsText; } } }); // take user to URL after selection $popupList.change(function (e) { window.location = $(this).val(); }); // populate tabs _.forEach(dataMap, function(dataType) { tabContents += '
    '; tabContents += '
      '; // add explainer doc to top of tab tabContents +=tabContentTemplate({ 'type' : dataType.title, 'text' : explainer.text, 'value' : explainer.value }); // prepare tab contents _.forEach(dataType.results, function(result){ tabContents +=tabContentTemplate({ 'type' : result.type, 'text' : result.text, 'value' : result.value }); }); tabContents += '
    '; tabContents += '
    '; }); // populate tab container $tabContainer.html(tabContents); $thisList.find('a.list-of-codes-modal-link').click(function(e){ e.preventDefault(); haas.components.Modal.open($thisList.find('.list-search-modal-wrapper').html()); // set up tab functionality inside modal haas.tabs.tabSetup($('.haas-modal-body').find('div.tabs')); }); return; } var dataSource = dataSourceQueue.shift(); $.get(dataSource.uri).done(function(response) { // process the queue if(response.result){ // first item in the JSON will be an explainer link // that gives examples of what the codes are and how they work explainer = response.result.shift() ; dataMap[dataSource.id] = { "id" : dataSource.id, "title" : dataSource.title, "results" : response.result }; _.forEach(response.result, function(result) { autocompleteList.push({ "text": result.text + ' - ' + dataSource.title, "id": result.value }); }); initDataSource(); } else { haas.LOGGER.warn('No list search results.') } }); } }); })(); $(function() { if ($('.linklist').length) { $('.linklist').each(function(ndx, elem) { var $elem = $(elem); var $data = $($elem.find('.ll-data-container')); var txtOverrideColor = $data.attr('data-text-color-override'); var iconOverrideColor = $data.attr('data-icon-color-override'); if (txtOverrideColor && txtOverrideColor.length) { $elem.find('a').css('color', txtOverrideColor); } if (iconOverrideColor && iconOverrideColor.length) { $elem.find('a span').css('color', iconOverrideColor); } }); } }); (function() { haas.components.LinkInBio = haas.Component.create({ valueMap: [], initialize: function() { }, }); })(); $(function() { var linkElems = $('.link > a'); var Modal = haas.components.Modal; linkElems.each(function(ndx, link) { if ($(link).attr('data-openmodal') === 'true') { var body = $(link).attr('data-modalbody'); var bodyHTML = ""; var fontFamily = $(link).attr('data-fontFamily'); var h1FontSize = parseInt($(link).attr('data-h1FontSize')); var h2FontSize = parseInt($(link).attr('data-h2FontSize')); var h3FontSize = parseInt($(link).attr('data-h3FontSize')); var pFontSize = parseInt($(link).attr('data-pFontSize')); var hasOverrides = fontFamily || h1FontSize || h2FontSize || h3FontSize || pFontSize; var lightboxHTML = bodyHTML; $(link).off('click').on('click', function() { // open the lightbox then apply styling Modal.open(lightboxHTML); // if override is checked, add inline styling to all text elements in body if (hasOverrides) { var textBody = $('.haas-modal').find('.link-lightbox-body'); var customClass = 'customText-' + ndx; var h1Selector = $(textBody).find('h1'); var h2Selector = $(textBody).find('h2'); var h3Selector = $(textBody).find('h3'); var pSelector = $(textBody).find('p'); $(textBody).addClass(customClass); if (fontFamily) { $(h1Selector) .add($(h2Selector)) .add($(h3Selector)) .add($(pSelector)) .css('font-family', fontFamily); } if (h1FontSize) { $(h1Selector).css('font-size', h1FontSize + 'px'); } if (h2FontSize) { $(h2Selector).css('font-size', h2FontSize + 'px'); } if (h3FontSize) { $(h3Selector).css('font-size', h3FontSize + 'px'); } if (pFontSize) { $(pSelector).css('font-size', pFontSize + 'px'); } } }); } }); }); $(function() { // CN Specific, prevent '/content/haascnc/en.html' from redirecting to '/index.html' by changing href to '/en.html' $.when(haas.region.priceGroupPromise).then(function(price_group) { if (price_group.region === 'CN') { $(".language .dropdownHidden a.language-link[href='/content/haascnc/en.html']").attr('href', '/en.html'); } }); $('.language-link').on('click', function(e) { e.preventDefault(); var langUrl = e.target.href; var langRegexPattern = /\/([a-z]{2})\/|\/([a-z]{2})\.html/; // get the site lang being clicked, if on home page [2] will have the lang, else [1] will var siteLang = langUrl.match(langRegexPattern)[1] || langUrl.match(langRegexPattern)[2] || 'en'; if (siteLang !== $('html').attr('lang')) { window.localStorage.storedSiteLang = siteLang; window.location = langUrl; } }); }); /* global haas, $, _ */ (function () { 'use strict'; haas.components.IndustryCards = haas.Component.create({ }); })(); (function() { haas.components.InStockMachinesTable = haas.Component.create({ inStockJSON: null, deferredRender: null, categorizedMachines: null, categoryOrder: ['VMC', 'HMC', 'LATHE'], initialize: function() { let self = this; haas.region.priceGroupPromise.then(res => { try { let jsonData = this.elementNode.querySelector('#in-stock-machines-data-container').dataset.json; if (jsonData) { this.inStockJSON = JSON.parse(jsonData); self.parseAttributeLists(); self.filterNonRegionMachines(); self.buildCategorizedMachines(); self.renderMachines(); } else { console.error('Error: Could not parse In Stock JSON Data'); } } catch (e) { console.error('Error: Could not parse In Stock JSON Data' + e); } }); }, contactUsClickHandler: function (e) { e.preventDefault(); let targetNode = e.target; let serialNo = targetNode.dataset.serial; let model = targetNode.dataset.model; console.log(targetNode, serialNo, model); haas.components.Modal.open(this.templates.contactForm()); this.populateFields(model, serialNo); haas.initContactUSForm(); }, populateFields: function (model, serialNo) { document.querySelector('.ai-contact-form #Model').value = model; document.querySelector('.ai-contact-form #Model').readOnly = true; document.querySelector('.ai-contact-form #SerialNo').value = serialNo; document.querySelector('.ai-contact-form #SerialNo').readOnly = true; }, bindEvents: function () { let self = this; Array.from(self.elementNode.querySelectorAll('.available-inventory-contact')).forEach(elem => { elem.onclick = self.contactUsClickHandler.bind(self); }); }, parseAttributeLists: function() { let self = this; const nonListAttributes = ['serialNumber', 'model', 'modelLocation', 'pdfURL', 'modelCat']; for (machineObj in self.inStockJSON) { for (attribute in self.inStockJSON[machineObj]) { if (!nonListAttributes.includes(attribute)) { self.inStockJSON[machineObj][attribute] = self.inStockJSON[machineObj][attribute].split(',&,'); self.inStockJSON[machineObj][attribute] = self.inStockJSON[machineObj][attribute].map(val => val.trim()); } } }; }, filterNonRegionMachines: function() { let self = this; for (machineObj in self.inStockJSON) { if (!self.inStockJSON[machineObj].region.includes(haas.region.props.region)) delete self.inStockJSON[machineObj]; }; }, buildCategorizedMachines: function() { let self = this; let categorized = {}; for (machineKey in self.inStockJSON) { let machine = self.inStockJSON[machineKey]; if (!categorized[machine.modelCat]) categorized[machine.modelCat] = []; categorized[machine.modelCat].push(machine); } self.categorizedMachines = categorized; }, renderMachines: function() { let self = this; let categories = Object.keys(self.categorizedMachines) categories = categories.sort((a, b) => { let ndxA = self.categoryOrder.indexOf(a); let ndxB = self.categoryOrder.indexOf(b); if (ndxA < 0) ndxA = 10; if (ndxB < 0) ndxB = 10; return ndxA - ndxB; }); haas.region.priceGroupPromise.then(res => { for (let category of categories) { let tableDiv = document.createElement('div'); let categoryName = self.elementNode.querySelector('#in-stock-machines-data-container').dataset[category.toLowerCase()]; tableDiv.innerHTML = self.templates.inStockCategoryTable({ machineCat: (categoryName && categoryName.length) ? categoryName : category }); for (let machine of self.categorizedMachines[category]) { let machineRow = document.createElement('tr'); let userPL = haas.region.props.region; let plPrice = machine.price[machine.region.indexOf(userPL)]; machineRow.innerHTML = self.templates.machineRowTemplate({ model: machine.model, serialNumber: machine.serialNumber, options: machine.additionalOptions, modelLocation: machine.modelLocation, price: haas.utils.formatCurrency(Number(plPrice)), pdfURL: machine.pdfURL }); tableDiv.querySelector('tbody').append(machineRow); } self.elementNode.querySelector('#in-stock-machines-tables').append(tableDiv); } }).then(res => { self.bindEvents(); }); } }); })(); $(function() { document.querySelectorAll('.imageWithExpansion').forEach((elem) => { if (elem.querySelector('img').classList.contains('expandable-image')) { elem.onclick = () => { let imgChild = elem.querySelector('img'); let imgSrc = imgChild.getAttribute('src'); let cutoff = imgSrc.indexOf("/_jcr_content"); if (cutoff !== -1) { $.fancybox.open([ {href : imgSrc.substring(0, cutoff) } ]); } else { $.fancybox.open([ {href : imgSrc} ]); } } } }); }); $(document).ready(function($){ var dragging = false, scrolling = false, resizing = false; //cache jQuery objects var imageComparisonContainers = $('.cd-image-container'); //check if the .cd-image-container is in the viewport //if yes, animate it checkPosition(imageComparisonContainers); $(window).on('scroll', function(){ if( !scrolling) { scrolling = true; ( !window.requestAnimationFrame ) ? setTimeout(function(){checkPosition(imageComparisonContainers);}, 100) : requestAnimationFrame(function(){checkPosition(imageComparisonContainers);}); } }); //make the .cd-handle element draggable and modify .cd-resize-img width according to its position imageComparisonContainers.each(function(){ var actual = $(this); drags(actual.find('.cd-handle'), actual.find('.cd-resize-img'), actual, actual.find('.cd-image-label[data-type="original"]'), actual.find('.cd-image-label[data-type="modified"]')); }); //upadate images label visibility $(window).on('resize', function(){ if( !resizing) { resizing = true; ( !window.requestAnimationFrame ) ? setTimeout(function(){checkLabel(imageComparisonContainers);}, 100) : requestAnimationFrame(function(){checkLabel(imageComparisonContainers);}); } }); function checkPosition(container) { container.each(function(){ var actualContainer = $(this); if( $(window).scrollTop() + $(window).height()*0.5 > actualContainer.offset().top) { actualContainer.addClass('is-visible'); } }); scrolling = false; } function checkLabel(container) { container.each(function(){ var actual = $(this); updateLabel(actual.find('.cd-image-label[data-type="modified"]'), actual.find('.cd-resize-img'), 'left'); updateLabel(actual.find('.cd-image-label[data-type="original"]'), actual.find('.cd-resize-img'), 'right'); }); resizing = false; } //draggable funtionality - credits to http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/ function drags(dragElement, resizeElement, container, labelContainer, labelResizeElement) { dragElement.on("mousedown vmousedown", function(e) { dragElement.addClass('draggable'); resizeElement.addClass('resizable'); var dragWidth = dragElement.outerWidth(), xPosition = dragElement.offset().left + dragWidth - e.pageX, containerOffset = container.offset().left, containerWidth = container.outerWidth(), minLeft = containerOffset + 10, maxLeft = containerOffset + containerWidth - dragWidth - 10; dragElement.parents().on("mousemove vmousemove", function(e) { if( !dragging) { dragging = true; ( !window.requestAnimationFrame ) ? setTimeout(function(){animateDraggedHandle(e, xPosition, dragWidth, minLeft, maxLeft, containerOffset, containerWidth, resizeElement, labelContainer, labelResizeElement);}, 100) : requestAnimationFrame(function(){animateDraggedHandle(e, xPosition, dragWidth, minLeft, maxLeft, containerOffset, containerWidth, resizeElement, labelContainer, labelResizeElement);}); } }).on("mouseup vmouseup", function(e){ dragElement.removeClass('draggable'); resizeElement.removeClass('resizable'); }); e.preventDefault(); }).on("mouseup vmouseup", function(e) { dragElement.removeClass('draggable'); resizeElement.removeClass('resizable'); }); } function animateDraggedHandle(e, xPosition, dragWidth, minLeft, maxLeft, containerOffset, containerWidth, resizeElement, labelContainer, labelResizeElement) { var leftValue = e.pageX + xPosition - dragWidth; //constrain the draggable element to move inside his container if(leftValue < minLeft ) { leftValue = minLeft; } else if ( leftValue > maxLeft) { leftValue = maxLeft; } var widthValue = (leftValue + dragWidth/2 - containerOffset)*100/containerWidth+'%'; $('.draggable').css('left', widthValue).on("mouseup vmouseup", function() { $(this).removeClass('draggable'); resizeElement.removeClass('resizable'); }); $('.resizable').css('width', widthValue); updateLabel(labelResizeElement, resizeElement, 'left'); updateLabel(labelContainer, resizeElement, 'right'); dragging = false; } function updateLabel(label, resizeElement, position) { if(position == 'left') { ( label.offset().left + label.outerWidth() < resizeElement.offset().left + resizeElement.outerWidth() ) ? label.removeClass('is-hidden') : label.addClass('is-hidden') ; } else { ( label.offset().left > resizeElement.offset().left + resizeElement.outerWidth() ) ? label.removeClass('is-hidden') : label.addClass('is-hidden') ; } } }); (function () { 'use strict'; haas.components.ImageCarousel = haas.Component.create({ displayCount: 1, titleList: [], initialize: function () { var displayCount = this.data.displayCount; var titleList = this.data.titleList ? this.data.titleList.split(',') : []; var slideTimer = Number(this.data.slideTimer); this.displayCount = displayCount; this.titleList = titleList; this.slickConfig = { infinite: true, slidesToShow: displayCount, slidesToScroll: displayCount, dots: true, adaptiveHeight: true, autoplay: slideTimer ? true : false, autoplaySpeed: slideTimer ? ( slideTimer * 1000 ) : 3000 }; }, render: function () { var self = this; if (self.titleList.length) { self.$element.prepend(self.templates.carouselHeader({ header: self.titleList[0] })); } self.refs.$carousel.on('afterChange', function(event, slick, currentSlide, nextSlide){ if (self.titleList.length) { if (currentSlide < self.titleList.length) { self.$element.find('#header-text').html(self.titleList[currentSlide]); } } }); self.refs.$carousel.slick(this.slickConfig); } }); })(); $(document).ready(function() { $(".expand-image-button").click(function(){ var $thisButton = $(this); var $parent = $thisButton.parent('.image-component-inner'); var $thisImg = $parent.find('img.expandable-image:visible'); var curStr = $thisImg.attr('src'); var cutoff = curStr.indexOf("/_jcr_content"); if (cutoff !== -1) { $.fancybox.open([ {href : curStr.substring(0, cutoff) } ]); } else { $.fancybox.open([ {href : curStr} ]); } }); var imageElems = $('.image-component'); var Modal = haas.components.Modal; let hideAtPixelsList = []; imageElems.each(function(ndx, imageParent) { let image = $(imageParent).find('.image-link'); const defaultImage = imageParent.querySelector('img.default-img'); const plant2000Image = imageParent.querySelector('img.plant-2000-img'); if (plant2000Image && haas.cookies.getCookie('salesOrg') === '2000') { plant2000Image.classList.remove('hidden'); } else { defaultImage.classList.remove('hidden'); } if (imageParent.dataset.hideAt) { let pixels = Number(imageParent.dataset.hideAt); if (!hideAtPixelsList.includes(pixels)) { hideAtPixelsList.push(pixels); let hideStyleElement = document.createElement('style'); hideStyleElement.innerHTML = '@media screen and (max-width: '+pixels+'px) { .image .image-component.img-hide-at-'+pixels+' { display: none!important; }}'; document.querySelector('head').append(hideStyleElement); } imageParent.classList.add('img-hide-at-'+pixels); } if (image && $(image).attr('data-openmodal') === 'true') { var body = $(image).attr('data-modalbody'); var bodyHTML = "
    " + body + "
    "; var fontFamily = $(image).attr('data-fontFamily'); var h1FontSize = parseInt($(image).attr('data-h1FontSize')); var h2FontSize = parseInt($(image).attr('data-h2FontSize')); var h3FontSize = parseInt($(image).attr('data-h3FontSize')); var pFontSize = parseInt($(image).attr('data-pFontSize')); var hasOverrides = fontFamily || h1FontSize || h2FontSize || h3FontSize || pFontSize; var lightboxHTML = bodyHTML; $(image).off('click').on('click', function() { // open the lightbox then apply styling Modal.open(lightboxHTML); // if override is checked, add inline styling to all text elements in body if (hasOverrides) { var textBody = $('.haas-modal').find('.image-lightbox-body'); var customClass = 'customText-' + ndx; var h1Selector = $(textBody).find('h1'); var h2Selector = $(textBody).find('h2'); var h3Selector = $(textBody).find('h3'); var pSelector = $(textBody).find('p'); $(textBody).addClass(customClass); if (fontFamily) { $(h1Selector) .add($(h2Selector)) .add($(h3Selector)) .add($(pSelector)) .css('font-family', fontFamily); } if (h1FontSize) { $(h1Selector).css('font-size', h1FontSize + 'px'); } if (h2FontSize) { $(h2Selector).css('font-size', h2FontSize + 'px'); } if (h3FontSize) { $(h3Selector).css('font-size', h3FontSize + 'px'); } if (pFontSize) { $(pSelector).css('font-size', pFontSize + 'px'); } } }); } }); }); window.FontAwesomeCdnConfig = { autoA11y: { enabled: false }, asyncLoading: { enabled: false }, reporting: { enabled: false }, useUrl: "use.fontawesome.com", faCdnUrl: "https://cdn.fontawesome.com:443", code: "95f7b4eb48" }; !function(){function a(a){var b,c=[],d=document,e=d.documentElement.doScroll,f="DOMContentLoaded",g=(e?/^loaded|^c/:/^loaded|^i|^c/).test(d.readyState);g||d.addEventListener(f,b=function(){for(d.removeEventListener(f,b),g=1;b=c.shift();)b()}),g?setTimeout(a,0):c.push(a)}function b(a,b){var c=!1;return a.split(",").forEach(function(a){var d=new RegExp(a.trim().replace(".","\\.").replace("*","(.*)"));b.match(d)&&(c=!0)}),c}function c(a){"undefined"!=typeof MutationObserver&&new MutationObserver(a).observe(document,{childList:!0,subtree:!0})}function d(a){var b,c,d,e;a=a||"fa",b=document.querySelectorAll("."+a),Array.prototype.forEach.call(b,function(a){c=a.getAttribute("title"),a.setAttribute("aria-hidden","true"),d=a.nextElementSibling?!a.nextElementSibling.classList.contains("sr-only"):!0,c&&d&&(e=document.createElement("span"),e.innerHTML=c,e.classList.add("sr-only"),a.parentNode.insertBefore(e,a.nextSibling))})}!function(){"use strict";function a(a){l.push(a),1==l.length&&k()}function b(){for(;l.length;)l[0](),l.shift()}function c(a){this.a=m,this.b=void 0,this.f=[];var b=this;try{a(function(a){f(b,a)},function(a){g(b,a)})}catch(c){g(b,c)}}function d(a){return new c(function(b,c){c(a)})}function e(a){return new c(function(b){b(a)})}function f(a,b){if(a.a==m){if(b==a)throw new TypeError;var c=!1;try{var d=b&&b.then;if(null!=b&&"object"==typeof b&&"function"==typeof d)return void d.call(b,function(b){c||f(a,b),c=!0},function(b){c||g(a,b),c=!0})}catch(e){return void(c||g(a,e))}a.a=0,a.b=b,h(a)}}function g(a,b){if(a.a==m){if(b==a)throw new TypeError;a.a=1,a.b=b,h(a)}}function h(b){a(function(){if(b.a!=m)for(;b.f.length;){var a=b.f.shift(),c=a[0],d=a[1],e=a[2],a=a[3];try{0==b.a?e("function"==typeof c?c.call(void 0,b.b):b.b):1==b.a&&("function"==typeof d?e(d.call(void 0,b.b)):a(b.b))}catch(f){a(f)}}})}function i(a){return new c(function(b,c){function d(c){return function(d){g[c]=d,f+=1,f==a.length&&b(g)}}var f=0,g=[];0==a.length&&b(g);for(var h=0;h=i?b():document.fonts.load(j(f,f.family),h).then(function(b){1<=b.length?a():setTimeout(c,25)},function(){b()})}c()}),o=new Promise(function(a,b){setTimeout(b,i)});Promise.race([o,n]).then(function(){a(f)},function(){e(f)})}else b(function(){function b(){var b;(b=-1!=q&&-1!=r||-1!=q&&-1!=s||-1!=r&&-1!=s)&&((b=q!=r&&q!=s&&r!=s)||(null===k&&(b=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent),k=!!b&&(536>parseInt(b[1],10)||536===parseInt(b[1],10)&&11>=parseInt(b[2],10))),b=k&&(q==t&&r==t&&s==t||q==u&&r==u&&s==u||q==v&&r==v&&s==v)),b=!b),b&&(w.parentNode&&w.parentNode.removeChild(w),clearTimeout(x),a(f))}function m(){if((new Date).getTime()-l>=i)w.parentNode&&w.parentNode.removeChild(w),e(f);else{var a=document.hidden;!0!==a&&void 0!==a||(q=n.a.offsetWidth,r=o.a.offsetWidth,s=p.a.offsetWidth,b()),x=setTimeout(m,50)}}var n=new c(h),o=new c(h),p=new c(h),q=-1,r=-1,s=-1,t=-1,u=-1,v=-1,w=document.createElement("div"),x=0;w.dir="ltr",d(n,j(f,"sans-serif")),d(o,j(f,"serif")),d(p,j(f,"monospace")),w.appendChild(n.a),w.appendChild(o.a),w.appendChild(p.a),document.body.appendChild(w),t=n.a.offsetWidth,u=o.a.offsetWidth,v=p.a.offsetWidth,m(),g(n,function(a){q=a,b()}),d(n,j(f,'"'+f.family+'",sans-serif')),g(o,function(a){r=a,b()}),d(o,j(f,'"'+f.family+'",serif')),g(p,function(a){s=a,b()}),d(p,j(f,'"'+f.family+'",monospace'))})})},f=h}();var g={observe:function(a,b){for(var c=b.prefix,d=function(a){var b=a.weight?"-"+a.weight:"",d=a.style?"-"+a.style:"",e=a.className?"-"+a.className:"",g=a.className?"-"+a.className+b+d:"",h=document.getElementsByTagName("html")[0].classList,i=function(a){h.add(c+e+"-"+a),h.add(c+g+"-"+a)},j=function(a){h.remove(c+e+"-"+a),h.remove(c+g+"-"+a)};i("loading"),new f(a.familyName).load(a.testString).then(function(){i("ready"),j("loading")},function(){i("failed"),j("loading")})},e=0;e { if (self.isRadioButtonMode) iconElem.onclick = self.handleIconClickRadioButtonMode.bind(self); else iconElem.onclick = self.handleIconClick.bind(self); }); }, handleIconClick: function(e) { let currentIcon = e.currentTarget; let iconToggleId = currentIcon.id; const idElemQuery = '#icon-content-container #' + iconToggleId; let idElem = this.elementNode.querySelector(idElemQuery); let idToggleGrid = idElem.closest('.grid'); if (currentIcon.classList.contains('selected')) { currentIcon.classList.remove('selected'); idToggleGrid.classList.add('hidden'); } else { currentIcon.classList.add('selected'); idToggleGrid.classList.remove('hidden'); } }, handleIconClickRadioButtonMode: function(e) { let self = this; let currentIcon = e.currentTarget; let iconToggleId = currentIcon.id; const idElemQuery = '#icon-content-container #' + iconToggleId; let idElem = this.elementNode.querySelector(idElemQuery); let idToggleGrid = idElem.closest('.grid'); // in radio button mode deselect & hide all grids other than current icon Array.from(self.elementNode.querySelectorAll('.icon-toggle-btn')).forEach(childIconElem => { let childIconToggleId = childIconElem.id; childIconElem.classList.remove('selected'); try { const childElemQuery = '#icon-content-container #' + childIconToggleId; let childIdElem = self.elementNode.querySelector(childElemQuery); let childIdToggleGrid = childIdElem.closest('.grid'); childIdToggleGrid.classList.add('hidden'); } catch (e) { console.warn('Could not hide grid with identifier: ', iconToggleId); } }); // In radio mode, if you click on the selected icon, it will not do anything if (currentIcon.classList.contains('selected')) {} else { currentIcon.classList.add('selected'); idToggleGrid.classList.remove('hidden'); } }, initializeInitiallySelectedSections: function() { let self = this; // For each icon button, initially set which grids are hidden Array.from(this.elementNode.querySelectorAll('.icon-toggle-btn')).forEach(iconElem => { let iconToggleId = iconElem.id; if (iconElem.dataset.initiallySelected) { iconElem.classList.add('selected'); } else if (!self.elementNode.classList.contains('edit-mode')) { try { const idElemQuery = '#icon-content-container #' + iconToggleId; let idElem = this.elementNode.querySelector(idElemQuery); let idToggleGrid = idElem.closest('.grid'); idToggleGrid.classList.add('hidden'); } catch (e) { console.warn('Could not hide grid with identifier: ', iconToggleId); } } }); // show content after hiding initially hidden grids this.elementNode.querySelector('#icon-content-container').style.display = ''; } }); })(); $(document).ready(function() { // sticky navigation functionality is handled by diySubNavigation.js // haascnc/ui/src/main/content/jcr_root/apps/haascnc/components/content/diy/diySubNavigation/clientlib/js/diySubNavigation.js var $contentBlock = $('.code-setting-detail-content'); // remove style and title tags from content to keep them from interfering with code $contentBlock.find('style').remove(); $contentBlock.find('title').remove(); }); /* global haas, $, _ */ (function () { 'use strict'; if ($("span.sprite-link").length < 1) { $(".sprite-wrapper").css("width", "100%"); } haas.components.HomeSprite = haas.Component.create({ render: function () { if ((this.refs.$slide).hasClass("righttoleft")){ this.refs.$slide.animate({left: '-999999px'}, 1000 * 60 * 60 * 6, 'linear'); } else if ((this.refs.$slide).hasClass("lefttoright")){ this.refs.$slide.animate({right: '0px'}, 1000 * 60 * 60 * 6, 'linear'); } else { } } }); })(); $(document).ready(function(){ // scroll to top function $(".scroll-button").click(function(){$("html, body").animate({scrollTop: $(".hero-video").position().top + $(".hero-video").offset().top + $(".hero-video").outerHeight(true)}, 800);}); jQuery(".scroll-button").click(function(){ jQuery("html, body").animate({scrollTop: $(".hero-video").position().top + $(".hero-video").offset().top + $(".hero-video").outerHeight(true)}, 800); return false; }); if (window.ContextHub) { window.ContextHub.eventing.on(ContextHub.SegmentEngine.PageInteraction.Teaser.prototype.info.loadEvent, function() { $(".scroll-button").off("click").on("click", (function(){$("html, body").animate({scrollTop: $(".hero-video").position().top + $(".hero-video").offset().top + $(".hero-video").outerHeight(true)}, 800);})); jQuery(".scroll-button").off("click").on("click", (function(){ jQuery("html, body").animate({scrollTop: $(".hero-video").position().top + $(".hero-video").offset().top + $(".hero-video").outerHeight(true)}, 800); return false; })); }); } // if no button in home hero, remove bottom padding if (!$('.hero-headline .hero-button-container').length) { $('.homeHero video').css('padding-bottom', 0); } }); $(function() { if ($('.hfoSubnav').length > 0) { // check if we're on HFO Subnav Page var currentPath = window.location.pathname.slice(window.location.pathname.lastIndexOf('/')); $('.page__main.container').prepend("
    "); $('.hfo-child-link').each(function(ndx, element) { if ($(element).attr('href').includes(currentPath)) $(element).addClass('active-link'); }); } }); $("nav select").change(function() { window.location = $(this).find("option:selected").val(); }); $(document).ready(function(){ var scrollTop = $(window).scrollTop(); var elementOffset = $('#nav_bar').offset(); // need to check if subnav offset exists before accessing .top // otherwise it throws a TypeError if (!elementOffset) return; elementOffset = elementOffset.top; var currentElementOffset = (elementOffset - scrollTop); $(window).scroll(function () { if(window.innerWidth < 800) { if (($(window).scrollTop() + parseInt($('.menu-container').outerHeight(true))) > currentElementOffset) { $('#nav_bar').addClass('navbar-fixed'); $('.navbar-fixed').css("top", parseInt($('.menu-container').position().top + $('.menu-container').outerHeight(true)) + 'px'); } if ($(window).scrollTop() < elementOffset) { $('#nav_bar').removeClass('navbar-fixed'); } } else { if (($(window).scrollTop() + parseInt($('.menu-container').position().top + $('#navibar').outerHeight(true))) > currentElementOffset) { $('#nav_bar').addClass('navbar-fixed'); $('.navbar-fixed').css("top", parseInt($('.menu-container').position().top + $('#navibar').outerHeight(true)) + 'px'); } if ($(window).scrollTop() < elementOffset) { $('#nav_bar').removeClass('navbar-fixed'); } } }); }); $(document).ready(function() { $("#option.subnav-menu > option").each(function() { if (this.value.includes(window.location.pathname)){ this.selected = 'selected'; } }); }); $(document).ready(function(){ $('.group-card a').click(function() { $('.group-detail').hide(); var linkid = $(this).attr('href'); $("div.group-detail"+linkid).show(); }); }); (function() { $.when(haas.region.priceGroupPromise).then(function(priceGroup) { if (priceGroup.country === 'DE') { $('.de-form-component').css("display", "block"); var initFancybox = function(deFormBtn) { deFormBtn.fancybox({ type : "iframe", width : 450, height : 750, fitToView : true, openEffect : 'none', closeEffect : 'none' }); }; initFancybox($('#fancybox-germanyfeedback')); } }); })(); $(document).ready(function(){ //mobile screen width cap var fw = $(window).width(); // scroll to top function if ( fw > 800 ) { $(".gototop").click(function(){$("html, body").animate({scrollTop: 0}, "slow");}); var pxShow = 600;//height on which the button will show var fadeInTime = 1000;//how slow/fast you want the button to show var fadeOutTime = 1000;//how slow/fast you want the button to hide var scrollSpeed = 1200;//how slow/fast you want the button to scroll to top. can be a value, 'slow', 'normal' or 'fast' jQuery(window).scroll(function() { if (jQuery(window).scrollTop() >= pxShow) { jQuery(".gototop").fadeIn(fadeInTime); } else { jQuery(".gototop").fadeOut(fadeOutTime); } }); jQuery('.gototop').click(function() { jQuery('html, body').animate({scrollTop:0}, scrollSpeed); return false; }); $('.fa-weixin').parent().off('click').on('click', function(e) { e.preventDefault(); haas.components.Modal.open(""); }); $.when(haas.region.priceGroupPromise).then(function(payload) { if (payload.region === 'CN') { var cn_social = ['fa-weixin', 'fa-linkedin']; $('#footer .navi_b .last li').each(function(ndx, elem) { if (ndx === 0) { return; } var elemIcon = $(elem).find('span')[0].className.split(/\s+/g)[1];; if (cn_social.indexOf(elemIcon) === -1) { $(elem).css('display', 'none'); } }); } }); } else { $(".gototop").hide(); } //mobile footer list functions if (fw<=800) { $(".navi_b div ul").addClass("open"); $(".navi_b div ul li:first-child").each(function(){ $(this).click( function() { //if ($(this).parent().hasClass("last")) { //} if ($(this).closest("div").hasClass("last")) { } else { $(this).parent().toggleClass("open"); $(this).parent().find("li:not(:first-child)").slideToggle(); } }); }); //$(".navi_b div ul li a").click(function(event){ // event.preventDefault(); // }); } // Event Handler for Haas Delivered Price Modal Button $.when(haas.region.priceGroupPromise).then(function(payload) { // Maintainance: If more regions require this message, add pl region below if (payload.region === "FR") { var $haasDeliveredButton = $('.haas-delivered-message.footer-msg button'); var modalHeight = $(window).height() * .80 + 'px'; var modalWidth = Math.min($(window).width() * .90, 1000) + 'px'; var pdfSource = '/content/dam/haascnc/assets/haas-delivered/fr/HaasDeliveredFrance_' + $('html').attr('lang') + '.pdf'; $haasDeliveredButton.on('click', function() { haas.components.Modal.open(' .tabs').hide(); $('#hfo-page-content > .tabs > ul').hide(); $('#first-tab-group > .tab').removeAttr('style'); $('#ot-sdk-btn-floating'); $('.hfo-page-background').css('background-color', 'white'); $('#hfo-nav-container').css('display', 'block'); $('#hfo-nav-container').css('background-color', 'white'); $('.hfo-nav-title').css('color', 'black'); $('.hfo-link-container').css('background-color', 'white'); $('.hfo-child-link').css('color', 'black'); $('.active-link').css('color', '#cb2c31'); $('.hfo-child-link').each(function() { let _href = $(this).attr('href'); $(this).attr('href', _href + '?simple=true'); }); $('.newpar').hide(); $('.par').hide(); } }); /* global haas, _, $ */ (function () { 'use strict'; var CLASS_STICKY = 'is-sticky'; var EVENT_CLICK = 'click'; var EVENT_SCROLL = 'scroll'; haas.components.ContactButton = haas.Component.create({ isSticky: true, onScroll: function () { var $button = this.refs.$button; if (this.$element.offset().top <= $(window).scrollTop() + window.innerHeight) { if (this.isSticky) { $button.removeClass(CLASS_STICKY); this.isSticky = false; } } else { if (!this.isSticky) { $button.addClass(CLASS_STICKY); this.isSticky = true; } } }, onButtonClick: function (e) { if (e && typeof e.preventDefault === 'function') e.preventDefault(); haas.LOGGER.log('Contact Clicked'); }, bindEvents: function () { // this.refs.$button.off(EVENT_CLICK).on(EVENT_CLICK, this.onButtonClick.bind(this)); $(window).off(EVENT_SCROLL, this.onScroll).on(EVENT_SCROLL, this.onScroll.bind(this)); }, render: function () { this.bindEvents(); } }); })(); (function () { /* z-index changes necessary for fleet modals to display correctly */ if ($('app-root').length > 0 && $('app-root').html()) { // check if we're on MyHaas page $('.page__main.container').css('z-index', 'auto'); // prevent manual hash changing in browser window.onhashchange = (e) => { if (location.hash.includes('signup')) window.location = '/ecommpartsstorefront/ecommparts/'+localStorage.storedSiteLang+'/register?referrer=aem'; }; // prevent manually navigating to signup page if (window.location.hash.indexOf('#/signup') > -1) window.location = '/ecommpartsstorefront/ecommparts/'+localStorage.storedSiteLang+'/register?referrer=aem'; // re-write the onclick function of the "create account" button on login page to navigate to hybris if (window.location.hash.indexOf('#/login') > -1) { const fleetContainer = document.querySelector('.fleet-application-wrapper'); const observerConfig = { childList: true, subtree: true } const fleetObserver = new MutationObserver((mutationList, observer) => { mutationList.forEach(mutation => { switch(mutation.type) { case 'childList': console.log(mutation); let addedNodes = Array.from(mutation.addedNodes); if (addedNodes.some(node => node.classList && node.classList.contains('create-account'))) { let createAccountElem = addedNodes.find(node => node.classList.contains('create-account')); let createAccountButton = createAccountElem.querySelector('button'); createAccountButton.onclick = (e) => { e.preventDefault(); window.location = '/ecommpartsstorefront/ecommparts/'+localStorage.storedSiteLang+'/register?referrer=aem'; } } else if (addedNodes.some(node => node.nodeType === 1 && node.querySelector('.store-icons'))) { let storeIconsParent = addedNodes.find(node => node.nodeType === 1 && node.querySelector('.store-icons')); let storeIconsContainer = storeIconsParent.querySelector('.store-icons'); let storeIconList = Array.from(storeIconsContainer.children); let appleStoreIcon = storeIconList[0], androidStoreIcon = storeIconList[1]; if (appleStoreIcon) appleStoreIcon.href = 'https://apps.apple.com/us/app/myhaas/id1549017599'; if (androidStoreIcon) androidStoreIcon.href = 'https://play.google.com/store/apps/details?id=com.haascnc.myHaas'; } break; default: break; } }); }); fleetObserver.observe(fleetContainer, observerConfig); } // re-write the onclick function of the "create account" button on signup page to do nothing if (window.location.hash.indexOf('#/signup') > -1) { const fleetContainer = document.querySelector('.fleet-application-wrapper'); const observerConfig = { childList: true, subtree: true } const fleetObserver = new MutationObserver((mutationList, observer) => { mutationList.forEach(mutation => { switch(mutation.type) { case 'childList': console.log(mutation); let addedNodes = Array.from(mutation.addedNodes); if (addedNodes.some(node => node.classList && node.classList.contains('btn-create-account'))) { let createAccountButton = addedNodes.find(node => node.classList.contains('btn-create-account')); createAccountButton.onclick = (e) => { e.preventDefault(); } observer.disconnect(); } break; default: break; } }); }); fleetObserver.observe(fleetContainer, observerConfig); } if (window.location.hash.indexOf('#/signup?state=hidelogin') > -1) $('.log-in-left').css('display', 'none'); if (window.location.hash !== '#/login' && window.location.hash !== '#/signup') $('.page__main.container').prepend("
    "); if (window.location.hash.indexOf('#/password-reset') > -1 || window.location.hash.indexOf('#/signup?referrer=certification') > -1 || window.location.hash.indexOf('#/signup?signupFlag=1') > -1) { $('.page__main.container').prepend("
    "); } else { $('.page__main.container').prepend("
    "); } } else { $('.page__main.container').css('z-index', 1); } })(); (function () { 'use strict'; var haas = window.haas || {}; haas.fleet = haas.fleet || {}; var LOGGED_IN = '.logged-in'; var LOGGED_OUT = '.logged-out'; var USERNAME = '.auth-username'; var ARROW_SELECTORS = '.fa-angle'; haas.fleet.myHaasDropdown = { loggedIn: false, username : '', logout: function() { haas.LOGGER.log('Logging user out from MyHaas dropdown'); var self = this; $(LOGGED_IN).removeClass('visible'); $(LOGGED_OUT).addClass('visible'); localStorage.removeItem('access_token'); }, login: function(payload) { var self = this; var isAdmin = payload.admin_flag; $(LOGGED_OUT).removeClass('visible'); $(LOGGED_IN).addClass('visible'); haas.LOGGER.debug(payload); // populate username if (payload.name){ $(USERNAME).html(payload.name); } else if (payload.userInfo.name) { $(USERNAME).html(payload.userInfo.name); } // if isAdmin isnt set, call promise, else check if user is admin, hide user permissions link if not if (!isAdmin) { haas.jwToken.getUserInfo().then(function(data) { isAdminValidation(data.admin_flag); }); } else { isAdminValidation(isAdmin); } }, init: function(payload){ var self = this; self.loggedIn = haas.jwToken.isValid(payload); console.log('THIS DROPDOWN PAYLOAD', payload); // show appropriate menu items if (self.loggedIn){ self.login(payload); $.get({ url: '/ecommpartsstorefront/ecommparts/en/hybris-cart', cache: false }).done(function(activeUser){ if (activeUser.user === 'anonymous' || payload.email.toLowerCase() != activeUser.user.toLowerCase()) { self.logout(); } else { return true; } }).fail(function(){ console.log('Hybris Session Mismatch, logging user out.'); self.logout(); }); } else { self.logout(); } }, refresh: function() { var self = this; $.when(haas.jwToken.jwtPromise).then(function (payload) { self.init(payload); }); } }; function init() { haas.LOGGER.debug('Initializing MyHaas dropdown'); $.when(haas.jwToken.jwtPromise).then(function (payload) { haas.LOGGER.debug(payload); return haas.jwToken.getUserInfo().then(function(userData) { haas.fleet.myHaasDropdown.init(userData); }); }); $('span.myHaas').off('click').on('click', function(e){ $(this).toggleClass('open'); }); $('body').mouseup(function(e) { if (!$('span.myHaasDropdown').is(e.target) && !$('span.myHaas *').is(e.target)) { $('span.myHaas').removeClass('open'); } }); if ($('.my-haas-legacy').length) { $('body').addClass('myHaas-hide'); } // add "return to" param in logout links $('#myhaas-logout-base').attr('href', $('#myhaas-logout-base').attr('href') + '?returnTo=' + window.location.pathname); $('#myhaas-logout-ecomm').attr('href', $('#myhaas-logout-ecomm').attr('href') + '?returnTo=' + window.location.pathname); } function isAdminValidation(adminStatus) { if (adminStatus !== '01') { $('.logged-in-bottom-menu a').filter(function(ndx, element) { return $(element).attr('href').indexOf('user-permissions') !== -1; }).hide(); } } $(document).ready(function(){ init(); }); })(); $(document).ready(function(){ var $machinesTab = $('.tabs a[href="#tab_machines_0"]'); var $optionsTab = $('.tabs a[href=\"#tab_options_0"]'); var $productTables = $("table.producttable"); var $optionTables = $("table.optiontable"); var $seriesImage = $(".series-image"); var $seriesIntro = $(".series-intro"); var $priceListSection = $(".price-list.section"); // Change ID and placeholder text on filter form $("ul.tabs li").click(function() { $seriesImage.show(); $(".series-intro").show(); $priceListSection.show(); if ($optionsTab.hasClass('active')) { $optionTables.each(function() { var $optionTable = $(this); var $series = $optionTable.parents(".series"); var $totalOptionTableRows = $optionTable.find("tr.item-name"); var $hiddenOptionTableRows = $totalOptionTableRows.filter(function(){ return this.style.display === 'none'}); if ($totalOptionTableRows.length === $hiddenOptionTableRows.length) { $series.find(".series-image").hide(); $series.find(".series-intro").hide(); $optionTable.hide(); } }); $(".price-list.section").each(function() { var $thisPriceList = $(this); var $totalOptionTables = $thisPriceList.find('.optiontable'); var $hiddenOptionTables = $totalOptionTables.filter(function(){ return this.style.display === 'none'}); if ($totalOptionTables.length === $hiddenOptionTables.length) { $thisPriceList.hide(); } }); } if ($machinesTab.hasClass('active')) { $productTables.each(function() { var $productTable = $(this); var $series = $productTable.parents(".series"); var $totalProductTableRows = $productTable.find("tr.item-name"); var $hiddenProductTableRows = $totalProductTableRows.filter(function(){ return this.style.display === 'none'}); if ($totalProductTableRows.length === $hiddenProductTableRows.length) { $series.find(".series-image").hide(); $series.find(".series-intro").hide(); $productTable.hide(); } }).show(); $(".price-list.section").each(function() { var $thisPriceList = $(this); var $totalProductTables = $thisPriceList.find('.producttable'); var $hiddenProductTables = $totalProductTables.filter(function(){ return this.style.display === 'none'}); if ($totalProductTables.length === $hiddenProductTables.length) { $thisPriceList.hide(); } }); } }); /////////////////////////////////// //Machine Search Code //code to wait for user to stop typing var typingTimer,optionTypingTimer; var doneTypingInterval = 800; var $inputMachine = $("#product-filter"); $inputMachine.on("keyup", function () { clearTimeout(typingTimer); typingTimer = setTimeout(doneTypingMachine, doneTypingInterval); }); $inputMachine.on("keydown", function () { clearTimeout(typingTimer); }); var $inputOption = $("#option-filter"); $inputOption.on("keyup", function () { clearTimeout(optionTypingTimer); optionTypingTimer = setTimeout(doneTypingOption, doneTypingInterval); }); $inputOption.on("keydown", function () { clearTimeout(optionTypingTimer); }); function doneTypingMachine () { $priceListSection.show(); $productTables.show(); $seriesImage.show(); $seriesIntro.show(); var optMachine = $inputMachine.val().toLowerCase(); $("table.producttable .item-name").each(function() { var sMachine = $(this).text().toLowerCase(); $(this).closest(".item-name")[ sMachine.indexOf(optMachine) !== -1 ? "show" : "hide" ](); }); if ((optMachine !== "") || (optMachine !== "null")){ $("table.producttable").each(function() { var $productTable = $(this); var $series = $productTable.parents(".series"); var $totalRowItems = $productTable.find("tr.item-name"); var $hiddenRowItems = $totalRowItems.filter(function(){ return this.style.display === 'none'}); if ($totalRowItems.length === $hiddenRowItems.length) { $series.find(".series-image").hide(); $series.find(".series-intro").hide(); $productTable.hide(); } }); $(".price-list.section").each(function() { var $priceList = $(this); var $totalTableItems = $priceList.find("table.producttable"); var $hiddenTableItems = $totalTableItems.filter(function(){ return this.style.display === 'none'});; if ($totalTableItems.length === $hiddenTableItems.length) { $priceList.hide(); } }); } else { $priceListSection.show(); $productTables.show(); $seriesImage.show(); $seriesIntro.show(); } } //Option Search Code //code to wait for user to stop typing function doneTypingOption () { $priceListSection.show(); $optionTables.show(); $seriesImage.show(); $seriesIntro.show(); var optOption = $inputOption.val().toLowerCase(); $("table.optiontable .item-name").each(function() { var sOption = $(this).text().toLowerCase(); $(this).closest(".item-name")[ sOption.indexOf(optOption) !== -1 ? "show" : "hide" ](); }); if ((optOption !== "") || (optOption !== "null")){ $("table.optiontable").each(function() { var $optionTable = $(this); var $series = $optionTable.closest(".series"); var $totalOptionRowItems = $optionTable.find("tr.item-name"); var $hiddenOptionRowItems = $totalOptionRowItems.filter(function(){ return this.style.display === 'none'}); if ($totalOptionRowItems.length === $hiddenOptionRowItems.length) { $series.find(".series-image").hide(); $series.find(".series-intro").hide(); $optionTable.hide(); } }); $(".price-list.section").each(function() { var $priceList = $(this); var $totalOptionTableItems = $priceList.find("table.optiontable"); var $hiddenOptionTableItems = $totalOptionTableItems.filter(function(){ return this.style.display === 'none'}); if ($totalOptionTableItems.length === $hiddenOptionTableItems.length) { $priceList.hide(); } }); } else { $priceListSection.show(); $optionTables.show(); $seriesImage.show(); $seriesIntro.show(); } } }); $(function() { if ($('.findADealer').length) { haas.findADealer.init(); } }); (function () { 'use strict'; var haas = window.haas || {}; haas.findADealer = { constants: { templates: { HFO_IMAGE: 'hfo-image', HFO_ADDRESS: 'hfo-address', HFO_CONTACT: 'hfo-contact', HFO_EMAIL: 'hfo-email', HFO_TELEPHONE: 'hfo-telephone', HFO_NO_RESULTS: 'findADealer-noResults' }, ENDPOINT: '/bin/haascnc/processFindADealer.json', REGION_ENDPOINT: '/bin/haascnc/region/list.json' }, countries: [], selectors: { COUNTRIES: '.countryAll', ERROR: '#ErrorDiv', LOADING: '#LoadingDiv', POSTAL: '#zipCode', POSTAL_WRAPPER: '.postalZip', REGIONS: '.country-region', headers: { ADDRESS: '#address-header', EDUCATION: '#education-header', SALES: '#sales-header', SERVICE: '#service-header' }, results: { ADDRESS: '#results', EDUCATION: '#contact-education', SALES: '#contact-sales', SERVICE: '#contact-service' } }, mode: 'long-form', hfoCountryOverride: '', hfoOverride: '', hfoZipcodeOverride: '', init: function () { var self = this; this.initMode(); this.configureEvents(); this.loadTemplates(); this.requestRegions(self, this.initializeCountries); this.populateHFO(); }, initMode: function() { var findADealerSelector = $('.findadealer')[0]; var isShortForm = $(findADealerSelector).data('shortform'); var hasHFOoverride = $(findADealerSelector).attr('data-hfo-id-override'); var hasHFOcountryOverride = $(findADealerSelector).attr('data-hfo-country-override'); var hasZipcodeOverride = $(findADealerSelector).attr('data-hfo-zipcode-override') || ''; if (hasHFOoverride && hasHFOoverride.length) this.hfoOverride = hasHFOoverride; if (hasHFOcountryOverride && hasHFOcountryOverride.length) this.hfoCountryOverride = hasHFOcountryOverride; if (hasZipcodeOverride && hasZipcodeOverride.length) this.hfoZipcodeOverride = hasZipcodeOverride; if (isShortForm) { this.mode = 'short-form'; for (var key in this.selectors.headers) { this.selectors.headers[key] = '#short-form ' + this.selectors.headers[key]; } for (var key in this.selectors.results) { this.selectors.results[key] = '#short-form ' + this.selectors.results[key]; } } else { for (var key in this.selectors.headers) { this.selectors.headers[key] = '#long-form ' + this.selectors.headers[key]; } for (var key in this.selectors.results) { this.selectors.results[key] = '#long-form ' + this.selectors.results[key]; } } }, initMultipleModes: function(ndx) { var findADealerSelector = $('div.findadealer')[ndx]; var isShortForm = $(findADealerSelector).data('shortform') ? 'short-form' : 'long-form'; var hasHFOoverride = $(findADealerSelector).attr('data-hfo-id-override') || ''; var hasHFOcountryOverride = $(findADealerSelector).attr('data-hfo-country-override') || ''; var hasZipcodeOverride = $(findADealerSelector).attr('data-hfo-zipcode-override') || ''; return [isShortForm, hasHFOoverride, hasHFOcountryOverride, hasZipcodeOverride]; }, clearResults: function() { $('#results, #contact-sales, #contact-service, #contact-education').empty(); this.displayHeader($(this.selectors.headers.ADDRESS), $(this.selectors.results.ADDRESS)); $(this.selectors.results.ADDRESS).addClass('hidden'); this.displayHeader($(this.selectors.headers.SALES), $(this.selectors.results.SALES)); this.displayHeader($(this.selectors.headers.SERVICE), $(this.selectors.results.SERVICE)); this.displayHeader($(this.selectors.headers.EDUCATION), $(this.selectors.results.EDUCATION)); $(this.selectors.ERROR).empty(); }, configureEvents: function () { var self = this; var submit_form = function() { var country = $(self.selectors.COUNTRIES).val(); var zip = $(self.selectors.POSTAL).val(); if(!self.validateZipCode(zip)) { return; } self.clearResults(); self.addLoadingGif(); self.requestHfo(country, null, zip, self.render); } $('#zipCode').blur(function() { return self.validateZipCode($(this).val()); }); $('#zipCode').keyup(function(e) { if (e.which === 13) { e.preventDefault(); submit_form(); } }); $('.findadealer').submit(function(e) { e.preventDefault(); submit_form(); }); $(document).on('change', self.selectors.COUNTRIES, function() { self.handleCountryChange(self, this); }); $(document).on('change', self.selectors.REGIONS, function() { self.handleRegionChange(self, this); }); }, displayHeader: function($header, $container, customMode) { var useMode = customMode ? customMode : this.mode; if (useMode === 'short-form') { $('#short-form .findadealer-loading').remove(); } if (useMode === 'long-form') { $('#long-form #LoadingDiv').hide(); } $container.children().length > 0 ? $header.show() : $header.hide(); }, handleCountryChange: function(self, event) { self.clearResults(); var zip = $(self.selectors.POSTAL_WRAPPER); var countryRegion = $(self.selectors.REGIONS); zip.hide(); countryRegion.hide().html(""); if (!event.value) { return; } var countryInfo = self.countries[event.value]; if (countryInfo.showPostal) { zip.show(); } else if (countryInfo.regions) { countryRegion.append(""); countryInfo.regions.map(function (region) { countryRegion.append(" "); }); countryRegion.show(); } else { self.addLoadingGif(); self.requestHfo(event.value, null, null, self.render); } }, handleRegionChange: function(self, event) { self.clearResults(); if (!event.value) { return; } var country = $(self.selectors.COUNTRIES).val(); self.addLoadingGif(); self.requestHfo(country, decodeURIComponent(event.value), null, self.render); }, initializeCountries: function(self, data) { self = self || this; if(data.success) { var ret = ''; for (var i = 0; i < data.result.length; i++) { var row = data.result[i]; self.countries[row.code] = row; ret += ''; } $(".countryAll").append(ret); } }, loadTemplates: function() { this.template = { hfoImage: _.template($('#' + this.constants.templates.HFO_IMAGE).html()), hfoAddress: _.template($('#' + this.constants.templates.HFO_ADDRESS).html()), hfoContact: _.template($('#' + this.constants.templates.HFO_CONTACT).html()), hfoEmail: _.template($('#' + this.constants.templates.HFO_EMAIL).html()), hfoTelephone: _.template($('#' + this.constants.templates.HFO_TELEPHONE).html()), hfoNoResults: _.template($('#' + this.constants.templates.HFO_NO_RESULTS).html()) }; }, addLoadingGif: function(){ $(this.selectors.LOADING).show(); }, removeLoadingGif: function(){ $(this.selectors.LOADING).hide(); }, render: function(self, payload) { self = self || this; self.removeLoadingGif(); self.clearResults(); var $results = $(self.selectors.results.ADDRESS); var $contactSales = $(self.selectors.results.SALES); var $contactService = $(self.selectors.results.SERVICE); var $contactEducation = $(self.selectors.results.EDUCATION); if(!payload || payload.length == 0) { var $errorDiv = $(self.selectors.ERROR); $errorDiv.html($errorDiv.data('results-error')); } else { _.each(payload, function(hfo) { var data = { hfo: hfo, email: self.template.hfoEmail, telephone: self.template.hfoTelephone }; switch(hfo.PartnerFunc) { case 'Y1': $results.append(self.template.hfoImage(data), self.template.hfoAddress(data)); break; case 'Y2': $contactEducation.append(self.template.hfoAddress(data)); break; case 'Y3': $contactSales.append(self.template.hfoContact(data)); break; case 'Y4': $contactService.append(self.template.hfoContact(data)); break; } }); } if ($('select.countryAll').val() === 'DE') { $('.hfo-column .default').hide(); $('.hfo-column .germany-variant').removeClass('hidden'); } else { $('.hfo-column .default').show(); $('.hfo-column .germany-variant').addClass('hidden'); } self.displayHeader($(self.selectors.headers.ADDRESS), $results); $results.removeClass('hidden'); self.displayHeader($(self.selectors.headers.SALES), $contactSales); self.displayHeader($(self.selectors.headers.SERVICE), $contactService); self.displayHeader($(self.selectors.headers.EDUCATION), $contactEducation); }, requestHfo: function(country, region, zip, callback) { var self = this; var data = { country: country, region: region, zip: zip }; $.ajax({ type: 'GET', url: self.constants.ENDPOINT, contentType: 'json', data: data, success: function (data) { data.sort((a,b) => (a.Default_Address === b.Default_Address) ? 1 : a.Default_Address ? -1 : 0); callback(self, data); console.log('FETCHED HFO DATA', data); } }); }, requestRegions: function(self, callback) { $.ajax({ type: 'GET', url: self.constants.REGION_ENDPOINT, contentType: 'json', success: function (data) { callback(self, data); } }); }, populateHFO: function() { var self = this; var multipleComponents = $('div.findadealer').length > 1; if (multipleComponents) { $.when(haas.region.priceGroupPromise).then(function(priceGroup) { $('div.findadealer').each(function(ndx, element) { var attributes = self.initMultipleModes(ndx); console.log(ndx, attributes, element); var mode = attributes[0]; var userCountry = attributes[2].length ? attributes[2] : priceGroup.country; var userHfo = attributes[1].length ? attributes[1] : priceGroup.hfoid; var userZipcode = attributes[3].length ? attributes[3] : ''; var disableAutocomplete = $(element).attr('data-disable-autocomplete'); var data = { country: userCountry }; if (userCountry === 'US' && userZipcode.length) { self.requestHfo(userCountry, '', userZipcode, self.render); } else if (priceGroup.country !== 'US' && disableAutocomplete && disableAutocomplete === 'true') { $(element).find('.countryAll').val(priceGroup.country).trigger('change'); self.configureEvents(); } else { self.addLoadingGif(); $.ajax({ type: 'GET', url: self.constants.ENDPOINT, contentType: 'json', data: data }).then(function(payload) { /* var $results = $(self.selectors.results.ADDRESS); var $contactSales = $(self.selectors.results.SALES); var $contactService = $(self.selectors.results.SERVICE); var $contactEducation = $(self.selectors.results.EDUCATION); */ var data = {}; var $results = $(element).find('#results'); var $contactSales = $(element).find('#contact-sales'); var $contactService = $(element).find('#contact-service'); var $contactEducation = $(element).find('#contact-education'); if (mode === 'short-form') { var personalHFO = payload.filter(function(hfo) { return hfo.PartnerFunc === 'Y1' && hfo.DealerId === userHfo; })[0]; data = { hfo: personalHFO, email: self.template.hfoEmail, telephone: self.template.hfoTelephone }; if (data.hfo) { $results.append(self.template.hfoImage(data), self.template.hfoAddress(data)); self.displayHeader($(element).find('#address-header'), $results, mode); } else { var contactUsLink = '/content/haascnc/' + $('html').attr('lang') + '/about/contact.html'; var $errorContainer = $('#error'); $errorContainer.append(self.template.hfoNoResults({contactUsLink: contactUsLink})); $(element).find('#short-form .findadealer-loading').remove(); self.configureEvents(); self.requestRegions(self, self.initializeCountries); } } if (mode === 'long-form') { var hfoList = payload.filter(function(hfo) { return hfo.DealerId === userHfo; }); var hfoResult = []; var hfoEducation = []; var hfoSales = []; var hfoService = []; console.log('HFOLIST', hfoList); _.each(hfoList, function(hfo) { var data = { hfo: hfo, email: self.template.hfoEmail, telephone: self.template.hfoTelephone }; switch(hfo.PartnerFunc) { case 'Y1': console.log('Y1', data); if (!hfoResult.length) { hfoResult.push(hfo); $results.append(self.template.hfoImage(data), self.template.hfoAddress(data)); } break; case 'Y2': var seen = hfoEducation.some(function(recordedHfo) { return hfo.HFOName === recordedHfo.HFOName && hfo.Longname === recordedHfo.Longname; }); if (!seen) { hfoEducation.push(hfo); $contactEducation.append(self.template.hfoAddress(data)); } break; case 'Y3': var seen = hfoSales.some(function(recordedHfo) { return (hfo.FirstName === recordedHfo.FirstName && hfo.LastName === recordedHfo.LastName) || hfo.Longname === recordedHfo.Longname; }); if (!seen) { hfoSales.push(hfo); $contactSales.append(self.template.hfoContact(data)); } break; case 'Y4': $contactService.append(self.template.hfoContact(data)); break; } }); self.displayHeader($(element).find('#address-header'), $results, mode); $results.removeClass('hidden'); self.displayHeader($(element).find('#sales-header'), $contactSales, mode); self.displayHeader($(element).find('#service-header'), $contactService, mode); self.displayHeader($(element).find('#education-header'), $contactEducation, mode); } }); } }); }); } else { $.when(haas.region.priceGroupPromise).then(function(priceGroup) { var userCountry = self.hfoCountryOverride.length ? self.hfoCountryOverride : priceGroup.country; var userHfo = self.hfoOverride.length ? self.hfoOverride : priceGroup.hfoid; var userZipcode = self.hfoZipcodeOverride.length ? self.hfoZipcodeOverride : ''; var disableAutocomplete = $('div.findadealer').attr('data-disable-autocomplete'); var data = { country: userCountry }; if (userCountry === 'US' && userZipcode.length) { self.requestHfo(userCountry, '', userZipcode, self.render); } else if (disableAutocomplete && disableAutocomplete === 'true') { $(element).find('.countryAll').val(priceGroup.country).trigger('change'); } else { $.ajax({ type: 'GET', url: self.constants.ENDPOINT, contentType: 'json', data: data }).then(function(payload) { var $results = $(self.selectors.results.ADDRESS); var $contactSales = $(self.selectors.results.SALES); var $contactService = $(self.selectors.results.SERVICE); var $contactEducation = $(self.selectors.results.EDUCATION); var data = {}; if (self.mode === 'short-form') { var personalHFO = payload.filter(function(hfo) { return hfo.PartnerFunc === 'Y1' && hfo.DealerId === userHfo; })[0]; data = { hfo: personalHFO, email: self.template.hfoEmail, telephone: self.template.hfoTelephone }; if (data.hfo) { $results.append(self.template.hfoImage(data), self.template.hfoAddress(data)); self.displayHeader($(self.selectors.headers.ADDRESS), $results); $results.removeClass('hidden'); } else { var contactUsLink = '/content/haascnc/' + $('html').attr('lang') + '/about/contact.html'; var $errorContainer = $('#error'); $errorContainer.append(self.template.hfoNoResults({contactUsLink: contactUsLink})); $('#short-form .findadealer-loading').remove(); self.configureEvents(); self.requestRegions(self, self.initializeCountries); } } if (self.mode === 'long-form') { var hfoList = payload.filter(function(hfo) { return hfo.DealerId === userHfo; }); var hfoResult = []; var hfoEducation = []; var hfoSales = []; var hfoService = []; _.each(hfoList, function(hfo) { var data = { hfo: hfo, email: self.template.hfoEmail, telephone: self.template.hfoTelephone }; switch(hfo.PartnerFunc) { case 'Y1': if (!hfoResult.length) { hfoResult.push(hfo); $results.append(self.template.hfoImage(data), self.template.hfoAddress(data)); } break; case 'Y2': var seen = hfoEducation.some(function(recordedHfo) { return hfo.HFOName === recordedHfo.HFOName && hfo.Longname === recordedHfo.Longname; }); if (!seen) { hfoEducation.push(hfo); $contactEducation.append(self.template.hfoAddress(data)); } break; case 'Y3': var seen = hfoSales.some(function(recordedHfo) { return (hfo.FirstName === recordedHfo.FirstName && hfo.LastName === recordedHfo.LastName) || hfo.Longname === recordedHfo.Longname; }); if (!seen) { hfoSales.push(hfo); $contactSales.append(self.template.hfoContact(data)); } break; case 'Y4': $contactService.append(self.template.hfoContact(data)); break; } }); self.displayHeader($(self.selectors.headers.ADDRESS), $results); $results.removeClass('hidden'); self.displayHeader($(self.selectors.headers.SALES), $contactSales); self.displayHeader($(self.selectors.headers.SERVICE), $contactService); self.displayHeader($(self.selectors.headers.EDUCATION), $contactEducation); } }); } }); } }, validateZipCode: function(zip) { var $errorDiv = $(this.selectors.ERROR); $errorDiv.empty(); var message = $errorDiv.data('zip-error'); var isValid = /(^\d{5}$)|(^\d{5}-\d{4}$)/.test(zip); if(!isValid) { $errorDiv.html(message); } return isValid; } }; })(); $(document).ready(function(){ var todayDate = new Date().valueOf(); todayDate = todayDate - 100000000; Array.from(document.querySelectorAll('.event_list')).forEach(eventElem => { let startDateElem = eventElem.querySelector('.stDate'); let endDateElem = eventElem.querySelector('.exDate'); if (startDateElem && !endDateElem) { let stDateValue = startDateElem.innerHTML; let stDateConverted = new Date(stDateValue).valueOf(); if (startDateElem.dataset.format === 'eu') stDateConverted = convertDate(stDateConverted); if (stDateConverted < todayDate) { eventElem.querySelector('table').classList.add('expired'); if (eventElem.querySelector('.event-status')) eventElem.querySelector('.event-status').innerHTML = 'EXPIRED'; } else { eventElem.querySelector('table').classList.remove('expired'); } } else if (startDateElem && endDateElem) { let exDateValue = endDateElem.innerHTML; let exDateConverted = new Date(exDateValue).valueOf(); if (endDateElem.dataset.format === 'eu') exDateConverted = convertDate(exDateConverted).valueOf(); if (exDateConverted < todayDate){ eventElem.querySelector('table').classList.add('expired'); if (eventElem.querySelector('.event-status')) eventElem.querySelector('.event-status').innerHTML = 'EXPIRED'; } else { eventElem.querySelector('table').classList.remove('expired'); } } }); function convertDate(dateString) { let date = new Date(dateString); return Date.parse(date.toLocaleDateString("en-GB")); } }); (function () { haas.components.EcommerceSearch = haas.Component.create({ zmachTypeMap: {}, machineTypeMinYearMap: { 'VERTICAL': 1992, 'HORIZONTAL': 1998, 'LATHE': 1998, 'ROTARY': 2000, 'BARFEEDER': 2007 }, siteSearch360languageIdMap: { 'en': '3293', 'nl': '8415', 'pl': '8413', 'es': '8371', 'it': '8410', 'fr': '8405', 'de': '8411' }, servicePartsSearchPath: '/Community/Events/Haas_Service_Parts/Serial_Number_Search.html', preRender: function() { // hide winner circle for non-US this.hideWinnerCircleItems(); // Unhide url specific features if (window.location.href.includes('haas-tooling')) { const userLang = haas.utils.getLanguage(); if (this.siteSearch360languageIdMap[userLang]) { // dynamically load search script for performance let siteSearch360Script = document.createElement('script'); siteSearch360Script.async = true; siteSearch360Script.src = 'https://js.sitesearch360.com/plugin/bundle/'+this.siteSearch360languageIdMap[userLang]+'.js'; this.elementNode.appendChild(siteSearch360Script); this.elementNode.querySelector('.ecomm-search-container-en').classList.remove('hidden'); } else { this.elementNode.querySelector('.ecomm-search-container').classList.remove('hidden'); } if (screen.width > 800) { this.$element.find('.ecomm-searchbar > .htooling').removeClass('hidden') } } if (window.location.href.includes('haas-service-parts')) { this.$element.find('.ecomm-searchbar > .hsparts').removeClass('hidden'); } if (window.location.href.includes('Serial_Number_Search')) { this.elementNode.querySelector('#hp-search-dropdown-btn').classList.add('hidden'); this.elementNode.querySelector('.ecomm-searchbar > .hsparts').classList.remove('hidden'); } // Hide Dropdown in Primary Nav $('.ecomm-nav-container > .ecomm-search-container > .ecomm-searchbar > .cat-dropdown').hide(); // Hide Spart Parts Category this.$element.find('.mob-subcats [href="/content/haascnc/en/haas-tooling/tooling_accessories/spare_parts.html"]').hide(); // Set Tooling Home URL this.$element.find('.hbut > a').attr('href', '/content/haascnc/' + localStorage.storedSiteLang + '/haas-tooling.html'); // Set Service Parts Home URL this.$element.find('.hbut > #hsp-home').attr('href', '/content/haascnc/' + localStorage.storedSiteLang + '/haas-service-parts.html'); }, hideCategoriesPerCurrency: function() { let self = this; let userCurrency = haas.cookies.getCookie('tooling-currency'); $('a[href="/content/haascnc/en/haas-tooling/holemaking/cobalt_drills_sets.html"]').attr('data-available-currencies', 'USD, EUR, PLN, CZK, DKK, SEK,'); Array.from(self.elementNode.querySelectorAll('.parent-cat.ecomm-category-link')).forEach(parentCategory => { let parentAvailableCurrencies = parentCategory.dataset.availableCurrencies; Array.from(parentCategory.parentElement.querySelectorAll('.mob-subcats .ecomm-category-link')).forEach(childCategory => { let childAvailableCurrencies = childCategory.dataset.availableCurrencies; if (childAvailableCurrencies.length > parentAvailableCurrencies.length) { parentAvailableCurrencies = childAvailableCurrencies; parentCategory.dataset.availableCurrencies = childAvailableCurrencies; } if (!childAvailableCurrencies.includes(userCurrency)) childCategory.parentElement.style.display = 'none'; }); if (!parentAvailableCurrencies.includes(userCurrency)) parentCategory.parentElement.style.display = 'none'; }); }, hideWinnerCircleItems: function() { let self = this; $.when(haas.region.priceGroupPromise).then(function(priceData) { if (priceData.country !== 'US') { let winnerCircleParent = Array.from(self.elementNode.querySelectorAll('.parent-cat')).find(parentCatElem => parentCatElem.href.includes('winner')); if (winnerCircleParent) { let winnerCircleCategory = winnerCircleParent.parentElement; winnerCircleCategory.style.display = 'none'; } } }); }, handleAdvancedSearch: function(e) { let self = this; let keywords = self.elementNode.querySelector('#ecomm-search-input').value; let bcsModalContent = document.querySelector('.bcs-modal .bcs-modal-body .bcs-results'); if (e.type === 'keydown' && !(e.keyCode === 13 && keywords.length)) return; haas.bcsToolingSearch.resetOffset(); document.querySelector('.bcs-pagination a.bcs-current-page').innerText = '1'; if (window.innerWidth <= 800) { bcsModalContent = document.querySelector('#mobile-search-box-container .bcs-modal .bcs-modal-body .bcs-results'); } haas.bcsToolingSearch.performSearch(keywords).then(res => { let webPages = (res.webPages && res.webPages.value) ? res.webPages.value : []; if (webPages && webPages.length) { let resultTemplate = _.template(document.querySelector('#pageResultTemplate').innerHTML); // empty container of results bcsModalContent.innerHTML = ''; // populate container with results webPages.forEach(function(page) { bcsModalContent.innerHTML = bcsModalContent.innerHTML + resultTemplate({ page_link: page.url, page_title: page.name, page_caption:page.snippet }); }); if (window.innerWidth <= 800) { document.querySelector('.search_box_top_wrapper').style.display = 'block'; document.querySelector('#mobile-search-box-container .bcs-modal').classList.add('bcs-tooling-search'); document.querySelector('#mobile-search-box-container .bcs-pagination-container').style.display = 'block'; document.querySelector('#mobile-search-box-container .bcs-modal').style.display = 'block'; } else { document.querySelector('.bcs-modal').classList.add('bcs-tooling-search'); document.querySelector('.bcs-pagination-container').style.display = 'block'; document.querySelector('.bcs-modal').style.display = 'block'; } } else { console.log('NO RESULTS for ', keywords); let noResultTemplate = _.template(document.querySelector('#pageResultNoResults').innerHTML); bcsModalContent.innerHTML = noResultTemplate({ result_text: document.querySelector('#pageResultNoResults').dataset.text, search_term: keywords }); if (window.innerWidth <= 800) { document.querySelector('#mobile-search-box-container .bcs-modal').classList.add('bcs-tooling-search'); document.querySelector('#mobile-search-box-container .bcs-pagination-container').style.display = 'none'; document.querySelector('#mobile-search-box-container .bcs-modal').style.display = 'block'; } else { document.querySelector('.bcs-modal').classList.add('bcs-tooling-search'); document.querySelector('.bcs-pagination-container').style.display = 'none'; document.querySelector('.bcs-modal').style.display = 'block'; } } }); }, bindMobileParentCategoryClick: function() { this.$element.find('.cat-column > a').on('touchstart', function(e) { e.stopImmediatePropagation(); e.preventDefault(); if (!$(this).siblings('.mob-subcats').hasClass('hidden')) { $(this).siblings('.mob-subcats').slideUp(); $(this).siblings('.mob-subcats').addClass('hidden'); } else { $(this).siblings('.mob-subcats').slideDown(); $(this).siblings('.mob-subcats').removeClass('hidden'); } $(this).children('h3').children('i').toggleClass('fa-caret-right fa-caret-down') }); }, bindMobileCategoryBtnClick: function() { this.$element.find('.cat-dropbtn').on('touchstart', function(e) { e.stopImmediatePropagation(); e.preventDefault(); if (!$(this).siblings('.cat-dropdown-content').hasClass('hidden')) { $(this).siblings('.cat-dropdown-content').addClass('hidden'); } else { $(this).siblings('.cat-dropdown-content').removeClass('hidden'); } }); }, bindDesktopCategoryBtnClick: function() { // Desktop Dropdown Button handler this.$element.find('.cat-dropbtn').on('click', function(e) { e.stopImmediatePropagation(); e.preventDefault(); $('.cat-navbar').css('background-color', '#cb2c31'); $('.mob-subcats').removeClass('hidden'); if (!$(this).siblings('.cat-dropdown-content').hasClass('hidden')) { $(this).siblings('.cat-dropdown-content').addClass('hidden'); } else { $('.cat-dropdown-content').addClass('fade-bg'); $(this).siblings('.cat-dropdown-content').removeClass('hidden'); } $('html').one('click',function() { $('.cat-dropdown-content').addClass('hidden'); }); }); }, bindServicePartsDowndownBtn: function() { let self = this; self.elementNode.querySelector('#hp-search-dropdown-btn').onclick = () => { if (self.elementNode.querySelector('#user-machine-input-container').classList.contains('hidden')) { self.elementNode.querySelector('#user-machine-input-container').classList.remove('hidden'); } else { self.elementNode.querySelector('#user-machine-input-container').classList.add('hidden'); } } }, bindInputEvents: function() { let self = this; let searchInput = self.elementNode.querySelector('#ecomm-search-input'); let searchBtn = self.elementNode.querySelector('#ecomm-search-btn') searchInput.onkeydown = self.handleAdvancedSearch.bind(self); searchBtn.onclick = self.handleAdvancedSearch.bind(self); }, clearYearOptions: function() { let self = this; Array.from(self.elementNode.querySelectorAll('#machineInfoYear option')).forEach(optElem => { if (!optElem.classList.contains('default')) optElem.outerHTML = ''; }); }, clearModelOptions: function() { let self = this; Array.from(self.elementNode.querySelectorAll('#machineInfoModel option')).forEach(optElem => { if (!optElem.classList.contains('default')) optElem.outerHTML = ''; }); }, initYears: function() { let self = this; let currentYear = new Date().getFullYear(); let firstYear = self.machineTypeMinYearMap[self.elementNode.querySelector('#machineInfoType').value]; // Using the min dates found per machine on parts haascnc let yearSelectElement = self.elementNode.querySelector('#machineInfoYear'); for (let year = currentYear; year >= firstYear; year--) { let yearOptionElement = document.createElement('option'); yearOptionElement.value = year; yearOptionElement.innerText = year; yearSelectElement.append(yearOptionElement); } }, initMachineModels: function(type, year, model) { let self = this; fetch(haas.constants.api.modelYearSearch(type, year)) .then(res => res.json()) .then(pl => { if (pl.exp_error_code.zreturncode !== '000') self.showTypeYearErrorModal(); let modelList = pl.exp_tab_model_list.map(elem => elem.zmaterial); let modelSelectElement = self.elementNode.querySelector('#machineInfoModel') for (const model of modelList) { if (model.endsWith('-V') || model.endsWith('-EU') || model.endsWith('-I') || model.endsWith('-UK') || model.endsWith('-SE')) continue; let modelOptionElement = document.createElement('option'); modelOptionElement.value = model; modelOptionElement.innerText = model; modelSelectElement.append(modelOptionElement); } }).then(() => { self.elementNode.querySelector('#machineInfoModel').disabled = false; self.elementNode.querySelector('#machineInfoSearchBtn').disabled = true; }) .then(() => { if (model) { self.elementNode.querySelector('#machineInfoModel option[value="'+model+'"').selected = true; self.handleMachineModelChange(); self.elementNode.querySelector('#machineInfoSearchBtn').click(); } }) }, handleMachineTypeChange: function(e) { let self = this; self.elementNode.querySelector('#machineInfoYear option.default').selected = true; self.elementNode.querySelector('#machineInfoModel option.default').selected = true; self.clearYearOptions(); self.clearModelOptions(); self.initYears(); self.elementNode.querySelector('#machineInfoYear').disabled = false; self.elementNode.querySelector('#machineInfoSearchBtn').disabled = true; self.elementNode.querySelector('#machineInfoModel').disabled = true; }, handleMachineYearChange: function(e) { let self = this; let type = self.elementNode.querySelector('#machineInfoType').value; let year = e.currentTarget.value; self.elementNode.querySelector('#machineInfoModel option.default').selected = true; self.clearModelOptions(); self.initMachineModels(type, year); }, handleMachineModelChange: function(e) { let self = this; self.elementNode.querySelector('#machineInfoSearchBtn').disabled = false; }, handleSerialValKeydown: function(e) { let self = this; if (e.keyCode === 13) self.elementNode.querySelector('#serialNumSearchBtn').click(); }, handleMachineInfoSearch: function() { let self = this; let machineType = self.elementNode.querySelector('#machineInfoType').value; let machineYear = self.elementNode.querySelector('#machineInfoYear').value; let machineModel = self.elementNode.querySelector('#machineInfoModel').value; window.location.href = '/content/haascnc/' + localStorage.storedSiteLang + self.servicePartsSearchPath + '?type=machineInfo&machineType='+machineType+'&machineYear='+machineYear+'&machineModel='+machineModel; }, handleMachineSerialSearch: function() { let self = this; let serialNumber = self.elementNode.querySelector('#serialNumInput').value; window.location.href = '/content/haascnc/' + localStorage.storedSiteLang + self.servicePartsSearchPath + '?type=serialNumber&serialNumber='+serialNumber; }, bindEvents: function () { let self = this; self.bindMobileParentCategoryClick(); self.bindMobileCategoryBtnClick(); self.bindDesktopCategoryBtnClick(); self.bindServicePartsDowndownBtn(); self.bindInputEvents(); self.elementNode.querySelector('#machineInfoSearchBtn').onclick = self.handleMachineInfoSearch.bind(self); self.elementNode.querySelector('#serialNumSearchBtn').onclick = self.handleMachineSerialSearch.bind(self); self.elementNode.querySelector('#serialNumInput').onkeydown = self.handleSerialValKeydown.bind(self); self.elementNode.querySelector('#machineInfoType').onchange = self.handleMachineTypeChange.bind(self); self.elementNode.querySelector('#machineInfoYear').onchange = self.handleMachineYearChange.bind(self); self.elementNode.querySelector('#machineInfoModel').onchange = self.handleMachineModelChange.bind(self); }, initialize: function () { let self = this; self.zmachTypeMap = { '01': self.elementNode.querySelector('#tl-data-container').dataset.vertical, '02': self.elementNode.querySelector('#tl-data-container').dataset.horizontal, '03': self.elementNode.querySelector('#tl-data-container').dataset.lathe, '04': self.elementNode.querySelector('#tl-data-container').dataset.automation, '05': self.elementNode.querySelector('#tl-data-container').dataset.rotary } self.bindEvents(); self.preRender(); if (!window.location.href.includes('haas-service-parts')) self.hideCategoriesPerCurrency(); } }); })(); (function() { haas.components.ServicePartsListing = haas.Component.create({ userData: '', hierarchyJson: {}, zmachTypeMap: {}, machineTypeMinYearMap: { 'VERTICAL': 1992, 'HORIZONTAL': 1998, 'LATHE': 1998, 'ROTARY': 2000, 'BARFEEDER': 2007 }, isInitialized: false, initialize: function() { let self = this; $.when(haas.jwToken.getUserInfo()).then((data) => { self.userData = data; console.log('JWT DECODED ASSIGNED', this.userData); }); self.hierarchyJson = JSON.parse(self.elementNode.querySelector('#part-listing-data').dataset.json); self.zmachTypeMap = { '01': self.elementNode.querySelector('#tl-data-container').dataset.vertical, '02': self.elementNode.querySelector('#tl-data-container').dataset.horizontal, '03': self.elementNode.querySelector('#tl-data-container').dataset.lathe, '04': self.elementNode.querySelector('#tl-data-container').dataset.automation, '05': self.elementNode.querySelector('#tl-data-container').dataset.rotary } }, addLoader: function() { this.elementNode.querySelector('.loader-container').innerHTML = haas.constants.loadingTmpl; }, removeLoader: function() { if (!this.isInitialized) { this.isInitialized = true; this.elementNode.querySelector('.loader-container').innerHTML = ''; this.elementNode.querySelector('.spa-container').classList.remove('hidden'); } }, render: function() { let self = this; let partsContainer = self.elementNode.querySelector('.spa-container'); this.addLoader(); self.renderCategories(self.hierarchyJson, partsContainer); this.renderPrices(); this.renderQuantityOptions(); this.bindEvents(); this.handleUrlParams(); }, handleUrlParams: function() { let self = this; let urlParams = new URLSearchParams(window.location.search); switch (urlParams.get('type')) { case 'machineInfo': let machineType = urlParams.get('machineType'); let machineYear = urlParams.get('machineYear'); let machineModel = urlParams.get('machineModel'); if (machineType && machineYear && machineModel) { self.elementNode.querySelector('#machineInfoType option[value="'+machineType+'"').selected = true; self.handleMachineTypeChange(); self.elementNode.querySelector('#machineInfoYear option[value="'+machineYear+'"').selected = true; self.handleYearAndModelSelection(machineModel); } break; case 'serialNumber': let qSerialNumber = urlParams.get('serialNumber'); if (qSerialNumber) { self.elementNode.querySelector('#serialNumInput').value = qSerialNumber; self.elementNode.querySelector('#serialNumSearchBtn').click(); } break; default: self.removeLoader(); break; } }, buildCategoryAccordion: function(categoryName) { let newAccordion = document.createElement('div'); let accordionHeader = document.createElement('div'); let accordionHeaderTxt = document.createElement('h2'); let accordionContent = document.createElement('div'); let accordionHeaderIcon = document.createElement('span'); newAccordion.classList.add('spl-category-accordion'); accordionHeader.classList.add('spl-accordion-header'); accordionHeaderIcon.classList.add('fa', 'fa-plus', 'spl-collapse-icon'); accordionHeaderTxt.innerText = categoryName; accordionContent.classList.add('spl-accordion-content'); accordionHeaderTxt.prepend(accordionHeaderIcon); accordionHeader.append(accordionHeaderTxt); newAccordion.append(accordionHeader); newAccordion.append(accordionContent); return newAccordion; }, renderCategories: function(parentCategory, parentContainer) { let self = this; if (parentCategory['isPLP']) { for (const key in parentCategory) { if (key === 'isPLP') continue; try { self.renderPartItem(JSON.parse(parentCategory[key]), parentContainer); } catch (e) { console.error('Error parsing object: ', parentCategory[key]); } } } else { for (const key in parentCategory) { let newContainer = self.buildCategoryAccordion(key); self.renderCategories(parentCategory[key], newContainer); if (parentContainer.classList.contains('spl-category-accordion')) parentContainer.querySelector('.spl-accordion-content').append(newContainer); else parentContainer.append(newContainer); } } }, renderPartItem: function(item, parentContainer) { let self = this; let itemContent = self.templates.partListItemTemplate({ itemSku: item.sku, itemCommonProduct: item.commonProduct, itemLink: item.link, itemImgSrc: item.imageHref, itemImgTitle: item.sku, itemImgAlt: item.sku, itemTitle: item.title, itemPrice: item.price.amount, itemAllPrices: item.allPrices.map(pItem => JSON.parse(pItem.replace("'", ''))), itemAllDiscountPrices: item.allDiscountPrices.map(pItem => JSON.parse(pItem.replace("'", ''))), hasStrikethroughPrice: item.hasStrikethroughPrice, rawPromoPrice: item.rawPromoPrice, propSixtyFive: item.californiaProposition65Required ? 'prop-sixty-five-req' : '', startDisabled: false }); parentContainer.querySelector('.spl-accordion-content').innerHTML = parentContainer.querySelector('.spl-accordion-content').innerHTML + itemContent; }, renderQuantityOptions: function() { this.$element.find('.part-list-item').each(function(ndx, elem) { var $quantityOptionContainer = $(elem).find('#quantity-select'); var options = ''; for (var i = 1; i <= 50; i++) { options = options + "'; } $quantityOptionContainer.html(options); }); }, renderPrices: function() { $.when(haas.region.priceGroupPromise).then(function() { if(haas.cookies.getCookie('tooling-currency') === 'undefined') { $('.check-out-container').hide(); $('.part-pricing').hide(); $('.alert').removeClass('hidden'); } else { $('.price-span').each(function() { $(this).html(haas.ecommUtils.formatPrice($(this).attr('data-price'))); if($(this).attr('data-currency') === haas.cookies.getCookie('tooling-currency')) { $(this).parent().removeClass('hidden'); $(this).show(); } }); $('.part-list-item').each(function(ndx, elem) { var $priceContainer = $(elem).find('.price-span ' + haas.cookies.getCookie('tooling-currency')); var $unitPriceContainer = $(elem).find('#unit-price'); $('.promo-' + haas.cookies.getCookie('tooling-currency')).each(function() { $(this).html(haas.ecommUtils.formatPrice($(this).attr('data-value'))); $(this).parent().removeClass('hidden'); $(this).parents('.part-list-item').addClass('ecomm-plp-promo'); }); if ($unitPriceContainer.attr('data-haspriceperpart') === 'true') { $unitPriceContainer.html('(' + haas.ecommUtils.formatPrice($unitPriceContainer.attr('data-perpricevalue')) + '/' + $unitPriceContainer.attr('data-partype') + ')'); $unitPriceContainer.removeClass('hidden'); } }); } }); }, timeoutModal: function() { setTimeout(function() { if ($('.haas-modal-wrapper').is('.open')) haas.components.Modal.close(); }, 1000); }, cartSuccessClickHandler: function() { haas.LOGGER.debug('Proceeding to Cart!'); $('#cart-success-btn').addClass('disabled'); $('#ecommerce-nav > a').click(); }, showSuccessModal: function(quantity) { // to-do: Add attributes in html to make this translatable var self = this; // Remove loading indicator $('body').removeClass('cursor-wait'); haas.components.Modal.open('

    Success! ' + quantity +' item(s) added to cart!

    '); $('#cart-success-btn').off('click').on('click', self.cartSuccessClickHandler); $('#continue-btn').off('click').on('click', haas.components.Modal.close); }, showErrorModal: function(error) { // Remove loading indicator $('body').removeClass('cursor-wait'); if (error.type === 'InsufficientStockError') { haas.components.Modal.open('

    Error! Item Out of Stock!

    '); this.timeoutModal(); } else if (error.type === 'CartError') { let self = this; haas.components.Modal.open('

    Error! Your cart has expired, creating new cart!

    '); let hybrisLogoutPayload = $.get(haas.constants.hybrisLogout); let eatCookiesPayload = $.get(haas.constants.api.eatcookies); return $.when(hybrisLogoutPayload, eatCookiesPayload).then((logoutData, eatCookiesData) => { localStorage.cartQuantity = 0; localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } else if(error.type === 'InvalidTokenError') { haas.components.Modal.open('
    Session Timed Out! Please sign in again
    '); self.timeoutModal(); haas.fleet.myHaasDropdown.logout(); } else { haas.components.Modal.open('
    Error! Encountered an error with your cart, creating new cart!
    '); let hybrisLogoutPayload = $.get(haas.constants.hybrisLogout); let eatCookiesPayload = $.get(haas.constants.api.eatcookies); return $.when(hybrisLogoutPayload, eatCookiesPayload).then((logoutData, eatCookiesData) => { localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } }, postPartToCart: function(partid, quantity) { var self = this; var email; var bearer; var endpoint = haas.constants.api.ecommerce; if(localStorage.access_token) { $.when(haas.jwToken.getUserInfo()).then(function(userPayload) { bearer = userPayload['ecomm_bearer_token_access_token']; if (userPayload.userInfo) { email = userPayload.userInfo.uid; } else { email = userPayload.email; } $.get({ url: '/ecommpartsstorefront/ecommparts/en/hybris-cart', cache: false }).then(function(cart) { endpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cart.cartId + '/entries/'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; }).fail(function(payload) { if(payload.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { self.showErrorModal(payload.responseJSON.errors[0]); } }).always(function() { haas.ecommUtils.renderCartQuantity(); }); }).fail(function(err) { if(err.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { $.post({ contentType: 'application/json', url: haas.constants.api.ecommerce + 'users/' + email + '/carts' + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') }, }).done(function(cartResponse){ endpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cartResponse.code + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; }).fail(function(payload) { self.showErrorModal(payload.responseJSON.errors[0]) }).always(function() { haas.ecommUtils.renderCartQuantity(); }); }); } }); return userPayload; }); } else { endpoint = haas.constants.api.ecommerce + 'users/anonymous/carts/' + localStorage.guid + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; }).fail(function(payload) { self.showErrorModal(payload.responseJSON.errors[0]) }).always(function() { haas.ecommUtils.renderCartQuantity(); }); } }, addToCartEventHandler: function(e) { var self = this; var $target = $(e.target); var $parent = $target.parents('.part-list-item'); var partid = $parent.attr('data-sku'); var quantity = $parent.find('#quantity-select').val(); // loading indicator $('body').addClass('cursor-wait'); if (localStorage.guid || localStorage.access_token) { self.postPartToCart(partid, quantity); } else { $.when(haas.ecommUtils.createCartPromise(this.authenticated)).then(function(payload) { localStorage.guid = payload.guid; haas.cookies.setCookie('ecommparts-cart', payload.guid); return self.postPartToCart(partid, quantity); }); } }, propSixtyFiveTooltipHandler: function(e) { e.preventDefault(); var redirectLink = $(e.target).attr('data-redirect'); window.location = redirectLink; }, bindEvents: function() { let self = this; self.$element.find('.spl-accordion-header').on('click', self.handleHeaderClick.bind(self)); self.$element.find('.prop-sixty-five').on('click', function(e) { e.preventDefault(); }); self.$element.find('.prop-tooltext').on('click', self.propSixtyFiveTooltipHandler.bind(self)); self.$element.find('.part-list-item #add-to-cart-btn').on('click', self.addToCartEventHandler.bind(self)); self.elementNode.querySelector('#serialNumSearchBtn').onclick = self.handleSerialNumSearch.bind(self); self.elementNode.querySelector('#serialNumInput').onkeydown = self.handleSerialValKeydown.bind(self); self.elementNode.querySelector('#machineInfoType').onchange = self.handleMachineTypeChange.bind(self); self.elementNode.querySelector('#machineInfoYear').onchange = self.handleMachineYearChange.bind(self); self.elementNode.querySelector('#machineInfoModel').onchange = self.handleMachineModelChange.bind(self); self.elementNode.querySelector('#machineInfoSearchBtn').onclick = self.handleMachineInfoSearch.bind(self); self.elementNode.querySelector('#edit-machine-info-btn').onclick = self.resetState.bind(self); self.elementNode.querySelector('#clear-machine-info-btn').onclick = self.hardResetState.bind(self); self.elementNode.querySelector('#expand-all-btn').onclick = self.handleExpandAllClick.bind(self); self.elementNode.querySelector('#collapse-all-btn').onclick = self.handleCollapseAllClick.bind(self); }, clearYearOptions: function() { let self = this; Array.from(self.elementNode.querySelectorAll('#machineInfoYear option')).forEach(optElem => { if (!optElem.classList.contains('default')) optElem.outerHTML = ''; }); }, clearModelOptions: function() { let self = this; Array.from(self.elementNode.querySelectorAll('#machineInfoModel option')).forEach(optElem => { if (!optElem.classList.contains('default')) optElem.outerHTML = ''; }); }, initYears: function() { let self = this; let currentYear = new Date().getFullYear(); let firstYear = self.machineTypeMinYearMap[self.elementNode.querySelector('#machineInfoType').value]; // Using the min dates found per machine on parts haascnc let yearSelectElement = self.elementNode.querySelector('#machineInfoYear'); for (let year = currentYear; year >= firstYear; year--) { let yearOptionElement = document.createElement('option'); yearOptionElement.value = year; yearOptionElement.innerText = year; yearSelectElement.append(yearOptionElement); } }, initMachineModels: function(type, year, model) { let self = this; fetch(haas.constants.api.modelYearSearch(type, year)) .then(res => res.json()) .then(pl => { if (pl.exp_error_code.zreturncode !== '000') self.showTypeYearErrorModal(); let modelList = pl.exp_tab_model_list.map(elem => elem.zmaterial); let modelSelectElement = self.elementNode.querySelector('#machineInfoModel') for (const model of modelList) { if (model.endsWith('-V') || model.endsWith('-EU') || model.endsWith('-I') || model.endsWith('-UK') || model.endsWith('-SE')) continue; let modelOptionElement = document.createElement('option'); modelOptionElement.value = model; modelOptionElement.innerText = model; modelSelectElement.append(modelOptionElement); } }) .then(() => { self.elementNode.querySelector('#machineInfoModel').disabled = false; self.elementNode.querySelector('#machineInfoSearchBtn').disabled = true; }) .then(() => { if (model) { self.elementNode.querySelector('#machineInfoModel option[value="'+model+'"').selected = true; self.handleMachineModelChange(); self.elementNode.querySelector('#machineInfoSearchBtn').click(); } }) .then(() => { self.removeLoader(); }); }, handleMachineTypeChange: function(e) { let self = this; self.elementNode.querySelector('#machineInfoYear option.default').selected = true; self.elementNode.querySelector('#machineInfoModel option.default').selected = true; self.clearYearOptions(); self.clearModelOptions(); self.initYears(); self.elementNode.querySelector('#machineInfoYear').disabled = false; self.elementNode.querySelector('#machineInfoSearchBtn').disabled = true; self.elementNode.querySelector('#machineInfoModel').disabled = true; }, handleMachineYearChange: function(e) { let self = this; let type = self.elementNode.querySelector('#machineInfoType').value; let year = e.currentTarget.value; self.elementNode.querySelector('#machineInfoModel option.default').selected = true; self.clearModelOptions(); self.initMachineModels(type, year); }, handleYearAndModelSelection: function(machineModel) { let self = this; let type = self.elementNode.querySelector('#machineInfoType').value; let year = self.elementNode.querySelector('#machineInfoYear').value; self.elementNode.querySelector('#machineInfoModel option.default').selected = true; self.clearModelOptions(); self.initMachineModels(type, year, machineModel); }, handleMachineModelChange: function(e) { let self = this; self.elementNode.querySelector('#machineInfoSearchBtn').disabled = false; }, handleMachineInfoSearch: function(e) { let self = this; let yearValue = self.elementNode.querySelector('#machineInfoYear').value; let modelValue = self.elementNode.querySelector('#machineInfoModel').value; haas.region.priceGroupPromise.then(priceList => { let priceListRegion = priceList.region; return fetch(haas.constants.api.machineInfoSearch(priceListRegion, yearValue, modelValue)); }) .then(res => res.json()) .then(payload => { let allowedParts = payload.exp_tab_matl_list.map(partObj => partObj.zmaterial); if (!allowedParts.length) { self.showYearModelSearchErrorModal(); } else { let typeValue = self.elementNode.querySelector('#machineInfoType').value; self.hideNonCompatiblePartsCats(allowedParts); self.populateMachineInfo(typeValue, modelValue, yearValue); self.expandAll(); } }) }, handleHeaderClick: function(e) { let accodionParent = e.currentTarget.parentElement; let accordionContent = accodionParent.querySelector('.spl-accordion-content'); $(accordionContent).slideToggle(); if ($(e.currentTarget).find('span').hasClass('rotate')) $(e.currentTarget).find('span').removeClass('rotate'); else $(e.currentTarget).find('span').addClass('rotate'); }, handleSerialValKeydown: function(e) { let self = this; if (e.keyCode === 13) self.elementNode.querySelector('#serialNumSearchBtn').click(); }, handleSerialNumSearch: function(e) { let self = this; let serialVal = e.currentTarget.parentElement.querySelector('#serialNumInput').value; haas.region.priceGroupPromise.then(priceList => { let priceListRegion = priceList.region; return fetch(haas.constants.api.servicePartsSerialSearch(priceListRegion, serialVal)) }) .then(res => res.json()) .then(payload => { let allowedParts = payload.exp_tab_ibase.map(partObj => partObj.zmaterial); let machineInfo = payload.exp_str_equip; if (!allowedParts.length) { self.showSerialSearchErrorModal(); } else { let typeValue = self.zmachTypeMap[machineInfo.zmach_type] ? self.zmachTypeMap[machineInfo.zmach_type] : self.zmachTypeMap['04']; self.hideNonCompatiblePartsCats(allowedParts); self.populateMachineInfo(typeValue, machineInfo.zmodel, machineInfo.zbuildate, serialVal); self.expandAll(); } }) .then(() => { self.removeLoader(); }) }, handleExpandAllClick: function(e) { let self = this; self.expandAll(); }, handleCollapseAllClick: function(e) { let self = this; self.collapseAll(); }, hideNonCompatiblePartsCats: function(allowedParts) { let self = this; // if part sku not in allowed parts list, hide Array.from(self.elementNode.querySelectorAll('.part-list-item')).forEach(item => { if (item.dataset.commonProduct !== 'true' && !allowedParts.includes(item.dataset.sku)) item.classList.add('hidden'); }); // if category has no non-hidden parts, hide category Array.from(self.elementNode.querySelectorAll('.spl-category-accordion')).forEach(accordion => { if (!accordion.querySelector('.part-list-item:not(.hidden)')) accordion.classList.add('hidden'); }); // flip component state self.elementNode.querySelector('#user-machine-input-container').classList.add('hidden'); self.elementNode.querySelector('#user-machine-info-container').classList.remove('hidden'); }, populateMachineInfo: function(type, model, date, serial) { let self = this; let mInfoContainer = self.elementNode.querySelector('#user-machine-info-container #machine-info-container'); let mTypeTextElement = mInfoContainer.querySelector('.machine-type p'); let mModelTextElement = mInfoContainer.querySelector('.machine-model p'); let mSerialTextElement = mInfoContainer.querySelector('.machine-serial p'); let mDateTextElement = mInfoContainer.querySelector('.machine-date p'); mTypeTextElement.innerText = type; mModelTextElement.innerText = model; mDateTextElement.innerText = date; if (serial) { mSerialTextElement.innerText = serial; mSerialTextElement.parentElement.classList.remove('hidden'); } else { mSerialTextElement.parentElement.classList.add('hidden'); } }, resetState: function(e) { let self = this; let mInfoContainer = self.elementNode.querySelector('#machine-info-container'); let mTypeTextElement = mInfoContainer.querySelector('.machine-type p'); let mModelTextElement = mInfoContainer.querySelector('.machine-model p'); let mSerialTextElement = mInfoContainer.querySelector('.machine-serial p'); let mDateTextElement = mInfoContainer.querySelector('.machine-date p'); // flip component state self.elementNode.querySelector('#user-machine-input-container').classList.remove('hidden'); self.elementNode.querySelector('#user-machine-info-container').classList.add('hidden'); // reset accordions self.collapseAll(); // un-hide everything Array.from(self.elementNode.querySelectorAll('.part-list-item')).forEach(item => { item.classList.remove('hidden'); }); Array.from(self.elementNode.querySelectorAll('.spl-category-accordion')).forEach(accordion => { accordion.classList.remove('hidden'); }); // reset machine info mTypeTextElement.innerText = ''; mModelTextElement.innerText = ''; mDateTextElement.innerText = ''; mSerialTextElement.innerText = ''; mSerialTextElement.parentElement.classList.remove('hidden'); }, hardResetState: function() { let self = this; let mInfoContainer = self.elementNode.querySelector('#machine-info-container'); let mTypeTextElement = mInfoContainer.querySelector('.machine-type p'); let mModelTextElement = mInfoContainer.querySelector('.machine-model p'); let mSerialTextElement = mInfoContainer.querySelector('.machine-serial p'); let mDateTextElement = mInfoContainer.querySelector('.machine-date p'); // reset machine info inputs self.elementNode.querySelector('#machineInfoType option.default').selected = true; self.elementNode.querySelector('#machineInfoYear option.default').selected = true; self.elementNode.querySelector('#machineInfoModel option.default').selected = true; self.clearYearOptions(); self.clearModelOptions(); self.elementNode.querySelector('#machineInfoYear').disabled = true; self.elementNode.querySelector('#machineInfoSearchBtn').disabled = true; self.elementNode.querySelector('#machineInfoModel').disabled = true; // reset serial number input self.elementNode.querySelector('#serialNumInput').value = ''; // flip component state self.elementNode.querySelector('#user-machine-input-container').classList.remove('hidden'); self.elementNode.querySelector('#user-machine-info-container').classList.add('hidden'); // reset accordions self.collapseAll(); // un-hide everything Array.from(self.elementNode.querySelectorAll('.part-list-item')).forEach(item => { item.classList.remove('hidden'); }); Array.from(self.elementNode.querySelectorAll('.spl-category-accordion')).forEach(accordion => { accordion.classList.remove('hidden'); }); // reset machine info mTypeTextElement.innerText = ''; mModelTextElement.innerText = ''; mDateTextElement.innerText = ''; mSerialTextElement.innerText = ''; mSerialTextElement.parentElement.classList.remove('hidden'); }, collapseAll: function() { let self = this; // flip state self.elementNode.querySelector('#collapse-all-btn').classList.add('hidden'); self.elementNode.querySelector('#expand-all-btn').classList.remove('hidden'); // reset accordions Array.from(self.elementNode.querySelectorAll('.spl-accordion-content')).forEach(elem => { elem.style.display = 'none'}); Array.from(self.elementNode.querySelectorAll('.spl-accordion-header > h2 > span')).forEach(elem => { elem.classList.remove('rotate')}); }, expandAll: function() { let self = this; // flip state self.elementNode.querySelector('#expand-all-btn').classList.add('hidden'); self.elementNode.querySelector('#collapse-all-btn').classList.remove('hidden'); // expand all accordions Array.from(self.elementNode.querySelectorAll('.spl-accordion-content')).forEach(elem => { elem.style.display = 'block'}); Array.from(self.elementNode.querySelectorAll('.spl-accordion-header > h2 > span')).forEach(elem => { elem.classList.add('rotate')}); }, showSerialSearchErrorModal: function() { let self = this; haas.components.Modal.open(self.templates.serialNumErrorModal({})); }, showTypeYearErrorModal: function() { let self = this; haas.components.Modal.open(self.templates.typeYearErrorModal({})); }, showYearModelSearchErrorModal: function() { let self = this; haas.components.Modal.open(self.templates.yearModelSearchErrorModal({})); } }); })(); (function() { haas.components.RelatedProducts = haas.Component.create({ initialize: function() { }, render: function() { console.log('JS INITIALIZED'); this.renderRelatedPartsData(); this.renderRelatedQuantity(); this.renderRelatedPartsPrices(); this.bindEvents(); this.removeUnpublishedParts(); }, removeUnpublishedParts: function() { let self = this; Array.from(self.elementNode.querySelectorAll('.related-part-list-item')).forEach(partElem => { let anchorElem = partElem.querySelector('a'); if (anchorElem.href.includes('haas-tooling.html')) partElem.outerHTML = ''; }); }, renderRelatedPartsData: function() { var self = this; $('.related-parts').each(function(){ var allParts = []; if($(this).attr('data-skip')) { return false; } var $relatedParts = $(this); var relatedPartsData = JSON.parse($(this).attr('data-json').toString()); jQuery.each(relatedPartsData, function(key, value){ jQuery.each(value, function(k, v){ allParts.push(v); }) }); console.log('ALLPARTS', allParts); allParts.forEach(function(el){ var relatedPartsContent = self.templates.relatedPartsTemplate({ partImage: el.image, partLinkUrl: el.linkUrl, partName: el.name, partNum: el.partNum, partPrices: JSON.parse(el.prices), partPromoPrice: el.promoPrice }); $relatedParts.append(relatedPartsContent); }); console.log('TEMPLATE', $relatedParts); self.checkPromos(); $(this).attr('data-skip', '1'); }); }, renderRelatedQuantity: function() { $('.related-part-list-item').each(function(ndx, elem) { var $quantityRelatedOptionContainer = $(elem).find('#quantity-select'); var relatedOptions = ''; for (var i = 1; i <= 50; i++) { relatedOptions = relatedOptions + "'; } $quantityRelatedOptionContainer.html(relatedOptions); console.log('QUANTITY UPDATED'); }); }, renderRelatedPartsPrices: function() { $.when(haas.region.priceGroupPromise).then(function() { if(haas.cookies.getCookie('tooling-currency') === 'undefined') { $('.related-check-out-container').hide(); $('.relatedProducts .part-pricing').hide(); $('.alert').removeClass('hidden'); } else { $('.relatedProducts .part-pricing').each(function(ndx, partPricing) { let hasUserCurrency = false; $(partPricing).find('.price-span').each(function(ndx, currencySpan) { $(currencySpan).html(new Intl.NumberFormat('en-US', {style: 'currency', currency: haas.cookies.getCookie('tooling-currency')}).format(parseFloat($(currencySpan).attr('data-price')))); if ($(currencySpan).attr('data-currency') === haas.cookies.getCookie('tooling-currency')) { hasUserCurrency = true; $(currencySpan).show(); } }); if (!hasUserCurrency) { $(partPricing).parents('.related-part-list-item').hide(); } }); } }); }, addToCartEventHandler: function(e) { var self = this; var $target = $(e.target); var $parent = $target.parents('.related-part-list-item'); var partid = $parent.attr('data-sku'); var quantity = $parent.find('#quantity-select').val(); // loading indicator $('body').addClass('cursor-wait'); if (localStorage.guid || localStorage.access_token) { console.log('PARTID', partid); console.log('QUANTITY', quantity); self.postPartToCart(partid, quantity); } else { console.log('ENTERED ELSE'); console.log('PARTID', this.partid); console.log('QUANTITY', this.quantity); $.when(haas.ecommUtils.createCartPromise(this.authenticated)).then(function(payload) { localStorage.guid = payload.guid; haas.cookies.setCookie('ecommparts-cart', payload.guid); return self.postPartToCart(partid, quantity); }); } }, bindEvents: function() { /* this.$element.find('.prop-sixty-five').on('click', function(e) { e.preventDefault(); }); this.$element.find('.prop-tooltext').on('click', this.propSixtyFiveTooltipHandler.bind(this)); */ this.$element.find('.related-part-list-item #add-to-cart-btn').on('click', this.addToCartEventHandler.bind(this)); }, postPartToCart: function(partid, quantity) { var self = this; var email; var bearer; var endpoint = haas.constants.api.ecommerce; if(localStorage.access_token) { $.when(haas.jwToken.getUserInfo()).then(function(userPayload) { bearer = userPayload['ecomm_bearer_token_access_token']; if (userPayload.userInfo) { email = userPayload.userInfo.uid; } else { email = userPayload.email; } $.get({ url: '/ecommpartsstorefront/ecommparts/en/hybris-cart', cache: false }).then(function(cart) { endpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cart.cartId + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; }).fail(function(payload) { console.log('PAYLOAD TIMEDOUT', payload); if(payload.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { self.showErrorModal(payload.responseJSON.errors[0]); } }).always(function() { haas.ecommUtils.renderCartQuantity(); }); console.log('Returned Cart', cart); }).fail(function(err) { console.log('TIMEDOUT', err.responseJSON.errors[0].type); if(err.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { $.post({ contentType: 'application/json', url: haas.constants.api.ecommerce + 'users/' + email + '/carts' + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') }, }).done(function(cartResponse){ console.log('Cart Created', cartResponse); endpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cartResponse.code + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; }).fail(function(payload) { console.log('TIMEDOUT', payload.errors.type); self.showErrorModal(payload.responseJSON.errors[0]) }).always(function() { haas.ecommUtils.renderCartQuantity(); }); }); } }); console.log('returned payload', userPayload); return userPayload; }); } else { endpoint = haas.constants.api.ecommerce + 'users/anonymous/carts/' + localStorage.guid + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; }).fail(function(payload) { self.showErrorModal(payload.responseJSON.errors[0]) }).always(function() { haas.ecommUtils.renderCartQuantity(); }); } }, cartSuccessClickHandler: function() { haas.LOGGER.debug('Proceeding to Cart!'); $('#cart-success-btn').addClass('disabled'); $('#ecommerce-nav > a').click(); }, showSuccessModal: function(quantity) { // to-do: Add attributes in html to make this translatable var self = this; // Remove loading indicator $('body').removeClass('cursor-wait'); haas.components.Modal.open(self.templates.addToCartSuccessModal({qty: quantity})); $('#cart-success-btn').off('click').on('click', self.cartSuccessClickHandler); $('#continue-btn').off('click').on('click', haas.components.Modal.close); }, showErrorModal: function(error) { let errorTLdata = this.elementNode.querySelector('#error-tl-data').dataset; let errorTL = errorTLdata.oos; let outOfStockTL = errorTLdata.oos; let expiredTL = errorTLdata.expired; let timeoutTL = errorTLdata.timeout; let signinTL = errorTLdata.signin; let genericErrorTL = errorTLdata.generic; // Remove loading indicator $('body').removeClass('cursor-wait'); if (error.type === 'InsufficientStockError') { haas.components.Modal.open('

    '+errorTL+' '+outOfStockTL+'

    '); this.timeoutModal(); } else if (error.type === 'CartError') { var self = this; haas.components.Modal.open('

    '+errorTL+' '+expiredTL+'

    '); let hybrisLogoutPayload = $.get(haas.constants.api.hybrisLogout(localStorage.storedSiteLang)); let eatCookiesPayload = $.get(haas.constants.api.eatcookies(localStorage.storedSiteLang)); return $.when(hybrisLogoutPayload, eatCookiesPayload).then((logoutData, eatCookiesData) => { localStorage.cartQuantity = 0; localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } else if(error.type === 'InvalidTokenError') { haas.components.Modal.open('
    '+timeoutTL+'
    '); haas.fleet.myHaasDropdown.logout(); self.timeoutModal(); } else { haas.components.Modal.open('
    '+errorTL+' '+genericErrorTL+'
    '); let hybrisLogoutPayload = $.get(haas.constants.api.hybrisLogout(localStorage.storedSiteLang)); let eatCookiesPayload = $.get(haas.constants.api.eatcookies(localStorage.storedSiteLang)); return $.when(hybrisLogoutPayload, eatCookiesPayload).then((logoutData, eatCookiesData) => { localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } }, checkPromos: function(){ $('.related-part-list-item').each(function(ndx, elem) { var promoPrice = $(elem).find('.plp-promo-price > span').attr('data-value'); if(promoPrice) { $(elem).find('.price-span').addClass('strikethrough'); console.log('PROMO FOUND', promoPrice); } }); } }); })(); (function() { haas.components.ProductFeedback = haas.Component.create({ totalReviews: '', fiveStars: 0, fourStars: 0, threeStars: 0, twoStars: 0, oneStar: 0, totalRating: 0, totalAvg: 0, ecommerceCartEndpoint : haas.constants.api.ecommerce, selectedRating: '', reviewerName: '', reviewTitle: '', reviewComment: '', partTitle: '', part_id : '', initialize: function() { this.partTitle = $(".part-content-right").children('h1').html(); this.part_id = $('.part-container').attr('data-partid'); // unhide reCaptcha icon on pages with forms this.unhideReCaptchaIcon(); this.bindEvents(); }, unhideReCaptchaIcon: function() { document.querySelector('body').classList.remove('hide-recaptcha'); }, render: function() { var urlParams = new URLSearchParams(window.location.search); this.renderTabs(); this.renderReviews(); this.renderQuestions(); if (urlParams.get('review') === 'true') { this.showFeedbackModal(); } }, showFeedbackModal: function() { var self = this; const urlRegex = /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/; const commentBlacklist = ['Hello. And Bye.']; const codeFlags = ['>', '<', '{', '}']; const errorMsgTLContainer = self.elementNode.querySelector('#error-message-container'); const successMsgTLContainer = self.elementNode.querySelector('#success-message-container'); $('#write-review-btn').on('click', function() { haas.components.Modal.open(self.templates.feedbackModalTemplate({partName: self.partTitle})); $('#post-review-btn').on('click', function() { self.selectedRating = $('.rating input:checked').val(); self.reviewerName = $('#reviewerName').val(); self.reviewTitle = $('#reviewTitle').val(); self.reviewComment = $('#reviewComment').val(); let hasCodeFlagError = false; let hasURLError = false; // Required Fields Value Checking if (!self.selectedRating) { const errorMsg = errorMsgTLContainer.dataset.requiredFieldsError; document.querySelector('.feedback-modal-container .rating-fieldset-container').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else { document.querySelector('.feedback-modal-container .rating-fieldset-container').style.border = ''; } if (!self.reviewerName) { const errorMsg = errorMsgTLContainer.dataset.requiredFieldsError; document.querySelector('.feedback-modal-container #reviewerName').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (self.reviewerName && !self.reviewerName.trim()) { // this means its a empty comment, like ' ' const errorMsg = errorMsgTLContainer.dataset.emptyNameError; document.querySelector('.feedback-modal-container #reviewerName').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (urlRegex.test(self.reviewerName)) { const errorMsg = errorMsgTLContainer.dataset.urlError; hasURLError = true; document.querySelector('.feedback-modal-container #reviewerName').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (codeFlags.some(flag => self.reviewerName.includes(flag))) { const errorMsg = errorMsgTLContainer.dataset.commentError; hasCodeFlagError = true; document.querySelector('.feedback-modal-container #reviewerName').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else { document.querySelector('.feedback-modal-container #reviewerName').style.border = ''; } if (!self.reviewTitle) { const errorMsg = errorMsgTLContainer.dataset.requiredFieldsError; document.querySelector('.feedback-modal-container #reviewTitle').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (self.reviewTitle && !self.reviewTitle.trim()) { // this means its a empty comment, like ' ' const errorMsg = errorMsgTLContainer.dataset.emptyTitleError; document.querySelector('.feedback-modal-container #reviewTitle').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (urlRegex.test(self.reviewTitle)) { const errorMsg = errorMsgTLContainer.dataset.urlError; hasURLError = true; document.querySelector('.feedback-modal-container #reviewTitle').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (codeFlags.some(flag => self.reviewTitle.includes(flag))) { const errorMsg = errorMsgTLContainer.dataset.commentError; hasCodeFlagError = true; document.querySelector('.feedback-modal-container #reviewTitle').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else { document.querySelector('.feedback-modal-container #reviewTitle').style.border = ''; } if (!self.reviewComment) { const errorMsg = errorMsgTLContainer.dataset.requiredFieldsError; document.querySelector('.feedback-modal-container #reviewComment').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (self.reviewComment && !self.reviewComment.trim()) { // this means its a empty comment, like ' ' const errorMsg = errorMsgTLContainer.dataset.emptyCommentError; document.querySelector('.feedback-modal-container #reviewComment').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (urlRegex.test(self.reviewComment)) { const errorMsg = errorMsgTLContainer.dataset.urlError; hasURLError = true; document.querySelector('.feedback-modal-container #reviewComment').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (codeFlags.some(flag => self.reviewComment.includes(flag))) { const errorMsg = errorMsgTLContainer.dataset.commentError; hasCodeFlagError = true; document.querySelector('.feedback-modal-container #reviewComment').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else { document.querySelector('.feedback-modal-container #reviewComment').style.border = ''; } // If all Required Fields populated, we can send if (self.selectedRating && (self.reviewerName && self.reviewerName.trim()) && (self.reviewTitle && self.reviewTitle.trim()) && (self.reviewComment && self.reviewComment.trim()) && !hasCodeFlagError && !hasURLError) { self.removeErrorMessage(); $.when(haas.jwToken.getUserInfo()).then(function(userPayload) { bearer = userPayload['ecomm_bearer_token_access_token']; var urlParams = new URLSearchParams(window.location.search); if (!bearer) { grecaptcha.enterprise.ready(async () => { const token = await grecaptcha.enterprise.execute(localStorage.reCaptchaKey, {action: 'POST_REVIEW'}); console.log(token); const assessment = await fetch('/ecommpartsstorefront/ecommparts/en/captcha/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ 'token': token, 'action': 'POST_REVIEW', 'salesOrg': haas.cookies.getCookie('salesOrg') }) }); const assessmentValue = await assessment.json(); if (assessmentValue) { $.post({ contentType: 'application/json', url: haas.constants.api.ecommerce + 'products/' + $('.part-container').attr('data-partid') + '/reviews?fields=DEFAULT&lang=' + localStorage.storedSiteLang, cache: false, dataType: 'json', headers: { 'salesOrg': haas.cookies.getCookie('salesOrg') }, data: JSON.stringify({ "alias": self.reviewerName, "message": self.reviewComment, "rating": self.selectedRating, "headline": self.reviewTitle, "comment": self.reviewComment, "token": urlParams.get('token') || '' }) }).then(function(result) { const successMsg = successMsgTLContainer.dataset.feedbackSuccess; haas.components.Modal.open('

    '+successMsg+'

    '); }).fail(function() { const errorMsg = errorMsgTLContainer.dataset.postError; self.renderErrorMessage(errorMsg); }); } else { const errorMsg = errorMsgTLContainer.dataset.recaptchaError; self.renderErrorMessage(errorMsg); } }); } else { grecaptcha.enterprise.ready(async () => { const token = await grecaptcha.enterprise.execute(localStorage.reCaptchaKey, {action: 'POST_REVIEW'}); console.log(token); const assessment = await fetch('/ecommpartsstorefront/ecommparts/en/captcha/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ 'token': token, 'action': 'POST_REVIEW', 'salesOrg': haas.cookies.getCookie('salesOrg') }) }); const assessmentValue = await assessment.json(); if (assessmentValue) { $.post({ contentType: 'application/json', headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg') }, url: haas.constants.api.ecommerce + 'products/' + $('.part-container').attr('data-partid') + '/reviews?fields=DEFAULT&lang=' + localStorage.storedSiteLang, cache: false, dataType: 'json', data: JSON.stringify({ "alias": self.reviewerName, "message": self.reviewComment, "rating": self.selectedRating, "headline": self.reviewTitle, "comment": self.reviewComment, "token": urlParams.get('token') || '' }) }).then(function(result) { const successMsg = successMsgTLContainer.dataset.feedbackSuccess; haas.components.Modal.open('

    '+successMsg+'

    '); }).fail(function() { const errorMsg = errorMsgTLContainer.dataset.postError; self.renderErrorMessage(errorMsg); }); } else { const errorMsg = errorMsgTLContainer.dataset.recaptchaError; self.renderErrorMessage(errorMsg); } }); } }); } }); }); //haas.components.Modal.open(''); }, renderReviews: function() { let self = this; let allPdpReviews; let totalPdpReviews; let sumPdpReviews = 0; const $reviewsData = $('#reviews-list-container'); const $headerData = $('#reviews-header'); const $avgFeedbackTemplate = $('#avgFeedbackTemplate'); $.get({ url: haas.constants.api.ecommerce + 'products/' + $('.part-container').attr('data-partid') + '/reviews?fields=DEFAULT', headers: { 'salesOrg': haas.cookies.getCookie('salesOrg') }, cache: false }).then(function(reviewsData) { allPdpReviews = reviewsData.reviews; totalPdpReviews = allPdpReviews ? allPdpReviews.length : 0; if (allPdpReviews && allPdpReviews.length) { // Part Header Render allPdpReviews.forEach(function(review) { sumPdpReviews = sumPdpReviews + review.rating; }); let headerStarsContent = self.templates.avgFeedbackTemplate({ totalReviews: totalPdpReviews, avg: sumPdpReviews / totalPdpReviews, avgStars: (sumPdpReviews / totalPdpReviews) / 5 * 100 || 0 }) $avgFeedbackTemplate.append(headerStarsContent); // Product Feedback Render self.totalReviews = allPdpReviews.length; let fiveStars = 0; let fourStars = 0; let threeStars = 0; let twostars = 0; let ones = 0; let avg = 0; allPdpReviews.forEach(function(review) { if (review.rating === 5) fiveStars++; else if (review.rating === 4) fourStars++; else if (review.rating === 3) threeStars++; else if (review.rating === 2) twostars++; else if (review.rating === 1) ones++; let dateFormat = review.date.split('-'); let dateDay = dateFormat[2].split('T'); self.totalRating = self.totalRating + review.rating; let productReviewsContent = self.templates.productReviewsTemplate({ reviewerName: review.alias || review.principal.name, review: (review.rating / 5) * 100, headline: review.headline, comment: review.comment, date: dateFormat[1] + '/' + dateDay[0] + '/' + dateFormat[0] }); $reviewsData.append(productReviewsContent); }); const twoStarsAvg = twostars / self.totalReviews; avg = self.totalRating / self.totalReviews; let headerDataContent = self.templates.headerDataTemplate({ totalReviews: self.totalReviews, avg: avg.toFixed(1), avgStars: (self.totalRating / self.totalReviews) / 5 * 100, fiveStars: fiveStars, fiveStarsAvg: fiveStars / self.totalReviews * 100, fourStars: fourStars, fourStarsAvg: fourStars / self.totalReviews * 100, threeStars: threeStars || 0, threeStarsAvg: threeStars / self.totalReviews * 100 || 0, twoStars: twostars || 0, twoStarsAvg: twoStarsAvg || 0, oneStar: ones, oneStarAvg: ones / self.totalReviews * 100 }); $headerData.append(headerDataContent); } }).fail(function() { }); }, renderQuestions: function() { var self = this; var allQuestions; var $questionsContainer = $('#questions-list-container'); const urlRegex = /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/; const commentBlacklist = ['Hello. And Bye.']; const codeFlags = ['>', '<', '{', '}']; const errorMsgTLContainer = self.elementNode.querySelector('#error-message-container'); const successMsgTLContainer = self.elementNode.querySelector('#success-message-container'); $.get({ url: haas.constants.api.ecommerce + 'products/' + $('.part-container').attr('data-partid') + '/questions?fields=DEFAULT', headers: { 'salesOrg': haas.cookies.getCookie('salesOrg') }, cache: false }).then(function(data) { allQuestions = data.customerQuestions; if (allQuestions) { allQuestions.forEach(function(question) { var questionsContent = self.templates.questionsDataTemplate({ qCode: question.code, qAnswersCount: question.answersCount, qCreationDate: new Date(question.creationDate).toDateString().split(' ').slice(1).join(' '), qCustomerName: question.customerName, qHeadline: question.headline, qText: question.questionText, qAnswers: question.answers }) $questionsContainer.append(questionsContent); }); } $('.answers-count').on('click', function() { $(this).parent().next('.answers-container').slideToggle(); $(this).children('i').toggleClass('fa-caret-right fa-caret-down'); }); $('.reply').on('click', function() { var qHeadline = $(this).attr('data-qHeadline'); var qId = $(this).attr('data-qid'); $.when(haas.jwToken.getUserInfo()).then(function(userPayload) { if (!userPayload['email']) { haas.components.Modal.open(self.templates.replyTemplateUnauthenticated({qHeadline: qHeadline})); $('button').on('click', $('#post-reply-btn'), function() { const replyCommentVal = document.querySelector('.feedback-modal-container #replyComment').value; const replyNameVal = document.querySelector('.feedback-modal-container #rName').value; let hasCodeFlagError = false; let hasURLError = false; if (!replyCommentVal) { const errorMsg = errorMsgTLContainer.dataset.requiredFieldsError; document.querySelector('.feedback-modal-container #replyComment').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (replyCommentVal && !replyCommentVal.trim()) { // this means its a empty comment, like ' ' const errorMsg = errorMsgTLContainer.dataset.emptyAnswerError; document.querySelector('.feedback-modal-container #replyComment').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (urlRegex.test(replyCommentVal)) { const errorMsg = errorMsgTLContainer.dataset.urlError; hasURLError = true; document.querySelector('.feedback-modal-container #replyComment').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (codeFlags.some(flag => replyCommentVal.includes(flag))) { const errorMsg = errorMsgTLContainer.dataset.commentError; hasCodeFlagError = true; document.querySelector('.feedback-modal-container #replyComment').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else { document.querySelector('.feedback-modal-container #replyComment').style.border = ''; } if (!replyNameVal) { const errorMsg = errorMsgTLContainer.dataset.requiredFieldsError; document.querySelector('.feedback-modal-container #rName').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (replyNameVal && !replyNameVal.trim()) { // this means its a empty comment, like ' ' const errorMsg = errorMsgTLContainer.dataset.emptyNameError; document.querySelector('.feedback-modal-container #rName').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (urlRegex.test(replyNameVal)) { const errorMsg = errorMsgTLContainer.dataset.urlError; hasURLError = true; document.querySelector('.feedback-modal-container #rName').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (codeFlags.some(flag => replyNameVal.includes(flag))) { const errorMsg = errorMsgTLContainer.dataset.commentError; hasCodeFlagError = true; document.querySelector('.feedback-modal-container #rName').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else { document.querySelector('.feedback-modal-container #rName').style.border = ''; } if ((replyCommentVal && replyCommentVal.trim()) && (replyNameVal && replyNameVal.trim()) && !hasCodeFlagError && !hasURLError) { self.removeErrorMessage(); grecaptcha.enterprise.ready(async () => { const token = await grecaptcha.enterprise.execute(localStorage.reCaptchaKey, {action: 'POST_ANSWER'}); console.log(token); const assessment = await fetch('/ecommpartsstorefront/ecommparts/en/captcha/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ 'token': token, 'action': 'POST_ANSWER', 'salesOrg': haas.cookies.getCookie('salesOrg') }) }); const assessmentValue = await assessment.json(); if (assessmentValue) { $.post({ contentType: 'application/json', headers: { 'salesOrg': haas.cookies.getCookie('salesOrg') }, url: haas.constants.api.ecommerce + 'products/' + $('.part-container').attr('data-partid') + '/' + qId + '/answer?fields=DEFAULT', cache: false, dataType: 'json', data: JSON.stringify({ 'customerID': 'anonymous', 'customerName': $('#rName').val(), 'answerText': $('#replyComment').val() }) }).then(function(adata) { const successMsg = successMsgTLContainer.dataset.replySuccess; haas.components.Modal.open('

    '+successMsg+'

    '); }).fail(function(err) { const errorMsg = errorMsgTLContainer.dataset.replyError; self.renderErrorMessage(errorMsg); }); } else { const errorMsg = errorMsgTLContainer.dataset.recaptchaError; self.renderErrorMessage(errorMsg); } }); } }); } else { haas.components.Modal.open(self.templates.replyTemplateAuthenticated({qHeadline: qHeadline})); $('button').on('click', $('#post-reply-btn'), function() { const replyCommentVal = document.querySelector('.feedback-modal-container #replyComment').value; let hasCodeFlagError = false; let hasURLError = false; if (!replyCommentVal) { const errorMsg = errorMsgTLContainer.dataset.requiredFieldsError; document.querySelector('.feedback-modal-container #replyComment').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (replyCommentVal && !replyCommentVal.trim()) { // this means its a empty comment, like ' ' const errorMsg = errorMsgTLContainer.dataset.emptyAnswerError; document.querySelector('.feedback-modal-container #replyComment').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (urlRegex.test(replyCommentVal)) { const errorMsg = errorMsgTLContainer.dataset.urlError; hasURLError = true; document.querySelector('.feedback-modal-container #replyComment').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (codeFlags.some(flag => replyCommentVal.includes(flag))) { const errorMsg = errorMsgTLContainer.dataset.commentError; hasCodeFlagError = true; document.querySelector('.feedback-modal-container #replyComment').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if ((replyCommentVal && replyCommentVal.trim()) && !hasURLError && !hasCodeFlagError) { document.querySelector('.feedback-modal-container #replyComment').style.border = ''; self.removeErrorMessage(); grecaptcha.enterprise.ready(async () => { const token = await grecaptcha.enterprise.execute(localStorage.reCaptchaKey, {action: 'POST_ANSWER'}); console.log(token); const assessment = await fetch('/ecommpartsstorefront/ecommparts/en/captcha/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ 'token': token, 'action': 'POST_ANSWER', 'salesOrg': haas.cookies.getCookie('salesOrg') }) }); const assessmentValue = await assessment.json(); if (assessmentValue) { $.post({ contentType: 'application/json', url: haas.constants.api.ecommerce + 'products/' + $('.part-container').attr('data-partid') + '/' + qId + '/answer?fields=DEFAULT', headers: { 'salesOrg': haas.cookies.getCookie('salesOrg') }, cache: false, dataType: 'json', data: JSON.stringify({ 'customerID': userPayload['email'], 'answerText': $('#replyComment').val() }) }).then(function(adata) { const successMsg = successMsgTLContainer.dataset.replySuccess; haas.components.Modal.open('

    '+successMsg+'

    '); }).fail(function(err) { const errorMsg = errorMsgTLContainer.dataset.replyError; self.renderErrorMessage(errorMsg); }); } else { const errorMsg = errorMsgTLContainer.dataset.recaptchaError; self.renderErrorMessage(errorMsg); } }); } }); } }); }); }) }, bindEvents: function() { $('#pr-tab').on('click', function() { $('#qa-content').fadeOut(100); $('#pr-content').delay(100).fadeIn(100); $('#qa-tab').removeClass('pr-active'); $('#qa-tab').addClass('inactive'); $('#pr-tab').addClass('pr-active'); $('#pr-tab').removeClass('inactive'); $('#pr-slider').animate({left: '0'}, 30); $('#pr-slider').width($('#pr-tab').outerWidth()); }); $('#qa-tab').on('click', function() { $('#pr-content').fadeOut(100); $('#qa-content').delay(100).fadeIn(100); $('#qa-tab').addClass('pr-active'); $('#qa-tab').removeClass('inactive'); $('#pr-tab').removeClass('pr-active'); $('#pr-tab').addClass('inactive'); $('#pr-slider').animate({left: $('#pr-tab').outerWidth() + 4}, 30); $('#pr-slider').width($('#qa-tab').outerWidth()); }); $('#write-review-btn').on('click', this.showFeedbackModal()); $('#ask-question-btn').on('click', this.showAskQuestionModal.bind(this)); }, renderTabs: function() { // Hide all elements with class="tabcontent" by default */ var i, tabcontent, tablinks; $('#pr-slider').width($('#pr-tab').outerWidth()); if ($(window).width() < 750) { $('#pr-slider').hide(); } tabcontent = $(".rev-tabcontent"); for (i = 0; i < tabcontent.length; i++) { tabcontent[i].style.display = "none"; } // Remove the background color of all tablinks/buttons tablinks = $(".rev-tablink"); for (i = 0; i < tablinks.length; i++) { tablinks[i].style.backgroundColor = ""; } // Show the specific tab content $('#pr-content').css('display', 'block'); $('#pr-tab').addClass('pr-active'); }, showAskQuestionModal: function() { var self = this; const urlRegex = /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/; const commentBlacklist = ['Hello. And Bye.']; const codeFlags = ['>', '<', '{', '}']; const errorMsgTLContainer = self.elementNode.querySelector('#error-message-container'); const successMsgTLContainer = self.elementNode.querySelector('#success-message-container'); const partSKU = document.querySelector('[data-partid]').dataset.partid; $.when(haas.jwToken.getUserInfo()).then(function(userPayload) { if (!userPayload['email']) { haas.components.Modal.open(self.templates.questionTemplateUnauthenticated({partSKU: partSKU})); $('button').on('click', $('#post-q-btn'), function() { const qTextVal = document.querySelector('.feedback-modal-container #qText').value; const qNameVal = document.querySelector('.feedback-modal-container #qName').value; let hasURLError = false; let hasCodeFlagError = false; if (!qTextVal) { const errorMsg = errorMsgTLContainer.dataset.requiredFieldsError; document.querySelector('.feedback-modal-container #qText').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (qTextVal && !qTextVal.trim()) { // this means its a empty comment, like ' ' const errorMsg = errorMsgTLContainer.dataset.emptyQuestionError; document.querySelector('.feedback-modal-container #qText').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (urlRegex.test(qTextVal)) { const errorMsg = errorMsgTLContainer.dataset.urlError; hasURLError = true; document.querySelector('.feedback-modal-container #qText').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (codeFlags.some(flag => qTextVal.includes(flag))) { const errorMsg = errorMsgTLContainer.dataset.commentError; hasCodeFlagError = true; document.querySelector('.feedback-modal-container #qText').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else { document.querySelector('.feedback-modal-container #qText').style.border = ''; } if (!qNameVal) { const errorMsg = errorMsgTLContainer.dataset.requiredFieldsError; document.querySelector('.feedback-modal-container #qName').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (qNameVal && !qNameVal.trim()) { // this means its a empty comment, like ' ' const errorMsg = errorMsgTLContainer.dataset.emptyNameError; document.querySelector('.feedback-modal-container #qName').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (urlRegex.test(qNameVal)) { const errorMsg = errorMsgTLContainer.dataset.urlError; hasURLError = true; document.querySelector('.feedback-modal-container #qName').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (codeFlags.some(flag => qNameVal.includes(flag))) { const errorMsg = errorMsgTLContainer.dataset.commentError; hasCodeFlagError = true; document.querySelector('.feedback-modal-container #qName').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else { document.querySelector('.feedback-modal-container #qName').style.border = ''; } if ((qTextVal && qTextVal.trim()) && (qNameVal && qTextVal.trim()) && !hasURLError && !hasCodeFlagError) { self.removeErrorMessage(); grecaptcha.enterprise.ready(async () => { const token = await grecaptcha.enterprise.execute(localStorage.reCaptchaKey, {action: 'POST_QUESTION'}); console.log(token); const assessment = await fetch('/ecommpartsstorefront/ecommparts/en/captcha/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ 'token': token, 'action': 'POST_QUESTION', 'salesOrg': haas.cookies.getCookie('salesOrg') }) }); const assessmentValue = await assessment.json(); if (assessmentValue) { $.post({ contentType: 'application/json', headers: { 'salesOrg': haas.cookies.getCookie('salesOrg') }, url: haas.constants.api.ecommerce + 'products/' + $('.part-container').attr('data-partid') + '/questions?fields=DEFAULT', cache: false, dataType: 'json', data: JSON.stringify({ 'customerID': 'anonymous', 'customerName': $('#qName').val(), 'questionText': $('#qText').val() }) }).then(function(qdata) { const successMsg = successMsgTLContainer.dataset.questionSuccess; haas.components.Modal.open('

    '+successMsg+'

    '); }).fail(function(err) { const errorMsg = errorMsgTLContainer.dataset.questionError; self.renderErrorMessage(errorMsg); }); } else { const errorMsg = errorMsgTLContainer.dataset.recaptchaError; self.renderErrorMessage(errorMsg); } }); } }); } else { haas.components.Modal.open(self.templates.questionTemplateAuthenticated({partSKU: partSKU})); $('button').on('click', $('#post-q-btn'), function() { const qTextVal = document.querySelector('.feedback-modal-container #qText').value; let hasURLError = false; let hasCodeFlagError = false; if (!qTextVal) { const errorMsg = errorMsgTLContainer.dataset.requiredFieldsError; document.querySelector('.feedback-modal-container #qText').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (qTextVal && !qTextVal.trim()) { // this means its a empty comment, like ' ' const errorMsg = errorMsgTLContainer.dataset.emptyQuestionError; document.querySelector('.feedback-modal-container #qText').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (urlRegex.test(qTextVal)) { const errorMsg = errorMsgTLContainer.dataset.urlError; hasURLError = true; document.querySelector('.feedback-modal-container #qText').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if (codeFlags.some(flag => qTextVal.includes(flag))) { const errorMsg = errorMsgTLContainer.dataset.commentError; hasCodeFlagError = true; document.querySelector('.feedback-modal-container #qText').style.border = '1px solid red'; self.renderErrorMessage(errorMsg); } else if ((qTextVal && qTextVal.trim()) && !hasURLError && !hasCodeFlagError) { document.querySelector('.feedback-modal-container #qText').style.border = ''; self.removeErrorMessage(); grecaptcha.enterprise.ready(async () => { const token = await grecaptcha.enterprise.execute(localStorage.reCaptchaKey, {action: 'POST_QUESTION'}); console.log(token); const assessment = await fetch('/ecommpartsstorefront/ecommparts/en/captcha/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ 'token': token, 'action': 'POST_QUESTION', 'salesOrg': haas.cookies.getCookie('salesOrg') }) }); const assessmentValue = await assessment.json(); if (assessmentValue) { $.post({ contentType: 'application/json', headers: { 'salesOrg': haas.cookies.getCookie('salesOrg') }, url: haas.constants.api.ecommerce + 'products/' + $('.part-container').attr('data-partid') + '/questions?fields=DEFAULT', cache: false, dataType: 'json', data: JSON.stringify({ 'customerID': userPayload['email'], 'questionText': $('#qText').val() }) }).then(function(qdata) { const successMsg = successMsgTLContainer.dataset.questionSuccess; haas.components.Modal.open('

    '+successMsg+'

    '); }).fail(function(err) { const errorMsg = errorMsgTLContainer.dataset.questionError; self.renderErrorMessage(errorMsg); }); } else { const errorMsg = errorMsgTLContainer.dataset.recaptchaError; self.renderErrorMessage(errorMsg); } }); } }); } }); }, renderErrorMessage: function(msg) { const errMsgContainer = document.querySelector('.feedback-modal-container .errMsg'); errMsgContainer.innerHTML = msg; errMsgContainer.classList.add('alert-danger'); }, removeErrorMessage: function() { const errMsgContainer = document.querySelector('.feedback-modal-container .errMsg'); errMsgContainer.innerHTML = ''; errMsgContainer.classList.remove('alert-danger'); } }); })(); (function() { haas.components.PartListingSections = haas.Component.create({ pageUrl: '', sectionOverrideNames: [], sectionOverrideValues1k: [], sectionOverrideValues2k: [], sectionOverrideImages: [], sectionOverrideImages2000: [], initialize: function() { let self = this; let quantityOverrideNames = this.elementNode.querySelector('.section-cards-container').dataset.sectionQuantityOverrideNames; let quantityOverrideValues1k = this.elementNode.querySelector('.section-cards-container').dataset.sectionQuantityOverrideValues1k; let quantityOverrideValues2k = this.elementNode.querySelector('.section-cards-container').dataset.sectionQuantityOverrideValues2k; let imagesOverrideValues = this.elementNode.querySelector('.section-cards-container').dataset.sectionImagesOverrideValues; let imagesOverrideValues2000 = this.elementNode.querySelector('.section-cards-container').dataset.sectionImagesOverrideValues2000; if (quantityOverrideNames) this.sectionOverrideNames = quantityOverrideNames.split(','); if (quantityOverrideValues1k) this.sectionOverrideValues1k = quantityOverrideValues1k.split(','); if (quantityOverrideValues2k) this.sectionOverrideValues2k = quantityOverrideValues2k.split(','); if (imagesOverrideValues) this.sectionOverrideImages = imagesOverrideValues.split(','); if (imagesOverrideValues2000) this.sectionOverrideImages2000 = imagesOverrideValues2000.split(','); if (self.sectionOverrideNames.length) self.handleSectionNameOverride(); self.renderCategoriesAndQuantities(); }, handleSectionNameOverride: function() { let self = this; self.sectionOverrideNames.forEach((element, ndx) => { try { let $sectionCard = $('.section-card[data-id="' + element + '"]'); if (self.sectionOverrideValues1k[ndx] && haas.cookies.getCookie('salesOrg') === '1000') $sectionCard.find('.qty-count').html(self.sectionOverrideValues1k[ndx]); if (self.sectionOverrideValues2k[ndx] && haas.cookies.getCookie('salesOrg') === '2000') $sectionCard.find('.qty-count').html(self.sectionOverrideValues2k[ndx]); if (self.sectionOverrideImages[ndx] && haas.cookies.getCookie('salesOrg') === '1000') $sectionCard.find('img').attr('src', self.sectionOverrideImages[ndx]); if (self.sectionOverrideImages2000[ndx] && haas.cookies.getCookie('salesOrg') === '2000') $sectionCard.find('img').attr('src', self.sectionOverrideImages2000[ndx]); } catch (e) { console.log('Could not override image.'); } }); }, renderCategoriesAndQuantities: function() { let self = this; let sectionCards = Array.from(self.elementNode.querySelectorAll('.section-card:not(.coming-soon-section)')); haas.region.priceGroupPromise.then(pl => { let userTC = haas.cookies.getCookie('tooling-currency'); sectionCards.forEach(cardElem => { let sectionLink = cardElem.querySelector('a'); console.log(sectionLink, pl); if (sectionLink && sectionLink.href.includes('winner') && pl.country !== 'US') { // if winner circle category and not US, hide cardElem.style.display = 'none'; } else { if (!cardElem.querySelector('#qty-'+userTC)) cardElem.style.display = 'none'; else cardElem.querySelector('#qty-'+userTC).style.display = 'inline-block'; } }); }); } }); })(); (function() { haas.components.PartListingItems = haas.Component.create({ initialize: function() { this.initQuantityOptions(); }, initQuantityOptions: function() { $('.part-list-item').each(function(ndx, elem) { var $quantityOptionContainer = $(elem).find('#quantity-select'); var options = ''; for (var i = 1; i <= 50; i++) { options = options + "'; } $quantityOptionContainer.html(options); }); }, }); })(); (function() { haas.components.PartListingItemsDynamic = haas.Component.create({ title: '', count: '', hasChildren: '', isProducts: '', sortByText: $('.dropdown-toggle').text(), items: [], filterValues: null, selectedFilters: [], hiddenFilters: ['Weight (lbs)', 'Weight (kgs)', 'Compliance - Prop 65', 'Plant(s) for Ecom Sale'], filterOrder: [], filterOrderDefaultEN: [], filterOriginsEN: [], categoryFilterOrder: [], inventoryObject: {}, userData: '', tooltipTitles: [], tooltipDescriptions: [], tooltipPaths: [], preselectedFilterNames: [], preselectedFilterValues: [], startEnabled: false, disableLiveCheck: false, sizeAndPitchOrder: ['#4-40','#6-32','#8-32','#10-32','1/4-20','1/4-28','5/16-18','5/16-24','3/8-16','3/8-24','7/16-14','7/16-20','1/2-13','1/2-20','9/16-12','5/8-11'], millingCutterSeriesOrder: ['HOP - Haas Octagon +', 'HSNP - Haas Square - / +', 'HRNP - Haas Rectangle - / +', 'HPNP - Haas Rectangle - / +', 'HPP - Haas + / +', 'HSHF - Haas Square High Feed', 'HS6NP - Haas Square 6 - / +'], urlParams: {}, filterLangMap: {}, displayOrderedFiltersOnly: false, initialize: function() { let self = this; let filterOrderData = $('#filter-order-data').attr('data-filterorder'); let urlObject = new URL(window.location.href); $.when(haas.jwToken.getUserInfo()).then(function(data) { this.userData = data; console.log('JWT DECODED ASSIGNED', this.userData); }); $.when(haas.region.priceGroupPromise).then(function(priceData) { if (priceData.country === 'US') { if (self.elementNode.classList.contains('winner-circle-plp')) self.elementNode.classList.remove('hidden'); } else { if (self.elementNode.classList.contains('winner-circle-plp')) document.querySelector('.breadcrumb').style.display = 'none'; } }); this.condenseSpacing(); this.mapJsonToAttributes(); // Remove Live Checks until service is improved this.startEnabled = true; this.disableLiveCheck = true; // add additional hidden filters if (this.title === 'ER Collet Kits & Accessories') { this.hiddenFilters = this.hiddenFilters.concat(['Collet System', 'Type', 'Pilot Diameter', 'Shank Type', 'Shank Size', 'Funtional Length ( FL )', 'Bore Diameter ( ⌀d )']); } if (this.title === 'Pull Studs') { this.hiddenFilters = this.hiddenFilters.concat(['Wrench Flat Diameter']); } if (this.title === 'Indexable Drill Inserts') { this.hiddenFilters = this.hiddenFilters.concat(['[D1] Insert Hole Size Inch', '[D1] Insert Hole Size Metric']); } // Add authored hidden filters to hidden filters list if ($('#hidden-filter-data').attr('data-hidden-filters') && $('#hidden-filter-data').attr('data-hidden-filters').length) { this.hiddenFilters = this.hiddenFilters.concat($('#hidden-filter-data').attr('data-hidden-filters').split(',')); } // initialize filter order if (filterOrderData && filterOrderData.length) { this.filterOrder = filterOrderData.split(','); } this.tooltipTitles = document.querySelector('#filter-tooltip-data').dataset.filterTooltipTitles ? document.querySelector('#filter-tooltip-data').dataset.filterTooltipTitles.split(',') : []; this.tooltipDescriptions = document.querySelector('#filter-tooltip-data').dataset.filterTooltipDescriptions ? document.querySelector('#filter-tooltip-data').dataset.filterTooltipDescriptions.split(',,') : []; this.tooltipPaths = document.querySelector('#filter-tooltip-data').dataset.filterTooltipPaths ? document.querySelector('#filter-tooltip-data').dataset.filterTooltipPaths.split(',,') : []; this.preselectedFilterNames = document.querySelector('#preselected-filter-data').dataset.preselectedFilterNames ? document.querySelector('#preselected-filter-data').dataset.preselectedFilterNames.split(',,').slice(0, -1) : []; this.preselectedFilterValues = document.querySelector('#preselected-filter-data').dataset.preselectedFilterValues ? document.querySelector('#preselected-filter-data').dataset.preselectedFilterValues.split(',,').slice(0, -1) : []; this.displayOrderedFiltersOnly = this.elementNode.querySelector('.spa-container').classList.contains('ordered-filters-only') ? true : false; // Map Url Param Filters urlObject.searchParams.forEach((val, key) => { if (self.filterValues[key] && self.filterValues[key].includes(val)) self.urlParams[key] = val; }); }, checkPartInventoryPromise: function(partId) { var endpoint = haas.constants.api.ecommerce + 'products/' + partId; var $part = $('.part-list-item[data-sku="' + partId + '"]'); var self = this; if (self.inventoryObject[partId]) { if (self.inventoryObject[partId] === 'inStock') { $part.find('#add-to-cart-btn').prop('disabled', false); } else { $part.find('#add-to-cart-btn').html($part.find('#add-to-cart-btn').attr('data-oos-text')); } } else { $.get(endpoint).then(function(result) { var stockObj = result.stock; var stockStatus = stockObj.stockLevelStatus; if (stockStatus === 'inStock' || stockStatus === 'lowStock') { self.inventoryObject[partId] = 'inStock'; $part.find('#add-to-cart-btn').prop('disabled', false); } else { self.inventoryObject[partId] = 'outOfStock'; $part.find('#add-to-cart-btn').html($part.find('#add-to-cart-btn').attr('data-oos-text')); } }) .fail(function(e) { // if call fails, just let hybris handle the error on add-to-cart self.inventoryObject[partId] = 'inStock'; $('.part-container #add-to-cart-btn').prop('disabled', false); }); } }, condenseSpacing: function() { let singleSpacedData = this.$element.find('#part-listing-data').attr('data-json').replace(/\s\s+/g, ' '); this.$element.find('#part-listing-data').attr('data-json', singleSpacedData); }, mapJsonToAttributes: function() { var dataText = this.$element.find('#part-listing-data').attr('data-json'); var rawJson = JSON.parse(dataText); this.title = rawJson.title; this.count = rawJson.count; this.hasChildren = rawJson.count; this.isProducts = rawJson.isProducts; this.items = rawJson.items; this.filterLangMap = rawJson.filterLanguageMap; this.filterOrderDefaultEN = rawJson.filterLanguageOrderEN; this.filterOriginsEN = rawJson.filterOriginsEN; this.categoryFilterOrder = (rawJson.categoryFilterOrder && rawJson.categoryFilterOrder.length) ? rawJson.categoryFilterOrder.split('&&') : []; rawJson.items.forEach((item, index) => { item.allPrices.forEach((price, pindex) => { rawJson.items[index].allPrices[pindex] = JSON.parse(price.replace("'", '')); }) }); rawJson.items.forEach((item, index) => { item.allDiscountPrices.forEach((price, pindex) => { rawJson.items[index].allDiscountPrices[pindex] = JSON.parse(price.replace("'", '')); }) }); this.filterValues = rawJson.filterValues; }, filterItems: function() { var self = this; var $filterContainer = $('#filter-container'); // Get unique filters self.selectedFilters = _.values($filterContainer.serializeArray().reduce(function(arr, cur) { if (arr[cur.name]) { arr[cur.name].value.push(cur.value); return arr; } arr[cur.name] = { name: cur.name, value: [cur.value] }; return arr; }, {})); // If there are no selected filters, just return all items if (!self.selectedFilters.length) { return self.items.filter((fItem => { if(self.returnPriceByCurrency(fItem.allPrices).length){ return fItem; }; })); } // Otherwise, filter! let filtered = self.items.filter(function(item) { return self.selectedFilters.every(function (filter) { return filter.value.some(function(value) { return item.classificationFilterValues.indexOf(filter.name +':'+ value) > -1; }); }); }); return filtered.filter((fItem => { if(self.returnPriceByCurrency(fItem.allPrices).length){ return fItem; } })); }, updateCount: function() { var $headerContainer = $('#items-header'); var $itemsContainer = $('#items-container'); var currentCount = $itemsContainer.children().length; $headerContainer.find('span').html(this.filterItems().length); if (!currentCount) $itemsContainer.append('

    Sorry, those parameters return no results..

    Try removing a filter and searching again.

    ') }, processPreselectedFilters: function() { let self = this; let filterKeys = Object.keys(self.urlParams); if (!self.preselectedFilterNames.length && (!filterKeys || !filterKeys.length)) return; self.preselectedFilterNames.forEach((key, ndx) => { let queryString; // When creating query string, check for " symbol and create accordingly, else statement is fall back in case value might have ' symbol if (self.preselectedFilterNames[ndx].includes('"')) queryString = "#filters-col input[name='"+self.preselectedFilterNames[ndx]+"']"; else queryString = '#filters-col input[name="'+self.preselectedFilterNames[ndx]+'"]'; if (self.preselectedFilterValues[ndx].includes('"')) queryString.concat("[value='"+self.preselectedFilterValues[ndx]+"']"); else queryString.concat('[value="'+self.preselectedFilterValues[ndx]+'"]'); document.querySelector(queryString).checked = true; document.querySelector(queryString).defaultChecked = true; }); filterKeys.forEach((key) => { let queryString; // When creating query string, check for " symbol and create accordingly, else statement is fall back in case value might have ' symbol if (key.includes('"')) queryString = "#filters-col input[name='"+key+"']"; else queryString = '#filters-col input[name="'+key+'"]'; if (self.urlParams[key].replace('\\', '\\\\').includes('"')) queryString = queryString.concat("[value='"+self.urlParams[key].replace('\\', '\\\\')+"']"); else queryString = queryString.concat('[value="'+self.urlParams[key].replace('\\', '\\\\')+'"]'); document.querySelector(queryString).checked = true; document.querySelector(queryString).defaultChecked = true; }); self.renderPartItems(); if (window.screen.width <= 800) self.renderMobileSelectedFilters(); }, scrollToPLP: function() { // if a filter was clicked, then scroll back to PLP $(function() { if (window.location.search.includes('scroll=true')) { window.scrollTo(0, document.querySelector('.partListing').offsetTop); } }); }, smoothScroll: function() { //if a filter was clicked and the top of the part list is out of the viewport, smooth scroll to the top let topEdge = document.querySelector('.partListing').getBoundingClientRect().top; $(function() { if(topEdge < 0) { if(window.innerWidth > 800) { window.scrollTo({ top: (document.querySelector('.partListing').offsetTop - 210), left: 0, behavior: 'smooth'}); } else { window.scrollTo({ top: document.querySelector('.partListing').offsetTop , left: 0, behavior: 'smooth'}); } } }); }, render: function() { this.renderHeader(); this.renderFilters(); this.renderFilterSearchBars(); this.renderWorkpieceMaterialFilterIcons(); this.renderFilterTooltips(); this.renderPartItems(); this.processPreselectedFilters(); this.bindEvents(); this.scrollToPLP(); }, renderHeader: function() { var $headerContainer = $('#items-header'); $headerContainer.find('h1').html(this.title); $headerContainer.find('span').html(this.filterItems().length); }, renderFilters: function() { var $filterContainer = $('#filter-container'); var self = this; var plantsForEcommSaleTerms = ['ecom', 'site', 'e-com']; // first sort alphabetically, then sort by given order Object.keys(this.filterValues) .sort(function(a, b) { let filterA_en = self.filterLangMap[a] ? self.filterLangMap[a][0] : a; let filterB_en = self.filterLangMap[b] ? self.filterLangMap[b][0] : b; var orderA, orderB; if (self.categoryFilterOrder.length) { orderA = self.categoryFilterOrder.indexOf(filterA_en) >= 0 ? self.categoryFilterOrder.indexOf(filterA_en) : Number.MAX_SAFE_INTEGER; orderB = self.categoryFilterOrder.indexOf(filterB_en) >= 0 ? self.categoryFilterOrder.indexOf(filterB_en) : Number.MAX_SAFE_INTEGER; } else { orderA = self.filterOrderDefaultEN.indexOf(filterA_en) >= 0 ? self.filterOrderDefaultEN.indexOf(filterA_en) : Number.MAX_SAFE_INTEGER; orderB = self.filterOrderDefaultEN.indexOf(filterB_en) >= 0 ? self.filterOrderDefaultEN.indexOf(filterB_en) : Number.MAX_SAFE_INTEGER; } return orderA - orderB; }) .sort(function(a, b) { let filterA_en = self.filterLangMap[a] ? self.filterLangMap[a][0] : a; let filterB_en = self.filterLangMap[b] ? self.filterLangMap[b][0] : b; var orderA = self.filterOrder.indexOf(filterA_en) >= 0 ? self.filterOrder.indexOf(filterA_en) : Number.MAX_SAFE_INTEGER; var orderB = self.filterOrder.indexOf(filterB_en) >= 0 ? self.filterOrder.indexOf(filterB_en) : Number.MAX_SAFE_INTEGER; return orderA - orderB; }) .filter(function(key) { let key_en = self.filterLangMap[key] ? self.filterLangMap[key][0] : key; // if the categories has filter origins filled in, then use those. Otherwise use default hidden filters. if (self.filterOriginsEN.length) { return self.filterOriginsEN.includes(key_en); } else { // if displaying only ordered filters, check if filter is in filterOrder if (self.displayOrderedFiltersOnly) { return self.filterOrder.indexOf(key_en) !== -1; } // else hide all hidden filters + "ecomm plants for sale" filter return self.hiddenFilters.indexOf(key_en) === -1 && !plantsForEcommSaleTerms.some(term => key.toLowerCase().includes(term)); } }).forEach(function(key) { var numberOfOptions = self.filterValues[key].length; var numberFilters = ['Diameter', 'Length']; var pitchFilter = ['SIZE & PITCH']; var millingCutterSeriesFilter = ['Milling Cutter Series']; var machineModelsFilter = ['Machine Models']; var matchingChucksFilter = ['matching chuck']; var sortedFilters; var inputItem = '

    '+key+'

    '; /* TO-DO: Need to blanket logic for ordering filters with numbers */ // will sort the filters alphanumerically & special case for filters with # symbol try { sortedFilters = self.filterValues[key].sort((a, b) => { if (a.includes('#') && b.includes('#')) { if (a.split('\\')[1].trim() > b.split('\\')[1].trim()) return -1; if (a.split('\\')[1].trim() < b.split('\\')[1].trim()) return 1; return 0 } else { if (a < b) return -1; if (b < a) return 1; return 0; } }); } catch(e) { sortedFilters = self.filterValues[key].sort(); } // find workpiece material specs & order try { if (self.filterLangMap[key] && self.filterLangMap[key].some(term => term.toLowerCase().includes('workpiece material'))) { const workpieceMaterialOrder = ['P', 'M', 'K', 'N', 'S', 'H']; sortedFilters = self.filterValues[key].sort((a, b) => { const materialA = a[0], materialB = b[0]; return workpieceMaterialOrder.indexOf(materialA) - workpieceMaterialOrder.indexOf(materialB); }); } } catch(e) { console.error("Error at : " + key) console.error(e); } /* * Sort filters with numeric values by actual numeric value */ if (numberFilters.some(function(filter) { return key.indexOf(filter) > -1; })) { try { sortedFilters = self.filterValues[key].sort(function(a, b) { let objA = a.split(' '), objB = b.split(' '); let valA, valB; if ((objA[0] && objA[0].includes('"')) || (objB[0] && objB[0].includes('"'))) { if (objA[0].includes('"')) valA = eval(objA[objA.length-2]), unitA = objA[objA.length-1]; else valA = eval(objA[0]), unitA = objA[1]; if (objB[0].includes('"')) valB = eval(objB[objB.length-2]), unitB = objB[objB.length-1]; else valB = eval(objB[0]), unitB = objB[1]; } else { valA = eval(objA[0]), valB = eval(objB[0]), unitA = objA[1], unitB = objB[1]; } const inToMM = 25.4; // for metric, keep the same. else, convert to metric if (!unitA || unitA !== 'mm') valA = valA * inToMM; if (!unitB || unitB !== 'mm') valB = valB * inToMM; return valA - valB; }) } catch (e) { console.log('Could not sort ' + key + ' by number value.'); } } if (pitchFilter.some(function(filter) { return key.indexOf(filter) > -1; })) { try { sortedFilters = self.filterValues[key].sort(function(a, b) { var valA = self.sizeAndPitchOrder.indexOf(a) > -1 ? self.sizeAndPitchOrder.indexOf(a) : Number.MAX_SAFE_INTEGER; var valB = self.sizeAndPitchOrder.indexOf(b) > -1 ? self.sizeAndPitchOrder.indexOf(b) : Number.MAX_SAFE_INTEGER; return valA - valB; }); } catch (e) { console.log('Could not sort ' + key + ' by number value.'); } } if (millingCutterSeriesFilter.some(function(filter) { return key.indexOf(filter) > -1; })) { try { sortedFilters = self.filterValues[key].sort(function(a, b) { var valA = self.millingCutterSeriesOrder.indexOf(a) > -1 ? self.millingCutterSeriesOrder.indexOf(a) : Number.MAX_SAFE_INTEGER; var valB = self.millingCutterSeriesOrder.indexOf(b) > -1 ? self.millingCutterSeriesOrder.indexOf(b) : Number.MAX_SAFE_INTEGER; return valA - valB; }); } catch (e) { console.log(e); } } if (machineModelsFilter.some((filter) => key.indexOf(filter) > -1)) { try { sortedFilters = self.filterValues[key].sort((a, b) => { var valA = a.indexOf('SS') > -1 ? 2 : 1; var valB = b.indexOf('SS') > -1 ? 2 : 1; return valA - valB; }); } catch (e) { console.log(e); } } if (matchingChucksFilter.some((filter) => key.toLowerCase().indexOf(filter) > -1)) { try { sortedFilters = self.filterValues[key].sort((a, b) => { var valA = Number(a.split('\\')[0].split(' ')[0]); var valB = Number(b.split('\\')[0].split(' ')[0]); return valA - valB; }); } catch (e) { console.log(e); } } // Create the Filters Container with its sorted filters if (sortedFilters.length === 1) { inputItem = inputItem + ''; inputItem = '
    ' + inputItem + '
    '; // Hide filter if only one inputItem = ''; } else { sortedFilters = [... new Set(sortedFilters)]; sortedFilters.forEach(function(option) { inputItem = inputItem + ''; }); inputItem = '
    ' + inputItem + '
    '; } // close filter values container div inputItem = inputItem + '
    '; $filterContainer.append(inputItem); }); if (!$('.filter-cat-container').length) { $('#filters-col').addClass('hidden'); $('.spa-container').addClass('hide-filters-col'); $('items-col > btn').addClass('hidden'); $('#mobile-filter-btn').addClass('hidden'); } }, renderWorkpieceMaterialFilterIcons: function() { const self = this; const jsonData = JSON.parse(self.elementNode.querySelector('[data-json]').dataset.json); const workpieceFilters = Object.keys(jsonData.filterLanguageMap).filter(key => jsonData.filterLanguageMap[key].some(mappedVal => mappedVal.toLowerCase().includes('workpiece material'))); workpieceFilters.forEach(filterKey => { Array.from(self.elementNode.querySelectorAll('[data-master-cat="'+filterKey+'"] .filter-item')).forEach(filterItem => { const workpieceId = filterItem.querySelector('input').value[0].toLowerCase(); filterItem.querySelector('span').classList.add('workpiece-filter'); filterItem.querySelector('span').classList.add('workpiece-'+workpieceId); }); }); }, renderFilterTooltips: function() { let self = this; let Modal = haas.components.LinkModal; self.tooltipTitles.forEach(function(title, ndx) { let $filterHeader = $('.filter-cat-container[data-master-cat="' + title + '"] h2'); let filterDescriptionHTMLFullscreen = ''; let pathBase = self.tooltipPaths[ndx]; let path = pathBase + '.html'; $filterHeader.append(filterDescriptionHTMLFullscreen); // Add tooltip descriptions that display on hover if (self.tooltipDescriptions[ndx] != ''){ $filterHeader.find('.filter-tooltip').hover( function() { $filterHeader.after('

    ' + self.tooltipDescriptions[ndx] + '

    '); }, function() { $filterHeader.parent().find('#tooltip-text-container').remove(); } ); } // Bind tooltip click action or remove click cursor styling if (pathBase && pathBase.length) { $filterHeader.find('.filter-tooltip').off("click").on("click", function() { $.get(path).then(function(res) { let pageText = res; let tempNode = document.createElement('div'); tempNode.innerHTML = pageText; let contentNode = tempNode.querySelector('.print-only'); Modal.open(contentNode.outerHTML); haas.utils.initTextComponents(); }); } ); } else { $filterHeader.find('.filter-tooltip').css('cursor', 'default'); } }); }, renderFilterSearchBars: function() { let self = this; let filterCategories = Array.from(document.querySelectorAll('.filter-values-container')); filterCategories.forEach(category => { if (category.children.length < 5) return; let searchItemContainer = document.createElement('div'); let searchItemIcon = document.createElement('i'); let searchBarElement = document.createElement('input'); searchItemContainer.classList.add('filter-search-container'); searchItemIcon.classList.add('fa'); searchItemIcon.classList.add('fa-search'); searchBarElement.classList.add('filter-item-search'); searchBarElement.type = 'text'; searchItemContainer.append(searchItemIcon); searchItemContainer.append(searchBarElement); category.before(searchItemContainer); searchBarElement.onkeyup = (e) => { Array.from(category.children).forEach(filterItem => { if (!filterItem.querySelector('input').value.toLowerCase().includes(e.currentTarget.value.toLowerCase())) filterItem.classList.add('hidden'); else filterItem.classList.remove('hidden'); }); } }); }, processSelectableFilters: function() { // clear all non-selectable filters before processing $('#filter-container label').removeClass('filter-disabled').removeClass('not-selectable'); $('#filter-container input').prop('disabled', false); var self = this; var filteredItemList = $('.part-list-item').map(function(ndx, item) { return $(item).attr('data-sku') }).toArray(); var currentItems = this.filterItems(); var availableFilters = {}; var selectedFilterNames = self.selectedFilters.map(function(elem) { return elem.name }); var unselectableFilterType = $('#filters-col').attr('data-unselectable-filter-type'); currentItems.forEach(function(item) { item.classificationFilterValues.forEach(function(filter) { var filterData = filter.split(':'); if (!availableFilters[filterData[0]]) availableFilters[filterData[0]] = []; availableFilters[filterData[0]].push(filterData[1]); }); }); $('.filter-cat-container').each(function(ndx, group) { var filterName = $(group).attr('data-master-cat'); var $filters = $(group).find('input:not([type="text"])'); var selectableFilters = availableFilters[filterName]; var count = 0; // if theres a filter in the group already selected, or only a single filter, we dont need to process the group if ($(group).attr('data-single-filter') === 'true') { $(this).find('p').html("( 1 )"); return; } if (!selectableFilters || !selectableFilters.length) { $filters.each(function(ndx, filter) { unselectableFilterType === 'disabled' ? $(filter).parent().addClass('filter-disabled') : $(filter).parent().addClass('not-selectable'); $(filter).prop('disabled', true); }); } else { $filters.each(function(ndx, filter) { var filterValue = $(filter).attr('value'); if (selectableFilters.indexOf(filterValue) === -1) { unselectableFilterType === 'disabled' ? $(filter).parent().addClass('filter-disabled') : $(filter).parent().addClass('not-selectable'); $(filter).prop('disabled', true); } else {count++;} }); } $(this).find('p').html("( " + count + " )"); }); }, displayChunks: function(items) { var self = this; var $itemsCol = $('#items-container'); let subscriptionCount = 0; items.forEach(function(item) { var itemTitle = item.title.toLowerCase(); var packOfNdx = item.packOf; var perPriceValue = 0; var productType = 'unit'; if (packOfNdx > -1) { var quantity = item.packOf; perPriceValue = Number((item.price.amount / quantity).toFixed(2)); if (itemTitle.indexOf('drill') > -1) productType = 'drill'; if (itemTitle.indexOf('insert') > -1) productType = 'insert'; } var itemContent = self.templates.partListItemTemplate({ itemSku: item.sku, itemLink: item.link, itemImgSrc: item.imageHref, itemImgTitle: item.sku, itemImgAlt: item.sku, itemTitle: item.title, itemPrice: item.price.amount, itemAllPrices: item.allPrices, itemAllDiscountPrices: item.allDiscountPrices, hasStrikethroughPrice: item.hasStrikethroughPrice, eligibleForSubscription: item.eligibleForSubscription, packOf: item.packOf || '', rawPromoPrice: item.rawPromoPrice, propSixtyFive: item.californiaProposition65Required ? 'prop-sixty-five-req' : '', startDisabled: (self.startEnabled || self.disableLiveCheck) ? false : true, hasPricePerPart: (packOfNdx > -1), pricePerPartValue: (self.returnPriceByCurrency(item.allPrices)[0].amount / quantity).toFixed(3).slice(0, -1), productTypeValue: productType, catalog: haas.cookies.getCookie('salesOrg'), isWinnerCircle: item.link && item.link.includes('winner') }); $itemsCol.append(itemContent); if (item.eligibleForSubscription) subscriptionCount++; if (!self.disableLiveCheck) self.checkPartInventoryPromise(item.sku); }); if (subscriptionCount) $('.subscribe').removeClass('hidden'); }, renderPartItems: function() { var self = this; var $itemsCol = $('#items-container'); var itemsChunk = 10; var itemsOffset = 20; var filtered = this.filterItems(); /* var allPlpReviews; PLP Disabled, needs API rework for multiple item numbers input var totalPlpReviews = 0; var sumPlpReviews = 0; */ $itemsCol.empty(); self.displayChunks(filtered.slice(0, itemsOffset)); this.updateCount(); this.renderPrices(); this.renderQuantityOptions(); this.processSelectableFilters(); // Lazy Load Scroll Handler $(window).off('scroll').on('scroll', function () { // check if the window is scrolling past the end of the items column. // items column's offset from the top + its height - by half the screen height ( trigger when bottom of items col is 250px past bottom of screen ) if ((window.scrollY >= (self.elementNode.querySelector('#items-col').getBoundingClientRect().top + self.elementNode.querySelector('#items-col').getBoundingClientRect().height) - (window.innerHeight - 250)) && itemsOffset < filtered.length) { self.displayChunks(_.slice(filtered, itemsOffset, itemsOffset + itemsChunk)); itemsOffset += itemsChunk; self.renderPrices(); self.renderQuantityOptions(); self.rebindPartItemsHandler(); self.bindSubscribeEvents(); } }); /* * Sort Items Handlers * To-Do: Decompose, pull these into own function for readability */ $('#low-high').on('click', () => { $('#items-container').empty(); $('.dropdown-toggle').text(''); filtered = filtered.sort((a, b) => (self.returnDiscountByCurrency(a.allDiscountPrices) || self.returnPriceByCurrency(a.allPrices)[0].amount) - (self.returnDiscountByCurrency(b.allDiscountPrices) || self.returnPriceByCurrency(b.allPrices)[0].amount)); self.displayChunks(filtered.slice(0, itemsOffset)); self.renderPrices(); self.renderQuantityOptions(); self.rebindPartItemsHandler(); $('.dropdown-toggle').text(self.sortByText + $('#low-high').text()); }); $('#high-low').on('click', () => { $('#items-container').empty(); filtered = filtered.sort((a, b) => (self.returnDiscountByCurrency(b.allDiscountPrices) || self.returnPriceByCurrency(b.allPrices)[0].amount) - (self.returnDiscountByCurrency(a.allDiscountPrices) || self.returnPriceByCurrency(a.allPrices)[0].amount)); self.displayChunks(filtered.slice(0, itemsOffset)); self.renderPrices(); self.renderQuantityOptions(); self.rebindPartItemsHandler(); $('.dropdown-toggle').text(''); $('.dropdown-toggle').text(self.sortByText + $('#high-low').text()); }); $('.action-container > button').each(function() { //Used for disabling specific part numbers if they are backordered or out of stock /* if ($(this).attr('data-partid') === '09-0020') { $(this).prop('disabled', true); } */ }); }, returnPriceByCurrency: function(priceObject) { return priceObject.filter(function(price){ return price.currency === haas.cookies.getCookie('tooling-currency'); }); }, returnDiscountByCurrency: function(discountPticeObject) { return (discountPticeObject.length ? this.returnPriceByCurrency(discountPticeObject)[0].amount : false); }, renderQuantityOptions: function() { $('.part-list-item').each(function(ndx, elem) { var $quantityOptionContainer = $(elem).find('#quantity-select'); var options = ''; for (var i = 1; i <= 50; i++) { options = options + "'; } $quantityOptionContainer.html(options); if($(elem).find('.sub-icon-select-container > img').length) { $quantityOptionContainer.addClass('img-included'); } }); }, renderPrices: function() { $.when(haas.region.priceGroupPromise).then(function() { if(haas.cookies.getCookie('tooling-currency') === 'undefined') { $('.check-out-container').hide(); $('.part-pricing').hide(); $('.alert').removeClass('hidden'); } else { $('.price-span').each(function() { $(this).html(haas.ecommUtils.formatPrice($(this).attr('data-price'))); if($(this).attr('data-currency') === haas.cookies.getCookie('tooling-currency')) { $(this).show(); } }); $('.part-list-item').each(function(ndx, elem) { var $priceContainer = $(elem).find('.price-span ' + haas.cookies.getCookie('tooling-currency')); var $unitPriceContainer = $(elem).find('#unit-price'); $('.promo-' + haas.cookies.getCookie('tooling-currency')).each(function() { $(this).html(haas.ecommUtils.formatPrice($(this).attr('data-value'))); $(this).parent().removeClass('hidden'); $(this).parents('.part-list-item').addClass('ecomm-plp-promo'); }) if ($unitPriceContainer.attr('data-haspriceperpart') === 'true') { $unitPriceContainer.html('(' + haas.ecommUtils.formatPrice($unitPriceContainer.attr('data-perpricevalue')) + '/' + $unitPriceContainer.attr('data-partype') + ')'); $unitPriceContainer.removeClass('hidden'); } }); } }); // $('.promo-false').css('display', 'none'); }, filterClickHandler: function(e) { let self = this; let encodedName = encodeURIComponent(e.target.name); let encodedValue = encodeURIComponent(e.target.value); let url = window.location.href; // if filter is clicked, just navigate to page w preselected filters if (window.location.search.length) { if (window.location.search.includes(encodedName)) { let filterNdx = window.location.href.indexOf(encodedName); let filterStrLength = encodedName.length + encodedValue.length + 1; url = window.location.href.slice(0, filterNdx - 1) + window.location.href.slice(window.location.href.indexOf(encodedName) + filterStrLength); } else if (!window.location.search.includes('scroll=true')) { url = window.location.href + "&scroll=true&" + encodedName + "=" + encodedValue; } else { url = window.location.href + "&" + encodedName + "=" + encodedValue; } } else { url = window.location.href + "?scroll=true&" + encodedName + "=" + encodedValue; } window.history.replaceState({}, '', url); this.renderPartItems(); this.rebindPartItemsHandler(); this.bindSubscribeEvents(); this.smoothScroll(); }, clearAllClickHandler: function(e) { this.$element.find('input:not(.single-filter)').prop('checked', false); this.renderPartItems(); this.rebindPartItemsHandler(); }, timeoutModal: function() { setTimeout(function() { if ($('.haas-modal-wrapper').is('.open')) haas.components.Modal.close(); }, 5000); }, cartSuccessClickHandler: function() { haas.LOGGER.debug('Proceeding to Cart!'); $('#cart-success-btn').addClass('disabled'); $('#ecommerce-nav > a').click(); }, showSuccessModal: function(quantity) { // to-do: Add attributes in html to make this translatable var self = this; // Remove loading indicator $('body').removeClass('cursor-wait'); haas.components.Modal.open(self.templates.addToCartSuccessModal({qty: quantity})); $('#cart-success-btn').off('click').on('click', self.cartSuccessClickHandler); $('#continue-btn').off('click').on('click', haas.components.Modal.close); }, showErrorModal: function(error) { let errorTLdata = this.elementNode.querySelector('#error-tl-data').dataset; let errorTL = errorTLdata.error; let outOfStockTL = errorTLdata.oos; let expiredTL = errorTLdata.expired; let timeoutTL = errorTLdata.timeout; let signinTL = errorTLdata.signin; let genericErrorTL = errorTLdata.generic; let wcErrorTL = errorTLdata.wcAlreadyAdded; let wcMemberErrorTL = errorTLdata.wcAlreadyMember; // Remove loading indicator $('body').removeClass('cursor-wait'); if (error.type === 'winnerCircleMaxOrderQuantityExceeded') { haas.components.Modal.open('

    '+errorTL+' '+wcErrorTL+'

    '); this.timeoutModal(); } else if (error.type === 'winnerCircleAlreadyMember') { haas.components.Modal.open('

    '+errorTL+' '+wcMemberErrorTL+'

    '); this.timeoutModal(); } else if (error.type === 'InsufficientStockError') { haas.components.Modal.open('

    '+errorTL+' '+outOfStockTL+'

    '); this.timeoutModal(); } else if (error.type === 'CartError') { var self = this; haas.components.Modal.open('

    '+errorTL+' '+expiredTL+'

    '); $.get(haas.constants.api.eatcookies(localStorage.storedSiteLang)).then(function(payload, status, xhr) { localStorage.cartQuantity = 0; localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } else if(error.type === 'InvalidTokenError') { haas.components.Modal.open('
    '+timeoutTL+'
    '); haas.fleet.myHaasDropdown.logout(); self.timeoutModal(); } else { haas.components.Modal.open('
    '+errorTL+' '+genericErrorTL+'
    '); $.get(haas.constants.api.eatcookies(localStorage.storedSiteLang)).then(function(payload, status, xhr) { localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } }, postPartToCart: function(partid, quantity) { var self = this; var email; var bearer; var endpoint = haas.constants.api.ecommerce; if(localStorage.access_token) { $.when(haas.jwToken.getUserInfo()).then(function(userPayload) { bearer = userPayload['ecomm_bearer_token_access_token']; if (userPayload.userInfo) { email = userPayload.userInfo.uid; } else { email = userPayload.email; } $.get({ url: '/ecommpartsstorefront/ecommparts/en/hybris-cart', cache: false }).then(function(cart) { endpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cart.cartId + '/entries/'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') }, }).done(function(payload){ if (payload.statusCode && payload.statusCode === 'winnerCircleMaxOrderQuantityExceeded') { let errorObj = {type : 'winnerCircleMaxOrderQuantityExceeded'}; self.showErrorModal(errorObj); } else if (payload.statusCode && payload.statusCode === 'winnerCircleAlreadyMember') { let errorObj = {type : 'winnerCircleAlreadyMember'}; self.showErrorModal(errorObj); } else { self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; } }).fail(function(payload) { if(payload.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { self.showErrorModal(payload.responseJSON.errors[0]); } }).always(function() { haas.ecommUtils.renderCartQuantity(); }); }).fail(function(err) { if(err.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { $.post({ contentType: 'application/json', url: haas.constants.api.ecommerce + 'users/' + email + '/carts/' + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') }, }).done(function(cartResponse){ endpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cartResponse.code + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ if (payload.statusCode && payload.statusCode === 'winnerCircleMaxOrderQuantityExceeded') { let errorObj = {type : 'winnerCircleMaxOrderQuantityExceeded'}; self.showErrorModal(errorObj); } else if (payload.statusCode && payload.statusCode === 'winnerCircleAlreadyMember') { let errorObj = {type : 'winnerCircleAlreadyMember'}; self.showErrorModal(errorObj); } else { self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; } }).fail(function(payload) { self.showErrorModal(payload.responseJSON.errors[0]) }).always(function() { haas.ecommUtils.renderCartQuantity(); }); }); } }); return userPayload; }); } else { endpoint = haas.constants.api.ecommerce + 'users/anonymous/carts/' + localStorage.guid + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, headers: { 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') }, data: reqBody }).done(function(payload){ if (payload.statusCode && payload.statusCode === 'winnerCircleMaxOrderQuantityExceeded') { let errorObj = {type : 'winnerCircleMaxOrderQuantityExceeded'}; self.showErrorModal(errorObj); } else if (payload.statusCode && payload.statusCode === 'winnerCircleAlreadyMember') { let errorObj = {type : 'winnerCircleAlreadyMember'}; self.showErrorModal(errorObj); } else { self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; } }).fail(function(payload) { self.showErrorModal(payload.responseJSON.errors[0]) }).always(function() { haas.ecommUtils.renderCartQuantity(); }); } }, updateNumSelected: function() { var self = this; var num = 0; self.selectedFilters.forEach(function(filter) { filter.value.forEach(function(value) { if (!$('input[name="'+filter.name+'"][value="'+value+'"]').hasClass('single-filter')) { num += 1; } }); }); if (num) $('.num-selected').html('(' + num + ')'); else $('.num-selected').empty(); }, bindExternalFilterButtonEvents: function() { var self = this $('.ext-filter').on('click', function(e) { var $parent = $(e.target).is('a') ? $(e.target) : $(e.target).parent('a'); var name = $parent.attr('name'); var value = $parent.attr('value'); var $input = $('input[name="' + name + '"][value="'+value+'"]'); $input.prop('checked', false).removeAttr('checked'); self.renderPartItems(); self.rebindPartItemsHandler(); self.updateNumSelected(); self.renderMobileSelectedFilters(); }); $('.ext-clear-all').on('click', function(e) { var $parent = $(e.target).is('a') ? $(e.target) : $(e.target).parent('a'); var name = $parent.attr('name'); var value = $parent.attr('value'); var $input = $('input:not(.single-filter)'); $input.prop('checked', false).removeAttr('checked'); self.renderPartItems(); self.rebindPartItemsHandler(); self.updateNumSelected(); self.renderMobileSelectedFilters(); }); }, renderMobileSelectedFilters: function() { var self = this; $('.mobile-selected-filters').empty(); if (self.selectedFilters.length) { $('.mobile-selected-filters').append(self.templates.clearButtonExternal()); self.selectedFilters.forEach(function(filter) { filter.value.forEach(function(value) { if (!$('input[name="'+filter.name+'"][value="'+value+'"]').hasClass('single-filter')) { $('.mobile-selected-filters').append(self.templates.filterButtonExternal({ name: filter.name, value: value })); } }) }); self.bindExternalFilterButtonEvents(); } }, addToCartEventHandler: function(e) { var self = this; var $target = $(e.target); var $parent = $target.parents('.part-list-item'); var partid = $parent.attr('data-sku'); var quantity = $parent.find('#quantity-select').val(); // loading indicator $('body').addClass('cursor-wait'); if (localStorage.guid || localStorage.access_token) { self.postPartToCart(partid, quantity); } else { $.when(haas.ecommUtils.createCartPromise(this.authenticated)).then(function(payload) { localStorage.guid = payload.guid; haas.cookies.setCookie('ecommparts-cart', payload.guid); return self.postPartToCart(partid, quantity); }); } }, bindMobileFilterActions: function() { self = this; var $applyBtn = $('.mobile-filter-actions #apply-btn'), $clearBtn = $('.mobile-filter-actions #clear-btn'); $applyBtn.on('click', function(e) { haas.components.Modal.close(); self.renderPartItems(); self.rebindPartItemsHandler(); self.updateNumSelected(); self.renderMobileSelectedFilters(); }); $clearBtn.on('click', function(e) { self.$element.find('input:not(.single-filter)').prop('checked', false); self.$element.find('input:not(.single-filter)').removeAttr('checked'); haas.components.Modal.close(); self.renderPartItems(); self.rebindPartItemsHandler(); self.updateNumSelected(); self.renderMobileSelectedFilters(); }); }, mobileTooltipClickHandler: function(e) { var $header = $(e.target).is('h2') ? $(e.target) : $(e.target).parents('h2'); var $filterDescription = $header.find('#mobile-filter-tooltip-description'); $filterDescription.slideToggle(); }, propSixtyFiveTooltipHandler: function(e) { e.preventDefault(); var redirectLink = $(e.target).attr('data-redirect'); window.location = redirectLink; }, sortByClickHandler: function(e) { let self = this; let dropdownMenuElem = self.elementNode.querySelector('.dropdown-menu'); if (dropdownMenuElem.style.display === 'block') dropdownMenuElem.style.display = ''; else dropdownMenuElem.style.display = 'block'; }, bindSubscribeEvents: () => { let src = '/content/dam/haascnc/ecommerce/subscribe/SubscribeAndSave_SignUpButton-' + localStorage.storedSiteLang + '.png'; let srcIcon = '/content/dam/haascnc/ecommerce/subscribe/Subscribe_PLP-' + localStorage.storedSiteLang + '.png'; $('.subscribe > img').attr('src', src) $('.sub-icon').attr('src', srcIcon) /* if(haas.cookies.getCookie('salesOrg') !== '1000') { $('.subscribe').hide(); $('.sub-icon').hide(); } */ let modal = haas.components.Modal; if(window.screen.width > 800) { $('.subscribe, .sub-icon').on('click', () => { modal.open($('#subscribe-text').html()); $('.haas-modal-body').css('width: 100%'); }); } else { $('.subscribe, .sub-icon').on('click', () => { modal.open($('#subscribe-text-mobile').html()); $('.haas-modal-body').css('width: 100%'); }); } }, bindMobileShowHideFilters: function() { let spaContainerElemClasses = this.elementNode.querySelector('.spa-container').classList; if (spaContainerElemClasses.contains('hide-filters-col')) spaContainerElemClasses.remove('hide-filters-col'); else spaContainerElemClasses.add('hide-filters-col'); this.$element.find('#show').toggleClass('hidden'); this.$element.find('#hide').toggleClass('hidden'); }, bindEvents: function() { this.$element.find('.prop-sixty-five').on('click', function(e) { e.preventDefault(); }); this.$element.find('.prop-tooltext').on('click', this.propSixtyFiveTooltipHandler.bind(this)); this.$element.find('input:not([type="text"])').on('click', this.filterClickHandler.bind(this)); this.$element.find('#clear-all').on('click', this.clearAllClickHandler.bind(this)); this.$element.find('.part-list-item #add-to-cart-btn').on('click', this.addToCartEventHandler.bind(this)); this.$element.find('#mobile-filter-btn').on('click', this.bindMobileShowHideFilters.bind(this)); this.$element.find('.dropdown').on('click', this.sortByClickHandler.bind(this)); this.bindSubscribeEvents(); }, rebindPartItemsHandler: function() { this.$element.find('.part-list-item #add-to-cart-btn').off().on('click', this.addToCartEventHandler.bind(this)); } }); })(); (function() { haas.components.ApparelListingItemsDynamic = haas.Component.create({ title: '', count: '', hasChildren: '', isProducts: '', items: [], sizes: [], uniques: [], uniqueItems: [], selectedSize: '', filterValues: null, selectedFilters: [], hiddenFilters: ['Weight (lbs)', 'Weight (kgs)', 'Compliance - Prop 65'], apparelSizes: ['S', 'M', 'L', 'XL', '2XL', '3XL', '4XL'], filterOrder: [], inventoryObject: {}, userData: '', startEnabled: false, disableLiveCheck: false, initialize: function() { console.log('APPAREL LOADED -------------------------------'); $.when(haas.jwToken.getUserInfo()).then(function(data) { this.userData = data; console.log('JWT DECODED ASSIGNED', this.userData); }); var filterOrderData = $('#filter-order-data').attr('data-filterorder'); // Remove once ecommerce is global // if (!localStorage.showEcommerce) haas.ecommUtils.setEcommercePermissions(); this.mapJsonToAttributes(); this.startEnabled = $('#live-check-attributes').attr('data-start-enabled') === 'true'; this.disableLiveCheck = $('#live-check-attributes').attr('data-disable-live-check') === 'true'; // add additional hidden filters if (this.title === 'ER Collet Kits & Accessories') { this.hiddenFilters = this.hiddenFilters.concat(['Collet System', 'Type', 'Pilot Diameter', 'Shank Type', 'Shank Size', 'Funtional Length ( FL )', 'Bore Diameter ( ⌀d )']); } if (this.title === 'Pull Studs') { this.hiddenFilters = this.hiddenFilters.concat(['Wrench Flat Diameter']); } // Add authored hidden filters to hidden filters list if ($('#hidden-filter-data').attr('data-hidden-filters') && $('#hidden-filter-data').attr('data-hidden-filters').length) { this.hiddenFilters = this.hiddenFilters.concat($('#hidden-filter-data').attr('data-hidden-filters').split(',')); } // initialize filter order if (filterOrderData && filterOrderData.length) { this.filterOrder = filterOrderData.split(','); } else { switch (this.title) { case 'ER Collet Kits & Accessories': this.filterOrder = ['Shank Type', 'Shank Size', 'Collet Series', 'Gage Length', 'Through Coolant ( TSC )', 'Body Diameter ( BD )','Body Length']; break; case 'End Mill Holders': this.filterOrder = ['Shank Type', 'Shank Size', 'Gage Length', 'Bore Diameter ( ⌀d )', 'Through Coolant ( TSC )', 'Body Diameter ( BD )', 'Body Length']; break; case 'Pull Studs': this.filterOrder = ['Taper Size', 'Thread Size', 'Through Coolant ( TSC )', 'Knob Angle', 'Flange to Beginning of Tap', 'Flange to end of knob', 'Knob Diameter', 'Neck Diameter', 'Number of Pieces']; break; case 'Shell Mill Holders': this.filterOrder = ['Shank Type', 'Shank Size', 'Gage Length', 'Pilot Diameter', 'Bore Diameter ( ⌀d )', 'Through Coolant ( TSC )', 'Body Diameter ( BD )', 'Body Length']; break; case 'ER Collet Chucks': this.filterOrder = ['Shank Type', 'Shank Size', 'Collet Series', 'Gage Length', 'Through Coolant ( TSC )', 'Body Diameter ( BD )','Body Length']; break; } } // Remove once ecommerce is global // if (!localStorage.showEcommerce) haas.ecommUtils.setEcommercePermissions(); }, checkPartInventoryPromise: function(partId) { var endpoint = haas.constants.api.ecommerce + 'products/' + partId; var $part = $('.part-list-item[data-sku="' + partId + '"]'); var self = this; if (self.inventoryObject[partId]) { if (self.inventoryObject[partId] === 'inStock') { $part.find('#add-to-cart-btn').prop('disabled', false); } else { $part.find('#add-to-cart-btn').html($part.find('#add-to-cart-btn').attr('data-oos-text')); } } else { $.get(endpoint).then(function(result) { var stockObj = result.stock; var stockStatus = stockObj.stockLevelStatus; if (stockStatus === 'inStock' || stockStatus === 'lowStock') { self.inventoryObject[partId] = 'inStock'; $part.find('#add-to-cart-btn').prop('disabled', false); } else { self.inventoryObject[partId] = 'outOfStock'; $part.find('#add-to-cart-btn').html($part.find('#add-to-cart-btn').attr('data-oos-text')); } }) .fail(function(e) { // if call fails, just let hybris handle the error on add-to-cart self.inventoryObject[partId] = 'inStock'; $('.part-container #add-to-cart-btn').prop('disabled', false); }); } }, mapJsonToAttributes: function() { var dataText = this.$element.find('#part-listing-data').attr('data-json'); var rawJson = JSON.parse(dataText); this.title = rawJson.title; this.count = rawJson.count; this.hasChildren = rawJson.count; this.isProducts = rawJson.isProducts; this.items = rawJson.items; this.filterValues = rawJson.filterValues; var self = this; rawJson.items.forEach((item, index) => { item.allPrices.forEach((price, pindex) => { rawJson.items[index].allPrices[pindex] = JSON.parse(price.replace("'", '')); }) }); this.items.forEach(function(item, index) { if (!item.sku ) { console.log('ITEM WITHOUT SKU', item); return; }; if(self.apparelSizes.indexOf(item['sku'].split('-').pop()) > -1) { console.log('ITEM ENTERED SIZES', item); baseSku = [item.sku.substring(0, item.sku.lastIndexOf('-'))]; item.size = item['sku'].split('-').pop(); if(self.sizes[baseSku]) { self.sizes[baseSku].push(item.size); } else { self.sizes[baseSku] = []; self.sizes[baseSku].push(item.size); } } if (item.size) { item.title = item.title.substring(0, item.title.lastIndexOf(' ')); item.link = item.link.substring(0, item.link.lastIndexOf('/')); item.sku = item.sku.substring(0, item.sku.lastIndexOf('-')); } if (self.uniques.indexOf(item.sku) === -1) { self.uniques.push(item.sku); } return item; }); self.uniques.forEach(function(uSku) { self.uniqueItems.push(self.items.find(function(item) { return item.sku === uSku; })); }); this.items = self.uniqueItems; console.log('ALL ITEMS', this.items); console.log('SIZES PER ITEM', this.sizes); }, filterItems: function() { var self = this; var $filterContainer = $('#filter-container'); // Get unique filters self.selectedFilters = _.values($filterContainer.serializeArray().reduce(function(arr, cur) { if (arr[cur.name]) { arr[cur.name].value.push(cur.value); return arr; } arr[cur.name] = { name: cur.name, value: [cur.value] }; return arr; }, {})); // If there are no selected filters, just return all items if (!self.selectedFilters.length) { return self.items.filter((fItem => { if(self.returnPriceByCurrency(fItem.allPrices).length){ return fItem; }; })); } // Otherwise, filter! return self.items.filter(function(item) { return self.selectedFilters.every(function (filter) { return filter.value.some(function(value) { return item.classificationFilterValues.indexOf(filter.name +':'+ value) > -1; }); }); }); }, returnPriceByCurrency: function(priceObject) { return priceObject.filter(function(price){ return price.currency === haas.cookies.getCookie('tooling-currency'); }); }, returnDiscountByCurrency: function(discountPticeObject) { return (discountPticeObject.length ? this.returnPriceByCurrency(discountPticeObject)[0].amount : false); }, updateCount: function() { var $headerContainer = $('#items-header'); var $itemsContainer = $('#items-container'); var currentCount = $itemsContainer.children().length; $headerContainer.find('span').html(currentCount); //if (!currentCount) $itemsContainer.append('

    Sorry, those parameters return no results..

    Try removing a filter and searching again.

    ') }, render: function() { this.renderHeader(); this.renderFilters(); this.renderPartItems(); this.bindEvents(); }, renderHeader: function() { var $headerContainer = $('#items-header'); $headerContainer.find('h1').html(this.title); $headerContainer.find('span').html(this.count); }, renderFilters: function() { var $filterContainer = $('#filter-container'); var self = this; // first sort alphabetically, then sort by given order Object.keys(this.filterValues) .sort() .sort(function(a, b) { var orderA = self.filterOrder.indexOf(a) >= 0 ? self.filterOrder.indexOf(a) : Number.MAX_SAFE_INTEGER; var orderB = self.filterOrder.indexOf(b) >= 0 ? self.filterOrder.indexOf(b) : Number.MAX_SAFE_INTEGER; return orderA - orderB; }) .filter(function(key) { return self.hiddenFilters.indexOf(key) === -1; }).forEach(function(key) { var inputItem = '

    '+key+'

    '; var numberOfOptions = self.filterValues[key].length; var numberFilters = ['Diameter', 'Length']; // will sort the filters alphanumerically var sortedFilters = self.filterValues[key].sort(); // Sort filters with numeric values by actual numeric value if (numberFilters.some(function(filter) { return key.indexOf(filter) > -1; })) { try { sortedFilters = self.filterValues[key].sort(function(a, b) { var valA = a.split(' ').reduce(function(x, y) { return eval(x) + eval(y); }, 0); var valB = b.split(' ').reduce(function(x, y) { return eval(x) + eval(y); }, 0); return valA - valB; }) } catch (e) { console.log(error); } } if (sortedFilters.length === 1) { inputItem = inputItem + ''; inputItem = '
    ' + inputItem + '
    '; // Hide filter if only one inputItem = ''; } else { sortedFilters.forEach(function(option) { inputItem = inputItem + ''; }); inputItem = '
    ' + inputItem + '
    '; } $filterContainer.append(inputItem); }); if (!$('.filter-cat-container').length) { $('#filters-col').addClass('hidden'); $('.spa-container').addClass('hide-filters-col'); } }, processSelectableFilters: function() { // clear all non-selectable filters before processing $('#filter-container label').removeClass('filter-disabled').removeClass('not-selectable'); $('#filter-container input').prop('disabled', false); var self = this; var filteredItemList = $('.part-list-item').map(function(ndx, item) { return $(item).attr('data-sku') }).toArray(); var currentItems = JSON.parse($('#part-listing-data').attr('data-json')).items.filter(function(dataItem) { return filteredItemList.indexOf(dataItem.sku) > -1; }); var availableFilters = {}; var selectedFilterNames = self.selectedFilters.map(function(elem) { return elem.name }); var unselectableFilterType = $('#filters-col').attr('data-unselectable-filter-type'); currentItems.forEach(function(item) { item.classificationFilterValues.forEach(function(filter) { var filterData = filter.split(':'); if (!availableFilters[filterData[0]]) availableFilters[filterData[0]] = []; availableFilters[filterData[0]].push(filterData[1]); }); }); console.log(availableFilters); console.log(selectedFilterNames); /* $('.filter-cat-container').each(function(ndx, group) { var filterName = $(group).attr('data-master-cat'); var $filters = $(group).find('input'); var selectableFilters = availableFilters[filterName]; // if theres a filter in the group already selected, or only a single filter, we dont need to process the group if ($(group).attr('data-single-filter') === 'true') return; $filters.each(function(ndx, filter) { var filterValue = $(filter).attr('value'); if (selectableFilters.indexOf(filterValue) === -1) { unselectableFilterType === 'disabled' ? $(filter).parent().addClass('filter-disabled') : $(filter).parent().addClass('not-selectable'); $(filter).prop('disabled', true); } }) }); */ }, renderPartItems: function() { var self = this; var $itemsCol = $('#items-container'); $itemsCol.empty(); this.filterItems().forEach(function(item, index) { if (!item.sku) return; var itemContent = self.templates.apparelListItemTemplate({ itemSku: item.sku, itemSkuShort: item.skuShort, itemLink: item.link, itemImgSrc: item.imageHref, itemImgTitle: item.sku, itemImgAlt: item.sku, itemTitle: item.title, itemPrice: item.price.amount, itemAllPrices: item.allPrices, itemSize: item.size, hasStrikethroughPrice: item.hasStrikethroughPrice, rawPromoPrice: item.rawPromoPrice, propSixtyFive: item.californiaProposition65Required ? 'prop-sixty-five-req' : '', startDisabled: (self.startEnabled || self.disableLiveCheck) ? false : true }); $itemsCol.append(itemContent); if (!self.disableLiveCheck) self.checkPartInventoryPromise(item.sku); }); this.updateCount(); this.renderPrices(); this.renderQuantityOptions(); this.renderSizeOptions(); this.processSelectableFilters(); }, renderQuantityOptions: function() { $('.part-list-item').each(function(ndx, elem) { var $quantityOptionContainer = $(elem).find('#quantity-select'); var options = ''; for (var i = 1; i <= 50; i++) { options = options + "'; } $quantityOptionContainer.html(options); }); }, renderSizeOptions: function() { var self = this; $('.part-list-item').each(function(ndx, elem) { var $parent = $(this).closest('.part-list-item'); var $link = $(this).closest('.part-list-item').children('a'); if ($parent.attr('data-size')) { var itemSku = $(this).attr('data-sku'); var $quantityOptionContainer = $(elem).find('#size-select'); // styling class for items with sizes $(this).addClass('sized-item'); var options = ''; if (self.sizes[itemSku] && self.sizes[itemSku].length) { for (var i = 0; i < self.sizes[itemSku].length; i++) { options = options + "'; } $quantityOptionContainer.html(options); $link.attr('href', $link.attr('href') + '/' + $parent.attr('data-sku') + '-' + $(this).children('.check-out-container').find('#size-select').val().toLowerCase() + '.html'); $quantityOptionContainer.change(function() { $link.attr('href', $link.attr('href').substring(0, $link.attr('href').lastIndexOf('/')) + '/' + $(this).closest('.part-list-item').attr('data-sku') + '-' + $(this).val().toLowerCase() + '.html'); console.log('SIZE CHANGED!'); }); } } else { $(elem).find('#size-select').hide(); $(elem).find('label[for="' + $(elem).find('#size-select').attr('id') + '"]').hide(); } }); }, renderPrices: function() { $.when(haas.region.priceGroupPromise).then(function() { if(haas.cookies.getCookie('tooling-currency') === 'undefined') { $('.check-out-container').hide(); $('.part-pricing').hide(); } else { $('.part-list-item').each(function(ndx, elem) { $('.price-span').each(function() { $(this).html(new Intl.NumberFormat('en-US', {style: 'currency', currency: haas.cookies.getCookie('tooling-currency')}).format(parseFloat($(this).attr('data-price')))); if($(this).attr('data-currency') === haas.cookies.getCookie('tooling-currency')) { console.log ('CURRENCY COOKIE', haas.cookies.getCookie('tooling-currency')); $(this).show(); } }); if ($(elem).find('.plp-promo-container.promo-true').length) { var promoAmount = new Intl.NumberFormat('en-US', {style: 'currency', currency: 'USD'}).format($(elem).find('.plp-promo-price > span').attr("data-value")); $(elem).find('.plp-promo-price > span').html(promoAmount); $(elem).addClass('ecomm-plp-promo'); } }); } }); }, filterClickHandler: function(e) { this.renderPartItems(); this.rebindPartItemsHandler(); }, clearAllClickHandler: function(e) { this.$element.find('input:not(.single-filter)').prop('checked', false); this.renderPartItems(); this.rebindPartItemsHandler(); }, timeoutModal: function() { setTimeout(function() { if ($('.haas-modal-wrapper').is('.open')) haas.components.Modal.close(); }, 1000); }, cartSuccessClickHandler: function() { haas.LOGGER.debug('Proceeding to Cart!'); $('#cart-success-btn').addClass('disabled'); $('#ecommerce-nav > a').click(); }, showSuccessModal: function(quantity) { // to-do: Add attributes in html to make this translatable var self = this; // Remove loading indicator $('body').removeClass('cursor-wait'); haas.components.Modal.open(self.templates.addToCartSuccessModal({qty: quantity})); $('#cart-success-btn').off('click').on('click', self.cartSuccessClickHandler); $('#continue-btn').off('click').on('click', haas.components.Modal.close); }, showErrorModal: function(error) { let errorTLdata = this.elementNode.querySelector('#error-tl-data').dataset; let errorTL = errorTLdata.oos; let outOfStockTL = errorTLdata.oos; let expiredTL = errorTLdata.expired; let timeoutTL = errorTLdata.timeout; let signinTL = errorTLdata.signin; let genericErrorTL = errorTLdata.generic; // Remove loading indicator $('body').removeClass('cursor-wait'); if (error.type === 'InsufficientStockError') { haas.components.Modal.open('

    '+errorTL+' '+outOfStockTL+'

    '); this.timeoutModal(); } else if (error.type === 'CartError') { var self = this; haas.components.Modal.open('

    '+errorTL+' '+expiredTL+'

    '); let hybrisLogoutPayload = $.get(haas.constants.api.hybrisLogout(localStorage.storedSiteLang)); let eatCookiesPayload = $.get(haas.constants.api.eatcookies(localStorage.storedSiteLang)); return $.when(hybrisLogoutPayload, eatCookiesPayload).then((logoutData, eatCookiesData) => { localStorage.cartQuantity = 0; localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } else if(error.type === 'InvalidTokenError') { haas.components.Modal.open('
    '+timeoutTL+'
    '); haas.fleet.myHaasDropdown.logout(); self.timeoutModal(); } else { haas.components.Modal.open('
    '+errorTL+' '+genericErrorTL+'
    '); let hybrisLogoutPayload = $.get(haas.constants.api.hybrisLogout(localStorage.storedSiteLang)); let eatCookiesPayload = $.get(haas.constants.api.eatcookies(localStorage.storedSiteLang)); return $.when(hybrisLogoutPayload, eatCookiesPayload).then((logoutData, eatCookiesData) => { localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } }, postPartToCart: function(partid, quantity) { var self = this; var email; var bearer; var endpoint = haas.constants.api.ecommerce; if(localStorage.access_token) { $.when(haas.jwToken.getUserInfo()).then(function(userPayload) { bearer = userPayload['ecomm_bearer_token_access_token']; if (userPayload.userInfo) { email = userPayload.userInfo.uid; } else { email = userPayload.email; } $.get({ url: '/ecommpartsstorefront/ecommparts/en/hybris-cart', cache: false }).then(function(cart) { endpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cart.cartId + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; }).fail(function(payload) { console.log('PAYLOAD TIMEDOUT', payload); if(payload.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { self.showErrorModal(payload.responseJSON.errors[0]); } }).always(function() { haas.ecommUtils.renderCartQuantity(); }); console.log('Returned Cart', cart); }).fail(function(err) { console.log('TIMEDOUT', err.responseJSON.errors[0].type); if(err.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { $.post({ contentType: 'application/json', url: haas.constants.api.ecommerce + 'users/' + email + '/carts' + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') }, }).done(function(cartResponse){ console.log('Cart Created', cartResponse); endpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cartResponse.code + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; }).fail(function(payload) { console.log('TIMEDOUT', payload.errors.type); self.showErrorModal(payload.responseJSON.errors[0]) }).always(function() { haas.ecommUtils.renderCartQuantity(); }); }); } }); console.log('returned payload', userPayload); return userPayload; }); } else { endpoint = haas.constants.api.ecommerce + 'users/anonymous/carts/' + localStorage.guid + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; }).fail(function(payload) { self.showErrorModal(payload.responseJSON.errors[0]) }).always(function() { haas.ecommUtils.renderCartQuantity(); }); } }, updateNumSelected: function() { var self = this; var num = 0; self.selectedFilters.forEach(function(filter) { filter.value.forEach(function(value) { if (!$('input[name="'+filter.name+'"][value="'+value+'"]').hasClass('single-filter')) { num += 1; } }); }); if (num) $('.num-selected').html('(' + num + ')'); else $('.num-selected').empty(); }, bindExternalFilterButtonEvents: function() { var self = this console.log($('.ext-filter')); $('.ext-filter').on('click', function(e) { var $parent = $(e.target).is('a') ? $(e.target) : $(e.target).parent('a'); var name = $parent.attr('name'); var value = $parent.attr('value'); var $input = $('input[name="' + name + '"][value="'+value+'"]'); $input.prop('checked', false).removeAttr('checked'); self.renderPartItems(); self.rebindPartItemsHandler(); self.updateNumSelected(); self.renderMobileSelectedFilters(); }); $('.ext-clear-all').on('click', function(e) { var $parent = $(e.target).is('a') ? $(e.target) : $(e.target).parent('a'); var name = $parent.attr('name'); var value = $parent.attr('value'); var $input = $('input:not(.single-filter)'); $input.prop('checked', false).removeAttr('checked'); self.renderPartItems(); self.rebindPartItemsHandler(); self.updateNumSelected(); self.renderMobileSelectedFilters(); }); }, renderMobileSelectedFilters: function() { var self = this; $('.mobile-selected-filters').empty(); if (self.selectedFilters.length) { $('.mobile-selected-filters').append(self.templates.clearButtonExternal()); self.selectedFilters.forEach(function(filter) { filter.value.forEach(function(value) { if (!$('input[name="'+filter.name+'"][value="'+value+'"]').hasClass('single-filter')) { $('.mobile-selected-filters').append(self.templates.filterButtonExternal({ name: filter.name, value: value })); } }) }); self.bindExternalFilterButtonEvents(); } }, addToCartEventHandler: function(e) { var self = this; var $target = $(e.target); var $parent = $target.parents('.part-list-item'); var partid = $parent.attr('data-sku'); if ($parent.find('#size-select').val()) { partid = $parent.attr('data-sku') + '-' + $parent.find('#size-select').val(); } var quantity = $parent.find('#quantity-select').val(); // loading indicator $('body').addClass('cursor-wait'); console.log('ADDED PARTID', partid); console.log('ADDED QTY', quantity); if (localStorage.guid || localStorage.access_token) { self.postPartToCart(partid, quantity); } else { $.when(haas.ecommUtils.createCartPromise(this.authenticated)).then(function(payload) { localStorage.guid = payload.guid; haas.cookies.setCookie('ecommparts-cart', payload.guid); return self.postPartToCart(partid, quantity); }); } }, bindMobileFilterActions: function() { self = this; var $applyBtn = $('.mobile-filter-actions #apply-btn'), $clearBtn = $('.mobile-filter-actions #clear-btn'); $applyBtn.on('click', function(e) { haas.components.Modal.close(); self.renderPartItems(); self.rebindPartItemsHandler(); self.updateNumSelected(); self.renderMobileSelectedFilters(); }); $clearBtn.on('click', function(e) { self.$element.find('input:not(.single-filter)').prop('checked', false); self.$element.find('input:not(.single-filter)').removeAttr('checked'); haas.components.Modal.close(); self.renderPartItems(); self.rebindPartItemsHandler(); self.updateNumSelected(); self.renderMobileSelectedFilters(); }); }, mobileFilterClickHandler: function(e) { /** * Maps modal filters to filters already on page */ var $input = $('#filters-col input[name="'+$(e.target).attr('name')+'"][value="'+$(e.target).attr('value')+'"]'); $input.prop('checked', !$input.prop('checked')); if ($input.prop('checked')) $input.attr('checked', true); else $input.removeAttr('checked'); }, sizeSelectEventHandler: function(e) { var self = this; var $target = $(e.target); var $parent = $target.parents('.part-list-item'); console.log('PARENT', $parent); console.log('Size Changed'); }, mobileFiltersButtonClickHandler: function(e) { var self = this; haas.components.Modal.open($(self.templates.modalWrapper()).append(self.$element.find('#filter-container').prop('outerHTML')).html()); $('.haas-modal input').on('click', self.mobileFilterClickHandler.bind(self)); self.bindMobileFilterActions(); }, propSixtyFiveTooltipHandler: function(e) { e.preventDefault(); var redirectLink = $(e.target).attr('data-redirect'); window.location = redirectLink; }, bindEvents: function() { this.$element.find('.prop-sixty-five').on('click', function(e) { e.preventDefault(); }); this.$element.find('.prop-tooltext').on('click', this.propSixtyFiveTooltipHandler.bind(this)); this.$element.find('input').on('click', this.filterClickHandler.bind(this)); this.$element.find('#clear-all').on('click', this.clearAllClickHandler.bind(this)); this.$element.find('.part-list-item #add-to-cart-btn').click(this.addToCartEventHandler.bind(this)); this.$element.find('#mobile-filter-btn').on('click', this.mobileFiltersButtonClickHandler.bind(this)); this.$element.find('.part-list-item #size-select').change(this.sizeSelectEventHandler.bind(this)); }, rebindPartItemsHandler: function() { this.$element.find('.part-list-item #add-to-cart-btn').off().on('click', this.addToCartEventHandler.bind(this)); } }); })(); $(function() { // remove the "Gallery" tab if there are no images in the gallery component if ($('.partImageGallery').length && !$('.partImageGallery .part-img-container').length) { $('.tabs li').filter(function(ndx, item) { return $(item).html() === 'Gallery'; }).remove(); } }); (function() { haas.components.PartClassificationsCharts = haas.Component.create({ primaryMaterials: '', secondaryMaterials: '', initialize: function() { var self = this; if ($('[id="Secondary Workpiece Material"]').length > 0) { this.secondaryMaterials = $('[id="Secondary Workpiece Material"]').attr('data-materials').split(','); console.log('DYNAMIC CHARTS LOADED!', this.secondaryMaterials); this.secondaryMaterials.forEach(function(material) { if($('.material-' + material.charAt(0).toLowerCase() + '-2').children().length < 1) { $('.material-' + material.charAt(0).toLowerCase() + '-2').append(''); console.log('CHECKING MATERIAL', material.charAt(0)); } }) } if ($('[id="Primary Workpiece Material"]').length > 0) { console.log('PWM', $('[id="Primary Workpiece Material"]').attr('data-materials')); this.primaryMaterials = $('[id="Primary Workpiece Material"]').attr('data-materials').split(','); console.log('DYNAMIC CHARTS LOADED!', this.primaryMaterials); this.primaryMaterials.forEach(function(material) { if($('.material-' + material.charAt(0).toLowerCase() + '-2').children().length < 1) { $('.material-' + material.charAt(0).toLowerCase() + '-2').append(''); console.log('CHECKING MATERIAL', material.charAt(0)); } }) } /* // For German Language if ($('[id="Sekundäres Werkstückmaterial"]').length > 0) { this.secondaryMaterials = $('[id="Sekundäres Werkstückmaterial"]').attr('data-materials').split(','); console.log('DYNAMIC CHARTS LOADED!', this.secondaryMaterials); this.secondaryMaterials.forEach(function(material) { $('.material-' + material.charAt(0).toLowerCase() + '-2').append(''); console.log('CHECKING MATERIAL', material.charAt(0)); }) } if ($('[id="Primäres Werkstückmaterial"]').length > 0) { console.log('PWM', $('[id="Primäres Werkstückmaterial"]').attr('data-materials')); this.primaryMaterials = $('[id="Primäres Werkstückmaterial"]').attr('data-materials').split(','); console.log('DYNAMIC CHARTS LOADED!', this.primaryMaterials); this.primaryMaterials.forEach(function(material) { $('.material-' + material.charAt(0).toLowerCase() + '-2').append(''); console.log('CHECKING MATERIAL', material.charAt(0)); }) } // For Spanish Language if ($('[id="Material de pieza secundario"]').length > 0) { this.secondaryMaterials = $('[id="Material de pieza secundario"]').attr('data-materials').split(','); console.log('DYNAMIC CHARTS LOADED!', this.secondaryMaterials); this.secondaryMaterials.forEach(function(material) { $('.material-' + material.charAt(0).toLowerCase() + '-2').append(''); console.log('CHECKING MATERIAL', material.charAt(0)); }) } if ($('[id="Material de pieza principal"]').length > 0) { console.log('PWM', $('[id="Material de pieza principal"]').attr('data-materials')); this.primaryMaterials = $('[id="Material de pieza principal"]').attr('data-materials').split(','); console.log('DYNAMIC CHARTS LOADED!', this.primaryMaterials); this.primaryMaterials.forEach(function(material) { $('.material-' + material.charAt(0).toLowerCase() + '-2').append(''); console.log('CHECKING MATERIAL', material.charAt(0)); }) } // For French Language if ($('[id="Matériau de la pièce à usiner secondaire"]').length > 0) { this.secondaryMaterials = $('[id="Matériau de la pièce à usiner secondaire"]').attr('data-materials').split(','); console.log('DYNAMIC CHARTS LOADED!', this.secondaryMaterials); this.secondaryMaterials.forEach(function(material) { $('.material-' + material.charAt(0).toLowerCase() + '-2').append(''); console.log('CHECKING MATERIAL', material.charAt(0)); }) } if ($('[id="Material de pieza principal"]').length > 0) { console.log('PWM', $('[id="Material de pieza principal"]').attr('data-materials')); this.primaryMaterials = $('[id="Material de pieza principal"]').attr('data-materials').split(','); console.log('DYNAMIC CHARTS LOADED!', this.primaryMaterials); this.primaryMaterials.forEach(function(material) { $('.material-' + material.charAt(0).toLowerCase() + '-2').append(''); console.log('CHECKING MATERIAL', material.charAt(0)); }) } // For Italian Language if ($('[id="Materiale del pezzo secondario"]').length > 0) { this.secondaryMaterials = $('[id="Materiale del pezzo secondario"]').attr('data-materials').split(','); console.log('DYNAMIC CHARTS LOADED!', this.secondaryMaterials); this.secondaryMaterials.forEach(function(material) { $('.material-' + material.charAt(0).toLowerCase() + '-2').append(''); console.log('CHECKING MATERIAL', material.charAt(0)); }) } if ($('[id="Materiale del pezzo primario"]').length > 0) { console.log('PWM', $('[id="Materiale del pezzo primario"]').attr('data-materials')); this.primaryMaterials = $('[id="Materiale del pezzo primario"]').attr('data-materials').split(','); console.log('DYNAMIC CHARTS LOADED!', this.primaryMaterials); this.primaryMaterials.forEach(function(material) { $('.material-' + material.charAt(0).toLowerCase() + '-2').append(''); console.log('CHECKING MATERIAL', material.charAt(0)); }) } // For Dutch Language if ($('[id="Secundair werkstukmateriaal"]').length > 0) { this.secondaryMaterials = $('[id="Secundair werkstukmateriaal"]').attr('data-materials').split(','); console.log('DYNAMIC CHARTS LOADED!', this.secondaryMaterials); this.secondaryMaterials.forEach(function(material) { $('.material-' + material.charAt(0).toLowerCase() + '-2').append(''); console.log('CHECKING MATERIAL', material.charAt(0)); }) } if ($('[id="Primair werkstukmateriaal"]').length > 0) { console.log('PWM', $('[id="Primair werkstukmateriaal"]').attr('data-materials')); this.primaryMaterials = $('[id="Primair werkstukmateriaal"]').attr('data-materials').split(','); console.log('DYNAMIC CHARTS LOADED!', this.primaryMaterials); this.primaryMaterials.forEach(function(material) { $('.material-' + material.charAt(0).toLowerCase() + '-2').append(''); console.log('CHECKING MATERIAL', material.charAt(0)); }) } */ }, render: function() { var self = this; } }); })(); (function() { haas.components.PartClassifications = haas.Component.create({ hasCategoryConfig: false, hiddenDelimiter: ",", orderDelimiter: ",", initialize: function() { this.hasCategoryConfig = document.querySelector('#category-config-data').dataset.order || document.querySelector('#category-config-data').dataset.hiddenFilters; this.hiddenDelimiter = this.hasCategoryConfig ? document.querySelector('#category-config-data').dataset.hiddenDelimiter : document.querySelector('#classifications-container').dataset.hiddenDelimiter; this.orderDelimiter = this.hasCategoryConfig ? document.querySelector('#category-config-data').dataset.orderDelimiter : document.querySelector('#classifications-container').dataset.orderDelimiter; }, render: function() { var self = this; self.formatBalancedToRPM(); self.removeAuthoredClassifications(); self.sortClassificationsByAuthoring(); self.bindSlideshowEvents(); }, formatBalancedToRPM: function() { // Format rpm so that thousands have commas var balancedRPMRowItems = $('.partClassifications table').find('td').filter(function(td, elem) { return $(elem).html() === "Balanced to RPM"; }).parents('tr').children(); if (balancedRPMRowItems.length) { var formattedRPMValue = Number($(balancedRPMRowItems[1]).html().trim()).toLocaleString('en'); $(balancedRPMRowItems[1]).html(formattedRPMValue); } }, removeAuthoredClassifications: function() { var self = this; var plantsForEcommSaleTerms = ['ecom', 'site', 'e-com']; // hotfix: remove "Related Tool Holder" Spec $('.partClassifications table').find('td').filter(function(td, elem) { return $(elem).html() === "Related Tool Holder"; }).parents('tr').remove(); // hide ecomm plant in all languages $('.partClassifications table').find('td').filter(function(td, elem) { return plantsForEcommSaleTerms.some(term => $(elem).html().toLowerCase().includes(term)); }).parents('tr').remove(); // Remove all classifications marked by authoring if ($('#classifications-container').length) { if (self.hasCategoryConfig && document.querySelector('#category-config-data').dataset.hiddenFilters) { document.querySelector('#category-config-data').dataset.hiddenFilters.split(self.hiddenDelimiter).forEach((spec) => { // Error handling when list ends with a comma or there are empty strings if (!spec.length) return; let specMapElem = Array.from(self.elementNode.querySelectorAll('#feature-lang-map div')).find(mapElem => mapElem.dataset.featureMap.split(':')[1] === spec); let specName = specMapElem ? specMapElem.dataset.featureMap.split(':')[0] : ''; let specTd = Array.from(document.querySelectorAll('.partClassifications table td')).filter((td, elem) => td.innerHTML.trim() === specName)[0]; if (specTd) specTd.parentElement.remove(); }); } else if (document.querySelector('#classifications-container').dataset.hiddenFilters) { document.querySelector('#classifications-container').dataset.hiddenFilters.split(self.hiddenDelimiter).forEach((spec) => { // Error handling when list ends with a comma or there are empty strings if (!spec.length) return; let specMapElem = Array.from(self.elementNode.querySelectorAll('#feature-lang-map div')).find(mapElem => mapElem.dataset.featureMap.split(':')[1] === spec); let specName = specMapElem ? specMapElem.dataset.featureMap.split(':')[0] : ''; let specTd = Array.from(document.querySelectorAll('.partClassifications table td')).filter((td, elem) => td.innerHTML.trim() === specName)[0]; if (specTd) specTd.parentElement.remove(); }); } } if (!$('.partClassifications table td').length) { $('.part-specs-header').hide(); } }, sortClassificationsByAuthoring: function() { // Sort table by authored order let self = this; let tableTds = Array.from(document.querySelectorAll('.partClassifications table td')); let specsOrder = []; if (self.hasCategoryConfig && document.querySelector('#category-config-data').dataset.order) { specsOrder = document.querySelector('#category-config-data').dataset.order.split(self.orderDelimiter).reverse(); } else if (document.querySelector('#classifications-container').dataset.order){ specsOrder = document.querySelector('#classifications-container').dataset.order.split(self.orderDelimiter).reverse(); } specsOrder.forEach((spec) => { let specMapElem = Array.from(self.elementNode.querySelectorAll('#feature-lang-map div')).find(mapElem => mapElem.dataset.featureMap.includes(spec)); let specName = specMapElem ? specMapElem.dataset.featureMap.split(':')[0] : ''; let specTd = tableTds.filter((td, elem) => td.innerHTML.trim() === specName)[0]; if (specTd) $('.partClassifications table').prepend(specTd.parentElement); }); }, bindSlideshowEvents: function() { // Bind Slideshow Events var shownNdx = 0; var numPics = $('.line-drawing-image-container').length; if (numPics > 1) { var leftBtnSelector = '.line-drawing-image-container .line-drawing-gallery-left'; var rightBtnSelector = '.line-drawing-image-container .line-drawing-gallery-right'; $(leftBtnSelector).add(rightBtnSelector).removeClass('hidden'); $(leftBtnSelector).off('click').on('click', function() { console.log(shownNdx, numPics); shownNdx = shownNdx <= 0 ? numPics - 1 : shownNdx - 1; console.log(shownNdx, numPics); $('.line-drawing-image-container').css('display','none'); $($('.line-drawing-image-container')[shownNdx]).css('display','block'); }); $(rightBtnSelector).off('click').on('click', function() { console.log(shownNdx, numPics); shownNdx = shownNdx >= numPics -1 ? 0 : shownNdx + 1; console.log(shownNdx, numPics); $('.line-drawing-image-container').css('display','none'); $($('.line-drawing-image-container')[shownNdx]).css('display','block'); }); } } }) })(); (function() { haas.components.EcommercePart = haas.Component.create({ part_id : '', authenticated : false, isApparel: false, apparelBasePartId: '', isSubscriptionEligible: false, apparelSizes: ['S', 'M', 'L', 'XL', '2XL', '3XL', '4XL'], ecommerceCartEndpoint : haas.constants.api.ecommerce, originalPrice: 0, initialize: function() { let self = this; self.initQuantityOptions(); if (localStorage.getItem('access_token')) { } else { self.ecommerceCartEndpoint = self.ecommerceCartEndpoint + 'users/anonymous/carts/'; } self.part_id = self.$element.attr('data-partid'); self.isSubscriptionEligible = self.elementNode.querySelector('#subscription-eligible-data').dataset.isEligible && self.elementNode.querySelector('#subscription-eligible-data').dataset.isEligible === 'true'; console.log(self.elementNode.querySelector('#subscription-eligible-data'), self.elementNode.querySelector('#subscription-eligible-data').dataset.isEligible, self.isSubscriptionEligible) // remove inventory check // this.checkPartInventoryPromise(this.part_id); self.productTypeCheck(self.part_id); self.renderReviews(); self.bindEvents(); // Remove once ecommerce is global // if (!localStorage.showEcommerce) haas.ecommUtils.setEcommercePermissions(); $.when(haas.region.priceGroupPromise).then(function(priceData) { // Set object price self.originalPrice = Number($('#' + haas.cookies.getCookie('tooling-currency')).html()); // format currency self.formatCurrency(); // render promo message self.renderPromoMessage(); // calculate shipping if (priceData.country === 'US') { let isWcApplicable = !window.location.pathname.includes('service-parts') && !window.location.pathname.includes('winner'); let currencySelector = '#' + priceData.currency; let hasPrice = self.elementNode.querySelector(currencySelector); if (self.elementNode.classList.contains('winner-circle-pdp')) self.elementNode.classList.remove('hidden'); if (isWcApplicable && hasPrice) self.renderShippingInfo(); } else { if (self.elementNode.classList.contains('winner-circle-pdp')) document.querySelector('.breadcrumb').style.display = 'none'; } if (priceData.country !== 'US' && self.isSubscriptionEligible) { self.elementNode.querySelector('.subscribe-to-save-container').classList.remove('hidden'); } // render price per unit self.renderPricePerUnit(); // render scale pricing table self.renderScalePricing(); }); }, productTypeCheck: function(partId) { var self = this; console.log('THIS PARTID', partId); var size = partId.split('-').pop(); var $h1 = $(".part-content-right").children('h1'); var $h2 = $(".part-content-right").children('h2'); var title = $h1.html().substring(0, $h1.html().lastIndexOf(' ')); this.apparelBasePartId = partId.substring(0, partId.lastIndexOf('-')); console.log('BASE APPAREL ID', this.apparelBasePartId); if (this.apparelSizes.indexOf(size) > -1) { $('.size-btn-group').show(); var $sizeButtonsContainer = $(".size-btn-group"); var sizeValues = $sizeButtonsContainer.attr('data-attr-sizes').split(', '); var buttons = ''; for (var i = 0; i < sizeValues.length; i++) { buttons = buttons + "'; } $sizeButtonsContainer.html(buttons); $('#' + size).addClass("selected"); $(".size-btn-group > .size-btn").click(function(){ $(".size-btn-group > .size-btn").removeClass("selected"); $(this).addClass("selected"); $h1.html(title + ' ' + $(this).attr('id')); $h2.html("Part #: " + self.apparelBasePartId + '-' + $(this).attr('id')); self.part_id = self.apparelBasePartId + '-' + $(this).attr('id'); }); $('.partClassifications').hide(); } console.log('APPAREL SIZE', size); }, checkPartInventoryPromise: function(partId) { var endpoint = haas.constants.api.ecommerce + 'products/' + partId; $.get(endpoint).then(function(result) { var stockObj = result.stock; var stockStatus = stockObj.stockLevelStatus; console.log(result, stockObj, stockStatus); if (stockStatus === 'inStock' || stockStatus === 'lowStock') { $('.part-container #add-to-cart-btn').prop('disabled', false); } else { $('.part-container #add-to-cart-btn').html($('.part-container #add-to-cart-btn').attr('data-oos-text')); } }) .fail(function(e) { // if call fails, just let hybris handle the error on add-to-cart $('.part-container #add-to-cart-btn').prop('disabled', false); }); }, initQuantityOptions: function() { var $quantityOptionContainer = $('#pdp-quantity-select'); var options = ''; for (var i = 1; i <= 50; i++) { options = options + "'; } $quantityOptionContainer.html(options); }, renderPromoMessage: function() { const self = this; const promoDataContainer = self.elementNode.querySelector('#tooling-promo-data'); const promoMessage = promoDataContainer.dataset.promoMessage; const promoMessageEU = promoDataContainer.dataset.promoMessageEu; const includedParts = promoDataContainer.dataset.promoIncludedParts ? promoDataContainer.dataset.promoIncludedParts.split(',') : []; const excludedParts = promoDataContainer.dataset.promoExcludedParts ? promoDataContainer.dataset.promoExcludedParts.split(',') : []; let hasPromo = (promoMessage && promoMessage.length && haas.cookies.getCookie('salesOrg') === '1000') || (promoMessageEU && promoMessageEU.length && haas.cookies.getCookie('salesOrg') === '2000'); // if includeParts are authored & dont include part ID, no promo // if excludedParts are authored & include part ID, no promo if ((includedParts.length && !includedParts.includes(self.part_id)) || (excludedParts.length && excludedParts.includes(self.part_id))) { hasPromo = false; } if (hasPromo) { if (haas.cookies.getCookie('salesOrg') === '1000') { self.elementNode.querySelector('.pdp-promo-message > p').innerHTML = promoMessage; } else if (haas.cookies.getCookie('salesOrg') === '2000') { self.elementNode.querySelector('.pdp-promo-message > p').innerHTML = promoMessageEU; } self.elementNode.querySelector('.pdp-promo-message').classList.remove('hidden'); } }, renderPricePerUnit: function() { var self = this; let packOf = $('#authored-unit').attr('data-pack'); var packOfNdx = packOf; if (packOfNdx > -1) { var quantity = Number(packOfNdx); var perPriceValue = Number(parseFloat(self.originalPrice / quantity).toFixed(3).slice(0, -1)); var perPriceStr = haas.ecommUtils.formatPrice(parseFloat(perPriceValue).toFixed(2)); var productType = $('#authored-unit').attr('data-unit'); /* if (header.indexOf('drill') > -1) productType = 'drill'; if (header.indexOf('insert') > -1) productType = 'insert'; */ self.$element.find('#' + haas.cookies.getCookie('tooling-currency')).siblings('#unit-price').html(" (" + perPriceStr + " / " + productType + ")").removeClass('hidden'); $('#unit-price-description').removeClass('hidden'); $('#unit-price-description > #quantity').html("(" + quantity + ")"); $('#unit-price-description > #product-type').html(productType + "s. " + _.capitalize(productType)); } }, renderScalePricing: function() { var scaleData = $('#scale-pricing-data-container').attr('data-scale-pricing'); var self = this; if (scaleData && scaleData.length) { try { var scaleDataObj = JSON.parse(scaleData); console.log('scaleDataObj', scaleDataObj); scaleDataObj = scaleDataObj.filter((ob) => ob.currencyIso === haas.cookies.getCookie('tooling-currency')); if(scaleDataObj.length) $('.part-scale-pricing-container').removeClass('hidden'); var $tableContainer = $('#scale-pricing-table-container'); var qtyHeaders = scaleDataObj.map(function(ob) { return ob.id.replace('QTY', ''); }); var qtyPrices = scaleDataObj.map(function(ob) { return haas.ecommUtils.formatPrice(Number(ob.value)); }); var priceValues = scaleDataObj.map(function(ob) { return Number(ob.value) }); var tableTemplate = self.templates.scalePricingTable(); var basePrice = priceValues[0]; var offTlTxt; $tableContainer.html(tableTemplate); offTlTxt = self.elementNode.querySelector('#scale-pricing-table').dataset.offTlTxt; qtyHeaders.forEach(function(header) { $('#scale-pricing-table').find('#qty-row').append('' + header + ''); }); qtyPrices.forEach(function(price, ndx) { $('#scale-pricing-table').find('#price-row').append('' + price + ''); if (ndx !== 0) { let discountRate = 100 - (Number((priceValues[ndx] / basePrice).toFixed(2)) * 100); $('#scale-pricing-table').find('#header-row').append(''+discountRate+'% '+offTlTxt+''); } }); } catch (e) { haas.LOGGER.debug(e); } } }, renderShippingInfo: function() { let self = this; let deliverTextElem = self.elementNode.querySelector('.delivery-text-left'); let wcPopupUrl = '/content/haascnc/en/reference-container/haas-tooling-references/Winners_Circle_Popup.html'; // If kit table exists on the page, use the weights from the kit table // Else, find weight in specs table and calculate try { // hardcoded freight items const freightItems = ['09-0019', '09-0020', '08-1200', '06-0200', '08-1085']; const isFreight = freightItems.includes(self.part_id) || window.location.pathname.includes('fixed_jaw_vises'); if (isFreight) { deliverTextElem.classList.add('freight'); deliverTextElem.querySelector('#freight-text').classList.remove('hidden'); self.elementNode.querySelector('.no-expedited-shipping-msg').classList.remove('hidden'); } else if (document.querySelector('#kit-products[data-json]')) { let dataContainer = document.querySelector('#kit-products[data-json]'); if (dataContainer) { let dataJSON = JSON.parse(dataContainer.dataset.json); let kitWeight = Number(dataJSON.kitTotalWeight); let hasWeightError; let kitProducts = JSON.parse(dataJSON.kitProducts); // Check if any weight is negative // If so then weight can't be caclulated properly and display default msg if (kitProducts) hasWeightError = kitProducts.some(product => Number(product.weight) < 0); if (!hasWeightError) { // If < 15, 1-day shipping // If 15 < weight < 150, 2-day // Else if > 150, freight + display "no expedited shipping" message if (kitWeight <= 15) { deliverTextElem.classList.add('one-day'); deliverTextElem.querySelector('#one-day-text').classList.remove('hidden'); } else if (kitWeight > 15 && kitWeight <= 150) { deliverTextElem.classList.add('two-day'); deliverTextElem.querySelector('#two-day-text').classList.remove('hidden'); } else { deliverTextElem.classList.add('freight'); deliverTextElem.querySelector('#freight-text').classList.remove('hidden'); self.elementNode.querySelector('.no-expedited-shipping-msg').classList.remove('hidden'); } } } else { console.log('No weight found for product'); } } else { let classificationsElem = document.querySelector('.partClassifications'); let specsEN = classificationsElem ? Array.from(classificationsElem.querySelectorAll('#classifications-data-en > div')) : null; let weightSpecElem = specsEN ? specsEN.find(spec => spec.id.toLowerCase() === 'weight') : null; if (weightSpecElem) { let weightVal; /* Expected Weight Formats: * - lb(s) \ kg * - kg \ lb(s) * - lb(s) - doesn't have unit in value * - kg - doesn't have unit in value */ if (weightSpecElem.dataset.value && weightSpecElem.dataset.value.includes('lb')) { let weightSpecVals = weightSpecElem.dataset.value.split('\\'); let poundVal = weightSpecVals.find(val => val.includes('lb')).trim(); poundVal = poundVal.split(' ')[0]; weightVal = Number(poundVal); } else { const kgConvert = 2.205; // if weight spec = "[lbs] weight", dont kg convert if (weightSpecElem.id.toLowerCase().includes('lb')) weightVal = Number(weightSpecElem.dataset.value.split(' ')[0]); else weightVal = Number(weightSpecElem.dataset.value.split(' ')[0]) * kgConvert; } // If < 15, 1-day shipping // If 15 < weight < 150, 2-day // Else if > 150, freight + display "no expedited shipping" message if (weightVal <= 15) { deliverTextElem.classList.add('one-day'); deliverTextElem.querySelector('#one-day-text').classList.remove('hidden'); } else if (weightVal > 15 && weightVal <= 150) { deliverTextElem.classList.add('two-day'); deliverTextElem.querySelector('#two-day-text').classList.remove('hidden'); } else { deliverTextElem.classList.add('freight'); deliverTextElem.querySelector('#freight-text').classList.remove('hidden'); self.elementNode.querySelector('.no-expedited-shipping-msg').classList.remove('hidden'); } } else { console.log('No weight found for product'); } } self.elementNode.querySelector('.wc-delivery-msg-container').style.cursor = 'pointer'; self.elementNode.querySelector('.wc-delivery-msg-container').onclick = () => { $.get(wcPopupUrl).then(function(res) { let tempNode = document.createElement('div'); tempNode.innerHTML = res; let contentNode = tempNode.querySelector('.print-only'); haas.components.Modal.open(contentNode.outerHTML, 'no-modal-defaults', true); haas.components.Modal.initComponents(); haas.utils.initTextComponents(); }); } } catch (e) { console.log('Error Setting Shipping Text: ', e); } // Calculate + Render 5% discount try { let wcPriceElem = this.elementNode.querySelector('.wc-savings-value'); let wcPriceVal = Number((this.originalPrice * 0.95).toFixed(2)); let wcPriceString = haas.ecommUtils.formatPrice(wcPriceVal.toFixed(2)); wcPriceElem.innerHTML = wcPriceString; } catch (e) { console.log('Error Rendering Price: ', e); } self.elementNode.querySelector('.wc-delivery-msg-container').classList.remove('hidden'); if (self.isSubscriptionEligible) { self.elementNode.querySelector('.wc-delivery-msg-container .ss-text').classList.remove('hidden'); } }, formatCurrency: function() { $(function() { $('.selected-currency').each(function() { if($(this).attr('id') !== haas.cookies.getCookie('tooling-currency')) { } else { $(this).parent().removeClass('hidden'); $(this).html(haas.ecommUtils.formatPrice($(this).html())); if ($('.pdp-promo-price > #promo-' + haas.cookies.getCookie('tooling-currency')).parent().hasClass('hidden')) { $('.pdp-promo-price > #promo-' + haas.cookies.getCookie('tooling-currency')).parent().removeClass('hidden'); $('#promo-' + haas.cookies.getCookie('tooling-currency')).html(haas.ecommUtils.formatPrice($('#promo-' + haas.cookies.getCookie('tooling-currency')).attr("data-value"))); $('.current-price-container').addClass('ecomm-pdp-promo'); } else { $('.part-price').css('margin-bottom', '10px'); } } }); if (!$('#' + haas.cookies.getCookie('tooling-currency')).length) { $('.add-to-cart-container').hide(); $('.alert2').removeClass('hidden'); $('.subscribe').addClass('hidden'); $('.sub-price').addClass('hidden'); $('.sub-price-pack').addClass('hidden'); } if(haas.cookies.getCookie('tooling-currency') === 'undefined') { $('.add-to-cart-container').hide(); $('.alert').removeClass('hidden'); $('.subscribe').addClass('hidden'); $('.sub-price').addClass('hidden'); $('.sub-price-pack').addClass('hidden'); } let curPrice = parseFloat($('#' + haas.cookies.getCookie('tooling-currency')).attr('data-value')); let subPrice = curPrice - (curPrice * 0.05); $('.sub-price').html(haas.ecommUtils.formatPrice(subPrice.toFixed(2))); if ($('#authored-unit').attr('data-pack')) { let subUnitPrice = subPrice / Number($('#authored-unit').attr('data-pack')); $('.sub-price-unit').parent().removeClass('hidden'); $('.sub-price-unit').html(haas.ecommUtils.formatPrice(subUnitPrice.toFixed(2))); } console.log('SUBSCRIPTION PRICE!', subPrice.toFixed(2)); }); }, timeoutModal: function() { setTimeout(function() { if ($('.haas-modal-wrapper').is('.open')) haas.components.Modal.close(); }, 5000); }, cartSuccessClickHandler: function() { haas.LOGGER.debug('Proceeding to Cart!'); $('#cart-success-btn').addClass('disabled'); $('#ecommerce-nav > a').click(); }, showSuccessModal: function(quantity) { // to-do: add attributes in html to make translatable var self = this; // Remove loading indicator $('body').removeClass('cursor-wait'); haas.components.Modal.open(self.templates.addToCartSuccessModal({qty: quantity})); $('#cart-success-btn').off('click').on('click', self.cartSuccessClickHandler); $('#continue-btn').off('click').on('click', haas.components.Modal.close); }, showErrorModal: function(error) { let errorTLdata = this.elementNode.querySelector('#error-tl-data').dataset; let errorTL = errorTLdata.error; let outOfStockTL = errorTLdata.oos; let expiredTL = errorTLdata.expired; let timeoutTL = errorTLdata.timeout; let signinTL = errorTLdata.signin; let genericErrorTL = errorTLdata.generic; let wcErrorTL = errorTLdata.wcAlreadyAdded; let wcMemberErrorTL = errorTLdata.wcAlreadyMember; // Remove loading indicator $('body').removeClass('cursor-wait'); if (error.type === 'winnerCircleMaxOrderQuantityExceeded') { haas.components.Modal.open('

    '+errorTL+' '+wcErrorTL+'

    '); this.timeoutModal(); } else if (error.type === 'winnerCircleAlreadyMember') { haas.components.Modal.open('

    '+errorTL+' '+wcMemberErrorTL+'

    '); this.timeoutModal(); } else if (error.type === 'InsufficientStockError') { haas.components.Modal.open('

    '+errorTL+' '+outOfStockTL+'

    '); this.timeoutModal(); } else if (error.type === 'CartError') { var self = this; haas.components.Modal.open('

    '+errorTL+' '+expiredTL+'

    '); let hybrisLogoutPayload = $.get(haas.constants.api.hybrisLogout(localStorage.storedSiteLang)); let eatCookiesPayload = $.get(haas.constants.api.eatcookies(localStorage.storedSiteLang)); return $.when(hybrisLogoutPayload, eatCookiesPayload).then((logoutData, eatCookiesData) => { localStorage.cartQuantity = 0; localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } else if(error.type === 'InvalidTokenError') { haas.components.Modal.open('
    '+timeoutTL+'
    '); self.timeoutModal(); haas.fleet.myHaasDropdown.logout(); } else { haas.components.Modal.open('
    '+errorTL+' '+genericErrorTL+'
    '); let hybrisLogoutPayload = $.get(haas.constants.api.hybrisLogout(localStorage.storedSiteLang)); let eatCookiesPayload = $.get(haas.constants.api.eatcookies(localStorage.storedSiteLang)); return $.when(hybrisLogoutPayload, eatCookiesPayload).then((logoutData, eatCookiesData) => { localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } }, initAuthenticatedUserInfo: function () { var self = this; }, postPartToCart: function(guid) { var self = this; var email; var bearer; var endpoint = this.ecommerceCartEndpoint + localStorage.guid + '/entries'; var quantity = Number($('#pdp-quantity-select').val()); var reqBody = haas.ecommUtils.buildReqBody(quantity, this.part_id); if(localStorage.getItem('access_token')) { $.when(haas.jwToken.getUserInfo()).then(function(userPayload) { bearer = userPayload['ecomm_bearer_token_access_token']; if (userPayload.userInfo) { email = userPayload.userInfo.uid; } else { email = userPayload.email; } $.get({ url: '/ecommpartsstorefront/ecommparts/en/hybris-cart', cache: false }).then(function(cart) { self.ecommerceCartEndpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cart.cartId + '/entries'; $.post({ contentType: 'application/json', headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') }, url: self.ecommerceCartEndpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody }).done(function(payload){ if (payload.statusCode && payload.statusCode === 'winnerCircleMaxOrderQuantityExceeded') { let errorObj = {type : 'winnerCircleMaxOrderQuantityExceeded'}; self.showErrorModal(errorObj); } else if (payload.statusCode && payload.statusCode === 'winnerCircleAlreadyMember') { let errorObj = {type : 'winnerCircleAlreadyMember'}; self.showErrorModal(errorObj); } else { self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; } }).fail(function(payload) { if(payload.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { self.showErrorModal(payload.responseJSON.errors[0]); } }).always(function() { haas.ecommUtils.renderCartQuantity(); }); }).fail(function(err){ if(err.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { $.post({ contentType: 'application/json', url: haas.constants.api.ecommerce + 'users/' + email + '/carts' + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') }, }).done(function(cartResponse) { console.log('Created Cart', cartResponse); self.ecommerceCartEndpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cartResponse.code + '/entries'; $.post({ contentType: 'application/json', headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') }, url: self.ecommerceCartEndpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody }).done(function(payload){ if (payload.statusCode && payload.statusCode === 'winnerCircleMaxOrderQuantityExceeded') { let errorObj = {type : 'winnerCircleMaxOrderQuantityExceeded'}; self.showErrorModal(errorObj); } else if (payload.statusCode && payload.statusCode === 'winnerCircleAlreadyMember') { let errorObj = {type : 'winnerCircleAlreadyMember'}; self.showErrorModal(errorObj); } else { self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; } }).fail(function(payload) { if(payload.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { self.showErrorModal(payload.responseJSON.errors[0]) } }).always(function() { haas.ecommUtils.renderCartQuantity(); }); }); } }); console.log('returned payload', payload); return payload; }); } else { $.post({ contentType: 'application/json', headers: { 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') }, url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody }).done(function(payload){ if (payload.statusCode && payload.statusCode === 'winnerCircleMaxOrderQuantityExceeded') { let errorObj = {type : 'winnerCircleMaxOrderQuantityExceeded'}; self.showErrorModal(errorObj); } else if (payload.statusCode && payload.statusCode === 'winnerCircleAlreadyMember') { let errorObj = {type : 'winnerCircleAlreadyMember'}; self.showErrorModal(errorObj); } else { self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; } }).fail(function(payload) { self.showErrorModal(payload.responseJSON.errors[0]) }).always(function() { haas.ecommUtils.renderCartQuantity(); }); } }, addToCartEventHandler: function() { var self = this; // loading indicator $('body').addClass('cursor-wait'); if (localStorage.guid || localStorage.access_token) { self.postPartToCart(localStorage.guid); } else { $.when(haas.ecommUtils.createCartPromise(this.authenticated)).then(function(payload) { localStorage.guid = payload.guid; haas.cookies.setCookie('ecommparts-cart', payload.guid); return self.postPartToCart(localStorage.guid); }); } }, renderReviews: function() { /* var self = this; var allPdpReviews; var totalPdpReviews; var sumPdpReviews = 0; var $reviewsData = $('#reviews-list-container'); var $headerData = $('#avgFeedbackTemplate'); $.get({ url: haas.constants.api.ecommerce + 'products/' + $('.part-container').attr('data-partid') + '/reviews?fields=DEFAULT', cache: false }).then(function(reviewsData){ allPdpReviews = reviewsData.reviews; totalPdpReviews = allPdpReviews ? allPdpReviews.length : 0; if (allPdpReviews && allPdpReviews.length) { allPdpReviews.forEach(function(review) { sumPdpReviews = sumPdpReviews + review.rating; }); console.log('ALL REVIEWS FETCHED 2', totalPdpReviews); console.log('REVIEWS SUM', sumPdpReviews); var headerDataContent = self.templates.avgFeedbackTemplate({ totalReviews: totalPdpReviews, avg: sumPdpReviews / totalPdpReviews, avgStars: (sumPdpReviews / totalPdpReviews) / 5 * 100 || 0 }) $headerData.append(headerDataContent); console.log('Reviews COntent', $reviewsData); } }).fail(function(){ var headerDataContent = self.templates.avgFeedbackTemplate({ totalReviews: 0, avg: 0, avgStars: 0, }) $headerData.append(headerDataContent); }) */ }, bindImageExpand: function() { $(".part-image-container .expand-image-plus").click(function(){ var $thisButton = $(this); var $parent = $thisButton.parent('.expand-image-container'); var $thisImg = $parent.find('img.expand-image'); var curStr = $thisImg.attr('src'); $.fancybox.open([{ href : curStr }]); }); }, bindHeroSlideshowEvents: function() { var self = this; var shownNdx = 0; var numPics = $('.part-image-container').length; var leftBtnSelector = '.part-image-container .part-pdp-gallery-left'; var rightBtnSelector = '.part-image-container .part-pdp-gallery-right'; if (numPics > 1) { $(leftBtnSelector).add(rightBtnSelector).removeClass('hidden'); $(leftBtnSelector).off('click').on('click', function() { shownNdx = shownNdx <= 0 ? numPics - 1 : shownNdx - 1; $('.part-image-container').css('display','none'); $($('.part-image-container')[shownNdx]).css('display','block'); }); $(rightBtnSelector).off('click').on('click', function() { shownNdx = shownNdx >= numPics -1 ? 0 : shownNdx + 1; $('.part-image-container').css('display','none'); $($('.part-image-container')[shownNdx]).css('display','block'); }); } }, bindSubscribeEvents: function() { let src = '/content/dam/haascnc/ecommerce/subscribe/SubscribeAndSave_SignUpButton-' + localStorage.storedSiteLang + '.png'; let modal = haas.components.Modal; this.$element.find('.subscribe > img').attr('src', src) this.$element.find('.subscribe').click(() => { modal.open($('#subscribe-text').html()); $('.haas-modal-body').css('width: 100%'); }); }, bindEvents: function() { var self = this; self.$element.find('#add-to-cart-btn').on('click', self.addToCartEventHandler.bind(self)); self.bindImageExpand(); self.bindHeroSlideshowEvents(); self.bindSubscribeEvents(); } }) })(); (function() { haas.components.EcommerceKitTable = haas.Component.create({ completeKitPartsJson: {}, kitPartsJSON: [], purchasedSeparatelyPrice: 0.0, kitTotalPrice: 0.0, kitSavingsPercentage: 0.0, kitSavingsAmount: 0.0, initialize: function() { var self = this; try { self.completeKitPartsJson = JSON.parse(self.$element.attr('data-json')); self.kitPartsJSON = JSON.parse(self.completeKitPartsJson.kitProducts); } catch (e) { console.log(e); } }, handleKitPartClick: function(e) { var self = this; var $elem = $(e.target).is('.kit-part-list-item') ? $(e.target) : $(e.target).parents('.kit-part-list-item'); var url = $elem.attr('data-url'); var imgSrc = $elem.attr('data-img'); var title = $elem.find('.list-item-header-container h1').html(); var Modal = haas.components.Modal; Modal.open(self.templates.kitPartModalTemplate({ modalImg: imgSrc, modalLink: url, modalPartName: title })); }, bindEvents: function() { var self = this; $('.kit-part-list-item a').off('click').on('click', self.handleKitPartClick.bind(self)); }, renderSavings: function() { let self = this; let savingsNotAuthored = self.$element.find('h3 #savings').is('.hidden'); let purchasedSeperatelyNotAuthored = self.$element.find('h3 #original').is('.hidden'); let userCurrency = haas.cookies.getCookie('tooling-currency'); self.kitTotalPrice = Number(Array.from(document.querySelectorAll('.part .part-price span')).find(price => price.id === userCurrency).dataset.value); self.purchasedSeparatelyPrice = Array.from(document.querySelectorAll('.kit-part-list-item .price-span')) .map(span => { let userPrice = JSON.parse(span.dataset.allPrices).find(price => price.currency === userCurrency); let pkgQty = Number(span.dataset.qty); if (userPrice) return Number(userPrice.amount) * pkgQty; else return 0 }).reduce((a, b) => a + b, 0); self.kitSavingsAmount = Number((self.purchasedSeparatelyPrice - self.kitTotalPrice).toFixed(2)); self.kitSavingsPercentage = Math.round((self.kitSavingsAmount / self.purchasedSeparatelyPrice) * 100); $.when(haas.region.priceGroupPromise).then(function() { if (savingsNotAuthored) { self.$element.find('h3 #savings').append(' ' + self.kitSavingsPercentage + '%').removeClass('hidden'); } if (purchasedSeperatelyNotAuthored) { self.$element.find('h3 #original-value').prepend(haas.ecommUtils.formatPrice(Number(self.purchasedSeparatelyPrice).toFixed(2))); self.$element.find('h3 #original').removeClass('hidden'); } }); }, renderPrices: function() { Array.from(this.elementNode.querySelectorAll('.kit-part-list-item')).forEach(plItem => { let priceSpanElem = plItem.querySelector('.price-span'); let qty = priceSpanElem.dataset.qty; let allPrices = JSON.parse(priceSpanElem.dataset.allPrices); let userCurrency = haas.cookies.getCookie('tooling-currency'); let userPrice = allPrices.find(price => price.currency === userCurrency); let finalPrice = Number(qty) * Number(userPrice.amount) || Number(userPrice.amount); if (userPrice) { priceSpanElem.innerHTML = haas.ecommUtils.formatPrice(finalPrice.toFixed(2)); priceSpanElem.style.display = 'inline-block'; } }) }, render: function() { var self = this; var $kitPartListContainer = $('#kit-products-list'); self.kitPartsJSON.forEach(function(elem) { $kitPartListContainer.append(self.templates.kitPartTemplate({ itemSku: elem.partNum, itemLink: elem.linkUrl, itemImgSrc: elem.image, itemLargeImgSrc: elem.largeImage, itemTitle: elem.name, allPrices: elem.allPrices, allDiscountPrices: elem.allDiscountPrices, kitQuantity: elem.quantity })); }); self.bindEvents(); self.renderPrices(); self.renderSavings(); } }); })(); (function() { haas.components.CustomPartListing = haas.Component.create({ title: '', count: '', hasChildren: '', isProducts: '', items: [], filterValues: null, selectedFilters: [], filterOrder: [], hiddenFilters: [], preselectedFilters: [], inventoryObject: {}, userData: '', tooltipTitles: [], tooltipDescriptions: [], startEnabled: true, disableLiveCheck: true, urlParams: {}, isLatheHoldingInsertsPage: false, isEndMillPage: false, isToolholderPage: false, categoryConfigFilterOrder: [], categoryConfigHiddenFilters: [], initialize: function() { let self = this; let filterOrderData = $('#filter-order-data').attr('data-filterorder'); let urlObject = new URL(window.location.href); let curPath = window.location.href; $.when(haas.jwToken.getUserInfo()).then(function(data) { this.userData = data; console.log('JWT DECODED ASSIGNED', this.userData); }); fetch(haas.constants.api.secondaryPLP(window.location.pathname)).then(res => res.json()).then(itemsJson => { self.elementNode.querySelector('#part-listing-data').dataset.json = JSON.stringify(itemsJson); self.isLatheInsertsPage = curPath.includes('turning_inser'); self.isLatheToolholdingPage = curPath.includes('boring_bars') || curPath.includes('od_toolholding'); self.isLatheHoldingInsertsPage = curPath.includes('boring_bars') || curPath.includes('od_toolholding'); self.isEndMillPage = curPath.includes("end_mills") || curPath.includes("thread_mills") || curPath.includes("carbide_drills"); self.isToolholderPage = curPath.includes("end_mill_holders") || curPath.includes("fit_holders") || curPath.includes("er_collet_chucks") || curPath.includes('hydraulic_milling') || curPath.includes('milling_chuck'); self.isQuickChangeColletPage = curPath.includes("quick_change_collets"); self.isLatheColletChuckPage = curPath.includes("lathe_collet_chucks"); self.isBotToolholderPage = curPath.includes('bot_toolholding'); self.isBmtToolholderPage = curPath.includes('bmt_toolholding'); self.isTlClToolholderPage = curPath.includes('tl_cl_toolholding'); self.isShellMillBodyPage = curPath.includes('shell_mill_bodies'); self.isShellMillHolderPage = curPath.includes('shell_mill_holders'); self.isIndexableEndMillBodyPage = curPath.includes('indexable_end_mill_b'); self.isMillingInsertsPage = curPath.includes('milling_inserts'); self.isReductionSleevePage = curPath.includes('reduction_sleeves'); self.condenseSpacing(); self.mapJsonToAttributes(); self.setCategoryConfig(); try { if (self.isLatheInsertsPage) { self.filterPartsForInserts(); } else if (self.isLatheToolholdingPage) { self.filterPartsforIdOdTH(); } else if (self.isBotToolholderPage) { self.filterPartsForBotTH(); } else if (self.isBmtToolholderPage) { self.filterPartsForBmtTH(); } else if (self.isTlClToolholderPage) { self.filterPartsForTlClTH(); } else if (self.isEndMillPage) { self.prefilterToolholders(); } else if (self.isToolholderPage) { self.prefilterEndmills(); } else if (self.isQuickChangeColletPage) { } else if (self.isLatheColletChuckPage) { self.prefilterQCcollets(); } else if (self.isShellMillBodyPage) { self.filterPartsForShillMillBodies(); } else if (self.isShellMillHolderPage) { self.filterPartsForShillMillHolders(); } else if (self.isIndexableEndMillBodyPage) { self.filterPartsForIndexableEndMillBodies(); } else if (self.isMillingInsertsPage) { self.filterPartsForMillingInserts(); } else if (self.isReductionSleevePage) { self.filterPartsForReductionSleeves(); } } catch (e) { console.warn('Error Filtering Parts: ' + e); } // Add authored hidden filters to hidden filters list if ($('#hidden-filter-data').attr('data-hidden-filters') && $('#hidden-filter-data').attr('data-hidden-filters').length) { self.hiddenFilters = self.hiddenFilters.concat($('#hidden-filter-data').attr('data-hidden-filters').split(',')); } // hard-coded order for tool holder pages if (self.isToolholderPage) { self.filterOrder = ['Cutting Diameter ( ⌀DC )', '[ØDC] Cutting Diameter', 'Coating', 'Corner', 'Length of Cut (L)', '[LOC] Length Of Cut', 'Number of Flutes (NOF)', 'Haas Grade']; } // initialize filter order if (filterOrderData && filterOrderData.length) { self.filterOrder = filterOrderData.split(','); } self.tooltipTitles = $('#filter-tooltip-data').attr('data-filter-tooltip-titles') ? $('#filter-tooltip-data').attr('data-filter-tooltip-titles').split(',') : []; self.tooltipDescriptions = $('#filter-tooltip-data').attr('data-filter-tooltip-descriptions') ? $('#filter-tooltip-data').attr('data-filter-tooltip-descriptions').split(',,') : []; // Map Url Param Filters urlObject.searchParams.forEach((val, key) => { try { if (self.filterValues[key] && self.filterValues[key].includes(val)) self.urlParams[key] = val; else if (key.includes('Part Category')) self.urlParams[key] = val; } catch(e) { console.warn(e); } }); this.renderFilters(); this.renderFilterTooltips(); this.renderPartItems(); this.processUrlFilters(); this.bindEvents(); this.scrollToPLP(); this.postRender(); }); // Remove once ecommerce is global // if (!localStorage.showEcommerce) haas.ecommUtils.setEcommercePermissions(); }, condenseSpacing: function() { let singleSpacedData = this.$element.find('#part-listing-data').attr('data-json').replace(/\s+/g, ' '); this.$element.find('#part-listing-data').attr('data-json', singleSpacedData); }, mapJsonToAttributes: function() { const self = this; const dataText = this.$element.find('#part-listing-data').attr('data-json'); const rawJson = JSON.parse(dataText); this.items = rawJson.items.filter(item => item.allPrices.some(priceObj => priceObj.currency === haas.cookies.getCookie('tooling-currency'))); this.filterValues = rawJson.filterValues; this.categoryPathTitleMap = rawJson.categoryPathTitleMap; }, setCategoryConfig: function() { const self = this; const categoryConfigContainer = document.querySelector('#category-config-data'); if (categoryConfigContainer) { const orderDelimiter = categoryConfigContainer.dataset.secondaryPlpOrderDelimiter; const hiddenDelimiter = categoryConfigContainer.dataset.secondaryPlpHiddenDelimiter; const orderString = categoryConfigContainer.dataset.secondaryPlpOrder; const hiddenString = categoryConfigContainer.dataset.secondaryPlpHidden; self.categoryConfigFilterOrder = orderString && orderString.length ? orderString.split(orderDelimiter) : []; self.categoryConfigHiddenFilters = hiddenString && hiddenString.length ? hiddenString.split(hiddenDelimiter) : []; } }, filterPartsForReductionSleeves: function() { let self = this; let tableData = Array.from(document.querySelectorAll('.partClassifications #classifications-data-en div')); let shankDiameter = tableData.find(td => td.id.includes('Shank Diameter')).dataset.materials; let boreDiameter = tableData.find(td => td.id.includes('Bore Diameter')).dataset.materials; let shankDiameterValue = Number(shankDiameter.split(' ')[0]); let boreDiameterValue = Number(boreDiameter.split(' ')[0]); // Reduction Sleeves, Shank Diameter Format: 20 mm or 1.0 in \ 1" // Reduction Sleeves, Bore Diameter Format: 20 mm or 1.0 in \ 1" self.items = self.items.filter(part => { if (part.link.includes('reduction_sleeves')) { let partShankDiameter = part.classificationFilterValuesEN.find(value => value.includes('Shank Diameter')); if (!partShankDiameter) return false; let partShankDiameterValue = Number(partShankDiameter.split(':')[1].split(' ')[0]); return shankDiameterValue === partShankDiameterValue; } else if (part.link.includes('bot_toolholding') || part.link.includes('bmt_toolholding')) { let partShankSize = part.classificationFilterValuesEN.find(val => val.includes('Shank Size')); let partType = part.classificationFilterValuesEN.find(val => val.includes('Toolholder Type')); if (!partShankSize) return false; if (!partType) return false; let partTypeVal = partType.split(':')[1]; let partShankSizeObj = partShankSize.split(':')[1]; // Can only match on Boring Bars if (!partTypeVal.includes('Boring Bar')) return false; // bot shank size format: (1" \ 1 in) or (10 mm) // bmt shank size format: (1" \ 1 in) or (10 mm) if (partShankSize.includes('in')) { let partShankSizeVal; if (partShankSizeObj.includes('\\')) { partShankSizeVal = Number(partShankSizeObj.split('\\')[1].trim().split(' ')[0]); } else if (partShankSizeObj.includes('\\')) { partShankSizeVal = Number(partShankSizeObj.split(' ')[1].trim().split(' ')[0]); } return partShankSizeVal === shankDiameterValue; } else if (partShankSize.includes('mm')) { let partShankSizeVal; partShankSizeVal = Number(partShankSizeObj.split(' ')[0].trim()); return partShankSizeVal === shankDiameterValue; } } else if (part.link.includes('boring_bars')) { let partShankSize = part.classificationFilterValuesEN.find(val => val.includes('Shank Diameter')); if (!partShankSize) return false; let partShankSizeObj = partShankSize.split(':')[1]; // id toolholders only in inches, format: 1.0 in let partShankSizeVal = Number(partShankSizeObj.split(' ')[0]); return boreDiameterValue === partShankSizeVal; } }); }, filterPartsForMillingInserts: function() { let self = this; let tableData = Array.from(document.querySelectorAll('.partClassifications #classifications-data-en div')); let millingCutterSeries = tableData.find(td => td.id.includes('Milling Cutter Series')).dataset.materials; self.items = self.items.filter(part => { let insertMillingCutterSeriesValues = part.classificationFilterValuesEN.filter(value => value.includes('Milling Cutter Series')); if (!insertMillingCutterSeriesValues.length) return false; return insertMillingCutterSeriesValues.some(insertMillingCutterSeriesValue => { let insertMillingCutterSeries = insertMillingCutterSeriesValue.split(':')[1]; return millingCutterSeries.includes(insertMillingCutterSeries) || insertMillingCutterSeries.includes(millingCutterSeries); }); }); }, filterPartsForShillMillBodies: function() { let self = this; let tableData = Array.from(document.querySelectorAll('.partClassifications #classifications-data-en div')); let millingCutterSeries = tableData.find(td => td.id.includes('Milling Cutter Series')).dataset.materials; let arborHoleDiameterObj = tableData.find(td => td.id.includes('Arbor Hole Diameter')).dataset.materials; let arborHoleDiameter; // Shell Mill Bodies, Arbor Hole Diameter fomat: (2 in) or (32 mm) if (arborHoleDiameterObj.includes('in')) { arborHoleDiameter = Number(arborHoleDiameterObj.split(' ')[0].trim()); } else { arborHoleDiameter = Number(arborHoleDiameterObj.split(' ')[0].trim()); } self.items = self.items.filter(part => { if (part.link.includes('shell_mill_holder')) { let pilotDiamValue = part.classificationFilterValuesEN.find(value => value.includes('[ØPD] Pilot Diameter')); if (!pilotDiamValue) return false; let pilotDiameter = Number(pilotDiamValue.split(':')[1].split(' ')[0]); return arborHoleDiameter === pilotDiameter; } else if (part.link.includes('milling_insert')) { let insertMillingCutterSeriesValues = part.classificationFilterValuesEN.filter(value => value.includes('Milling Cutter Series')); if (!insertMillingCutterSeriesValues.length) return false; return insertMillingCutterSeriesValues.some(insertMillingCutterSeriesValue => { let insertMillingCutterSeries = insertMillingCutterSeriesValue.split(':')[1]; return millingCutterSeries === insertMillingCutterSeries; }); } return false; }); }, filterPartsForShillMillHolders: function() { let self = this; let tableData = Array.from(document.querySelectorAll('.partClassifications #classifications-data-en div')); let pilotDiamValue = Number(tableData.find(td => td.id.includes('[ØPD] Pilot Diameter')).dataset.materials.split(' ')[0]); self.items = self.items.filter(part => { if (part.link.includes('shell_mill_bodies')) { let arborHoleDiameter = part.classificationFilterValuesEN.find(value => value.includes('Arbor Hole Diameter')); if (!arborHoleDiameter) return false; let arborHoldDiameterObj = arborHoleDiameter.split(':')[1].split(' '); let arborHoleDiameterVal = arborHoldDiameterObj ? Number(arborHoldDiameterObj[0]) : -1; return pilotDiamValue === arborHoleDiameterVal; } return false; }); }, filterPartsForIndexableEndMillBodies: function() { let self = this; let tableData = Array.from(document.querySelectorAll('.partClassifications #classifications-data-en div')); let shankDiameter = tableData.find(td => td.id.includes('Shank Diameter')).dataset.materials; let millingCutterSeries = tableData.find(td => td.id.includes('Milling Cutter Series')).dataset.materials; // shank diameter format: // imperial: 1 in // metric: 12 mm let shankDiameterValue = Number(shankDiameter.split(' ')[0].trim()); self.items = self.items.filter(part => { if (part.link.includes('end_mill_holder')) { let boreDiameterValue = part.classificationFilterValuesEN.find(value => value.includes('[ØD] Bore Diameter')); if (!boreDiameterValue) return false; let boreDiameter = Number(boreDiameterValue.split(':')[1].split(' ')[0]); return shankDiameterValue === boreDiameter; } else if (part.link.includes('milling_insert')) { let insertMillingCutterSeriesValues = part.classificationFilterValuesEN.filter(value => value.includes('Milling Cutter Series')); if (!insertMillingCutterSeriesValues.length) return false; return insertMillingCutterSeriesValues.some(insertMillingCutterSeriesValue => { let insertMillingCutterSeries = insertMillingCutterSeriesValue.split(':')[1]; return millingCutterSeries === insertMillingCutterSeries; }); } return false; }); }, filterPartsForInserts: function() { let self = this; let tableData = Array.from(document.querySelectorAll('.partClassifications #classifications-data-en div')); let insertStyle = tableData.find(td => td.id.includes('Insert Style')).dataset.materials; let clampingType = tableData.find(td => td.id.includes('Clamping Type')).dataset.materials; let insertSizeObj = tableData.find(td => td.id.includes('Inscribed Circle Diameter')).dataset.materials; let insertSizeImp, insertSizeMet; const groupMatch = ['M - Top and Hole Clamping', 'P - Hole Clamp', 'D - Double Clamp']; // turning inserts & cbn inserts & cermet inserts, insert ic size format: (1 in \ 10 mm) if (insertSizeObj) { insertSizeImp = Number(insertSizeObj.split('\\')[0].trim().split(' ')[0]); insertSizeMet = Number(insertSizeObj.split('\\')[1].trim().split(' ')[0]); } self.items = self.items.filter(part => { let partInsertStyle = part.classificationFilterValuesEN.find(value => value.includes('Insert Style')).split(':')[1]; let partClampingType = part.classificationFilterValuesEN.filter(value => value.includes('Clamping Type')).map(vals => vals.split(':')[1]).join(','); let partInsertSizeObj = part.classificationFilterValuesEN.find(value => value.includes('Inscribed Circle Diameter')).split(':')[1]; let partInsertSizeImp, partInsertSizeMet; // id od toolholders, insert ic size format: (1 in \ 10 mm) if (partInsertSizeObj) { partInsertSizeImp = Number(partInsertSizeObj.split('\\')[0].trim().split(' ')[0]); partInsertSizeMet = Number(partInsertSizeObj.split('\\')[1].trim().split(' ')[0]); } let clampingTypeMatch = (clampingType.includes(partClampingType) || partClampingType.includes(clampingType)) || (groupMatch.some(type => partClampingType.includes(type)) && groupMatch.some(type => clampingType.includes(type))); let insertStyleMatch = insertStyle === partInsertStyle; let icSizeMatch = (insertSizeImp === partInsertSizeImp || insertSizeMet === partInsertSizeMet); return clampingTypeMatch && insertStyleMatch && icSizeMatch; }); }, filterPartsforIdOdTH: function() { let self = this; let tableData = Array.from(document.querySelectorAll('.partClassifications #classifications-data-en div')); let insertStyle = tableData.find(td => td.id.includes('Insert Style')).dataset.materials; let clampingType = tableData.find(td => td.id.includes('Clamping Type')).dataset.materials; let insertSizeObj = tableData.find(td => td.id.includes('Inscribed Circle Diameter')).dataset.materials; let insertSizeImp = -1; let insertSizeMet = -1; const groupMatch = ['M - Top and Hole Clamping', 'P - Hole Clamp', 'D - Double Clamp']; // id od toolholders, insert ic size format: (1 in \ 10 mm) if (insertSizeObj) { insertSizeImp = Number(insertSizeObj.split('\\')[0].trim().split(' ')[0]); insertSizeMet = Number(insertSizeObj.split('\\')[1].trim().split(' ')[0]); } self.items = self.items.filter(part => { try { if (part.link.includes('turning_inserts') || part.link.includes('cbn_turning') || part.link.includes('cermet_turning')) { let partInsertStyle = part.classificationFilterValuesEN.find(value => value.includes('Insert Style')).split(':')[1]; let partClampingType = part.classificationFilterValuesEN.filter(value => value.includes('Clamping Type')).map(vals => vals.split(':')[1]).join(','); let partInsertSizeObj = part.classificationFilterValuesEN.find(value => value.includes('Inscribed Circle Diameter')).split(':')[1]; let partInsertSizeImp, partInsertSizeMet; // turning inserts & cbn inserts & cermet inserts, insert ic size format: (1 in \ 10 mm) if (partInsertSizeObj) { partInsertSizeImp = Number(partInsertSizeObj.split('\\')[0].trim().split(' ')[0]); partInsertSizeMet = Number(partInsertSizeObj.split('\\')[1].trim().split(' ')[0]); } let clampingTypeMatch = (clampingType.includes(partClampingType) || partClampingType.includes(clampingType)) || (groupMatch.some(type => partClampingType.includes(type)) && groupMatch.some(type => clampingType.includes(type))); let insertStyleMatch = insertStyle === partInsertStyle; let icSizeMatch = (insertSizeImp === partInsertSizeImp || insertSizeMet === partInsertSizeMet); return clampingTypeMatch && insertStyleMatch && icSizeMatch; } else if (window.location.pathname.includes('boring_bars')) { let shankDiamImp; let shankDiamObj = tableData.find(td => td.id.includes('Shank Diameter')).dataset.materials; // id toolholding, current shank diam format: (1 in) <- imperial unit only if (shankDiamObj) { shankDiamImp = Number(shankDiamObj.split(' ')[0]); } if (part.link.includes('bot_toolholding') || part.link.includes('bmt_toolholding') || part.link.includes('tl_cl_toolholding')) { let partShankSize = part.classificationFilterValuesEN.find(val => val.includes('Shank Size')).split(':')[1]; let partType = part.classificationFilterValuesEN.find(val => val.includes('Toolholder Type')).split(':')[1]; // Cannot match on Boring Bars if (partType !== 'Boring Bar') return false; // bot shank size format: (1" \ 1 in) or (10 mm) // bmt shank size format: (1" \ 1 in) or (10 mm) // tl cl shank size format: (1" 1 in) or (10 mm) if (partShankSize.includes('in')) { let partShankSizeVal; if (partShankSize.includes('\\')) { partShankSizeVal = Number(partShankSize.split('\\')[1].trim().split(' ')[0]); } else { partShankSizeVal = Number(partShankSize.split('"')[1].trim().split(' ')[0]); } return partShankSizeVal === shankDiamImp; } /* Removed matching on mm for now since id shank diameter only in inches */ return false; } if (part.link.includes('reduction_sleeves')) { // reduction sleeve, bore diameter format: 1.0 in \ 1" or 50 mm let partBoreDiameter = part.classificationFilterValuesEN.find(val => val.includes('Bore Diameter')).split(':')[1]; if (partBoreDiameter.includes('mm')) { return false; } else if (partBoreDiameter.includes('in')) { let partBoreDiameterVal = Number(partBoreDiameter.split(' ')[0].trim()); return partBoreDiameterVal === shankDiamImp; } return false; } return false; } else if (window.location.pathname.includes('od_toolholding')) { let shankHeightImp; let shankHeightObj = tableData.find(td => td.id.includes('Shank Height')).dataset.materials; // od toolholding, current shank height format: (1 in) <- imperial unit only if (shankHeightObj) { shankHeightImp = Number(shankHeightObj.split(' ')[0]); } if (part.link.includes('bot_toolholding') || part.link.includes('bmt_toolholding')) { let partShankSize = part.classificationFilterValuesEN.find(val => val.includes('Shank Size')).split(':')[1]; let partType = part.classificationFilterValuesEN.find(val => val.includes('Toolholder Type')).split(':')[1]; // Cannot match on Turning or Face Groove holding if (partType !== 'Turning' && partType !== 'Face Groove') return false; // bot shank size format: (1" \ 1 in) or (10 mm) // bmt shank size format: (1" \ 1 in) or (10 mm) if (partShankSize.includes('in')) { let partShankSizeVal; if (partShankSize.includes('\\')) { partShankSizeVal = Number(partShankSize.split('\\')[1].trim().split(' ')[0]); } return partShankSizeVal === shankHeightImp; } /* Removed matching on mm for now since id shank diameter only in inches */ return false; } return false; } } catch (e) { console.log('Error Parsing Part: ', part); return false; } }); }, filterPartsForBotTH: function() { let self = this; let tableData = Array.from(document.querySelectorAll('.partClassifications #classifications-data-en div')); let thSeries = tableData.find(td => td.id.includes('Toolholder Series')).dataset.materials; let thType = tableData.find(td => td.id.includes('Toolholder Type')).dataset.materials; let shankSizeObj = tableData.find(td => td.id.includes('Shank Size')).dataset.materials; let systemOfMeasurement = tableData.find(td => td.id.includes('System of Measurement')).dataset.materials; let shankSize; // bot shank size format: (1" \ 1 in) or (10 mm) if (shankSizeObj.includes('in')) { shankSize = Number(shankSizeObj.split('\\').find(measurement => measurement.includes('in')).trim().split(' ')[0]); } else if (shankSizeObj.includes('mm')) { shankSize = Number(shankSizeObj.split(' ')[0]); } self.items = self.items.filter(part => { try { if (part.link.includes('bot_toolholding')) { let partSeries = part.classificationFilterValuesEN.find(val => val.includes('Toolholder Series')).split(':')[1]; let partType = part.classificationFilterValuesEN.find(val => val.includes('Toolholder Type')).split(':')[1]; let partSystemOfMeasurement = part.classificationFilterValuesEN.find(val => val.includes('System of Measurement')).split(':')[1]; return partSeries === thSeries && partType === thType && systemOfMeasurement === partSystemOfMeasurement; } else if (thType.includes('Boring Bar') && part.link.includes('boring_bars')) { let shankDiameterObj = part.classificationFilterValuesEN.find(val => val.includes('Shank Diameter')).split(':')[1]; let shankDiameterImp, shankDiameterMet; // id toolholding, current shank diam format: (1 in) or (1 in \ 10 mm) if (shankDiameterObj && shankDiameterObj.includes('\\')) { shankDiameterImp = Number(shankDiameterObj.split('\\')[0].trim().split(' ')[0]); shankDiameterMet = Number(shankDiameterObj.split('\\')[1].trim().split(' ')[0]); } else if (shankDiameterObj) { shankDiameterImp = Number(shankDiameterObj.split(' ')[0]); } else { return false; } return shankDiameterImp === shankSize || shankDiameterMet === shankSize; } else if (thType.includes('Boring Bar') && part.link.includes('reduction_sleeves')) { // reduction sleeve, shank diameter format: 1.0 in \ 1" or 50 mm let partShankDiameter = part.classificationFilterValuesEN.find(val => val.includes('Shank Diameter')).split(':')[1]; let partShankDiameterVal = Number(partShankDiameter.split(' ')[0].trim()); return partShankDiameterVal === shankSize; } else if ((thType.includes('Turning') || thType.includes('Face Groove')) && part.link.includes('od_toolholding')) { let partShankHeightObj = part.classificationFilterValuesEN.find(val => val.includes('Shank Height')).split(':')[1]; let shankHeightImp, shankHeightMet; // od toolholding, current shank height format: (1 in) or (1 in \ 10 mm) if (partShankHeightObj && partShankHeightObj.includes('\\')) { shankHeightImp = Number(partShankHeightObj.split('\\')[0].trim().split(' ')[0]); shankHeightMet = Number(partShankHeightObj.split('\\')[1].trim().split(' ')[0]); } else if (partShankHeightObj) { shankHeightImp = Number(partShankHeightObj.split(' ')[0]); } else { return false; } return shankHeightImp === shankSize || shankHeightMet === shankSize; } return false; } catch (e) { console.log('Error Parsing Part: ', part); return false; } }); }, filterPartsForBmtTH: function() { let self = this; let tableData = Array.from(document.querySelectorAll('.partClassifications #classifications-data-en div')); let thSeries = tableData.find(td => td.id.includes('Toolholder Series')).dataset.materials; let thType = tableData.find(td => td.id.includes('Toolholder Type')).dataset.materials; let shankSizeObj = tableData.find(td => td.id.includes('Shank Size')).dataset.materials; let systemOfMeasurement = tableData.find(td => td.id.includes('System of Measurement')).dataset.materials; let shankSize; // bmt shank size format: (1" 1in) or (1" \ 1 in) or (10 mm) if (shankSizeObj.includes('in') && shankSizeObj.includes('\\')) { shankSize = Number(shankSizeObj.split('\\').find(measurement => measurement.includes('in')).trim().split(' ')[0]); } else if (shankSizeObj.includes('in')) { shankSize = Number(shankSizeObj.split('"')[1].trim().split(' ')[0]); } else if (shankSizeObj.includes('mm')) { shankSize = Number(shankSizeObj.split(' ')[0]); } self.items = self.items.filter(part => { try { if (part.link.includes('bmt_toolholding')) { let partSeries = part.classificationFilterValuesEN.find(val => val.includes('Toolholder Series')).split(':')[1]; let partType = part.classificationFilterValuesEN.find(val => val.includes('Toolholder Type')).split(':')[1]; let partSystemOfMeasurement = part.classificationFilterValuesEN.find(val => val.includes('System of Measurement')).split(':')[1]; return partSeries === thSeries && partType === thType && systemOfMeasurement === partSystemOfMeasurement; } else if (thType.includes('Boring Bar') && part.link.includes('boring_bars')) { let shankDiameterObj = part.classificationFilterValuesEN.find(val => val.includes('Shank Diameter')).split(':')[1]; let shankDiameterImp, shankDiameterMet; // id toolholding, current shank diam format: (1 in) or (1 in \ 10 mm) if (shankDiameterObj && shankDiameterObj.includes('\\')) { shankDiameterImp = Number(shankDiameterObj.split('\\')[0].trim().split(' ')[0]); shankDiameterMet = Number(shankDiameterObj.split('\\')[1].trim().split(' ')[0]); } else if (shankDiameterObj) { shankDiameterImp = Number(shankDiameterObj.split(' ')[0]); } else { return false; } return shankDiameterImp === shankSize || shankDiameterMet === shankSize; } else if (thType.includes('Boring Bar') && part.link.includes('reduction_sleeves')) { // reduction sleeve, shank diameter format: 1.0 in \ 1" or 50 mm let partShankDiameter = part.classificationFilterValuesEN.find(val => val.includes('Shank Diameter')).split(':')[1]; let partShankDiameterVal = Number(partShankDiameter.split(' ')[0].trim()); return partShankDiameterVal === shankSize; } else if (thType.includes('Turning') && part.link.includes('od_toolholding')) { let partShankHeightObj = part.classificationFilterValuesEN.find(val => val.includes('Shank Height')).split(':')[1]; let shankHeightImp, shankHeightMet; // od toolholding, current shank height format: (1 in) or (1 in \ 10 mm) if (partShankHeightObj && partShankHeightObj.includes('\\')) { shankHeightImp = Number(partShankHeightObj.split('\\')[0].trim().split(' ')[0]); shankHeightMet = Number(partShankHeightObj.split('\\')[1].trim().split(' ')[0]); } else if (partShankHeightObj) { shankHeightImp = Number(partShankHeightObj.split(' ')[0]); } else { return false; } return shankHeightImp === shankSize || shankHeightMet === shankSize; } } catch (e) { console.log('Error:' + e + 'When Parsing Part: ', part, ); return false; } }); }, filterPartsForTlClTH: function() { let self = this; let tableData = Array.from(document.querySelectorAll('.partClassifications #classifications-data-en div')); let thSeries = tableData.find(td => td.id.includes('Toolholder Series')).dataset.materials; let thType = tableData.find(td => td.id.includes('Toolholder Type')).dataset.materials; let shankSizeObj = tableData.find(td => td.id.includes('Shank Size')).dataset.materials; let systemOfMeasurement = tableData.find(td => td.id.includes('System of Measurement')).dataset.materials; let shankSize; // tl cl shank size format: (1" 1 in) or (10 mm) if (shankSizeObj.includes('in')) { shankSize = Number(shankSizeObj.split('"')[1].trim().split(' ')[0]); } else if (shankSizeObj.includes('mm')) { shankSize = Number(shankSizeObj.split(' ')[0]); } self.items = self.items.filter(part => { try { if (part.link.includes('tl_cl_toolholding')) { let partSeries = part.classificationFilterValuesEN.find(val => val.includes('Toolholder Series')).split(':')[1]; let partType = part.classificationFilterValuesEN.find(val => val.includes('Toolholder Type')).split(':')[1]; let partSystemOfMeasurement = part.classificationFilterValuesEN.find(val => val.includes('System of Measurement')).split(':')[1]; return partSeries === thSeries && partType === thType && systemOfMeasurement === partSystemOfMeasurement; } else if (thType === 'Boring Bar' && part.link.includes('boring_bars')) { let shankDiameterObj = part.classificationFilterValuesEN.find(val => val.includes('Shank Diameter')).split(':')[1]; let shankDiameterImp, shankDiameterMet; // id toolholding, current shank diam format: (1 in) or (1 in \ 10 mm) if (shankDiameterObj && shankDiameterObj.includes('\\')) { shankDiameterImp = Number(shankDiameterObj.split('\\')[0].trim().split(' ')[0]); shankDiameterMet = Number(shankDiameterObj.split('\\')[1].trim().split(' ')[0]); } else if (shankDiameterObj) { shankDiameterImp = Number(shankDiameterObj.split(' ')[0]); } else { return false; } return shankDiameterImp === shankSize || shankDiameterMet === shankSize; } } catch (e) { console.log('Error Parsing Part: ', part); return false; } }); }, prefilterQCcollets: function() { let self = this; let type = document.querySelector('.part .part-content-left h1').innerText; if (type.includes('65')) { self.items = self.items.filter(item => item.title.includes('65')); } if (type.includes('42')) { self.items = self.items.filter(item => item.title.includes('42')); } }, prefilterEndmills: function() { let self = this; let curPage = window.location.pathname let isWeldonTH = curPage.includes('end_mill_holders'); let isShrinkFit = curPage.includes('shrink_fit'); let isERCollet = curPage.includes('er_collet'); let isHydraulicOrMillingChuck = curPage.includes('hydraulic_milling') || curPage.includes('milling_chuck'); let tableData = Array.from(document.querySelectorAll('.partClassifications #classifications-data-en div')); let boreDiameterImp = -1; let boreDiameterMet = -1; if (tableData.find(res => res.id.includes('Bore Diameter'))) { // for shrink fit holders, current bore diameter format: (2 in \ 20 mm) // for end mill holders, current bore diameter format: (2 in) or (2 mm) const boreDiameterObj = tableData.find(res => res.id.includes('Bore Diameter')).dataset.materials; if (boreDiameterObj.includes('\\')) { boreDiameterImp = Number(boreDiameterObj.split('\\')[0].trim().split(' ')[0]); boreDiameterMet = Number(boreDiameterObj.split('\\')[1].trim().split(' ')[0]); } else { if (boreDiameterObj.includes('mm')) { boreDiameterMet = Number(boreDiameterObj.split(' ')[0]); boreDiameterImp = Number((boreDiameterMet / 25.4).toFixed(2)); } if (boreDiameterObj.includes('in')) { boreDiameterImp = Number(boreDiameterObj.split(' ')[0]); boreDiameterMet = Number((boreDiameterImp * 25.4).toFixed(2)); } } } // End Mill, Shank Diam Format: (1 in) or (1 mm) or (1" \ 1 in) // Ball End Mill, Shank Diam Format: (1 in) or (1 in \ 1 mm) // Roughing End Mill, Shank Diam Format: (3/4) <- not sure what the unit is // Carbide Drill Inch / Metric, Shank Diam Format: (1 in) or (1 mm) // Reamers, Shank Diam Format: (1 in \ 1 mm) // Thread Mills, Shank Diam Format: (1 in) if (isWeldonTH) { // weldon toolholders only allow weldon tools and bore diameter === shank diameter self.items = self.items.filter(part => { if (!part.classificationFilterValuesEN) return false; let shankType = part.classificationFilterValuesEN.find(value => value.includes('Shank Type')); let shankDiameterObj = part.classificationFilterValuesEN.find(value => value.includes('Shank Diameter')); let shankDiameterValue = shankDiameterObj ? shankDiameterObj.split(':')[1] : ''; let shankDiameterImp, shankDiameterMet; // if (1" \ 1 in) // else if (1 in \ 1 mm) // else if (1 in) // else if (1 mm) if (shankDiameterValue.includes('"')) { shankDiameterImp = Number(shankDiameterValue.split('\\')[1].trim().split(' ')[0]); shankDiameterMet = Number((shankDiameterImp * 25.4).toFixed(2)); } else if (shankDiameterValue.includes('in') && shankDiameterValue.includes('mm')) { shankDiameterImp = Number(shankDiameterValue.split('\\')[0].trim().split(' ')[0]); shankDiameterMet = Number(shankDiameterValue.split('\\')[1].trim().split(' ')[0]); } else if (shankDiameterValue.includes('in')) { shankDiameterImp = Number(shankDiameterValue.split(' ')[0]); shankDiameterMet = Number((shankDiameterImp * 25.4).toFixed(2)); } else if (shankDiameterValue.includes('mm')) { shankDiameterMet = Number(shankDiameterValue.split(' ')[0]); shankDiameterImp = Number((shankDiameterMet / 25.4).toFixed(2)); } return shankType && shankType.length && shankType.split(':')[1].toLowerCase() === 'weldon' && (boreDiameterImp === shankDiameterImp || boreDiameterMet === shankDiameterMet); }); } else if (isShrinkFit) { // shrink fit require material === carbide and bore diamter === shank diameter self.items = self.items.filter(part => { if (!part.classificationFilterValuesEN) return false; let shankMaterial = part.classificationFilterValuesEN.find(value => value.startsWith('Material')); let shankDiameterObj = part.classificationFilterValuesEN.find(value => value.includes('Shank Diameter')); let shankDiameterValue = shankDiameterObj ? shankDiameterObj.split(':')[1] : ''; let shankDiameterImp, shankDiameterMet; // if (1" \ 1 in) // else if (1 in \ 1 mm) // else if (1 in) // else if (1 mm) if (shankDiameterValue.includes('"')) { shankDiameterImp = Number(shankDiameterValue.split('\\')[1].trim().split(' ')[0]); shankDiameterMet = Number((shankDiameterImp * 25.4).toFixed(2)); } else if (shankDiameterValue.includes('in') && shankDiameterValue.includes('mm')) { shankDiameterImp = Number(shankDiameterValue.split('\\')[0].trim().split(' ')[0]); shankDiameterMet = Number(shankDiameterValue.split('\\')[1].trim().split(' ')[0]); } else if (shankDiameterValue.includes('in')) { shankDiameterImp = Number(shankDiameterValue.split(' ')[0]); shankDiameterMet = Number((shankDiameterImp * 25.4).toFixed(2)); } else if (shankDiameterValue.includes('mm')) { shankDiameterMet = Number(shankDiameterValue.split(' ')[0]); shankDiameterImp = Number((shankDiameterMet / 25.4).toFixed(2)); } return shankMaterial && shankMaterial.length && shankMaterial.split(':')[1].toLowerCase() === 'carbide' && (boreDiameterImp === shankDiameterImp || boreDiameterMet === shankDiameterMet); }); } else if (isERCollet) { // For ER collets, set max shank diameter size collet series, then filter out shank diameter > max const colletSeries = document.querySelector('.partClassifications #classifications-data-en div#Collet\\ Series') ? document.querySelector('.partClassifications #classifications-data-en div#Collet\\ Series').dataset.materials : null; let shankDiamMax = 0.75; self.items = self.items.filter(part => { if (!part.classificationFilterValuesEN) return false; let shankDiameterObj = part.classificationFilterValuesEN.find(value => value.includes('Shank Diameter')); let shankDiameterValue = shankDiameterObj ? shankDiameterObj.split(':')[1] : ''; let shankDiameterImp, shankDiameterMet; // if (1" \ 1 in) // else if (1 in \ 1 mm) // else if (1 in) // else if (1 mm) if (shankDiameterValue.includes('"')) { shankDiameterImp = Number(shankDiameterValue.split('\\')[1].trim().split(' ')[0]); shankDiameterMet = Number((shankDiameterImp * 25.4).toFixed(2)); } else if (shankDiameterValue.includes('in') && shankDiameterValue.includes('mm')) { shankDiameterImp = Number(shankDiameterValue.split('\\')[0].trim().split(' ')[0]); shankDiameterMet = Number(shankDiameterValue.split('\\')[1].trim().split(' ')[0]); } else if (shankDiameterValue.includes('in')) { shankDiameterImp = Number(shankDiameterValue.split(' ')[0]); shankDiameterMet = Number((shankDiameterImp * 25.4).toFixed(2)); } else if (shankDiameterValue.includes('mm')) { shankDiameterMet = Number(shankDiameterValue.split(' ')[0]); shankDiameterImp = Number((shankDiameterMet / 25.4).toFixed(2)); } if (colletSeries === 'ER-11') shankDiamMin = 0.020, shankDiamMax = 0.315; if (colletSeries === 'ER-16') shankDiamMin = 0.020, shankDiamMax = 0.394; if (colletSeries === 'ER-25') shankDiamMin = 0.039, shankDiamMax = 0.630; if (colletSeries === 'ER-32') shankDiamMin = 0.079, shankDiamMax = 0.787; return shankDiameterImp >= shankDiamMin && shankDiameterImp <= shankDiamMax; }); } else if (isHydraulicOrMillingChuck) { self.items = self.items.filter(part => { if (!part.classificationFilterValuesEN) return false; let shankDiameterObj = part.classificationFilterValuesEN.find(value => value.includes('Shank Diameter')); let shankDiameterValue = shankDiameterObj ? shankDiameterObj.split(':')[1] : ''; let shankDiameterImp, shankDiameterMet; let shankDiameterFloor, shankDiameterRound; // if (1" \ 1 in) // else if (1 in \ 1 mm) // else if (1 in) // else if (1 mm) if (shankDiameterValue.includes('"')) { shankDiameterImp = Number(shankDiameterValue.split('\\')[1].trim().split(' ')[0]); shankDiameterMet = Number((shankDiameterImp * 25.4).toFixed(2)); } else if (shankDiameterValue.includes('in') && shankDiameterValue.includes('mm')) { shankDiameterImp = Number(shankDiameterValue.split('\\')[0].trim().split(' ')[0]); shankDiameterMet = Number(shankDiameterValue.split('\\')[1].trim().split(' ')[0]); } else if (shankDiameterValue.includes('in')) { shankDiameterImp = Number(shankDiameterValue.split(' ')[0]); shankDiameterMet = Number((shankDiameterImp * 25.4).toFixed(2)); } else if (shankDiameterValue.includes('mm')) { shankDiameterMet = Number(shankDiameterValue.split(' ')[0]); shankDiameterImp = Number((shankDiameterMet / 25.4).toFixed(2)); } if (shankDiameterImp && shankDiameterMet) { // round + floor round end mill shank diameter to thousandth then compare shankDiameterRound = (Math.round(shankDiameterImp * 1000) / 1000); shankDiameterFloor = (Math.floor(shankDiameterImp * 1000) / 1000); } return boreDiameterImp === shankDiameterRound || boreDiameterImp === shankDiameterFloor || boreDiameterMet === shankDiameterMet; }); } else { // else just return empty array self.items = []; } }, prefilterToolholders: function() { let self = this; let shankType = document.querySelector('.partClassifications #classifications-data-en div#Shank\\ Type') ? document.querySelector('.partClassifications #classifications-data-en div#Shank\\ Type').dataset.materials : null; let materialType = document.querySelector('.partClassifications #classifications-data-en div#Material') ? document.querySelector('.partClassifications #classifications-data-en div#Material').dataset.materials : null; let tableData = Array.from(document.querySelectorAll('.partClassifications #classifications-data-en div')); let shankDiamObj = tableData.find(res => res.id.includes('Shank Diameter')).dataset.value; let shankDiameter = -1; let shankDiameterImp = -1; let shankDiameterFloor = -1; let shankDiameterRound = -1; if (shankDiamObj) { let system = (shankDiamObj.includes('mm') && shankDiamObj.includes('in')) ? 'mixed' : shankDiamObj.includes('mm') ? 'metric' : 'imperial'; switch(system) { case 'mixed': // mixed format, ball end mills have it like this: (2 in \ 40 mm) shankDiameter = Number(shankDiamObj.split('\\')[1].trim().split(' ')[0]); shankDiameterImp = Number(shankDiamObj.split('\\')[0].trim().split(' ')[0]); // round + floor round end mill shank diameter to thousandth then compare shankDiameterRound = (Math.round(shankDiameter * 1000) / 1000); shankDiameterFloor = (Math.floor(shankDiameter * 1000) / 1000); break; case 'metric': // metric format: 2.0 mm shankDiameter = Number(shankDiamObj.trim().split(' ')[0]); shankDiameterImp = Number((shankDiameter / 25.4).toFixed(2)); // round + floor round end mill shank diameter to thousandth then compare shankDiameterRound = (Math.round(shankDiameter * 1000) / 1000); shankDiameterFloor = (Math.floor(shankDiameter * 1000) / 1000); break; case 'imperial': // imperial format: (2" \ 2 in) // On roughing end mills its (1/4) // On carbide drills page its (2 in) if (shankDiamObj.includes('\\')) { shankDiameter = Number(shankDiamObj.split('\\')[1].trim().split(' ')[0]); shankDiameterImp = shankDiameter; } else if (shankDiamObj.includes('/')) { shankDiameter = eval(shankDiamObj.trim()); shankDiameterImp = shankDiameter; } else { shankDiameter = Number(shankDiamObj.trim().split(' ')[0]); shankDiameterImp = shankDiameter; } // round + floor round end mill shank diameter to thousandth then compare shankDiameterRound = (Math.round(shankDiameter * 1000) / 1000); shankDiameterFloor = (Math.floor(shankDiameter * 1000) / 1000); break; default: break; } } // Filter Weldon Toolholders by Shank Diameter if (shankType && shankType.toLowerCase() === 'weldon') { // End Mill Holder, Bore Diameter format: (1 in) or (1 mm) self.items = self.items.filter(part => { let isWeldon = part.link.includes('end_mill_holders'); let boreDiameterObj = part.classificationFilterValuesEN.find(value => value.includes('[ØD] Bore Diameter')); let boreDiameter = boreDiameterObj ? Number(boreDiameterObj.split(':')[1].split(' ')[0]) : -1; return !isWeldon || boreDiameter === shankDiameter; }); } else { self.items = self.items.filter(part => !part.link.includes('end_mill_holders')); } /* * Filter ER Collets by Shank Diameter */ let erCollets = self.items.filter(part => { let colletSeries = part.classificationFilterValuesEN.find(value => value.includes('Collet Series')); return colletSeries; }); // Start by removing all ER Collets self.items = self.items.filter(part => { let colletSeries = part.classificationFilterValuesEN.find(value => value.includes('Collet Series')); return !colletSeries; }); // Add all applicable collets depending on shank size if (shankDiameterImp >= 0.020 && shankDiameterImp <= 0.315) { self.items = self.items.concat(erCollets.filter(part => { let colletSeries = part.classificationFilterValuesEN.find(value => value.includes('Collet Series')); return colletSeries.includes('ER-11'); })); } if (shankDiameterImp >= 0.020 && shankDiameterImp <= 0.394) { self.items = self.items.concat(erCollets.filter(part => { let colletSeries = part.classificationFilterValuesEN.find(value => value.includes('Collet Series')); return colletSeries.includes('ER-16'); })); } if (shankDiameterImp >= 0.039 && shankDiameterImp <= 0.630) { self.items = self.items.concat(erCollets.filter(part => { let colletSeries = part.classificationFilterValuesEN.find(value => value.includes('Collet Series')); return colletSeries.includes('ER-25'); })); } if (shankDiameterImp >= 0.079 && shankDiameterImp <= 0.787) { self.items = self.items.concat(erCollets.filter(part => { let colletSeries = part.classificationFilterValuesEN.find(value => value.includes('Collet Series')); return colletSeries.includes('ER-32'); })); } // Filter Milling Chucks & Collets and Hydraulics Milling Chucks & Collets self.items = self.items.filter(part => { if (part.link.includes('hydraulic_milling') || part.link.includes('milling_chucks')) { let boreDiameterObj = part.classificationFilterValuesEN.find(value => value.includes('Bore Diameter')); // Milling Chucks & Hydraulic Mill Chuck Bore Diameter Formats // Imperial : 0.125 in \ 1/8" // Metric : 8.0 mm // Comparing to nearest thousandth let boreDiameter = boreDiameterObj ? Number(boreDiameterObj.split(':')[1].split(" ")[0].trim()) : -1; return boreDiameter === shankDiameterFloor || boreDiameter === shankDiameterRound; } else { return true; } }); // Filter Shrink Fit Holders if (materialType && materialType.toLowerCase() === 'carbide') { // Bore Diameter on Shrink Fit Holders - current format: (3 in \ 3 mm) self.items = self.items.filter(part => { let isShrinkFit = part.link.includes('shrink_fit_holders'); let boreDiameterObj = part.classificationFilterValuesEN.find(value => value.includes('Bore Diameter')); let boreDiameterImp = boreDiameterObj ? Number(boreDiameterObj.split(':')[1].split('\\')[0].split(' ')[0]) : -1; let boreDiameterMet = boreDiameterObj ? Number(boreDiameterObj.split(':')[1].split('\\')[0].split(' ')[1]) : -1; return !isShrinkFit || boreDiameterImp === shankDiameter || boreDiameterMet === shankDiameter; }); } else { self.items = self.items.filter(part => !part.link.includes('shrink_fit_holders')); } }, filterItems: function() { var self = this; var $filterContainer = $('#filter-container'); var allCriteria = []; // Get unique filters self.selectedFilters = _.values($filterContainer.serializeArray().reduce(function(arr, cur) { if (arr[cur.name]) { arr[cur.name].value.push(cur.value); return arr; } arr[cur.name] = { name: cur.name, value: [cur.value] }; return arr; }, {})); allCriteria = self.preselectedFilters.concat(self.selectedFilters); // If there are no selected filters, just return all items if (!allCriteria) { return self.items; } // Otherwise, filter! return self.items.filter(function(item) { return allCriteria.every(function (filter) { return filter.value.some(function(value) { return item.classificationFilterValues.indexOf(filter.name +':'+ value) > -1 || (filter.name.includes('Part Category') && value.includes(item.link.substring(0, item.link.lastIndexOf('/')))); }); }); }); }, updateCount: function(totalCount) { var $headerContainer = $('#items-header'); var $itemsContainer = $('#items-container'); var currentCount = totalCount; $headerContainer.find('span').html(currentCount); if (!currentCount) $itemsContainer.append('

    Sorry, those parameters return no results..

    Try removing a filter and searching again.

    ') }, processUrlFilters: function() { let self = this; let filterKeys = Object.keys(self.urlParams); if (!filterKeys || !filterKeys.length) return; filterKeys.forEach((key) => { let queryString = '#filters-col input[name="'+key+'"][value="'+self.urlParams[key].replace('\\', '\\\\')+'"]'; document.querySelector(queryString).checked = true; document.querySelector(queryString).defaultChecked = true; }); self.renderPartItems(); if (window.screen.width <= 800) self.renderMobileSelectedFilters(); }, scrollToPLP: function() { // if a filter was clicked and the page was re-loaded, then scroll back to PLP $(function() { if (window.location.search.includes('scroll=true')) { window.scrollTo(0, document.querySelector('.customPartListing').offsetTop); } }); }, smoothScroll: function() { //if a filter was clicked and the top of the part list is out of the viewport, smooth scroll to the top let topEdge = document.querySelector('.customPartListing').getBoundingClientRect().top; $(function() { if(topEdge < 0) { if(window.innerWidth > 800) { window.scrollTo({ top: (document.querySelector('.customPartListing').offsetTop - 200), left: 0, behavior: 'smooth'}); } else { window.scrollTo({ top: document.querySelector('.customPartListing').offsetTop , left: 0, behavior: 'smooth'}); } } }); }, renderFilters: function() { const $filterContainer = $('#filter-container'); const self = this; if(document.querySelector('.hide-all-filters')) { document.querySelector('.hide-all-filters').classList.add('hide-filters-col'); document.querySelector('#mobile-filter-btn').classList.add('hidden'); } // first sort alphabetically, then sort by given order Object.keys(this.filterValues) .sort() .sort(function(a, b) { let orderA = self.categoryConfigFilterOrder.indexOf(a) >= 0 ? self.categoryConfigFilterOrder.indexOf(a) : Number.MAX_SAFE_INTEGER; let orderB = self.categoryConfigFilterOrder.indexOf(b) >= 0 ? self.categoryConfigFilterOrder.indexOf(b) : Number.MAX_SAFE_INTEGER; return orderA - orderB; }) .sort(function(a, b) { let orderA = self.filterOrder.indexOf(a) >= 0 ? self.filterOrder.indexOf(a) : Number.MAX_SAFE_INTEGER; let orderB = self.filterOrder.indexOf(b) >= 0 ? self.filterOrder.indexOf(b) : Number.MAX_SAFE_INTEGER; return orderA - orderB; }) .filter(function(key) { // Hard-coded filters const toolholderFilters = ['cutting diameter', 'coating', 'corner','length of cut','number of flutes','haas grade']; const shellMillBodyFilters = ['primary workpiece material', 'secondary workpiece material', 'taper', '[gl] gage length']; const indexableEndMillBodies = ['primary workpiece material', 'secondary workpiece material', 'taper', '[Ød] bore diameter', '[gl] gage length'] const millingInsertsFilters = ['toolpath type', '[ødc] cutting diameter', '[z] number of cutting teeth']; if (self.isEndMillPage) return key === 'Taper'; else if (self.isToolholderPage) return toolholderFilters.some(filter => key.toLowerCase().includes(filter)); else if (self.isShellMillBodyPage) return shellMillBodyFilters.some(filter => key.toLowerCase().includes(filter)); else if (self.isIndexableEndMillBodyPage) return indexableEndMillBodies.some(filter => key.toLowerCase().includes(filter)); else if (self.isMillingInsertsPage) return millingInsertsFilters.some(filter => key.toLowerCase().includes(filter)); else if (self.categoryConfigHiddenFilters.length) return !self.categoryConfigHiddenFilters.includes(key) return self.hiddenFilters.indexOf(key) === -1; }).forEach(function(key) { var inputItem = '

    '+key+'

    '; var numberOfOptions = self.filterValues[key].length; var numberFilters = ['Diameter', 'Length']; var pitchFilter = ['SIZE & PITCH']; var millingCutterSeriesFilter = ['Milling Cutter Series']; var plantsForEcommSaleTerms = ['ecom', 'site', 'e-com']; if (plantsForEcommSaleTerms.some(term => key.toLowerCase().includes(term))) return; // will sort the filters alphanumerically var sortedFilters = self.filterValues[key].sort(); // Sort filters with numeric values by actual numeric value if (numberFilters.some(function(filter) { return key.indexOf(filter) > -1; })) { try { sortedFilters = self.filterValues[key].sort(function(a, b) { var valA = a.split(' ').reduce(function(x, y) { return eval(x) + eval(y); }, 0); var valB = b.split(' ').reduce(function(x, y) { return eval(x) + eval(y); }, 0); return valA - valB; }) } catch (e) { console.log(e); } } if (pitchFilter.some(function(filter) { return key.indexOf(filter) > -1; })) { try { sortedFilters = self.filterValues[key].sort(function(a, b) { var valA = self.sizeAndPitchOrder.indexOf(a) > -1 ? self.sizeAndPitchOrder.indexOf(a) : Number.MAX_SAFE_INTEGER; var valB = self.sizeAndPitchOrder.indexOf(b) > -1 ? self.sizeAndPitchOrder.indexOf(b) : Number.MAX_SAFE_INTEGER; return valA - valB; }); } catch (e) { console.log(e); } } if (sortedFilters.length === 1) { inputItem = inputItem + ''; inputItem = '
    ' + inputItem + '
    '; // Hide filter if only one inputItem = ''; } else { sortedFilters = [... new Set(sortedFilters)]; sortedFilters.forEach(function(option) { inputItem = inputItem + ''; }); inputItem = '
    ' + inputItem + '
    '; } // close filter values container div inputItem = inputItem + '
    '; $filterContainer.append(inputItem); }); if (!$('.filter-cat-container').length) { $('#filters-col').addClass('hidden'); } // For all preselected filters, check & disable self.preselectedFilters.forEach(function(filter) { $('input[name="'+ filter.name +'"]:not(.not-selectable input)').prop('checked', true); $('input[name="'+ filter.name +'"]:not(.not-selectable input)').prop('disabled', true); }); // Category Filters if (Object.keys(self.categoryPathTitleMap).length > 1) { let parentContainer = document.createElement('div'); let headerElement = document.createElement('h2'); let filterCounter = document.createElement('p'); let valuesContainer = document.createElement('div'); let selectableCategories = Array.from(new Set(self.items.map(item => item.link ? item.link.substring(0, item.link.lastIndexOf('/')) : null))); const partCategoryTlText = document.querySelector('#part-category-tl').dataset.partCategoryTl; for (const key in self.categoryPathTitleMap) { if (selectableCategories.every(category => !self.categoryPathTitleMap[key].includes(category))) delete self.categoryPathTitleMap[key]; } // Make sure that the selectable items are from multiple categories if (Object.keys(self.categoryPathTitleMap).length > 1) { parentContainer.classList.add('filter-cat-container'); valuesContainer.classList.add('filter-values-container'); let count = 0; parentContainer.dataset.masterCat = 'Part Category'; headerElement.innerHTML = partCategoryTlText; parentContainer.appendChild(headerElement); Object.keys(self.categoryPathTitleMap).forEach(categoryKey => { let categoryElement = document.createElement('label'); let categoryInput = document.createElement('input'); let categoryText = document.createElement('span'); categoryElement.classList.add('filter-item'); categoryInput.type = 'checkbox'; categoryInput.name = 'Part Category-'+categoryKey; categoryInput.value = self.categoryPathTitleMap[categoryKey]; categoryText.innerHTML = categoryKey; categoryElement.append(categoryInput); categoryElement.append(categoryText); valuesContainer.append(categoryElement); count++; }); parentContainer.append(valuesContainer); filterCounter.innerHTML = "( "+ count +" )"; headerElement.appendChild(filterCounter); document.querySelector('#filter-container').prepend(parentContainer); } } }, renderFilterTooltips: function() { var self = this; self.tooltipTitles.forEach(function(title, ndx) { var $filterHeader = $('.filter-cat-container[data-master-cat="' + title + '"] h2'); var filterDescriptionHTMLFullscreen = ''; $filterHeader.append(filterDescriptionHTMLFullscreen); $filterHeader.find('.filter-tooltip').hover( function() { $filterHeader.after('

    ' + self.tooltipDescriptions[ndx] + '

    '); }, function() { $filterHeader.parent().find('#tooltip-text-container').remove(); } ); }); }, processSelectableFilters: function() { // clear all non-selectable filters before processing $('#filter-container label').removeClass('filter-disabled').removeClass('not-selectable'); $('#filter-container input').prop('disabled', false); $('#filter-container .filter-cat-container').removeClass('hidden-category') // For all preselected filters, check & disable this.preselectedFilters.forEach(function(filter) { filter.value.forEach(function(value) { $('input[value="'+ value +'"]').prop('checked', true); $('input[value="'+ value +'"]').prop('disabled', true); }); }); const self = this; let filteredItemList = $('.part-list-item').map(function(ndx, item) { return $(item).attr('data-sku') }).toArray(); let currentItems = JSON.parse($('#part-listing-data').attr('data-json')).items.filter(function(dataItem) { return filteredItemList.indexOf(dataItem.sku) > -1; }); let availableFilters = {}; let unselectableFilterType = $('#filters-col').attr('data-unselectable-filter-type'); currentItems.forEach(function(item) { item.classificationFilterValues.forEach(function(filter) { var filterData = filter.split(':'); if (!availableFilters[filterData[0]]) availableFilters[filterData[0]] = []; availableFilters[filterData[0]].push(filterData[1]); }); }); Array.from(document.querySelectorAll('.filter-cat-container')).forEach((group) => { let filterName = group.dataset.masterCat; let filters = Array.from(group.querySelectorAll('input')); let selectableFilters = availableFilters[filterName]; let count = 0; // if theres a filter in the group already selected, or only a single filter, we dont need to process the group if ($(group).attr('data-single-filter') === 'true') { $(group).find('p').html("( 1 )"); return; } if (filterName === 'Part Category') { const hasCategorySelected = filters.some(filter => filter.checked); filters.forEach(filter => { // add not selectable class to not checked inputs if there is a category selected if (hasCategorySelected && !filter.checked) { unselectableFilterType === 'disabled' ? filter.parentElement.classList.add('filter-disabled') : filter.parentElement.classList.add('not-selectable'); filter.disabled = true; } else { count++; } }); } else { if (!selectableFilters || !selectableFilters.length) { filters.forEach((filter) => { unselectableFilterType === 'disabled' ? filter.parentElement.classList.add('filter-disabled') : filter.parentElement.classList.add('not-selectable'); filter.disabled = true; }); } else { filters.forEach((filter) => { let filterValue = filter.value; if (selectableFilters.indexOf(filterValue) === -1) { unselectableFilterType === 'disabled' ? filter.parentElement.classList.add('filter-disabled') : filter.parentElement.classList.add('not-selectable'); filter.disabled = true; } else { count++; } }); } } $(group).find('p').html("( "+count+" )"); // If no filters are selectable, hide whole category if (filters.every(filter => filter.parentElement.classList.contains('not-selectable'))) group.classList.add('hidden-category'); }); }, renderPartItems: function() { var self = this; var $itemsCol = $('#items-container'); var itemsChunk = 10; var itemsOffset = 20; var filtered = this.filterItems(); $itemsCol.empty(); self.displayChunks(filtered.slice(0, itemsOffset)); this.updateCount(filtered.length); this.renderPrices(); this.renderQuantityOptions(); this.processSelectableFilters(); // Lazy Load Scroll Handler $(window).off('scroll').on('scroll', function () { // check if the window is scrolling past the end of the items column. // items column's offset from the top + its height - by half the screen height ( trigger when bottom of items col is 250px past bottom of screen ) if ((window.scrollY >= (self.elementNode.querySelector('#items-col').getBoundingClientRect().top + self.elementNode.querySelector('#items-col').getBoundingClientRect().height) - (window.innerHeight - 250)) && itemsOffset < filtered.length) { self.displayChunks(_.slice(filtered, itemsOffset, itemsOffset + itemsChunk)); itemsOffset += itemsChunk; self.renderPrices(); self.renderQuantityOptions(); self.rebindPartItemsHandler(); } }); }, displayChunks: function(items) { var self = this; var $itemsCol = $('#items-container'); items.forEach(function(item) { var itemTitle = item.title.toLowerCase(); var packOfNdx = item.packOf; var perPriceValue = 0; var productType = 'unit'; if (packOfNdx > -1) { var quantity = item.packOf; perPriceValue = Number((item.price.amount / quantity).toFixed(2)); if (itemTitle.indexOf('drill') > -1) productType = 'drill'; if (itemTitle.indexOf('insert') > -1) productType = 'insert'; } var itemContent = self.templates.partListItemTemplate({ itemSku: item.sku, itemLink: item.link, itemImgSrc: item.imageHref, itemImgTitle: item.sku, itemImgAlt: item.sku, itemTitle: item.title, itemAllPrices: item.allPrices, itemAllDiscountPrices: item.allDiscountPrices, hasStrikethroughPrice: item.hasStrikethroughPrice, propSixtyFive: item.californiaProposition65Required ? 'prop-sixty-five-req' : '', startDisabled: (self.startEnabled || self.disableLiveCheck) ? false : true }); $itemsCol.append(itemContent); }) }, renderQuantityOptions: function() { $('.part-list-item').each(function(ndx, elem) { var $quantityOptionContainer = $(elem).find('#quantity-select'); var options = ''; for (var i = 1; i <= 50; i++) { options = options + "'; } $quantityOptionContainer.html(options); }); }, renderPrices: function() { $.when(haas.region.priceGroupPromise).then(function() { if (haas.cookies.getCookie('tooling-currency') === 'undefined') { $('.check-out-container').hide(); $('.part-pricing').hide(); $('.alert').removeClass('hidden'); } else { $('.customPartListing .part-list-item').each(function(ndx, elem) { let $priceContainer = $(elem).find('.price-span ' + haas.cookies.getCookie('tooling-currency')); let $unitPriceContainer = $(elem).find('#unit-price'); let hasCurrency = false; $(elem).find('.price-span').each(function() { $(this).html(haas.ecommUtils.formatPrice($(this).attr('data-price'))); if ($(this).attr('data-currency') === haas.cookies.getCookie('tooling-currency')) { hasCurrency = true; $(this).parent().removeClass('hidden'); $(this).show(); } }); if (!hasCurrency) $(elem).hide(); $('.promo-' + haas.cookies.getCookie('tooling-currency')).each(function() { $(this).html(haas.ecommUtils.formatPrice($(this).attr('data-value'))); $(this).parent().removeClass('hidden'); $(this).parents('.part-list-item').addClass('ecomm-plp-promo'); }); if ($unitPriceContainer.attr('data-haspriceperpart') === 'true') { $unitPriceContainer.html('(' + haas.ecommUtils.formatPrice($unitPriceContainer.attr('data-perpricevalue')) + '/' + $unitPriceContainer.attr('data-partype') + ')'); $unitPriceContainer.removeClass('hidden'); } }); } }); }, postRender: function() { this.elementNode.querySelector('.loader-gif-container').style.display = 'none'; this.elementNode.querySelector('.spa-container').style.display = ''; }, filterClickHandler: function(e) { let self = this; let encodedName = encodeURIComponent(e.target.name); let encodedValue = encodeURIComponent(e.target.value); let url = window.location.href; // if filter is clicked, just navigate to page w preselected filters if (window.location.search.length) { if (window.location.search.includes(encodedName)) { let filterNdx = window.location.href.indexOf(encodedName); let filterStrLength = encodedName.length + encodedValue.length + 1; url = window.location.href.slice(0, filterNdx - 1) + window.location.href.slice(window.location.href.indexOf(encodedName) + filterStrLength); } else if (!window.location.search.includes('scroll=true')) { url = window.location.href + "&scroll=true&" + encodedName + "=" + encodedValue; } else { url = window.location.href + "&" + encodedName + "=" + encodedValue; } } else { url = window.location.href + "?scroll=true&" + encodedName + "=" + encodedValue; } window.history.replaceState({}, '', url); this.renderPartItems(); this.rebindPartItemsHandler(); this.smoothScroll(); }, clearAllClickHandler: function(e) { this.$element.find('input:not(.single-filter)').prop('checked', false); this.renderPartItems(); this.rebindPartItemsHandler(); }, timeoutModal: function() { setTimeout(function() { if ($('.haas-modal-wrapper').is('.open')) haas.components.Modal.close(); }, 1000); }, cartSuccessClickHandler: function() { haas.LOGGER.debug('Proceeding to Cart!'); $('#cart-success-btn').addClass('disabled'); $('#ecommerce-nav > a').click(); }, showSuccessModal: function(quantity) { // to-do: Add attributes in html to make this translatable var self = this; // Remove loading indicator $('body').removeClass('cursor-wait'); haas.components.Modal.open(self.templates.addToCartSuccessModal({qty: quantity})); $('#cart-success-btn').off('click').on('click', self.cartSuccessClickHandler); $('#continue-btn').off('click').on('click', haas.components.Modal.close); }, showErrorModal: function(error) { let errorTLdata = this.elementNode.querySelector('#error-tl-data').dataset; let errorTL = errorTLdata.oos; let outOfStockTL = errorTLdata.oos; let expiredTL = errorTLdata.expired; let timeoutTL = errorTLdata.timeout; let signinTL = errorTLdata.signin; let genericErrorTL = errorTLdata.generic; // Remove loading indicator $('body').removeClass('cursor-wait'); if (error.type === 'InsufficientStockError') { haas.components.Modal.open('

    '+errorTL+' '+outOfStockTL+'

    '); this.timeoutModal(); } else if (error.type === 'CartError') { let self = this; haas.components.Modal.open('

    '+errorTL+' '+expiredTL+'

    '); let hybrisLogoutPayload = $.get(haas.constants.api.hybrisLogout(localStorage.storedSiteLang)); let eatCookiesPayload = $.get(haas.constants.api.eatcookies(localStorage.storedSiteLang)); return $.when(hybrisLogoutPayload, eatCookiesPayload).then((logoutData, eatCookiesData) => { localStorage.cartQuantity = 0; localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } else if(error.type === 'InvalidTokenError') { haas.components.Modal.open('
    '+timeoutTL+'
    '); self.timeoutModal(); haas.fleet.myHaasDropdown.logout(); } else { haas.components.Modal.open('
    '+errorTL+' '+genericErrorTL+'
    '); let hybrisLogoutPayload = $.get(haas.constants.api.hybrisLogout(localStorage.storedSiteLang)); let eatCookiesPayload = $.get(haas.constants.api.eatcookies(localStorage.storedSiteLang)); return $.when(hybrisLogoutPayload, eatCookiesPayload).then((logoutData, eatCookiesData) => { localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } }, postPartToCart: function(partid, quantity) { var self = this; var email; var bearer; var endpoint = haas.constants.api.ecommerce; if(localStorage.access_token) { $.when(haas.jwToken.getUserInfo()).then(function(userPayload) { bearer = userPayload['ecomm_bearer_token_access_token']; if (userPayload.userInfo) { email = userPayload.userInfo.uid; } else { email = userPayload.email; } $.get({ url: '/ecommpartsstorefront/ecommparts/en/hybris-cart', cache: false }).then(function(cart) { endpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cart.cartId + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; }).fail(function(payload) { if(payload.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { self.showErrorModal(payload.responseJSON.errors[0]); } }).always(function() { haas.ecommUtils.renderCartQuantity(); }); }).fail(function(err) { if(err.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { $.post({ contentType: 'application/json', url: haas.constants.api.ecommerce + 'users/' + email + '/carts' + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') }, }).done(function(cartResponse){ endpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cartResponse.code + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; }).fail(function(payload) { self.showErrorModal(payload.responseJSON.errors[0]) }).always(function() { haas.ecommUtils.renderCartQuantity(); }); }); } }); return userPayload; }); } else { endpoint = haas.constants.api.ecommerce + 'users/anonymous/carts/' + localStorage.guid + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; }).fail(function(payload) { self.showErrorModal(payload.responseJSON.errors[0]) }).always(function() { haas.ecommUtils.renderCartQuantity(); }); } }, updateNumSelected: function() { var self = this; var num = 0; self.selectedFilters.forEach(function(filter) { filter.value.forEach(function(value) { if (!$('input[name="'+filter.name+'"][value="'+value+'"]').hasClass('single-filter')) { num += 1; } }); }); if (num) $('.num-selected').html('(' + num + ')'); else $('.num-selected').empty(); }, addToCartEventHandler: function(e) { var self = this; var $target = $(e.target); var $parent = $target.parents('.part-list-item'); var partid = $parent.attr('data-sku'); var quantity = $parent.find('#quantity-select').val(); // loading indicator $('body').addClass('cursor-wait'); if (localStorage.guid || localStorage.access_token) { self.postPartToCart(partid, quantity); } else { $.when(haas.ecommUtils.createCartPromise(this.authenticated)).then(function(payload) { localStorage.guid = payload.guid; haas.cookies.setCookie('ecommparts-cart', payload.guid); return self.postPartToCart(partid, quantity); }); } }, mobileTooltipClickHandler: function(e) { var $header = $(e.target).is('h2') ? $(e.target) : $(e.target).parents('h2'); var $filterDescription = $header.find('#mobile-filter-tooltip-description'); $filterDescription.slideToggle(); }, propSixtyFiveTooltipHandler: function(e) { e.preventDefault(); var redirectLink = $(e.target).attr('data-redirect'); window.location = redirectLink; }, bindMobileShowHideFilters: function() { let spaContainerElemClasses = this.elementNode.querySelector('.spa-container').classList; if (spaContainerElemClasses.contains('hide-filters-col')) spaContainerElemClasses.remove('hide-filters-col'); else spaContainerElemClasses.add('hide-filters-col'); this.$element.find('#show').toggleClass('hidden'); this.$element.find('#hide').toggleClass('hidden'); }, bindEvents: function() { let self = this; this.$element.find('.prop-sixty-five').on('click', function(e) { e.preventDefault(); }); this.$element.find('.prop-tooltext').on('click', this.propSixtyFiveTooltipHandler.bind(this)); this.$element.find('input').on('click', this.filterClickHandler.bind(this)); this.$element.find('#clear-all').on('click', this.clearAllClickHandler.bind(this)); this.$element.find('.part-list-item #add-to-cart-btn').on('click', this.addToCartEventHandler.bind(this)); if (Array.from(self.elementNode.querySelectorAll('#filter-container .filter-cat-container')).length) { this.$element.find('#mobile-filter-btn').on('click', this.bindMobileShowHideFilters.bind(this)); } else { this.elementNode.querySelector('#mobile-filter-btn').classList.add('hidden'); this.elementNode.querySelector('.spa-container').classList.add('hide-filters-col'); } }, rebindPartItemsHandler: function() { this.$element.find('.part-list-item #add-to-cart-btn').off().on('click', this.addToCartEventHandler.bind(this)); } }); })(); (function() { haas.components.ChildPdpConfig = haas.Component.create({ initialize: function() {}, render: function() {} }); })(); (function() { haas.components.AuthoredPartListing = haas.Component.create({ title: '', count: '', hasChildren: '', isProducts: '', selectedFilters: [], hiddenFilters: ['Weight (lbs)', 'Weight (kgs)', 'Compliance - Prop 65', 'Plant(s) for Ecom Sale'], filterOrder: [], filterOrderDefaultEN: [], filterOriginsEN: [], items: [], userData: '', tooltipTitles: [], tooltipDescriptions: [], preselectedFilterNames: [], preselectedFilterValues: [], startEnabled: true, disableLiveCheck: true, isPopupMode: false, displayOrderedFiltersOnly: false, initialize: function() { const self = this; $.when(haas.jwToken.getUserInfo()).then(function(data) { this.userData = data; console.log('JWT DECODED ASSIGNED', this.userData); }); const filterOrderDataContainer = self.elementNode.querySelector('#filter-order-data'); const hiddenFilterContainer = self.elementNode.querySelector('#hidden-filter-data'); const preselectedFilterDataContainer = self.elementNode.querySelector('#preselected-filter-data'); if (hiddenFilterContainer) { self.hiddenFilters = hiddenFilterContainer.dataset.hiddenFilters ? hiddenFilterContainer.dataset.hiddenFilters.split(',') : []; } if (filterOrderDataContainer) { self.filterOrder = filterOrderDataContainer.dataset.filterOrder ? filterOrderDataContainer.dataset.filterOrder.split(',') : []; } if (preselectedFilterDataContainer) { self.preselectedFilterNames = preselectedFilterDataContainer.dataset.preselectedFilterNames ? preselectedFilterDataContainer.dataset.preselectedFilterNames.split(',,').slice(0, -1) : []; self.preselectedFilterValues = preselectedFilterDataContainer.dataset.preselectedFilterValues ? preselectedFilterDataContainer.dataset.preselectedFilterValues.split(',,').slice(0, -1) : []; } this.displayOrderedFiltersOnly = this.elementNode.querySelector('.spa-container').classList.contains('ordered-filters-only') ? true : false; this.condenseSpacing(); this.mapJsonToAttributes(); this.isPopupMode = this.checkIsPopup(); }, checkIsPopup: function() { return this.elementNode.querySelector('[data-popup-mode]') !== null; }, condenseSpacing: function() { let singleSpacedData = this.$element.find('#part-listing-data').attr('data-json').replace(/\s\s+/g, ' '); this.$element.find('#part-listing-data').attr('data-json', singleSpacedData); }, mapJsonToAttributes: function() { var dataText = this.$element.find('#part-listing-data').attr('data-json'); var rawJson = JSON.parse(dataText); this.title = rawJson.title; this.count = rawJson.count; this.hasChildren = rawJson.count; this.isProducts = rawJson.isProducts; this.items = rawJson.items; this.filterLangMap = rawJson.filterLanguageMap; this.filterValues = rawJson.filterValues; this.filterOrderDefaultEN = rawJson.filterLanguageOrderEN; this.filterOriginsEN = rawJson.filterOriginsEN; rawJson.items.forEach((item, index) => { item.allPrices.forEach((price, pindex) => { rawJson.items[index].allPrices[pindex] = JSON.parse(price.replace("'", '')); }) }); rawJson.items.forEach((item, index) => { item.allDiscountPrices.forEach((price, pindex) => { rawJson.items[index].allDiscountPrices[pindex] = JSON.parse(price.replace("'", '')); }) }); }, render: function() { let self = this; $.when(haas.region.priceGroupPromise).then(function(pl) { self.renderFilters(); self.renderFilterSearchBars(); self.renderWorkpieceMaterialFilterIcons(); self.renderPartItems(); self.processPreselectedFilters(); self.bindEvents(); }); }, renderFilters: function() { const self = this; const plantsForEcommSaleTerms = ['ecom', 'site', 'e-com']; const filterContainer = self.elementNode.querySelector('#filter-container'); // first sort alphabetically, then sort by given order Object.keys(self.filterValues) .sort(function(a, b) { let filterA_en = self.filterLangMap[a] ? self.filterLangMap[a][0] : a; let filterB_en = self.filterLangMap[b] ? self.filterLangMap[b][0] : b; var orderA = self.filterOrderDefaultEN.indexOf(filterA_en) >= 0 ? self.filterOrderDefaultEN.indexOf(filterA_en) : Number.MAX_SAFE_INTEGER; var orderB = self.filterOrderDefaultEN.indexOf(filterB_en) >= 0 ? self.filterOrderDefaultEN.indexOf(filterB_en) : Number.MAX_SAFE_INTEGER; return orderA - orderB; }) .sort(function(a, b) { let filterA_en = self.filterLangMap[a] ? self.filterLangMap[a][0] : a; let filterB_en = self.filterLangMap[b] ? self.filterLangMap[b][0] : b; var orderA = self.filterOrder.indexOf(filterA_en) >= 0 ? self.filterOrder.indexOf(filterA_en) : Number.MAX_SAFE_INTEGER; var orderB = self.filterOrder.indexOf(filterB_en) >= 0 ? self.filterOrder.indexOf(filterB_en) : Number.MAX_SAFE_INTEGER; return orderA - orderB; }) .filter(function(key) { let key_en = self.filterLangMap[key] ? self.filterLangMap[key][0] : key; // if the categories has filter origins filled in, then use those. Otherwise use default hidden filters. if (self.filterOriginsEN.length) { return self.filterOriginsEN.includes(key_en); } else { // if displaying only ordered filters, check if filter is in filterOrder if (self.displayOrderedFiltersOnly) { return self.filterOrder.indexOf(key_en) !== -1; } // else hide all hidden filters + "ecomm plants for sale" filter return self.hiddenFilters.indexOf(key_en) === -1 && !plantsForEcommSaleTerms.some(term => key.toLowerCase().includes(term)); } }).forEach(function(key) { let inputItem = '

    '+key+'

    '; let sortedFilters; const numberFilters = ['Diameter', 'Length']; const pitchFilter = ['SIZE & PITCH']; const millingCutterSeriesFilter = ['Milling Cutter Series']; const machineModelsFilter = ['Machine Models']; const matchingChucksFilter = ['matching chuck']; /* TO-DO: Need to blanket logic for ordering filters with numbers */ // will sort the filters alphanumerically & special case for filters with # symbol try { sortedFilters = self.filterValues[key].sort((a, b) => { if (a.includes('#') && b.includes('#')) { if (a.split('\\')[1].trim() > b.split('\\')[1].trim()) return -1; if (a.split('\\')[1].trim() < b.split('\\')[1].trim()) return 1; return 0 } else { if (a < b) return -1; if (b < a) return 1; return 0; } }); } catch(e) { sortedFilters = self.filterValues[key].sort(); } // find workpiece material specs & order try { if (self.filterLangMap[key] && self.filterLangMap[key].some(term => term.toLowerCase().includes('workpiece material'))) { const workpieceMaterialOrder = ['P', 'M', 'K', 'N', 'S', 'H']; sortedFilters = self.filterValues[key].sort((a, b) => { const materialA = a[0], materialB = b[0]; return workpieceMaterialOrder.indexOf(materialA) - workpieceMaterialOrder.indexOf(materialB); }); } } catch(e) { console.error("Error at : " + key) console.error(e); } /* * Sort filters with numeric values by actual numeric value */ if (numberFilters.some(function(filter) { return key.indexOf(filter) > -1; })) { try { sortedFilters = self.filterValues[key].sort(function(a, b) { let objA = a.split(' '), objB = b.split(' '); let valA, valB; if ((objA[0] && objA[0].includes('"')) || (objB[0] && objB[0].includes('"'))) { if (objA[0].includes('"')) valA = eval(objA[objA.length-2]), unitA = objA[objA.length-1]; else valA = eval(objA[0]), unitA = objA[1]; if (objB[0].includes('"')) valB = eval(objB[objB.length-2]), unitB = objB[objB.length-1]; else valB = eval(objB[0]), unitB = objB[1]; } else { valA = eval(objA[0]), valB = eval(objB[0]), unitA = objA[1], unitB = objB[1]; } const inToMM = 25.4; // for metric, keep the same. else, convert to metric if (!unitA || unitA !== 'mm') valA = valA * inToMM; if (!unitB || unitB !== 'mm') valB = valB * inToMM; return valA - valB; }) } catch (e) { console.log('Could not sort ' + key + ' by number value.'); } } if (pitchFilter.some(function(filter) { return key.indexOf(filter) > -1; })) { try { sortedFilters = self.filterValues[key].sort(function(a, b) { var valA = self.sizeAndPitchOrder.indexOf(a) > -1 ? self.sizeAndPitchOrder.indexOf(a) : Number.MAX_SAFE_INTEGER; var valB = self.sizeAndPitchOrder.indexOf(b) > -1 ? self.sizeAndPitchOrder.indexOf(b) : Number.MAX_SAFE_INTEGER; return valA - valB; }); } catch (e) { console.log('Could not sort ' + key + ' by number value.'); } } if (millingCutterSeriesFilter.some(function(filter) { return key.indexOf(filter) > -1; })) { try { sortedFilters = self.filterValues[key].sort(function(a, b) { var valA = self.millingCutterSeriesOrder.indexOf(a) > -1 ? self.millingCutterSeriesOrder.indexOf(a) : Number.MAX_SAFE_INTEGER; var valB = self.millingCutterSeriesOrder.indexOf(b) > -1 ? self.millingCutterSeriesOrder.indexOf(b) : Number.MAX_SAFE_INTEGER; return valA - valB; }); } catch (e) { console.log(e); } } if (machineModelsFilter.some((filter) => key.indexOf(filter) > -1)) { try { sortedFilters = self.filterValues[key].sort((a, b) => { var valA = a.indexOf('SS') > -1 ? 2 : 1; var valB = b.indexOf('SS') > -1 ? 2 : 1; return valA - valB; }); } catch (e) { console.log(e); } } if (matchingChucksFilter.some((filter) => key.toLowerCase().indexOf(filter) > -1)) { try { sortedFilters = self.filterValues[key].sort((a, b) => { var valA = Number(a.split('\\')[0].split(' ')[0]); var valB = Number(b.split('\\')[0].split(' ')[0]); return valA - valB; }); } catch (e) { console.log(e); } } // Create the Filters Container with its sorted filters if (sortedFilters.length === 1) { inputItem = inputItem + ''; inputItem = '
    ' + inputItem + '
    '; // Hide filter if only one inputItem = ''; } else { sortedFilters = [... new Set(sortedFilters)]; sortedFilters.forEach(function(option) { inputItem = inputItem + ''; }); inputItem = '
    ' + inputItem + '
    '; } // close filter values container div inputItem = inputItem + '
    '; filterContainer.innerHTML = filterContainer.innerHTML + inputItem; }); if (!Array.from(this.elementNode.querySelectorAll('.filter-cat-container')).length) { this.elementNode.querySelector('#filters-col').classList.add('hidden'); } }, renderFilterSearchBars: function() { let self = this; let filterCategories = Array.from(self.elementNode.querySelectorAll('.filter-values-container')); filterCategories.forEach(category => { if (category.children.length < 5) return; let searchItemContainer = document.createElement('div'); let searchItemIcon = document.createElement('i'); let searchBarElement = document.createElement('input'); searchItemContainer.classList.add('filter-search-container'); searchItemIcon.classList.add('fa'); searchItemIcon.classList.add('fa-search'); searchBarElement.classList.add('filter-item-search'); searchBarElement.type = 'text'; searchItemContainer.append(searchItemIcon); searchItemContainer.append(searchBarElement); category.before(searchItemContainer); searchBarElement.onkeyup = (e) => { Array.from(category.children).forEach(filterItem => { if (!filterItem.querySelector('input').value.toLowerCase().includes(e.currentTarget.value.toLowerCase())) filterItem.classList.add('hidden'); else filterItem.classList.remove('hidden'); }); } }); }, renderPartItems: function() { let self = this; let $itemsCol = $(self.$element).find('#items-container'); let filtered = this.filterItems(); $itemsCol.empty(); let titleOverrideArr = Array.from(self.elementNode.querySelectorAll('#title-overrides-container div')).map(overrideElem => overrideElem.dataset.titleOverride); let qtyOverrideArr = Array.from(self.elementNode.querySelectorAll('#qty-overrides-container div')).map(qtyOverrideElem => qtyOverrideElem.dataset.qtyOverride); let itemTemplate = self.isPopupMode ? self.templates.partListItemPopupTemplate : self.templates.partListItemTemplate; filtered.forEach(function(item, ndx) { if (item.link.includes('winner') && haas.region.props.country !== 'US') return; var itemContent = itemTemplate({ itemSku: item.sku, itemLink: item.link, itemImgSrc: item.imageHref, itemImgTitle: item.sku, itemImgAlt: item.sku, itemTitle: titleOverrideArr[ndx] ? titleOverrideArr[ndx] : item.title, itemPrice: item.price.amount, itemAllPrices: item.allPrices, itemStartingQty: qtyOverrideArr[ndx] ? qtyOverrideArr[ndx] : '1', itemAllDiscountPrices: item.allDiscountPrices, hasStrikethroughPrice: item.hasStrikethroughPrice, rawPromoPrice: item.rawPromoPrice, propSixtyFive: item.californiaProposition65Required ? 'prop-sixty-five-req' : '', startDisabled: false, isWcProduct: item.link && item.link.includes('winner') }); $itemsCol.append(itemContent); self.renderPrices(); self.renderQuantityOptions(); self.processSelectableFilters(); }); }, renderQuantityOptions: function() { this.$element.find('.part-list-item').each(function(ndx, elem) { var $quantityOptionContainer = $(elem).find('#quantity-select'); var options = ''; for (var i = 1; i <= 50; i++) { options = options + "'; } $quantityOptionContainer.html(options); if ($quantityOptionContainer.attr('data-qty-override')) { $quantityOptionContainer.find('option[val=' + $quantityOptionContainer.attr('data-qty-override') +']').attr('selected', 'selected'); } }); }, renderPrices: function() { $.when(haas.region.priceGroupPromise).then(function() { if (haas.cookies.getCookie('tooling-currency') === 'undefined') { $('.check-out-container').hide(); $('.part-pricing').hide(); $('.alert').removeClass('hidden'); } else { $('.authoredPartListing .part-list-item').each(function(ndx, elem) { let $priceContainer = $(elem).find('.price-span ' + haas.cookies.getCookie('tooling-currency')); let $unitPriceContainer = $(elem).find('#unit-price'); let hasCurrency = false; $(elem).find('.price-span').each(function() { $(this).html(haas.ecommUtils.formatPrice($(this).attr('data-price'))); if ($(this).attr('data-currency') === haas.cookies.getCookie('tooling-currency')) { hasCurrency = true; $(this).parent().removeClass('hidden'); $(this).show(); } }); if (!hasCurrency) $(elem).hide(); $('.promo-' + haas.cookies.getCookie('tooling-currency')).each(function() { $(this).html(haas.ecommUtils.formatPrice($(this).attr('data-value'))); $(this).parent().removeClass('hidden'); $(this).parents('.part-list-item').addClass('ecomm-plp-promo'); }); if ($unitPriceContainer.attr('data-haspriceperpart') === 'true') { $unitPriceContainer.html('(' + haas.ecommUtils.formatPrice($unitPriceContainer.attr('data-perpricevalue')) + '/' + $unitPriceContainer.attr('data-partype') + ')'); $unitPriceContainer.removeClass('hidden'); } }); } }); }, renderWorkpieceMaterialFilterIcons: function() { const self = this; const jsonData = JSON.parse(self.elementNode.querySelector('[data-json]').dataset.json); const workpieceFilters = Object.keys(jsonData.filterLanguageMap).filter(key => jsonData.filterLanguageMap[key].some(mappedVal => mappedVal.toLowerCase().includes('workpiece material'))); workpieceFilters.forEach(filterKey => { Array.from(self.elementNode.querySelectorAll('[data-master-cat="'+filterKey+'"] .filter-item')).forEach(filterItem => { const workpieceId = filterItem.querySelector('input').value[0].toLowerCase(); filterItem.querySelector('span').classList.add('workpiece-filter'); filterItem.querySelector('span').classList.add('workpiece-'+workpieceId); }); }); }, timeoutModal: function() { setTimeout(function() { if ($('.haas-modal-wrapper').is('.open')) haas.components.Modal.close(); }, 5000); }, cartSuccessClickHandler: function() { haas.LOGGER.debug('Proceeding to Cart!'); $('#cart-success-btn').addClass('disabled'); $('#ecommerce-nav > a').click(); }, showSuccessModal: function(quantity) { // to-do: Add attributes in html to make this translatable var self = this; // Remove loading indicator $('body').removeClass('cursor-wait'); haas.components.Modal.open(self.templates.addToCartSuccessModal({qty: quantity})); $('#cart-success-btn').off('click').on('click', self.cartSuccessClickHandler); $('#continue-btn').off('click').on('click', haas.components.Modal.close); }, showErrorModal: function(error) { let errorTLdata = this.elementNode.querySelector('#error-tl-data').dataset; let errorTL = errorTLdata.error; let outOfStockTL = errorTLdata.oos; let expiredTL = errorTLdata.expired; let timeoutTL = errorTLdata.timeout; let signinTL = errorTLdata.signin; let genericErrorTL = errorTLdata.generic; let wcErrorTL = errorTLdata.wcAlreadyAdded; let wcMemberErrorTL = errorTLdata.wcAlreadyMember; // Remove loading indicator $('body').removeClass('cursor-wait'); if (error.type === 'winnerCircleMaxOrderQuantityExceeded') { haas.components.Modal.open('

    '+errorTL+' '+wcErrorTL+'

    '); this.timeoutModal(); } else if (error.type === 'winnerCircleAlreadyMember') { haas.components.Modal.open('

    '+errorTL+' '+wcMemberErrorTL+'

    '); this.timeoutModal(); } else if (error.type === 'InsufficientStockError') { haas.components.Modal.open('

    '+errorTL+' '+outOfStockTL+'

    '); this.timeoutModal(); } else if (error.type === 'CartError') { let self = this; haas.components.Modal.open('

    '+errorTL+' '+expiredTL+'

    '); let hybrisLogoutPayload = $.get(haas.constants.api.hybrisLogout(localStorage.storedSiteLang)); let eatCookiesPayload = $.get(haas.constants.api.eatcookies(localStorage.storedSiteLang)); return $.when(hybrisLogoutPayload, eatCookiesPayload).then((logoutData, eatCookiesData) => { localStorage.cartQuantity = 0; localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } else if(error.type === 'InvalidTokenError') { haas.components.Modal.open('
    '+timeoutTL+'
    '); self.timeoutModal(); haas.fleet.myHaasDropdown.logout(); } else { haas.components.Modal.open('
    '+errorTL+' '+genericErrorTL+'
    '); let hybrisLogoutPayload = $.get(haas.constants.api.hybrisLogout(localStorage.storedSiteLang)); let eatCookiesPayload = $.get(haas.constants.api.eatcookies(localStorage.storedSiteLang)); return $.when(hybrisLogoutPayload, eatCookiesPayload).then((logoutData, eatCookiesData) => { localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); localStorage.removeItem('guid'); haas.ecommUtils.renderCartQuantity(); self.timeoutModal(); }); } }, postPartToCart: function(partid, quantity) { var self = this; var email; var bearer; var endpoint = haas.constants.api.ecommerce; if(localStorage.access_token) { $.when(haas.jwToken.getUserInfo()).then(function(userPayload) { bearer = userPayload['ecomm_bearer_token_access_token']; if (userPayload.userInfo) { email = userPayload.userInfo.uid; } else { email = userPayload.email; } $.get({ url: '/ecommpartsstorefront/ecommparts/en/hybris-cart', cache: false }).then(function(cart) { endpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cart.cartId + '/entries/'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload) { if (payload.statusCode && payload.statusCode === 'winnerCircleMaxOrderQuantityExceeded') { let errorObj = {type : 'winnerCircleMaxOrderQuantityExceeded'}; self.showErrorModal(errorObj); } else if (payload.statusCode && payload.statusCode === 'winnerCircleAlreadyMember') { let errorObj = {type : 'winnerCircleAlreadyMember'}; self.showErrorModal(errorObj); } else { self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; } }).fail(function(payload) { if(payload.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { self.showErrorModal(payload.responseJSON.errors[0]); } }).always(function() { haas.ecommUtils.renderCartQuantity(); }); }).fail(function(err) { if(err.responseJSON.errors[0].type == 'InvalidTokenError') { haas.ecommUtils.logoutHybris().then(() => { haas.fleet.myHaasDropdown.logout(); localStorage.removeItem('access_token'); localStorage.removeItem('cartQuantity'); self.showErrorModal(payload.responseJSON.errors[0]); }); } else { $.post({ contentType: 'application/json', url: haas.constants.api.ecommerce + 'users/' + email + '/carts' + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') }, }).done(function(cartResponse){ endpoint = haas.constants.api.ecommerce + 'users/' + email + '/carts/' + cartResponse.code + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'Authorization': 'Bearer ' + bearer, 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload) { if (payload.statusCode && payload.statusCode === 'winnerCircleMaxOrderQuantityExceeded') { let errorObj = {type : 'winnerCircleMaxOrderQuantityExceeded'}; self.showErrorModal(errorObj); } else if (payload.statusCode && payload.statusCode === 'winnerCircleAlreadyMember') { let errorObj = {type : 'winnerCircleAlreadyMember'}; self.showErrorModal(errorObj); } else { self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; } }).fail(function(payload) { self.showErrorModal(payload.responseJSON.errors[0]) }).always(function() { haas.ecommUtils.renderCartQuantity(); }); }); } }); return userPayload; }); } else { endpoint = haas.constants.api.ecommerce + 'users/anonymous/carts/' + localStorage.guid + '/entries'; var reqBody = haas.ecommUtils.buildReqBody(Number(quantity), partid); $.post({ contentType: 'application/json', url: endpoint + '?curr=' + haas.cookies.getCookie('tooling-currency') + '&lang=' + localStorage.storedSiteLang, data: reqBody, headers: { 'salesOrg': haas.cookies.getCookie('salesOrg'), 'language': localStorage.storedSiteLang, 'currency': haas.cookies.getCookie('tooling-currency') } }).done(function(payload){ if (payload.statusCode && payload.statusCode === 'winnerCircleMaxOrderQuantityExceeded') { let errorObj = {type : 'winnerCircleMaxOrderQuantityExceeded'}; self.showErrorModal(errorObj); } else if (payload.statusCode && payload.statusCode === 'winnerCircleAlreadyMember') { let errorObj = {type : 'winnerCircleAlreadyMember'}; self.showErrorModal(errorObj); } else { self.showSuccessModal(payload.quantityAdded); localStorage.cartQuantity = Number(localStorage.cartQuantity) + payload.quantityAdded; } }).fail(function(payload) { self.showErrorModal(payload.responseJSON.errors[0]) }).always(function() { haas.ecommUtils.renderCartQuantity(); }); } }, addToCartEventHandler: function(e) { var self = this; var $target = $(e.target); var $parent = $target.parents('.part-list-item'); var partid = $parent.attr('data-sku'); var quantity = $parent.find('#quantity-select').val(); // loading indicator $('body').addClass('cursor-wait'); if (localStorage.guid || localStorage.access_token) { self.postPartToCart(partid, quantity); } else { $.when(haas.ecommUtils.createCartPromise(this.authenticated)).then(function(payload) { localStorage.guid = payload.guid; haas.cookies.setCookie('ecommparts-cart', payload.guid); return self.postPartToCart(partid, quantity); }); } }, propSixtyFiveTooltipHandler: function(e) { e.preventDefault(); var redirectLink = $(e.target).attr('data-redirect'); window.location = redirectLink; }, bindEvents: function() { let self = this; this.$element.find('.prop-sixty-five').on('click', function(e) { e.preventDefault(); }); this.$element.find('.prop-tooltext').on('click', self.propSixtyFiveTooltipHandler.bind(self)); this.$element.find('.part-list-item #add-to-cart-btn').on('click', self.addToCartEventHandler.bind(self)); this.$element.find('input:not([type="text"])').on('click', this.filterClickHandler.bind(this)); this.$element.find('#clear-all').on('click', this.clearAllClickHandler.bind(this)); if (self.isPopupMode) this.$element.find('.part-list-item > a').on('click', self.popupClickHandler.bind(self)); }, popupClickHandler: function(e) { let self = this; let partParent = e.currentTarget.parentElement; let partSKU = partParent.dataset.sku; let partImgSrc = partParent.querySelector('img').src; let partTitle = partParent.querySelector('h1').innerHTML; let partPriceObj = Array.from(partParent.querySelectorAll('.part-pricing .price-span')).find(priceSpan => priceSpan.dataset.currency === haas.cookies.getCookie('tooling-currency')); let partPrice = partPriceObj && partPriceObj.innerHTML; let partLink = partParent.querySelector('a').dataset.link; haas.components.Modal.open(self.templates.toolingPartDetails({ sku: partSKU, title: partTitle, imgSrc: partImgSrc.substring(0, partImgSrc.indexOf('.jpg') + 4).concat('/jcr:content/renditions/original'), price: partPrice, link: partLink }), 'tooling-modal'); }, filterClickHandler: function(e) { this.renderPartItems(); this.rebindPartItemsHandler(); }, filterItems: function() { const self = this; const $filterContainer = self.$element.find('#filter-container'); // Get unique filters self.selectedFilters = _.values($filterContainer.serializeArray().reduce(function(arr, cur) { if (arr[cur.name]) { arr[cur.name].value.push(cur.value); return arr; } arr[cur.name] = { name: cur.name, value: [cur.value] }; return arr; }, {})); // If there are no selected filters, just return all items if (!self.selectedFilters.length) { return self.items.filter((fItem => { if(self.returnPriceByCurrency(fItem.allPrices).length){ return fItem; }; })); } // Otherwise, filter! let filtered = self.items.filter(function(item) { return self.selectedFilters.every(function (filter) { return filter.value.some(function(value) { return item.classificationFilterValues.indexOf(filter.name +':'+ value) > -1; }); }); }); return filtered.filter((fItem => { if(self.returnPriceByCurrency(fItem.allPrices).length){ return fItem; } })); }, processPreselectedFilters: function() { const self = this; if (!self.preselectedFilterNames.length) return; self.preselectedFilterNames.forEach((key, ndx) => { let queryString; // For values that have "\\" change to double '\\\\' self.preselectedFilterValues[ndx] = self.preselectedFilterValues[ndx].replaceAll('\\', '\\\\'); // When creating query string, check for " symbol and create accordingly, else statement is fall back in case value might have ' symbol if (self.preselectedFilterNames[ndx].includes('"')) queryString = "#filters-col input[name='"+self.preselectedFilterNames[ndx]+"']"; else queryString = '#filters-col input[name="'+self.preselectedFilterNames[ndx]+'"]'; if (self.preselectedFilterValues[ndx].includes('"')) queryString = queryString.concat("[value='"+self.preselectedFilterValues[ndx]+"']"); else queryString = queryString.concat('[value="'+self.preselectedFilterValues[ndx]+'"]'); try { self.elementNode.querySelector(queryString).checked = true; self.elementNode.querySelector(queryString).defaultChecked = true; } catch (e) { console.warn('Filter Not Found: ', queryString); } }); self.renderPartItems(); }, processSelectableFilters: function() { const self = this; // clear all non-selectable filters before processing Array.from(self.elementNode.querySelectorAll('#filter-container label')).forEach(filter => { filter.classList.remove('filter-disabled'); filter.classList.remove('not-selectable'); }); Array.from(self.elementNode.querySelectorAll('#filter-container input')).forEach(filter => filter.disabled = false); let currentItems = self.filterItems(); let availableFilters = {}; let unselectableFilterType = $('#filters-col').attr('data-unselectable-filter-type'); currentItems.forEach(function(item) { item.classificationFilterValues.forEach(function(filter) { let filterData = filter.split(':'); if (!availableFilters[filterData[0]]) availableFilters[filterData[0]] = []; availableFilters[filterData[0]].push(filterData[1]); }); }); self.$element.find('.filter-cat-container').each(function(ndx, group) { let filterName = $(group).attr('data-master-cat'); let $filters = $(group).find('input:not([type="text"])'); let selectableFilters = availableFilters[filterName]; var count = 0; // if theres a filter in the group already selected, or only a single filter, we dont need to process the group if ($(group).attr('data-single-filter') === 'true') { $(this).find('p').html("( 1 )"); return; } if (!selectableFilters || !selectableFilters.length) { $filters.each(function(ndx, filter) { unselectableFilterType === 'disabled' ? $(filter).parent().addClass('filter-disabled') : $(filter).parent().addClass('not-selectable'); $(filter).prop('disabled', true); }); } else { $filters.each(function(ndx, filter) { let filterValue = $(filter).attr('value'); if (selectableFilters.indexOf(filterValue) === -1) { unselectableFilterType === 'disabled' ? $(filter).parent().addClass('filter-disabled') : $(filter).parent().addClass('not-selectable'); $(filter).prop('disabled', true); } else { count++; } }); } $(this).find('p').html("( " + count +" )"); }); }, clearAllClickHandler: function(e) { this.$element.find('input:not(.single-filter)').prop('checked', false); this.renderPartItems(); this.rebindPartItemsHandler(); }, returnPriceByCurrency: function(priceObject) { return priceObject.filter(function(price){ return price.currency === haas.cookies.getCookie('tooling-currency'); }); }, rebindPartItemsHandler: function() { this.$element.find('.part-list-item #add-to-cart-btn').off().on('click', this.addToCartEventHandler.bind(this)); } }); })(); (function () { haas.components.DropdownLinkList = haas.Component.create({ handleInputChange: function() { var self = this; window.location.href = self.$element.find('#link-select').val() + ".html"; }, bindEvents: function() { var self = this; this.$element.find('#link-select').on('change', self.handleInputChange.bind(self)); }, initialize: function() { this.bindEvents(); }, render: function() { } }); })(); (function() { // lightweight handling of stale global object if (!haas.objects) haas.objects = {}; haas.objects.DrilldownPackageListObject = DrilldownPackageListObject; function DrilldownPackageListObject(elemObj) { const formModel = { machines: [{ model: '', included: '', options: '', machine_language: '', machine_region: '', machine_currency: '', machine_hfo_id: '', discounts: [{ discount: 'configured', type: 'flat', value: 0, amount: 0 }], tooling_qty: {} }], customer: { company: '', email: '', first_name: '', last_name: '', phone: '' }, address: { city: '', country: '', post_code: '', region: '', street: '', additionalComments:'' }, serial: '', isPackage: true, notes: '' }; const authFormModel = { machines: [{ model: '', included: '', options: '', machine_language: '', machine_region: '', machine_currency: '', machine_hfo_id: '', discounts: [{ discount: 'configured', type: 'flat', value: 0, amount: 0 }], tooling_qty: {} }], customer: { id : '', first_name : '', last_name : '' }, serial: '', isPackage: true, notes: '' }; const nonZipCodeCountries = ['SA', 'EG', 'OM', 'QA', 'KW', 'BH', 'LB', 'AE', 'VN', 'CN']; const missingOptionNameMap = { 'AIR VISE-210' : '75 mm Air Vise', 'PRB-TRT': 'Probe Riser Block, TRT' }; let Modal = haas.components.Modal; let haasModalElem = document.querySelector('.haas-modal'); let showValidationState = haas.utils.showValidationState; let validateInput = haas.utils.validateInput; this.token = null; this.successMessage = ''; this.errorMessage = ''; this.forceGLUSD = false; this.packagePayload = {}; this.element = elemObj; this.templates = {}; this.initialize = function(contactFormTemplateAuthenticated, contactFormTemplate) { let _self = this; _self.templates.contactFormTemplateAuthenticated = contactFormTemplateAuthenticated; _self.templates.contactFormTemplate = contactFormTemplate; $.when(haas.jwToken.jwtPromise).then(function (token) { _self.token = token; }); } this.setPackagePayload = function(payload) { this.packagePayload = payload; } this.populateMissingOptionNames = function(packageObj, optionNamesList) { let importedPackage = packageObj.importedPackageJSON ? JSON.parse(packageObj.importedPackageJSON) : null; let options = packageObj.options ? packageObj.options.split('&&') : (importedPackage && importedPackage.parentOptions) ? importedPackage.parentOptions.split('&&') : []; let automationOptions = packageObj.automationMachineOptions ? packageObj.automationMachineOptions.split('&&') : (importedPackage && importedPackage.secondChildOptions) ? importedPackage.secondChildOptions.split('&&') : []; let associateOptions = packageObj.associatedMachineOptions ? packageObj.associatedMachineOptions.split('&&') : (importedPackage && importedPackage.firstChildOptions) ? importedPackage.firstChildOptions.split('&&') : []; let allOptions = options.concat(automationOptions).concat(associateOptions); return optionNamesList.concat(allOptions.filter(opt => missingOptionNameMap[opt] && !optionNamesList.includes(missingOptionNameMap[opt])).map(missingOption => missingOptionNameMap[missingOption])); } this.showContactForm = function(element) { let _self = this; let importedPackage = _self.packagePayload.importedPackageJSON ? JSON.parse(_self.packagePayload.importedPackageJSON) : null; let packageModel = _self.packagePayload.machines ? _self.packagePayload.machines : importedPackage.parentModel; let modelDetails = haas.services.modelDetail.getModel(packageModel); _self.successMessage = _self.successMessage ? _self.successMessage : element.querySelector('#ddpl-data-container').dataset.successMessage; _self.errorMessage = _self.errorMessage ? _self.errorMessage : element.querySelector('#ddpl-data-container').dataset.errorMessage; _self.forceGLUSD = _self.forceGLUSD ? _self.forceGLUSD : element.querySelector('#ddpl-data-container').dataset.forceGLUSD; Modal.open("Loading"); // Populate Machine Options $.when(modelDetails).then(function(details) { if(haas.jwToken.isValid(_self.token)){ Modal.open(_self.templates.contactFormTemplateAuthenticated({ quoteNotes: _self.packagePayload.quoteNotes })); _self.bindSubmitHandler(_self); } else { Modal.open(_self.templates.contactFormTemplate({ quoteNotes: _self.packagePayload.quoteNotes })); haas.utils.initAutocomplete(); _self.disableAutocomplete(); _self.bindEventHandlers(_self); } let standardOptions = details.getStandardOptions(); if (_self.packagePayload.hasSpindle) standardOptions = standardOptions.filter(function(option) { return option.categoryId !== 'spindles'; }) if (_self.packagePayload.hasTC) standardOptions = standardOptions.filter(function(option) { return option.categoryId !== 'tool-changers'; }) standardOptions = standardOptions.map(function(option) { return option.name; }); let optionNames = _self.packagePayload.optionNames ? _self.packagePayload.optionNames.split('&&') : (importedPackage && importedPackage.optionNames) ? importedPackage.optionNames.split('&&').filter((opt) => opt && !standardOptions.includes(opt)) : []; let toolingOptions = _self.packagePayload.toolingOptionNames ? _self.packagePayload.toolingOptionNames.split('&&') : []; optionNames = _self.populateMissingOptionNames(_self.packagePayload, optionNames); if (!toolingOptions.length && (importedPackage && importedPackage.toolingOptionNames)) { let toolingQtys = importedPackage.toolingQuants.split('&&').map(qty => Number(qty)); toolingOptions = importedPackage.toolingOptionNames.split('&&').map((opt, ndx) => opt + ' x ' + toolingQtys[ndx]); } haasModalElem.querySelector('#standard-ops').append(_self.buildListItemHTML(standardOptions)); haasModalElem.querySelector('#package-ops').append(_self.buildListItemHTML(optionNames)); if (toolingOptions.length) haasModalElem.querySelector('#tooling-ops').append(_self.buildListItemHTML(toolingOptions)); else haasModalElem.querySelector('#tooling-txt').remove(); }); } this.buildListItemHTML = function(opList) { let listItemFragment = document.createDocumentFragment(); opList.forEach(function(option) { let listItemElement = document.createElement('li'); listItemElement.innerHTML = option; listItemFragment.append(listItemElement); }); return listItemFragment; } this.bindSubmitHandler = function(_self) { haasModalElem.querySelector('#pkg-form').onsubmit = this.submitForm.bind(_self); } this.bindEventHandlers = function(_self) { haasModalElem.querySelectorAll('.bp-input').forEach(input => { input.onblur = this.getInputChangeHandler(_self); }); haasModalElem.querySelector('#autocomplete').onchange = this.getInputChangeHandler(_self); haasModalElem.querySelector('#autocomplete').onfocus = this.disableAddressAutocomplete.bind(_self); haasModalElem.querySelector('#pkg-form').onsubmit = this.submitForm.bind(_self); haasModalElem.querySelector('#Country').onchange = this.handleCountryChange(_self); haasModalElem.querySelector('#pkg-form').addEventListener('autocompleteFilled', _self.handleCountryChange(_self)); } this.getInputChangeHandler = function (_self) { return function () { return _self.validateInput($(this)); }; } this.validateInput = function ($input) { let validation = validateInput($($input)); showValidationState(validation); return validation.isValid; } this.validateForm = function () { let form = this; let inputs = [...haasModalElem.querySelectorAll('[data-validators]')]; let validationStates = inputs.map(elem => form.validateInput(elem)); // blur all address fields to trigger field validations haasModalElem.querySelectorAll('.bp-input').forEach(input => { input.blur(); }); return _.every(validationStates); } this.showSubmissionLoader = function() { document.querySelector('.haas-modal-wrapper #submission-loader').classList.remove('hidden'); } this.hideSubmissionLoader = function() { document.querySelector('.haas-modal-wrapper #submission-loader').classList.add('hidden'); } this.showSuccessDialog = function (msg) { Modal.open(_.template('

    {{=msg}}

    ')({msg: msg})); } this.showErrorDialog = function (msg) { Modal.open(_.template('

    {{=msg}}

    ')({msg: msg})); } this.handleCountryChange = function(_self) { return function() { haasModalElem.querySelector('#Region').parentElement.querySelector('.error-output').innerHTML = ''; haasModalElem.querySelector('#PostCode').parentElement.querySelector('.error-output').innerHTML = ''; if (haasModalElem.querySelector('#Region').attributes.disabled) { haasModalElem.querySelector('#Region').dataset.validators = ''; } else { haasModalElem.querySelector('#Region').dataset.validators = 'required'; } // if new country val is ME, dont require post code if (nonZipCodeCountries.indexOf(document.querySelector('#Country').value > -1)) { haasModalElem.querySelector('#PostCode').dataset.validators = ''; } else { haasModalElem.querySelector('#PostCode').dataset.validators ='required'; } }; } this.disableAddressAutocomplete = function(e) { let newAttr = document.createAttribute('autocomplete'); newAttr.value = 'new-password'; haasModalElem.querySelector('#autocomplete').setAttributeNode(newAttr); } this.disableAutocomplete = function() { if (!!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime)) { // for chrome haasModalElem.querySelectorAll('input.bp-input').forEach(input => { let newAttr = document.createAttribute('autocomplete'); newAttr.value = 'new-password'; input.setAttributeNode(newAttr); }); } else { // Non-chorme browsers haasModalElem.querySelectorAll('input.bp-input').forEach(input => { let newAttr = document.createAttribute('autocomplete'); newAttr.value = 'off'; input.setAttributeNode(newAttr); }); } } this.submitForm = function(e) { e.preventDefault(); if (!this.validateForm()) { return; } let serial = this.packagePayload.serialNumber ? this.packagePayload.serialNumber : ''; let form = this.serializeInputs(serial); let authenticated = haas.jwToken.isValid(this.token); this.buildMachinePayloadObjAndSubmit(form, serial, authenticated, this.packagePayload); } this.serializeInputs = function (serial) { let form = this; let inputs = haasModalElem.querySelectorAll('.bp-input'); let tmp = {}; let inputsObj = _.assign({}, formModel); let authInputsObj = _.assign({}, authFormModel); inputs.forEach(function(elem) { let val = elem.value; if (elem.attributes.type === 'checkbox') { val = elem.checked; } let key = elem.attributes.name ? elem.attributes.name.value : null; // Check if the input's val is not empty // NOTE: IE11 specific check for duplicate input fields erasing populated fields if (key && val && val.length > 0) { tmp[key] = val; } }); // check to see if user is logged in; // if so, submit form with information from token if (haas.jwToken.isValid(form.token)){ _.assign(authInputsObj.customer, { id : form.token.customerId, contact_id : form.token.contactId, first_name : form.token.firstName, last_name : form.token.lastName }); return authInputsObj; } else { _.assign(inputsObj.customer, { company: tmp.company, email: tmp.email, first_name: tmp.first_name, last_name: tmp.last_name, phone: tmp.phone }); if(tmp.opt_status) { _.assign(inputsObj.customer, { opt_status: '01' }); } else if(inputsObj.customer.opt_status) { delete inputsObj.customer.opt_status; } _.assign(inputsObj.address, { city: tmp.city, country: tmp.country, post_code: tmp.post_code, region: tmp.region, street: tmp.address2 ? tmp.street + ", " + tmp.address2 : tmp.street + ", ", additionalComments: tmp.additionalComments }); inputsObj.include_specs = tmp.include_specs; return inputsObj; } } this.buildMachinePayloadObjAndSubmit = function(payloadObj, serial, authenticated, packageObj) { let _self = this; let importedPackage = packageObj.importedPackageJSON ? JSON.parse(packageObj.importedPackageJSON) : null; let model = packageObj.machines ? packageObj.machines : importedPackage.parentModel; let modelDetails = haas.services.modelDetail.getModel(model); let associate = packageObj.associatedMachine ? packageObj.associatedMachine : (importedPackage && importedPackage.firstChildModel) ? importedPackage.firstChildModel : null ; let associateDetails = (associate && associate.length) ? haas.services.modelDetail.getModel(associate) : null; let automation = packageObj.automationMachine ? packageObj.automationMachine : (importedPackage && importedPackage.secondChildModel) ? importedPackage.secondChildModel : null; let automationDetails = (automation && automation.length) ? haas.services.modelDetail.getModel(automation) : null; let overridePrice = packageObj.overridePrice ? Number(packageObj.overridePrice) : (importedPackage && importedPackage.overridePrice) ? Number(importedPackage.overridePrice) : null; let overrideDiscountAmount = packageObj.overrideDiscountAmount ? Number(packageObj.overrideDiscountAmount) : (importedPackage && importedPackage.overrideDiscount) ? Math.round(Number(importedPackage.overrideDiscount)) : null; let toolingOptionsObj = packageObj.tooling_qty ? JSON.parse(packageObj.tooling_qty) : null; console.log(importedPackage, associate, automation); if (!toolingOptionsObj && importedPackage) { toolingOptionsObj = {}; let toolingIds = importedPackage.toolingIDs ? importedPackage.toolingIDs.split('&&') : []; let toolingQtys = importedPackage.toolingQuants ? importedPackage.toolingQuants.split('&&').map((elem) => Number(elem)) : []; toolingIds.forEach((id, ndx) => { toolingOptionsObj[id] = toolingQtys[ndx]; }); } _self.showSubmissionLoader(); $.when(modelDetails, associateDetails, automationDetails).then(function(details, associateModelDetails, automationModelDetails) { let allOptions = packageObj.options ? packageObj.options.split('&&') : (importedPackage && importedPackage.parentOptions) ? importedPackage.parentOptions.split('&&') : []; let includedOptions = []; let addedOptions = []; allOptions.forEach(function(opId) { let optionObj = details.options.filter(function(option) { return option.id === opId }); if (optionObj[0]) { let isStandard = optionObj[0].isStandard; if (isStandard) includedOptions.push(opId); else addedOptions.push(opId); } }); if (importedPackage && importedPackage.parentIncludedOptions) { importedPackage.parentIncludedOptions.split('&&').forEach((opId) => { let optionObj = details.options.filter(function(option) { return option.id === opId }); if (optionObj[0] && !includedOptions.includes(opId)) includedOptions.push(opId); }); }; _.assign(payloadObj.machines[0], { model: model, included: includedOptions.join(','), options: addedOptions.join(','), machine_language: haas.utils.getLanguage(), machine_region: _self.forceGLUSD ? 'GL' : haas.region.props.region, machine_currency: _self.forceGLUSD ? 'USD' : haas.region.props.currency, machine_hfo_id: haas.region.props.hfoid }); // clear out tooling and associates _.assign(payloadObj.machines[0], { tooling_qty: {} }); payloadObj.machines.splice(1); if (toolingOptionsObj) _.assign(payloadObj.machines[0], { tooling_qty: toolingOptionsObj }); else _.assign(payloadObj.machines[0], { tooling_qty: {} }); if (!overrideDiscountAmount) { _.assign(payloadObj.machines[0], { discounts: [] }); } else { _.assign(payloadObj.machines[0], { discounts: [{ discount: 'configured', type: 'flat', value: overridePrice, amount: overrideDiscountAmount }] }); } if (automationModelDetails) { let automationModelObj = { model: '', included: '', options: '', machine_language: haas.utils.getLanguage(), machine_region: _self.forceGLUSD ? 'GL' : haas.region.props.region, machine_currency: _self.forceGLUSD ? 'USD' : haas.region.props.currency, machine_hfo_id: haas.region.props.hfoid, discounts: [] } let allAutomationOptions = packageObj.automationMachineOptions ? packageObj.automationMachineOptions.split('&&') : (importedPackage && importedPackage.secondChildOptions) ? importedPackage.secondChildOptions.split('&&') : []; let includedAutomationOptions = []; let addedAutomationOptions = []; allAutomationOptions.forEach(function(opId) { let optionObj = automationModelDetails.options.filter(function(option) { return option.id === opId }); if (optionObj[0]) { let isStandard = optionObj[0].isStandard; if (isStandard) includedAutomationOptions.push(opId); else addedAutomationOptions.push(opId); } }); if (importedPackage && importedPackage.secondChildIncludedOptions) { importedPackage.secondChildIncludedOptions.split('&&').forEach((opId) => { let optionObj = automationModelDetails.options.filter(function(option) { return option.id === opId }); if (optionObj[0] && !includedAutomationOptions.includes(opId)) includedAutomationOptions.push(opId); }); }; _.assign(automationModelObj, { model: automation, included: includedAutomationOptions.join(','), options: addedAutomationOptions.join(','), machine_language: haas.utils.getLanguage(), machine_region: _self.forceGLUSD ? 'GL' : haas.region.props.region, machine_currency: _self.forceGLUSD ? 'USD' : haas.region.props.currency, machine_hfo_id: haas.region.props.hfoid, discounts: [] }); if (payloadObj.machines.length > 1) payloadObj.machines[1] = automationModelObj; else payloadObj.machines.push(automationModelObj); } if (associateModelDetails) { let associateModelObj = { model: '', included: '', options: '', machine_language: haas.utils.getLanguage(), machine_region: _self.forceGLUSD ? 'GL' : haas.region.props.region, machine_currency: _self.forceGLUSD ? 'USD' : haas.region.props.currency, machine_hfo_id: haas.region.props.hfoid, discounts: [] } let allAssociateOptions = packageObj.associatedMachineOptions ? packageObj.associatedMachineOptions.split('&&') : (importedPackage && importedPackage.firstChildOptions) ? importedPackage.firstChildOptions.split('&&') : []; let includedAssociateOptions = []; let addedAssociateOptions = []; allAssociateOptions.forEach(function(opId) { let optionObj = associateModelDetails.options.filter(function(option) { return option.id === opId }); if (optionObj[0]) { let isStandard = optionObj[0].isStandard; if (isStandard) includedAssociateOptions.push(opId); else addedAssociateOptions.push(opId); } }); if (importedPackage && importedPackage.firstChildIncludedOptions) { importedPackage.firstChildIncludedOptions.split('&&').forEach((opId) => { let optionObj = associateModelDetails.options.filter(function(option) { return option.id === opId }); if (optionObj[0] && !includedAssociateOptions.includes(opId)) includedAssociateOptions.push(opId); }); }; _.assign(associateModelObj, { model: associate, included: includedAssociateOptions.join(','), options: addedAssociateOptions.join(','), machine_language: haas.utils.getLanguage(), machine_region: _self.forceGLUSD ? 'GL' : haas.region.props.region, machine_currency: _self.forceGLUSD ? 'USD' : haas.region.props.currency, machine_hfo_id: haas.region.props.hfoid, discounts: [] }); if (payloadObj.machines.length > 1 && !automationModelDetails) payloadObj.machines[1] = associateModelObj; else payloadObj.machines.push(associateModelObj); } if (payloadObj.machines.length > 1 && !(associateModelDetails || automationModelDetails)) payloadObj.machines.splice(1); payloadObj.serial = serial; payloadObj.notes = packageObj.quoteNotes ? packageObj.quoteNotes : (importedPackage && importedPackage.notes) ? importedPackage.notes : ''; if (authenticated){ haas.services.createQuote.submit(payloadObj, true).then(function(res) { let payload = JSON.parse(res); let resultState = payload.success; _self.hideSubmissionLoader(); if (resultState) _self.showSuccessDialog(_self.successMessage); else _self.showErrorDialog(_self.errorMessage); }); } else { haas.services.createQuote.submit(payloadObj, false).then(function(res) { let payload = JSON.parse(res); let resultState = payload.success; _self.hideSubmissionLoader(); if (resultState) _self.showSuccessDialog(_self.successMessage); else _self.showErrorDialog(_self.errorMessage); }); } }); } }; })(); (function() { haas.components.DrilldownPackageList = haas.Component.create({ getPackageEndpoint: '/bin/haascnc/getPackage.json?package_url=', packageTreeJson: null, drilldownOptionsElem: null, drilldownPackageListObject: {}, defaultTextLevels: [], singlePackagePath: '', singleTierMode: false, initialize: function() { this.drilldownPackageListObject = new haas.objects.DrilldownPackageListObject(this.elementNode.querySelector('#ddpl-submit-btn')); this.drilldownPackageListObject.initialize(this.templates.contactFormTemplateAuthenticated, this.templates.contactFormTemplate); this.singlePackagePath = this.$element[0].querySelector('#ddpl-data-container').dataset.singlePackage; this.packageTreeJson = JSON.parse(this.$element[0].querySelector('#ddpl-data-container').dataset.pathTrees); this.drilldownOptionsElem = this.elementNode.querySelector('#ddpl-data-container'); console.log(this.singlePackagePath); if (this.singlePackagePath) this.elementNode.querySelector('#ddpl-submit-btn').disabled = false; this.defaultTextLevels = this.$element[0].querySelector('#ddpl-data-container').dataset.defaultValueTextList ? this.$element[0].querySelector('#ddpl-data-container').dataset.defaultValueTextList.split(',') : []; }, render: function() { if (!this.singlePackagePath) this.populateTopLevelChoices(); this.bindEvents(); }, populateTopLevelChoices: function() { let _self = this; let topLevelKeys = Object.keys(_self.packageTreeJson); _self.$element[0].querySelector('#ddpl-tier-0').append(_self.createDefaultOptionElement(0)); if (topLevelKeys.length == 1) { let singleTreeParentKey = topLevelKeys[0]; let singleTree = _self.packageTreeJson[singleTreeParentKey]; let drilldownOptionsData = _self.drilldownOptionsElem.dataset.drilldownOptions.split(',').filter(key => key.length); _self.singleTierMode = true; drilldownOptionsData.push(singleTreeParentKey); _self.drilldownOptionsElem.dataset.drilldownOptions = drilldownOptionsData.toString(); for (const key in singleTree) { _self.$element[0].querySelector('#ddpl-tier-0').append(_self.createOptionElement(key)); } } else { for (const key of topLevelKeys) { _self.$element[0].querySelector('#ddpl-tier-0').append(_self.createOptionElement(key)); } } }, clearAfterTier: function(tier) { let drilldownOptionsData = this.drilldownOptionsElem.dataset.drilldownOptions.split(',').filter(key => key.length); this.elementNode.querySelector('#ddpl-submit-btn').disabled = true; this.elementNode.querySelectorAll('select').forEach(selectElem => { if (Number(selectElem.dataset.tier) > tier) selectElem.remove(); }); drilldownOptionsData = drilldownOptionsData.slice(0, tier); this.drilldownOptionsElem.dataset.drilldownOptions = drilldownOptionsData.toString(); }, populateChoices: function(optionsToPopulate, tier) { // append new select let _self = this; let newSelectElement = _self.createSelectElement(tier + 1); for (let option in optionsToPopulate) { newSelectElement.append(_self.createOptionElement(option)); } _self.$element[0].querySelector('#ddpl-input-container').append(newSelectElement); _self.bindEvents(); }, createSelectElement: function(tier) { let selectElement = document.createElement('select'); selectElement.id = "ddpl-tier-" + tier; selectElement.dataset.tier = tier; selectElement.append(this.createDefaultOptionElement(tier)); return selectElement; }, createOptionElement: function(key) { let inputElement = document.createElement('option'); inputElement.value = key; inputElement.innerHTML = key; return inputElement; }, createDefaultOptionElement: function(tier) { let inputElement = document.createElement('option'); inputElement.value = ''; inputElement.innerHTML = this.defaultTextLevels[tier] ? this.defaultTextLevels[tier] : 'Select A Value'; inputElement.disabled = true; inputElement.selected = true; return inputElement; }, traverseTree: function() { let currentNode = this.packageTreeJson; let drilldownOptionsData = this.drilldownOptionsElem.dataset.drilldownOptions.split(',').filter(key => key.length); for (let key of drilldownOptionsData) { currentNode = currentNode[key]; } return currentNode; }, handleSubmitClick: function(e) { let _self = this; let finalNode = this.traverseTree(); let packagePath = this.singlePackagePath ? this.singlePackagePath : finalNode.path; let fetchPackageUrl = this.getPackageEndpoint + packagePath; fetch(fetchPackageUrl).then(res => res.json()).then(data => { _self.drilldownPackageListObject.setPackagePayload(data); _self.drilldownPackageListObject.showContactForm(_self.elementNode); }); }, handleBnpClick: function(e) { let _self = this; let finalNode = this.traverseTree(); let packagePath = this.singlePackagePath ? this.singlePackagePath : finalNode.path; let fetchPackageUrl = this.getPackageEndpoint + packagePath; fetch(fetchPackageUrl).then(res => res.json()).then(data => { window.open('/content/haascnc/'+haas.utils.getLanguage()+'/build-and-price/choose-options.'+data.machines+'.html?preconfiguredPackagePath='+packagePath, '_blank'); }); }, handleInputChange: function(e) { if (this.singleTierMode) this.clearAfterTier(1); else this.clearAfterTier(Number(e.target.dataset.tier)); let drilldownOptionsData = this.drilldownOptionsElem.dataset.drilldownOptions.split(',').filter(key => key.length); drilldownOptionsData.push(e.target.value); this.drilldownOptionsElem.dataset.drilldownOptions = drilldownOptionsData.toString(); let currentNodeObj = this.traverseTree(); if (currentNodeObj.hasOwnProperty('path')) { this.elementNode.querySelector('#ddpl-submit-btn').disabled = false; if (this.elementNode.querySelector('#ddpl-bnp-btn')) { this.elementNode.querySelector('#ddpl-bnp-btn').disabled = false; } } else { this.populateChoices(currentNodeObj, Number(e.target.dataset.tier)); } }, bindEvents: function() { let _self = this; this.elementNode.querySelectorAll('select').forEach(selectElem => selectElem.onchange = _self.handleInputChange.bind(_self)); this.elementNode.querySelector('#ddpl-submit-btn').onclick = _self.handleSubmitClick.bind(_self); if (this.elementNode.querySelector('#ddpl-bnp-btn')) { this.elementNode.querySelector('#ddpl-bnp-btn').onclick = _self.handleBnpClick.bind(_self); } } }); })(); (function() { haas.components.DrilldownLinkList = haas.Component.create({ linkTreeJson: null, drilldownOptions: [], defaultTextLevels: [], initialize: function() { this.linkTreeJson = JSON.parse(this.$element[0].querySelector('#ddll-data-container').dataset.pathTrees); this.defaultTextLevels = this.$element[0].querySelector('#ddll-data-container').dataset.defaultValueTextList ? this.$element[0].querySelector('#ddll-data-container').dataset.defaultValueTextList.split(',') : []; }, render: function() { this.populateTopLevelChoices(); this.bindEvents(); }, populateTopLevelChoices: function() { let _self = this; _self.$element[0].querySelector('#ddll-tier-0').append(_self.createDefaultOptionElement(0)); for (let key in _self.linkTreeJson) { _self.$element[0].querySelector('#ddll-tier-0').append(_self.createOptionElement(key)); } }, clearAfterTier: function(tier) { this.$element[0].querySelector('#ddll-submit-btn').disabled = true; this.$element[0].querySelectorAll('select').forEach(selectElem => { if (Number(selectElem.dataset.tier) > Number(tier)) selectElem.remove(); }); this.drilldownOptions = this.drilldownOptions.slice(0, tier); }, populateChoices: function(optionsToPopulate, tier) { // append new select let _self = this; let newSelectElement = _self.createSelectElement(Number(tier) + 1); for (let option in optionsToPopulate) { newSelectElement.append(_self.createOptionElement(option)); } _self.$element[0].querySelector('#ddll-input-container').append(newSelectElement); _self.bindEvents(); }, createSelectElement: function(tier) { let selectElement = document.createElement('select'); selectElement.id = "ddll-tier-" + tier; selectElement.dataset.tier = tier; selectElement.append(this.createDefaultOptionElement(tier)); return selectElement; }, createOptionElement: function(key) { let inputElement = document.createElement('option'); inputElement.value = key; inputElement.innerHTML = key; return inputElement; }, createDefaultOptionElement: function(tier) { console.log(this.defaultTextLevels, tier); let inputElement = document.createElement('option'); inputElement.value = ''; inputElement.innerHTML = this.defaultTextLevels[tier] ? this.defaultTextLevels[tier] : 'Select A Value'; inputElement.disabled = true; inputElement.selected = true; return inputElement; }, traverseTree: function() { let currentNode = this.linkTreeJson; for (let key of this.drilldownOptions) { currentNode = currentNode[key]; } return currentNode; }, handleSubmitClick: function(e) { let finalNode = this.traverseTree(); let finalPath = finalNode.path + '.html'; window.location = finalPath; }, handleInputChange: function(e) { this.clearAfterTier(e.target.dataset.tier); this.drilldownOptions.push(e.target.value); let currentNodeObj = this.traverseTree(); if (currentNodeObj.hasOwnProperty('path')) this.$element[0].querySelector('#ddll-submit-btn').disabled = false; else this.populateChoices(currentNodeObj, e.target.dataset.tier); }, bindEvents: function() { let _self = this; this.$element[0].querySelectorAll('select').forEach(selectElem => selectElem.onchange = _self.handleInputChange.bind(_self)); this.$element[0].querySelector('#ddll-submit-btn').onclick = _self.handleSubmitClick.bind(_self); } }); })(); /* global $, haas */ (function () { 'use strict'; var SERVICEUPDATES = ".service-update-list"; $(document).ready(function() { $(SERVICEUPDATES).each(function(){ var $thisUpdate = $(this); var $thisContainer = $thisUpdate.find('.update-container'); var SEARCHURI = $thisContainer.attr('data-search-uri'); if (window.wcmmode && window.wcmmode.edit) { $thisUpdate.show(); // always show the component in author mode } haas.search.fetchResults(SEARCHURI).then(function(data){ if(data.success === true){ var updateTemplate = _.template($('#serviceUpdateList').html()); var updates = data.result.webPages.sort(function(a,b){ return new Date(b.tags[4].content).getTime() - new Date(a.tags[4].content).getTime(); }); console.log('ALL UPDATES DATA', updates); console.log('SINGLE DATE', new Date(updates[0].tags[4].content).getTime()); if(updates.length){ var updateData = ''; _.each(updates, function(update, index) { var title = update.title; var path = haas.search.insertAlarmSelectorInHTMLURI(update.path); var description = ''; var docType = update.tags[0].content; var date = ''; var dateTime = ''; var alarmList = ''; var alarmArray = []; _.each(update.tags, function(tag, index){ if(tag.name === 'serviceUpdateDescription'){ description = tag.content; } if(tag.name === 'serviceUpdateDate'){ date = tag.content; } if(tag.name === 'lastUpdated'){ console.log('TAG CONTENT', new Date(tag.content)); dateTime = new Date(tag.content).toString().split(' '); console.log('DATETIME TAG', dateTime); date = dateTime[1] + ' ' + dateTime[2] + ', ' + dateTime[3]; } if(tag.name === 'localizedAlarms'){ alarmList = tag.content.replace(/-/g, ' • '); alarmArray = alarmList.split(','); } }); updateData += updateTemplate({ 'title' : title, 'docType': docType, 'path' : path, 'description' : description, 'date' : date, 'alarmArray' : alarmArray }); }); console.log('UPDATESLIST', updateData); $thisContainer.html(updateData); $thisUpdate.show(); } } else{ haas.LOGGER.warn(data.error.message); } }); }); }); })(); $(document).ready(function() { }); /* global $, haas */ (function () { 'use strict'; // there may be multiple instances of this component on one page, // so we need to iterate through them $(document).ready(function() { var $DOCSEARCHCTAS = $('.document-search-CTA'); if($DOCSEARCHCTAS.length > 0){ $DOCSEARCHCTAS.each(function(){ var $thisCTA = $(this); var $thisSelect = $thisCTA.find('select.document-year'); var $thisHiddenDiv = $thisCTA.find('.document-search-CTA-hidden'); var $thisResultsDiv = $thisHiddenDiv.find('.document-search-CTA-results'); var $thisErrorDiv = $thisHiddenDiv.find('.document-search-CTA-error'); var baseSearchURI = $thisHiddenDiv.attr('data-search-uri'); var $thisButton = $thisCTA.find('.btn-submit'); // disable search button if year is not selected $thisButton.addClass('disabled').prop('disabled', true); $thisSelect.change(function(){ var thisYear = $thisSelect.val(); if(thisYear !== 'default'){ $thisButton.removeClass('disabled').prop('disabled', false); var newSearchURI = baseSearchURI.replace('%s', thisYear); $thisButton.attr('data-search-uri-complete', newSearchURI); } else { $thisButton.addClass('disabled').prop('disabled', true); } }); $thisButton.click(function(e){ e.preventDefault(); var searchURI = $thisButton.attr('data-search-uri-complete'); // disable the current button, as well as any other buttons // so that multiple searches can't be submitted at once $DOCSEARCHCTAS.find('.btn-submit').addClass('disabled').prop('disabled', true); //open modal with spinning loading logo while search results are fetched haas.bus.modal.publish({loading: true, content: '', isOpen: true}); // fetch search results haas.search.fetchResults(searchURI).then(function(data){ var modalContent; var isError = false; if (data.success && data.result.totalEstimatedMatches > 0){ if(data.result.totalEstimatedMatches === 1){ // if only one result, and the result has a path, open that result in a new window var entry = data.result.webPages[0]; if(entry.path){ window.location.assign(entry.path); return; } else { haas.LOGGER.error('Search error: single entry had no path'); //populate modal content with error message modalContent = $thisErrorDiv.html(); } } else { // if more than one result, open a modal showing the results var searchResults = data.result.webPages; var searchResultTemplate = _.template($('#document-search-CTA-template').html()); var resultList = ''; // compile results into HTML _.each(searchResults, function (result, index) { var type = ''; _.each(result.tags, function (tag, index) { if (tag.name === 'localizedContentType') { type = tag.content; } }); resultList += searchResultTemplate({ 'path': result.path, 'title': result.title, 'type': type }); }); // add results to hidden div $thisResultsDiv.find('.document-search-CTA-results-content').html(resultList); //populate modal content with results modalContent = $thisResultsDiv.html(); } } else { var errMsg = (data.hasOwnProperty('error')) ? data.error.message : 'No results found.'; haas.LOGGER.error('A search error has occurred: ' + errMsg); //populate modal content with error message modalContent = $thisErrorDiv.html(); } //publish modal if(modalContent !== ''){ haas.bus.modal.publish({loading: false, content: modalContent, isOpen: true}); $('.haas-modal-body').addClass('document-search-CTA-modal'); // re-enable any eligible buttons $DOCSEARCHCTAS.find('.btn-submit').each(function(){ var $this = $(this); var $siblingSelect = $this.parent().find('select.document-year'); if($siblingSelect.val() !== 'default' && $siblingSelect.val() !== null){ $this.removeClass('disabled').prop('disabled', false); } }); } else { haas.components.Modal.close(); } }); }); }); } }); })(); /* global haas, $, waypoints.js */ $(document).ready(function() { if($('#service-sub-navigation-sticky-nav').length !== 0){ var $subnav = $('#service-sub-navigation-sticky-nav'); // sticky navigation, using waypoints.js var wrapperID = 'service-sub-navigation-sticky-wrapper'; var subnavID = 'service-sub-navigation-sticky-nav'; var targetID ='waypoint-target'; haas.utils.targetSticky(wrapperID, targetID, subnavID); // open select on hover var $select = $('#service-sub-navigation-select'); var $optionContainer = $select.find(".option-container"); var $default = $select.find("a.option.default"); $optionContainer.mouseenter(function() { $select.addClass( "open" ); }); $optionContainer.mouseleave(function() { $select.removeClass( "open" ); }); // open select on click for mobile; $default.click(function(e) { e.preventDefault(); $select.toggleClass("open" ); }); // scroll to hash when option is clicked $("a.option:not(.default)").click(function(e) { var $this = $(this), href = $this.attr('href'), position = $(href).offset().top, subNavHeight = $subnav.outerHeight(); e.preventDefault(); $select.removeClass('open'); $('html, body').animate({ scrollTop: $(href).offset().top - $subnav.outerHeight() }, 750); $this.siblings().removeClass('selected'); $this.addClass('selected'); }); // scroll to top when back-to-top is clicked $("a.back-to-top").click(function(e) { var $this = $(this); e.preventDefault(); $select.removeClass('open'); $('html, body').animate({ scrollTop: 0 }, 750); $this.siblings().removeClass('selected'); }); $('.printCTA').off('click').on('click', function(e) { e.preventDefault(); var curPage = window.location.href; var cssPage = 'http://data.haascnc.com/printfriendly.css'; var endpoint = 'https://api.printfriendly.com/v2/pdf/create?api_key=eddaa736a3ecaaab4a0031e197a376f0' + '&page_url=' + curPage + '&css_url=' + cssPage; $.get(endpoint).then(function(res) { var pdfSrc = res.file_url; window.open(pdfSrc); }) }); if(window.location.href.indexOf('/service') < 0) $('.diySubNavigation').hide(); } }); $(document).ready(function() { $(".diy-step").each(function() { var $this = $(this); var $tag = $this.find(".recently-updated-tag"); // if not authored to show the tag, then no need to compare timestamps if ($tag.length === 0) { return; } var compareDate = new Date(); // now compareDate.setDate(compareDate.getDate() - $this.data("recentness-duration")); // 30 days ago if ($this.data("last-modified-timestamp") > compareDate.getTime()) { $tag.removeClass("hidden"); } }) }); /* global $, haas */ (function () { 'use strict'; // there may be multiple instances of this component on one page, // so we need to iterate through them $(document).ready(function() { var $SEARCHRESULTS = $('.prefiltered-search-results'); $SEARCHRESULTS.each(function(){ var $this = $(this); var SEARCHURI = $this.attr('data-search-uri'); var alarmCodeString = decodeURIComponent(SEARCHURI); var alarmCodeTerm = alarmCodeString.substring(alarmCodeString.indexOf('search.alarms:' ), alarmCodeString.indexOf('"]&setLang')).replace('search.alarms:+"', ''); if (window.wcmmode && window.wcmmode.edit) { $this.parents('.prefiltered-search-wrapper').removeClass('hidden').show(); // always show the component in author mode } haas.search.fetchResults(SEARCHURI).then(function(data){ if(data.success === true){ var updateTemplate = _.template($('#prefilteredSearch').html()); var updates = data.result.webPages; if(updates.length){ var updateData = ''; _.each(updates, function(update, index) { var title = update.title; var path = haas.search.insertAlarmSelectorInHTMLURI(update.path); var type = ''; var causeCount = ''; var alarmArray = []; var localizedAlarmArray = []; var firstAlarm =''; _.each(update.tags, function(tag, index){ if(tag.name === 'localizedContentType'){ type = tag.content; } if(tag.name === 'possibleCauses'){ causeCount = tag.content; } if(tag.name === 'alarms') { alarmArray = tag.content.split(','); } if(tag.name === 'localizedAlarms') { localizedAlarmArray = tag.content.replace(/-/g, ' • ').split(','); } }); // Display only the alarm that's being searched (on the alarm search page) if (alarmCodeTerm && alarmArray && localizedAlarmArray && alarmArray.length === localizedAlarmArray.length) { for (var i = 0; i < alarmArray.length; i++) { var alarm = alarmArray[i]; if (alarm === alarmCodeTerm) { firstAlarm = localizedAlarmArray[i]; break; } } } updateData += updateTemplate({ 'title' : title, 'path' : path, 'type' : type, 'causeCount' : causeCount, 'firstAlarm' : firstAlarm }); }); $this.html(updateData).parents('.prefiltered-search-wrapper').removeClass('hidden').show(); } } else{ haas.LOGGER.warn(data.error.message); } }); }); }); })(); /* global $, haas, priceGroupPromise */ (function () { 'use strict'; var MODAL = '.haas-modal'; var ISADVANCEDSEARCHRESULTSPAGE = ($('.diyAdvancedSearch').length > 0); var SEARCHCONTAINER = '.search-container'; var SEARCHBUTTON = '.diy-advanced-search-button'; var SEARCHFORM = '#search-filter-form'; var MOBILEFILTERBUTTON = '#mobile-filter-button'; var SEARCHRESULTS = '#search-results'; var ENDPOINT = haas.constants.api.search; var RESETFILTERS = '.reset-filters'; var QUERYFIELD = '#diy-advanced-search-query'; var FILTERBUTTONCONTAINER = '.filter-button-container'; var FILTERBUTTONS = '.filter-button'; var CONTENTTYPES = '.content-type-checkbox'; var CATEGORYHEADERS = 'li.category'; var POPULARTOPICS = '.popular-topic-checkbox'; var YEAR = '.year-checkbox'; var DIAGRAM = '.diagram-checkbox'; var CATEGORY = '.category'; var PRIMARY = '.primary'; var CATEGORY_HEADER_INNER = '.category-header-inner'; var CATEGORY_SUBMENU = '.submenu'; var CATEGORY_SUB_INNER = '.category-sub-inner'; var TOPIC_HEADER_INNER = '.topic-header-inner'; var TOPIC_SUBMENU = '.subsubmenu'; var TOPIC_SUB_INNER = '.topic-sub-inner'; var VIEWCOUNTS = '.view-count'; var CURRENTCOUNT = '15'; var RESULTCOUNT = 0; var RESULTSCONTAINER = '#results-container'; var PAGINATION = '#pagination'; var CURRENTREGION = ''; var SEARCHURI = ''; var NORESULTS = ''; (function () { 'use strict'; var haas = window.haas || {}; haas.advancedSearch = { bindAll: function($searchForm, submitFormOnChecked){ var self = haas.advancedSearch; var $categoryHeaders = $searchForm.find(CATEGORYHEADERS); var $queryField = $searchForm.find(QUERYFIELD); var $searchButton = $searchForm.find(SEARCHBUTTON); var $resetFilters = $searchForm.find(RESETFILTERS); self.bindCheckboxes($searchForm, submitFormOnChecked); self.bindQueryField($queryField, $searchButton); self.bindFilterButtons($searchForm, submitFormOnChecked); self.bindResetFilters($searchForm, $resetFilters, $categoryHeaders); self.bindSearchButton($searchForm, $searchButton, $queryField); if(!submitFormOnChecked){ self.overrideModalClose(); } }, bindCheckboxes: function($searchForm, submitForm) { $searchForm.find('input[type=checkbox]').change(function(e) { var $this = $(this); var $container = $this.parent('span').parent('li'); // only go up one level // accordion submenu if it's a category header if ($container.hasClass('category') && $this.hasClass('header-checkbox')){ if(!$container.hasClass('open')){ // open the accordion if it's closed $container.addClass('open'); } else if($container.hasClass('open')) { // uncheck child checkboxes $container.find('input[type=checkbox]').filter(':checked').each(function(){ $(this).prop('checked', false).removeAttr('checked'); }); // close any open child accordions $container.find('.category.open').each(function(){ $(this).removeClass('open'); }); // close the accordion if it's unchecked $container.removeClass('open'); } } // or if category header and all submenu checkboxes are unchecked if ($container.find('input[type=checkbox]').filter(':checked').length === 0){ $container.removeClass('open'); } if($container.find('input[type=checkbox]').filter(':checked').length === 0){ $container.removeClass('open'); } // allows checkboxes to remain checked when inside mobile modal if($this.attr('checked') === "checked"){ $this.removeAttr('checked'); } else { $this.attr('checked', 'checked'); } if(submitForm){ // resubmit form when checked $searchForm.find(SEARCHBUTTON).trigger('click'); } }); }, bindQueryField: function($queryField, $searchButton) { $queryField.off().keyup(function(e) { if (e.keyCode === 13) { e.preventDefault(); $searchButton.trigger('click'); } }); }, bindResetFilters: function($parent, $resetButton, $categoryHeaders) { $resetButton.off().click(function(e){ e.preventDefault(); $categoryHeaders.removeClass('open'); haas.advancedSearch.setupCheckBoxes($parent, $categoryHeaders); }); }, bindSearchButton: function($searchForm, $searchButton, $queryField) { $searchButton.off().click(function(e){ e.preventDefault(); if($queryField.val() && $searchForm.find(FILTERBUTTONS).length < 5){ var value = $queryField.val().replace(/"/g, "").trim(); // remove all quotes from query and trim leading/trailing whitespace if (value.length > 0) { // only apply query if it's not empty haas.advancedSearch.createFilterButton($searchForm, value); } $queryField.val(''); } haas.advancedSearch.buildQuery(0, CURRENTCOUNT); haas.advancedSearch.fetchResults(SEARCHURI, true); if(haas.bus.modal.state.isOpen === true){ haas.advancedSearch.stashMobileSearch(); haas.components.Modal.close(); } }); }, /** * Build popular topics term string like the following examples: * ("Vertical" && ("Anchoring, Installation and Leveling" || ("Air-Lubrication Systems" && ("Bijur Mechanical Lubrication" || "MQL"))) || ("Horizontal" && "Casting") * ("Vertical" && ("Anchoring, Installation and Leveling" || ("Air-Lubrication Systems" && "Bijur Mechanical Lubrication"))) || ("Horizontal" && "Casting") * ("Vertical" && ("Anchoring, Installation and Leveling" || "Air-Lubrication Systems")) || ("Horizontal" && "Casting") * ("Vertical" && "Air-Lubrication Systems") || ("Horizontal" && "Casting") * "Vertical" || "Horizontal" * "Vertical" && "Air-Lubrication Systems" * "Vertical" * @param $parent parent element * @returns {string} popular topics term string, or an empty string if there are none */ buildPopularTopicsTerm: function($parent) { var term = ""; var orClauses = []; var $primaryTopics = $parent.find(CATEGORY + PRIMARY); $primaryTopics.each(function() { var $this = $(this); var subTerm = ""; var $primaryHeader = $this.find(CATEGORY_HEADER_INNER); var $secondaryMenu = $this.find(CATEGORY_SUBMENU); if ($primaryHeader.length > 0 && $secondaryMenu.length > 0) { var subOrClauses = []; var $primaryTopic = $primaryHeader.find(POPULARTOPICS); var $secondaryTopics = $this.find(CATEGORY_SUB_INNER); $secondaryTopics.each(function() { var $this = $(this); var subclause = ""; var $tertiaryMenu = $this.find(TOPIC_SUBMENU); var $secondaryTopic; if ($tertiaryMenu.length > 0) { var $secondaryHeader = $this.find(TOPIC_HEADER_INNER); $secondaryTopic = $secondaryHeader.find(POPULARTOPICS); var $checkedTertiaryTopics = $($tertiaryMenu[0]).find(POPULARTOPICS).filter(':checked'); if ($checkedTertiaryTopics.length > 0) { // automatically add the secondary topic (even if it's not checked) subclause += '"' + $secondaryTopic.val() + '" && '; var subvalues = []; $checkedTertiaryTopics.each(function () { subvalues.push('"' + $(this).val() + '"'); }); if (subvalues.length > 1) { subclause += '(' + subvalues.join(' || ') + ')'; } else if (subvalues.length === 1) { subclause += subvalues[0]; } } else if ($secondaryTopic.prop("checked")) { subclause += '"' + $secondaryTopic.val() + '"'; } } else { $secondaryTopic = $this.find(POPULARTOPICS); if ($secondaryTopic.prop("checked")) { subclause += '"' + $secondaryTopic.val() + '"'; } } if (subclause.length > 0) { subOrClauses.push(subclause); } }); if (subOrClauses.length > 1) { // automatically add the primary topic (even if it's not checked) subTerm += '"' + $primaryTopic.val() + '" && ('; var subClause; while (subOrClauses.length > 1) { subClause = subOrClauses.shift(); subTerm += (subClause.indexOf(' && ') > -1) ? '(' + subClause + ')' : subClause; subTerm += ' || '; } subClause = subOrClauses.pop(); subTerm += (subClause.indexOf(' && ') > -1) ? '(' + subClause + ')' : subClause; // nested clause must be surrounded with quotes subTerm += ')'; } else if (subOrClauses.length === 1) { // automatically add the primary topic (even if it's not checked) subTerm += '"' + $primaryTopic.val() + '" && '; subTerm += subOrClauses[0]; } } else { var $primaryTopic = $this.find(POPULARTOPICS); if ($primaryTopic.prop("checked")) { subTerm += '"' + $primaryTopic.val() + '"'; } } if (subTerm.length > 0) { orClauses.push(subTerm); } else if ($primaryTopic.prop("checked")) { subTerm += '"' + $primaryTopic.val() + '"'; orClauses.push(subTerm); } }); if (orClauses.length > 1) { var clause; while (orClauses.length > 1) { clause = orClauses.shift(); term += (clause.indexOf(' && ') > -1) ? '(' + clause + ')' : clause; term += ' || '; } clause = orClauses.pop(); term += (clause.indexOf(' && ') > -1) ? '(' + clause + ')' : clause; // nested clause must be surrounded with quotes } else if (orClauses.length > 0) { term = orClauses.pop(); } return term; }, buildQuery: function(offset, count) { // if there are any grey filter buttons, build querystring var hasLeadingTerm = false; var queryString = ''; var URIQuery = ''; var $parent = (haas.bus.modal.state.isOpen === true) ? $(MODAL) : $(SEARCHCONTAINER); var $queryButtonCount = $parent.find('.filter-button'); if ($queryButtonCount.length){ URIQuery += 'keywords='; var keywordTerms = []; $queryButtonCount.each(function(i){ keywordTerms.push('"' + $(this).attr('data-value') + '"'); URIQuery += $(this).attr('data-value'); if (($queryButtonCount.length > 1) && ((i + 1) !== $queryButtonCount.length)) { URIQuery += ',' } }); if(keywordTerms.length > 0){ queryString += keywordTerms.join(' && '); } } if (queryString.length > 0) { hasLeadingTerm = true; } // if there are checked content types, build content types querystring var $contentTypesCount = $parent.find(CONTENTTYPES).filter(':checked'); var contentTypeString = ""; if ($contentTypesCount.length) { if (hasLeadingTerm) { contentTypeString += ' && '; URIQuery += '&'; } contentTypeString += '[search.contentType: '; URIQuery += 'contentTypes='; $contentTypesCount.each(function (i) { var $this = $(this); contentTypeString += '"' + $this.val() + '"'; URIQuery += $this.val(); if (($contentTypesCount.length > 1) && ((i + 1) !== $contentTypesCount.length)) { contentTypeString += ' || '; URIQuery += ','; } }); contentTypeString += ']'; } if (contentTypeString.length > 0) { hasLeadingTerm = true; } var $yearCount = $parent.find(YEAR).filter(':checked'); var yearString = ""; if ($yearCount.length) { if (hasLeadingTerm) { yearString += ' && '; URIQuery += '&'; } yearString += '[search.years: '; URIQuery += 'years='; $yearCount.each(function (i) { var $this = $(this); yearString += '"' + $this.val() + '"'; URIQuery += $this.val(); if (($yearCount.length > 1) && ((i + 1) !== $yearCount.length)) { yearString += ' || '; URIQuery += ','; } }); yearString += ']'; } if (yearString.length > 0) { hasLeadingTerm = true; } var $diagramCount = $parent.find(DIAGRAM).filter(':checked'); var diagramString = ""; if ($diagramCount.length) { if (hasLeadingTerm) { diagramString += ' && '; URIQuery += '&'; } diagramString += '[search.diagrams: '; URIQuery += 'diagrams='; var diagrams = []; var diagramsQuotes = []; $diagramCount.each(function(i) { diagrams.push($(this).val()); diagramsQuotes.push('"' + $(this).val() + '"'); }); diagramString += diagramsQuotes.join(' || '); URIQuery += diagrams.join(','); diagramString += ']'; } if (diagramString.length > 0) { hasLeadingTerm = true; } // if there are checked popular topics, build popular topics querystring // note that popular topics uses the data-hash-value attribute to build the URL hash // and select its checkboxes // This is because multiple topics share the same subtopics // e.g., Vertical, Horizontal, and Lathe topics each have an entry for "Bijur Mechanical Lubrication" var popularTopicsTerm = this.buildPopularTopicsTerm($parent); var popularTopicsString = ""; if (popularTopicsTerm.length > 0) { if (hasLeadingTerm) { popularTopicsString += ' && '; URIQuery += '&'; } popularTopicsString += '[search.popularTopics: ' + popularTopicsTerm + ']'; URIQuery += 'popularTopics='; var $popularTopicsCount = $parent.find(POPULARTOPICS).filter(':checked'); $popularTopicsCount.each(function (i) { var $this = $(this); URIQuery += $this.attr('data-hash-value'); if (($popularTopicsCount.length > 1) && ((i + 1) !== $popularTopicsCount.length)) { URIQuery += ','; } }); } if (popularTopicsString.length > 0) { hasLeadingTerm = true; } haas.LOGGER.log('raw querystring: ' + queryString + contentTypeString + yearString + diagramString + popularTopicsString); haas.LOGGER.log('raw URIQuery: ' + URIQuery); var encodedQuery = encodeURIComponent(encodeURIComponent(queryString) + contentTypeString + yearString + diagramString + popularTopicsString); SEARCHURI = ENDPOINT + '?type=diy&q=' + encodedQuery + '&setLang=' + CURRENTREGION + '&offset=' + offset + '&count=' + count; haas.LOGGER.log('encoded search url: ' + SEARCHURI); // add search query to current URL window.location.hash = encodeURIComponent(URIQuery); return SEARCHURI; }, bindFilterButtons: function($parent, submitForm){ // use of 'on' instead of standard click binding // is to ensure that the pagination links work // after being dynamically generated $parent.on('click', FILTERBUTTONS, function(e){ e.preventDefault(); $(this).remove(); if(submitForm){ haas.advancedSearch.buildQuery(0, CURRENTCOUNT); haas.advancedSearch.fetchResults(SEARCHURI, true); } }); }, createFilterButton: function($parent, queryString){ // Strip any HTML that might be present in input (from user or from url query param) // Strip full tags as well as individual left or right angle brackets queryString = queryString.replace(/(<([^>]+)>)|<|>|&|#|;|%/ig,""); // TODO: use a XSS sanitizing library instead $parent.find(FILTERBUTTONCONTAINER).append(''+ queryString + '') }, fetchResults: function(SEARCHURI, rebuildPagination){ // fade in loading graphic $(SEARCHRESULTS).fadeOut(200, function(){ $(SEARCHRESULTS).html('Loading').fadeIn(200); }); // fade out pagination if rebuilding if(rebuildPagination){ $(PAGINATION).fadeOut(200); } // disable all items that can submit until the search results are returned $('.can-submit').addClass('disabled').prop('disabled', true); haas.search.fetchResults(SEARCHURI).then(function(data){ var searchResultTemplate = _.template($('#advancedSearchResults').html()); var resultList = ''; if (data.success){ var searchResults = data.result.webPages; RESULTCOUNT = data.result.totalEstimatedMatches; if(searchResults.length){ _.each(searchResults, function(result, index) { var type = ''; _.each(result.tags, function(tag, index){ if(tag.name === 'localizedContentType'){ type = tag.content; } }); resultList +=searchResultTemplate({ 'path' : result.path, 'title' : result.title, 'type' : type }); }); if(rebuildPagination) { haas.advancedSearch.setPagination(RESULTCOUNT, CURRENTCOUNT); } } else { resultList = NORESULTS; RESULTCOUNT = 0; } } else { resultList = NORESULTS; RESULTCOUNT = 0; haas.LOGGER.error('A search error has occurred: ' + data.error.message); } haas.advancedSearch.populateResults($(SEARCHRESULTS), resultList); haas.advancedSearch.updateResultsCount(RESULTCOUNT); // re-enable all items that can submit $('.can-submit').removeClass('disabled').prop('disabled', false); }); }, overrideModalClose: function(){ $('.modal-close-btn').off().on('click', function(e){ haas.advancedSearch.stashMobileSearch(); haas.components.Modal.close(); }); }, populateResults: function($target, resultString){ $target.fadeOut(200, function(){ $target.html(resultString).fadeIn(200); }); }, setPagination:function(resultCount, currentCount){ var numberOfPages = Math.ceil(Number(resultCount) / Number(currentCount)); var paginationString = ''; if(numberOfPages === 0){ return false; } else if (numberOfPages === 1){ paginationString += '1'; } else{ for(var i = 0; i < numberOfPages; i++){ var pageNumber = (i+1); paginationString += '' + pageNumber + ''; if(pageNumber !== numberOfPages){ paginationString += ' | '; } } } $(PAGINATION).html(paginationString).fadeIn(200); }, setupCategoryHeaders: function($categoryHeaders) { $categoryHeaders.each(function(){ var $this = $(this); if($this.find('input[type=checkbox]').is(":checked")) { $this.addClass('open'); } }) }, setupCheckBoxes: function($parent){ $parent.find('input[type=checkbox]').each(function(){ var $checkbox = $(this); if($checkbox.attr('data-initial-check') === "true"){ $checkbox.attr('checked', 'checked').prop('checked', true); } else { $checkbox.removeAttr('checked').prop('checked', false); } }); haas.advancedSearch.setupCategoryHeaders($parent.find(CATEGORYHEADERS)); }, setupQueryStringValues: function($parent, currentQuery){ // if there's search criteria stashed in the hash var queryArray = decodeURIComponent(currentQuery).replace("#", '').split('&'); if(queryArray.length){ // first split the string and use it to separate checkbox and filter button values var keywordArray =[]; var checkboxArray =[]; var $checkboxes = $parent.find('input[type=checkbox]'); _.each(queryArray, function(query){ var pair = query.split('='); var itemArray = (pair[1]) ? pair[1].split(',') : []; if (pair[0] === 'keywords'){ keywordArray = itemArray; } else if ( (pair[0] === 'contentTypes') || (pair[0] === 'years') || (pair[0] === 'popularTopics')){ if(checkboxArray.length){ if(itemArray.length){ checkboxArray = checkboxArray.concat(itemArray); } } else{ checkboxArray = itemArray; } } }); // wipe all existing checkboxes' preset values $checkboxes.removeAttr('checked').removeAttr('data-initial-check').prop('checked', false); // create filter buttons if(keywordArray.length){ _.each(keywordArray, function(keyword){ haas.advancedSearch.createFilterButton($parent, keyword); }); } // recheck checkboxes // Note that popular topic checkboxes use the data-hash-value attribute // instead of value to build the URL hash and select its checkboxes // This is because multiple topics share the same subtopics // e.g., Vertical, Horizontal, and Lathe topics each have an entry for "Bijur Mechanical Lubrication" if(checkboxArray.length){ $checkboxes.each(function(){ var $checkbox = $(this); if( (!$checkbox.hasClass('popular-topic-checkbox') && checkboxArray.indexOf($checkbox.attr('name')) !== -1) || ($checkbox.hasClass('popular-topic-checkbox') && checkboxArray.indexOf($checkbox.attr('data-hash-value')) !== -1)){ $checkbox.attr('data-initial-check' , true).attr('checked', 'checked').prop('checked', true); } }); } } haas.advancedSearch.setupCategoryHeaders($parent.find(CATEGORYHEADERS)); }, stashMobileSearch: function(){ $(SEARCHCONTAINER).find(SEARCHFORM).html($(MODAL).find(SEARCHFORM).html()); }, updateResultsCount: function(resultsCount){ $(RESULTSCONTAINER).html(resultsCount); } }; })(); $(document).ready(function() { if(ISADVANCEDSEARCHRESULTSPAGE) { var self = haas.advancedSearch; var hash = window.location.hash; var currentQuery = (hash) ? hash : null; CURRENTREGION = haas.utils.getLanguage(); var $searchResults = $(SEARCHRESULTS); var errorLine1 = $searchResults.data("errorline1"); var errorLine2 = $searchResults.data("errorline2"); NORESULTS = '
    '+errorLine1+'.
    '+errorLine2+'
    '; var $searchForm = $(SEARCHFORM); // if this is an Advanced Search Results Page, // and if there's search criteria in the hash, // treat that as the initial setup values if (currentQuery) { self.setupQueryStringValues($searchForm, currentQuery); } else { // otherwise set up the checkboxes with their initial values self.setupCheckBoxes($searchForm); } self.bindAll($searchForm, true); $(VIEWCOUNTS).click(function (e) { e.preventDefault(); var $view = $(this); $('.pageSize').find('.selected').removeClass('selected'); $view.addClass('selected'); CURRENTCOUNT = $view.attr('data-count'); self.buildQuery(0, CURRENTCOUNT); self.fetchResults(SEARCHURI, true); }); $(MOBILEFILTERBUTTON).click(function (e) { e.preventDefault(); haas.components.Modal.open($(SEARCHFORM).parent().html()); var $searchForm = $(MODAL).find(SEARCHFORM); self.bindAll($searchForm, false); }); var scrollTop = $(window).scrollTop(); var elementOffset = $('.search-container').offset(); // need to check if element offset exists before accessing .top // otherwise it throws a TypeError if (elementOffset) { elementOffset = elementOffset.top - 25; $(window).scroll(function () { scrollTop = $(window).scrollTop(); if (scrollTop > elementOffset) { $('#search-filter-form').addClass('search-form-sticky'); } if (scrollTop < elementOffset) { $('#search-filter-form').removeClass('search-form-sticky'); } }); } // use of 'on' instead of standard click binding // is to ensure that the pagination links work // after being dynamically generated $('#pagination').on('click', 'a.pagination-link', function (e) { e.preventDefault(); var $this = $(this); self.buildQuery($this.attr('data-offset'), CURRENTCOUNT); self.fetchResults(SEARCHURI, false); $this.siblings('a.current-page').removeClass('current-page'); $this.addClass('current-page'); }); // run the values pre-selected in the checkboxes self.buildQuery(0, CURRENTCOUNT); self.fetchResults(SEARCHURI, true); } }); })(); /* global haas, _, $, LZString */ (function () { 'use strict'; var PersistedCache = haas.utils.PersistedCache; var alarmListUrl = haas.constants.api.alarmList; haas.services.alarmService = { cache: new PersistedCache('alarmList'), getAlarmList: function () { var self = this; var cached = self.cache.get(); if (cached && !_.isEmpty(cached)) { return Promise.resolve(cached); } return $.getJSON(alarmListUrl).then(function (alarmList) { self.cache.set(alarmList.result); return alarmList.result; }); } }; })(); /* global $, _, haas */ (function () { 'use strict'; haas.components.AlarmQuickSearch = haas.Component.create({ host : '', defaultUrl : '', initialized : false, initialize: function () { let self = this; // need to change z-index of body here for modal to show correctly document.querySelector('.page__main').style.zIndex = 'auto'; self.host = window.location.protocol + "//" + window.location.host; self.elementNode.querySelector('.search-expanded .search-form').style.opacity = 1.0; self.bindEvents(); }, activeSearchToggle: function() { let self = this; if (self.elementNode.querySelector('.alarm-quick-search').classList.contains('search-expanded')) { self.elementNode.querySelector('.alarm-quick-search').classList.remove('search-expanded'); self.elementNode.querySelector('.alarm-quick-search .search-form').style.display = 'none'; self.elementNode.querySelector('.advanced-quick-search').classList.remove('search-collapsed'); self.elementNode.querySelector('.alarm-quick-search').classList.add('search-collapsed'); self.elementNode.querySelector('.advanced-quick-search').classList.add('search-expanded'); $(self.elementNode.querySelector('.advanced-quick-search .search-form')).delay(100).fadeTo(500, 1.0); } else if (self.elementNode.querySelector('.advanced-quick-search').classList.contains('search-expanded')) { self.elementNode.querySelector('.advanced-quick-search').classList.remove('search-expanded'); self.elementNode.querySelector('.advanced-quick-search .search-form').style.display = 'none'; self.elementNode.querySelector('.alarm-quick-search').classList.remove('search-collapsed'); self.elementNode.querySelector('.advanced-quick-search').classList.add('search-collapsed'); self.elementNode.querySelector('.alarm-quick-search').classList.add('search-expanded'); $(self.elementNode.querySelector('.alarm-quick-search .search-form')).delay(100).fadeTo(500, 1.0); } }, handleInputChange: function(e) { let self = this; let inputVal = e.target.value; if (inputVal && inputVal.length && e.keyCode === 13) self.elementNode.querySelector('#alarm-quick-search-button-self').click(); else if (inputVal && inputVal.length) self.elementNode.querySelector('#alarm-quick-search-button-self').classList.remove('disabled'); else self.elementNode.querySelector('#alarm-quick-search-button-self').classList.add('disabled'); }, renderLoader: function() { let self = this; self.elementNode.querySelector('.alarm-expanded .search-form').classList.add('hidden'); self.elementNode.querySelector('.alarm-loader').classList.remove('hidden'); document.querySelector('body').style.cursor = 'wait'; }, removeLoader: function() { // remove loading state let self = this; document.querySelector('body').style.cursor = 'default'; self.elementNode.querySelector('.alarm-expanded .search-form').classList.remove('hidden'); self.elementNode.querySelector('.alarm-loader').classList.add('hidden'); }, handleAlarmSearch: function(e) { let self = this; let alarmQuery = self.elementNode.querySelector('.alarm-quick-search input#alarm-search').value.trim(); let isCodeSearch = alarmQuery.includes('.') ? true : false; // show that query is pending let pendingQuery = new Promise((res, rej) => { self.renderLoader(); setTimeout(() => { res(); }, 500) }) pendingQuery.then(() => { return haas.services.alarmService.getAlarmList() }) .then(alarmList => { let matches = alarmList.filter(alarm => isCodeSearch ? alarm.code === alarmQuery : alarm.base === alarmQuery); if (!matches.length) { self.removeLoader(); haas.components.Modal.open(self.templates.noMatchingAlarmModal()); } else if (matches.length === 1) { let alarmCode = matches[0].code, alarmType = matches[0].type; window.location = self.createAlarmURL(alarmCode, alarmType.toLowerCase()); } else if (matches.length > 1) { let alarmCode = matches[0].code; if (!matches.every(alarm => alarm.code === alarmCode)) { self.removeLoader(); haas.components.Modal.open(self.templates.noMatchingAlarmModal()); } else { let alarmLinkList = []; matches.forEach(alarm => { alarmLinkList.push(self.createAlarmURL(alarm.code, alarm.type.toLowerCase())); }); self.removeLoader(); haas.components.Modal.open(self.templates.multipleTypesModal({ alarmMatches: matches, alarmLinks: alarmLinkList })); self.bindAlarmModalEvents(); } } }); }, handleServiceQSEnterKey: function(e) { let self = this; let keywords = self.elementNode.querySelector('#service-quick-search-input').value; if (e.keyCode === 13 && keywords.length) self.elementNode.querySelector('#service-quick-search-button').click(); }, handleAdvancedSearch: function(e) { let self = this; let keywords = self.elementNode.querySelector('#service-quick-search-input').value; let bcsModalContent = document.querySelector('.bcs-modal .bcs-modal-body .bcs-results'); haas.bcsServiceSearch.resetOffset(); document.querySelector('.bcs-pagination a.bcs-current-page').innerText = '1'; if (window.innerWidth <= 800) { bcsModalContent = document.querySelector('#mobile-search-box-container .bcs-modal .bcs-modal-body .bcs-results'); } haas.bcsServiceSearch.performSearch(keywords).then(res => { let webPages = (res.webPages && res.webPages.value) ? res.webPages.value : []; if (webPages && webPages.length) { let resultTemplate = _.template(document.querySelector('#pageResultTemplate').innerHTML); // empty container of results bcsModalContent.innerHTML = ''; // populate container with results webPages.forEach(function(page) { bcsModalContent.innerHTML = bcsModalContent.innerHTML + resultTemplate({ page_link: page.url, page_title: page.name, page_caption:page.snippet }); }); if (window.innerWidth <= 800) { document.querySelector('.search_box_top_wrapper').style.display = 'block'; document.querySelector('#mobile-search-box-container .bcs-modal').classList.add('bcs-service-search'); document.querySelector('#mobile-search-box-container .bcs-pagination-container').style.display = 'block'; document.querySelector('#mobile-search-box-container .bcs-modal').style.display = 'block'; } else { document.querySelector('.bcs-modal').classList.add('bcs-service-search'); document.querySelector('.bcs-pagination-container').style.display = 'block'; document.querySelector('.bcs-modal').style.display = 'block'; } } else { console.log('NO RESULTS for ', keywords); let noResultTemplate = _.template(document.querySelector('#pageResultNoResults').innerHTML); bcsModalContent.innerHTML = noResultTemplate({ result_text: document.querySelector('#pageResultNoResults').dataset.text, search_term: keywords }); if (window.innerWidth <= 800) { document.querySelector('#mobile-search-box-container .bcs-modal').classList.add('bcs-service-search'); document.querySelector('#mobile-search-box-container .bcs-pagination-container').style.display = 'none'; document.querySelector('#mobile-search-box-container .bcs-modal').style.display = 'block'; } else { document.querySelector('.bcs-modal').classList.add('bcs-service-search'); document.querySelector('.bcs-pagination-container').style.display = 'none'; document.querySelector('.bcs-modal').style.display = 'block'; } } }); }, handleMultipleAlarmClick: function(e) { window.location = e.currentTarget.dataset.redirectTo; }, bindAlarmModalEvents: function() { let self = this; Array.from(document.querySelectorAll('.alarm-modal-link')).forEach(linkBtn => { linkBtn.onclick = self.handleMultipleAlarmClick; }); }, bindEvents: function() { // Toggle active search, advanced / alarm let self = this; Array.from(self.elementNode.querySelectorAll('.search-expand-collapse-btn')).forEach(expColBtn => { expColBtn.onclick = self.activeSearchToggle.bind(self); }); // Alarm Handler to search for alarm + either redirect or prompt for more input self.elementNode.querySelector('#alarm-quick-search-button-self').onclick = self.handleAlarmSearch.bind(self); // Handle alarm search enter key click // Disable / enable alarm search button depending on if text is filled in self.elementNode.querySelector('input#alarm-search').onkeyup = self.handleInputChange.bind(self); // handle bing search self.elementNode.querySelector('#service-quick-search-button').onclick = self.handleAdvancedSearch.bind(self); // handle service quick search enter key click self.elementNode.querySelector('#service-quick-search-input').onkeydown = self.handleServiceQSEnterKey.bind(self); }, createAlarmURL: function(alarmCode, alarmType) { let encodedAlarmCode = alarmCode.replace('.', '-'); return '/content/haascnc/' + localStorage.storedSiteLang + '/service/alarm-search.alarm=' + alarmType + '_' + encodedAlarmCode + '.html'; } }); })(); $(window).bind("load", function() { var setHeight = function() { var tallest = 0; var $ctas = $(".cta-image-wrapper").not(".two-up-cta .cta-image-wrapper, .image-align-set-center .cta-image-wrapper"); $ctas.each(function(){ if($(this).height() > tallest) tallest = $(this).height(); }); $ctas.height(tallest); } setHeight(); if (window.ContextHub) { window.ContextHub.eventing.on(ContextHub.SegmentEngine.PageInteraction.Teaser.prototype.info.loadEvent, function() { setHeight(); }); } }); (function() { haas.components.CtaHomepageHalf = haas.Component.create({ initialize: function() { this.staggerHalves(); }, staggerHalves: function() { $('.homepage-half').odd().css('margin-left', 'auto'); }, render: function() { } }); })(); (function() { haas.components.CookieSettingsButton = haas.Component.create({ analyticsCookieFlags: [ '__utm', '_g', 'allowTrackingCookies', 'wise', 'rr' ], initialize: function() { }, cooieSettingsButtonClickHandler : function() { let host = window.location.hostname; delete(localStorage.allowTrackingCookies); // TO-DO: Fix remove cookies, ex. document.cookie = "__utmb=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;domain=.aemuat.haascnc.com"; Object.keys(haas.cookies._cookies()).forEach((cookie) => { if (this.analyticsCookieFlags.filter((flag) => cookie.includes(flag)).length) { haas.cookies.removeCookie(cookie); document.cookie = cookie + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;domain=.haascnc.com"; document.cookie = cookie + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;domain=" + host; } }); haas.region.initCookieModal(); document.querySelector('#acceptCookieModalTemplate #settings-btn').click(); }, bindButtonEvents: function() { document.querySelector('#cookie-settings-button').onclick = this.cooieSettingsButtonClickHandler.bind(this); }, render: function() { this.bindButtonEvents(); } }); })(); /* global $, _, haas */ (function () { 'use strict'; var Modal = haas.components.Modal; var EVENT_CLICK = 'click'; var cookieAlertModal = haas.components.CookieAlertModal = haas.Component.create({ acceptCookieTemplate: _.noop(), initialize: function(){ cookieAlertModal.acceptCookieTemplate = this.templates.acceptCookieTemplate; cookieAlertModal.cookiePromise = cookieAlertModal.sendCookiePromise(); } }); cookieAlertModal.sendCookiePromise = function(){ return new Promise(function(resolve, reject) { resolve({ 'cookieAlertModalReady': true }); }); }; cookieAlertModal.acceptCookieModal = function () { var clickResponse; var alertButtonSetup = function(){ cookieAlertModal.setUpTermsLink(); // prevent users from closing modal without selecting a button // adding CSS hack until I can revisit modal situation $('.haas-modal-body').off().css( { right:"0", left:"0", top:"0", bottom:"0", margin: "5% auto 0 auto" } ); $('.modal-closer').off(); $('#acceptCookies').on(EVENT_CLICK, function() { Modal.unload(); haas.region.setCookiesAccepted(true); }); $('#declineCookies').on(EVENT_CLICK, function() { Modal.unload(); haas.region.setCookiesAccepted(false); }); }; Modal.prompt(cookieAlertModal.acceptCookieTemplate(), alertButtonSetup); }; cookieAlertModal.setUpTermsLink = function () { var $termsLink = $('#terms-link'); var url = window.location.protocol + "//" + window.location.host + "/content/haascnc/" + haas.utils.getLanguage().toLowerCase() + $termsLink.attr('data-link-stub'); $termsLink.attr('href', url); }; })(); /* global $ */ $(function() { // TO-DO: This file was implemented in exactly the same way as the contact us form, will override the whole contact us forms function. Neet to refine. if (document.querySelector('.contestEntryForm')) { // Callable init function, in case form is in modal haas.initContactUSForm = function () { 'use strict'; const nonZipCodeCountries = ['SA', 'EG', 'OM', 'QA', 'KW', 'BH', 'LB', 'AE', 'VN', 'CN']; const $contactForm = $('#contact-form'); const urlRegex = /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/; const commentBlacklist = ['Hello. And Bye.']; let unhideAddressFields = function() { $('.contact-fields').removeClass('hidden'); } let showErrorDialog = function(err) { haas.components.Modal.open(_.template('

    {{=err}}

    ')({err: err})); } let testCommentBlacklist = function(formComments) { if (!formComments || !formComments.length) return false; let testStates = commentBlacklist.map(testString => formComments.indexOf(testString) > -1); return _.some(testStates); }; let testCodeInput = function(formComments) { const codeFlags = ['>', '<', '(', ')', '{', '}']; if (!formComments || !formComments.length) return false; // check all characts in comment to see if they let flagsPresent = codeFlags.map(flag => formComments.indexOf(flag) > -1); return _.some(flagsPresent); }; let validateInput = function($target) { let validation = haas.utils.validateInput($target); haas.utils.showValidationState(validation); return validation.isValid; }; let validateForm = function() { let $inputs = $('#contact-form *[data-validators]').filter(':visible'); let validationStates = $inputs.map(function () { return validateInput($(this)); }); return _.every(validationStates); }; let handleCountryChange = function() { $('#contact-form #Region').parent().find('.error-output').empty(); $('#contact-form #PostCode').parent().find('.error-output').empty(); // if new country val is ME, dont require post code if (nonZipCodeCountries.indexOf($('#contact-form #Country').val()) > -1) { $('#contact-form #PostCode').data('validators', ''); } else { $('#contact-form #PostCode').attr('data-validators', 'required'); } }; let initPhoneFormat = function(region) { if (region === 'US') { //add US-centric phone formatting $('#Telephone').keydown(function (e) { let key = e.which || e.charCode || e.keyCode || 0; let $phone = $(this); // Don't let them remove the starting '(' if ($phone.val().length === 1 && (key === 8 || key === 46)) { $phone.val('('); return false; } // Reset if they highlight and type over first char. else if ($phone.val().charAt(0) !== '(') { $phone.val('(' + String.fromCharCode(e.keyCode) + ''); } // Auto-format- do not expose the mask as the user begins to type if (key !== 8 && key !== 9) { if ($phone.val().length === 4) { $phone.val($phone.val() + ')'); } if ($phone.val().length === 5) { $phone.val($phone.val() + ' '); } if ($phone.val().length === 9) { $phone.val($phone.val() + '-'); } } // Allow numeric (and tab, backspace, delete) keys only return (key === 8 || // backspace key === 9 || // tab key === 46 || // delete (key >= 48 && key <= 57) || // Numbers (key >= 96 && key <= 105)); // Numbers (Keypad) }).bind('focus click', function () { let $phone = $(this); if ($phone.val().length === 0) { $phone.val('('); } else { let val = $phone.val(); $phone.val('').val(val); // Ensure cursor remains at the end } }).blur(function () { let $phone = $(this); if ($phone.val() === '(') { $phone.val(''); } }); } else { //add international phone formatting $('#Telephone').prop('maxLength', 30).keydown(function (e) { let key = e.which || e.charCode || e.keyCode || 0; // Allow numeric (and tab, backspace, delete) keys only return (key === 8 || // backspace key === 9 || // tab key === 32 || // space key === 46 || // delete key === 61 || // plus symbol ( + ) (for international phone codes), firefox's version key === 107 || // plus symbol ( + ) (for international phone codes), numberpad key === 187 || // plus symbol ( + ) (for international phone codes), IE / Chrome's version (key >= 48 && key <= 57) || // Numbers (key >= 96 && key <= 105)); // Numbers (Keypad) }); } }; let disableAutocomplete = function() { // handle chrome and non-chrome browsers differently if (!!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime)) $('#contact-form input').attr('autocomplete', 'new-password'); else $('#contact-form input').attr('autocomplete', 'off'); }; let bindFieldEvents = function() { // Prevent browser autocomplete on the address (will still allow google maps autocomplete) $('#contact-form #autocomplete').on('focus', function() { $('#autocomplete').attr('autocomplete', 'new-password'); }); // On input focus & unfocus, validate the input $('#contact-form input').on('blur', function() { validateInput($(this)); }); // On filling autocomplete field, unhide rest of address items $('#contact-form #autocomplete').on('change', unhideAddressFields); // On country country change, require / unrequire zipcode $('#contact-form #Country').off('change').on('change', handleCountryChange); // When autocomplete is finished, handle the country change $('#contact-form').on('autocompleteFilled', handleCountryChange); }; let buildValueString = function(key, value) { return key + ' : ' + value + ';\n'; }; let consolidateIntoComments = function() { // TO-DO: Consolidate all other form inputs into the comments field const contactFormContainer = document.forms['contact-form']; const availabilityContainer = contactFormContainer.querySelector('.call-availability-row'); let serialNumber = buildValueString('Model Number / Serial Number', contactFormContainer.querySelector('#ModelSerialNumber').value); let availabilityHour = availabilityContainer.querySelector('#Hour').value; let availabilityMinute = availabilityContainer.querySelector('#Minute').value; let availabilityAMPM = availabilityContainer.querySelector('#AMPM').value; let availability = buildValueString('Call Availability', availabilityHour + ':' + availabilityMinute + availabilityAMPM); let machineStatus = buildValueString('Machine Status', contactFormContainer.querySelector('#MachineStatus').value); let purchaseOrderNumber = buildValueString('Purchase Order Number', contactFormContainer.querySelector('#POnumber').value); let alarmCode = buildValueString('Alarm Code', contactFormContainer.querySelector('#alarmCode').value); let problemDescription = buildValueString('Problem Description', contactFormContainer.querySelector('#problemDescription').value); return serialNumber + availability + machineStatus + purchaseOrderNumber + alarmCode + problemDescription; }; if (!$contactForm) return; if ($('#contact-form').length && window.location.pathname.indexOf('video.html') === -1) { $('#contact-form input').keydown(function(event){ if (event.keyCode === 13) { // if item in google maps dropdown is selected, allow enter click if ($('.pac-item-selected').length) { $('#autocomplete').blur(); } else { event.preventDefault(); return false; } } }); } setTimeout(function() { // TODO: update this to avoid race condition, by replacing timeout with something more reliable haas.utils.initAutocomplete(); }, 500); $(document).ready(function() { // Disable Brower's autocomplete (will still allow google maps autocomplete for address disableAutocomplete(); // check to see if user is logged in $.when(haas.jwToken.jwtPromise).then(function (token) { // hide primary fields for authenticated if(haas.jwToken.isValid(token)){ $('.findadealer').removeClass('hidden'); if($('#disableFirstName').val()) $('#FirstName').attr('readonly', 'true'); if($('#disableLastName').val()) $('#LastName').attr('readonly', 'true'); if($('#disableEmail').val()) $('#Email').attr('readonly', 'true'); $('.contest-guest').hide(); $(".hide-on-auth").hide(); //$(".dealer-field").children().not('.comment').not('.submitBtn').not('#ErrorDiv').hide(); $("#comments").css('height', '200px'); $("#FirstName").val(token.firstName); $("#LastName").val(token.lastName); $("#Telephone").removeAttr('required'); $("#Email").val(token.email); $("#Email").parent().parent().parent().removeClass('col-md-6').addClass('col-md-12'); $("#CompanyName").removeAttr('required'); $("#Street").removeAttr('required'); $("#City").removeAttr('required'); $("#Region").removeAttr('required'); $("#PostCode").removeAttr('required'); $("#Country").removeAttr('required'); $("#autocomplete").removeAttr('required'); $("#contactId").val(token.contactId); unhideAddressFields(); } }); $.when(this.priceGroupPromise).then(function(price_group){ initPhoneFormat(haas.region.props.region); let campaignInfo = haas.analytics.getCampaignInfo(); if (!_.isEmpty(campaignInfo)) { $contactForm.find("#utm_info").val(campaignInfo); } }); $('#contest-btn1').click(function() { window.location.href = $(this).attr('data-redirect'); }) /* $('#contest-btn2').click(function() { window.location.href = $(this).attr('data-redirect'); }) */ bindFieldEvents(); // Check if email is valid before submission, if not prevent form from submitting $('#contact-form').on('submit', function(e) { let formValid = validateForm(); let formComments = $('#contact-form #comments').val(); const df = document.forms['contact-form']; if (!formValid) { e.preventDefault(); } else if (df.querySelector('#FirstName').value.trim().toLowerCase() === df.querySelector('#LastName').value.trim().toLowerCase()) { showErrorDialog($('#error-message-container').attr('data-generic-error')); e.preventDefault(); } else if (urlRegex.test(formComments)) { showErrorDialog($('#error-message-container').attr('data-url-error')); e.preventDefault(); } else if (testCommentBlacklist(formComments) || testCodeInput(formComments)) { showErrorDialog($('#error-message-container').attr('data-comment-error')); e.preventDefault(); } else { $('#submission-loader').removeClass('hidden'); if (df.classList.value.includes('service-request-form')) { df.querySelector('#comments').value = df.querySelector('#comments').value.length ? df.querySelector('#comments').value + ';\n' + consolidateIntoComments() : consolidateIntoComments(); } } }); }); }; // call for forms that live on page haas.initContactUSForm(); } }); /* global $ */ (function () { 'use strict'; var Modal = haas.components.Modal; var EVENT_CLICK = 'click'; haas.components.ContactUsButton = haas.Component.create({ getClickHandler: function (self) { return function (e) { e.preventDefault(); var $this = $(this); var header = $this.attr('data-header') || ''; var subtitle = $this.attr('data-subtitle') || ''; var headerSection = header ? "
    " + "

    " + header + "

    " + "

    " + subtitle + "

    " + "
    " + "
    " : ''; var modalTemplate = headerSection + self.templates.contactFormTemplate(); Modal.open(modalTemplate); haas.initContactUSForm(); $('.modal-contact-form').children().find('#comments').append($this.attr('data-comment')); }; }, bindEvents: function () { this.refs.$contact.off(EVENT_CLICK).on(EVENT_CLICK, this.getClickHandler(this)); }, render: function () { this.bindEvents(); } }); })(); /* global $ */ $(function() { // Callable init function, in case form is in modal haas.initContactUSForm = function () { 'use strict'; const nonZipCodeCountries = ['SA', 'EG', 'OM', 'QA', 'KW', 'BH', 'LB', 'AE', 'VN', 'CN']; const $contactForm = $('#contact-form'); const urlRegex = /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/; const commentBlacklist = ['Hello. And Bye.']; let unhideAddressFields = function() { $('.contact-fields').removeClass('hidden'); } let showErrorDialog = function(err) { haas.components.Modal.open(_.template('

    {{=err}}

    ')({err: err})); } let testCommentBlacklist = function(formComments) { if (!formComments || !formComments.length) return false; let testStates = commentBlacklist.map(testString => formComments.indexOf(testString) > -1); return _.some(testStates); }; let testCodeInput = function(formComments) { const codeFlags = ['>', '<', '{', '}']; if (!formComments || !formComments.length) return false; // check all characts in comment to see if they let flagsPresent = codeFlags.map(flag => formComments.indexOf(flag) > -1); return _.some(flagsPresent); }; let validateInput = function($target) { let validation = haas.utils.validateInput($target); haas.utils.showValidationState(validation); return validation.isValid; }; let validateForm = function() { let $inputs = $('#contact-form *[data-validators]').filter(':visible'); let validationStates = $inputs.map(function () { return validateInput($(this)); }); return _.every(validationStates); }; let handleCountryChange = function() { $('#contact-form #Region').parent().find('.error-output').empty(); $('#contact-form #PostCode').parent().find('.error-output').empty(); // if new country val is ME, dont require post code if (nonZipCodeCountries.indexOf($('#contact-form #Country').val()) > -1) { $('#contact-form #PostCode').data('validators', ''); } else { $('#contact-form #PostCode').attr('data-validators', 'required'); } }; let initPhoneFormat = function(region) { if (region === 'US') { //add US-centric phone formatting $('#Telephone').keydown(function (e) { let key = e.which || e.charCode || e.keyCode || 0; let $phone = $(this); // Don't let them remove the starting '(' if ($phone.val().length === 1 && (key === 8 || key === 46)) { $phone.val('('); return false; } // Reset if they highlight and type over first char. else if ($phone.val().charAt(0) !== '(') { $phone.val('(' + String.fromCharCode(e.keyCode) + ''); } // Auto-format- do not expose the mask as the user begins to type if (key !== 8 && key !== 9) { if ($phone.val().length === 4) { $phone.val($phone.val() + ')'); } if ($phone.val().length === 5) { $phone.val($phone.val() + ' '); } if ($phone.val().length === 9) { $phone.val($phone.val() + '-'); } } // Allow numeric (and tab, backspace, delete) keys only return (key === 8 || // backspace key === 9 || // tab key === 46 || // delete (key >= 48 && key <= 57) || // Numbers (key >= 96 && key <= 105)); // Numbers (Keypad) }).bind('focus click', function () { let $phone = $(this); if ($phone.val().length === 0) { $phone.val('('); } else { let val = $phone.val(); $phone.val('').val(val); // Ensure cursor remains at the end } }).blur(function () { let $phone = $(this); if ($phone.val() === '(') { $phone.val(''); } }); } else { //add international phone formatting $('#Telephone').prop('maxLength', 30).keydown(function (e) { let key = e.which || e.charCode || e.keyCode || 0; // Allow numeric (and tab, backspace, delete) keys only return (key === 8 || // backspace key === 9 || // tab key === 32 || // space key === 46 || // delete key === 61 || // plus symbol ( + ) (for international phone codes), firefox's version key === 107 || // plus symbol ( + ) (for international phone codes), numberpad key === 187 || // plus symbol ( + ) (for international phone codes), IE / Chrome's version (key >= 48 && key <= 57) || // Numbers (key >= 96 && key <= 105)); // Numbers (Keypad) }); } }; let disableAutocomplete = function() { // handle chrome and non-chrome browsers differently if (!!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime)) $('#contact-form input').attr('autocomplete', 'new-password'); else $('#contact-form input').attr('autocomplete', 'off'); }; let bindFieldEvents = function() { // Prevent browser autocomplete on the address (will still allow google maps autocomplete) $('#contact-form #autocomplete').on('focus', function() { $('#autocomplete').attr('autocomplete', 'new-password'); }); // On input focus & unfocus, validate the input $('#contact-form input').on('blur', function() { validateInput($(this)); }); // On filling autocomplete field, unhide rest of address items $('#contact-form #autocomplete').on('change', unhideAddressFields); // On country country change, require / unrequire zipcode $('#contact-form #Country').off('change').on('change', handleCountryChange); // When autocomplete is finished, handle the country change $('#contact-form').on('autocompleteFilled', handleCountryChange); }; let buildValueString = function(key, value) { return key + ' : ' + value + ';\n'; }; let consolidateIntoComments = function() { // TO-DO: Consolidate all other form inputs into the comments field const contactFormContainer = document.forms['contact-form']; const availabilityContainer = contactFormContainer.querySelector('.call-availability-row'); let serialNumber = buildValueString('Model Number / Serial Number', contactFormContainer.querySelector('#ModelSerialNumber').value); let availabilityHour = availabilityContainer.querySelector('#Hour').value; let availabilityMinute = availabilityContainer.querySelector('#Minute').value; let availabilityAMPM = availabilityContainer.querySelector('#AMPM').value; let availability = buildValueString('Call Availability', availabilityHour + ':' + availabilityMinute + availabilityAMPM); let machineStatus = buildValueString('Machine Status', contactFormContainer.querySelector('#MachineStatus').value); let purchaseOrderNumber = buildValueString('Purchase Order Number', contactFormContainer.querySelector('#POnumber').value); let alarmCode = buildValueString('Alarm Code', contactFormContainer.querySelector('#alarmCode').value); let problemDescription = buildValueString('Problem Description', contactFormContainer.querySelector('#problemDescription').value); return serialNumber + availability + machineStatus + purchaseOrderNumber + alarmCode + problemDescription; }; if (!$contactForm) return; if ($('#contact-form').length && window.location.pathname.indexOf('video.html') === -1) { // Unhide reCaptcha on pages with contact form document.querySelector('body').classList.remove('hide-recaptcha'); $('#contact-form input').keydown(function(event){ if (event.keyCode === 13) { // if item in google maps dropdown is selected, allow enter click if ($('.pac-item-selected').length) { $('#autocomplete').blur(); } else { event.preventDefault(); return false; } } }); } setTimeout(function() { // TODO: update this to avoid race condition, by replacing timeout with something more reliable haas.utils.initAutocomplete(); }, 500); $(document).ready(function() { // Disable Brower's autocomplete (will still allow google maps autocomplete for address disableAutocomplete(); // check to see if user is logged in $.when(haas.jwToken.jwtPromise).then(function (token) { // hide primary fields for authenticated if(haas.jwToken.isValid(token)){ $(".hide-on-auth").hide(); //$(".dealer-field").children().not('.comment').not('.submitBtn').not('#ErrorDiv').hide(); $("#comments").css('height', '200px'); $("#FirstName").val(token.firstName); $("#LastName").val(token.lastName); $("#Telephone").removeAttr('required'); $("#Email").val(token.email); $("#Email").parent().parent().parent().removeClass('col-md-6').addClass('col-md-12'); $("#CompanyName").removeAttr('required'); $("#Street").removeAttr('required'); $("#City").removeAttr('required'); $("#Region").removeAttr('required'); $("#PostCode").removeAttr('required'); $("#Country").removeAttr('required'); $("#autocomplete").removeAttr('required'); $("#contactId").val(token.contactId); unhideAddressFields(); } }); $.when(this.priceGroupPromise).then(function(price_group){ initPhoneFormat(haas.region.props.region); let campaignInfo = haas.analytics.getCampaignInfo(); if (!_.isEmpty(campaignInfo)) { $contactForm.find("#utm_info").val(campaignInfo); } }); bindFieldEvents(); // Check if email is valid before submission, if not prevent form from submitting $('#contact-form').on('submit', function(e) { let formValid = validateForm(); let formComments = $('#contact-form #comments').val(); const df = document.forms['contact-form']; if (!formValid) { e.preventDefault(); } else if (urlRegex.test(formComments)) { showErrorDialog($('#error-message-container').attr('data-url-error')); e.preventDefault(); } else if (testCommentBlacklist(formComments) || testCodeInput(formComments)) { showErrorDialog($('#error-message-container').attr('data-comment-error')); e.preventDefault(); } else { e.preventDefault(); $('#submission-loader').removeClass('hidden'); grecaptcha.enterprise.ready(async () => { const token = await grecaptcha.enterprise.execute(localStorage.reCaptchaKey, {action: 'CONTACT_US'}); console.log(token); const assessment = await fetch('/ecommpartsstorefront/ecommparts/en/captcha/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ 'token': token, 'action': 'CONTACT_US', 'salesOrg': haas.cookies.getCookie('salesOrg') }) }); const assessmentValue = await assessment.json(); if (assessmentValue) { // if assessment value is true, submit form as normal if (df.classList.value.includes('service-request-form')) { df.querySelector('#comments').value = df.querySelector('#comments').value.length ? df.querySelector('#comments').value + ';\n' + consolidateIntoComments() : consolidateIntoComments(); } const formData = new FormData(df); const createContactPromise = await fetch('/bin/haascnc/createContact', { method: 'POST', body: formData }); if (df.querySelector('#redirectTo')) { window.location = df.querySelector('#redirectTo').value + '.html'; } else { window.location = '/content/haascnc/'+haas.utils.getLanguage()+'/about/thankyou.html' } } else { showErrorDialog($('#error-message-container').attr('data-recaptcha-error')); } }); } }); }); }; // call for forms that live on page haas.initContactUSForm(); }); /* global haas */ (function () { 'use strict'; var Store = haas.data.Store; haas.data.h2hStore = Store.create('h2h_store', {}); })(); /* global haas, $, _, priceGroupPromise */ (function () { 'use strict'; var EVENT_CLICK = 'click'; var H2H_MILLS_SERIES_PATHS = [ 'mini-mill', 'toolroom-mill' ]; var TOOLROOM_LATHE_SERIES_PATH = 'toolroom-lathe'; var VF_SERIES_PATH = 'vf-series'; var ST_SERIES_PATH = 'st'; var router = haas.router; var getSlingSelectors = haas.utils.getSlingSelectors; var store = haas.data.configuratorStore; var formatURI = haas.utils.formatURI; var encodeSlingSelector = haas.utils.encodeSlingSelector; var Modal = haas.components.Modal; var QueryModel = { x: Number, y: Number, z: Number, yAxis: function (str) { return str !== 'false'; } }; var regionBus = haas.bus.region; haas.components.ConfiguratorSelectSeries = haas.Component.create({ params: {}, state: { recommended: { primary: {}, alt: [] } }, unsubRegionBus:_.noop, initialize: function () { var self = this; router.init(); Modal.load(); self.unsubRegionBus(); self.unsubRegionBus = regionBus.subscribe(self.onRegionChange.bind(self)); this.state.functionality = getSlingSelectors(0); this.params = router.getCoercedQuery(QueryModel); $.when(haas.region.priceGroupPromise).then(function(price_group) { haas.services.configurator.fetchMachines().then(function () { Modal.unload(); self.determineUIPath(); }); }); }, onRegionChange: function () { var self = this; haas.LOGGER.log('rerendering configurator select series on region change'); haas.services.configurator.fetchMachines().then(function () { self.refs.$output.html(self.templates.selectSeries(self.state)); }); }, renderQuestion: function () { this.refs.$output.html(this.templates.selectSeries(this.state)); this.bindEvents(); }, bindEvents: function () { var self = this; this.$('.configurator-card').off(EVENT_CLICK).on(EVENT_CLICK, function () { var selectedSeries = self.state.selectedSeries = $(this).data('series'); var recSeriesPath = self.state.recommended.primary.series.id; if (selectedSeries !== recSeriesPath) { var prevPrimary = Object.assign({}, self.state.recommended.primary); self.state.recommended.primary = _.find(self.state.recommended.alt, function (machine) { return machine.series.id === selectedSeries; }); var replaceIndex = _.findIndex(self.state.recommended.alt, {id: self.state.recommended.primary.id}); self.state.recommended.alt[replaceIndex] = prevPrimary; } self.goToNextStep(); }); }, determineUIPath: function () { var dims = this.params; var recommendation; var nextStep = this.renderQuestion.bind(this); var primary = {}; var considerations = []; var pri, alt; var h2hText = haas.data.h2hStore.hydrate().getState(); if (this.state.functionality === 'milling') { haas.LOGGER.debug('Finding ' + this.state.functionality + ' machines for dimensions: ' + dims.x + '" x ' + dims.y + '" x ' + dims.z + '" (xyz)'); recommendation = haas.services.configurator.getRecommendedMillingMachinesForDims({ x: dims.x, y: dims.y, z: dims.z }); if (!recommendation || !recommendation.primary) { alert('No machines found for the given dimensions'); return; } primary = recommendation.primary; considerations = recommendation.considerations; if (H2H_MILLS_SERIES_PATHS.indexOf(primary.series.id) === -1) { nextStep = this.goToNextStep.bind(this); } else { alt = this.state.recommendedAlt = _.find(considerations, function (machine) { return machine.series.id === VF_SERIES_PATH; }); pri = this.state.recommendedPrimary = primary; if (pri.series.id === 'mini-mill' && alt.series.id === 'vf-series') { pri.h2hText = h2hText.MM; alt.h2hText = h2hText.VF; } else if (pri.series.id === 'toolroom-mill' && alt.series.id === 'vf-series') { pri.h2hText = h2hText.TM; alt.h2hText = h2hText.VF; } else if (pri.series.id === 'toolroom-lathe' && alt.series.id === 'st') { pri.h2hText = h2hText.TL; alt.h2hText = h2hText.ST; } else { pri.h2hText = ''; alt.h2hText = ''; } } } else if (this.state.functionality === 'turning') { haas.LOGGER.debug('Finding ' + this.state.functionality + ' machines for dimensions: ' + dims.width + '" x ' + dims.depth + '" (width x depth). Y-Axis: ' + dims.yAxis); recommendation = haas.services.configurator.getRecommendedTurningMachinesForDims({ x: dims.x, z: dims.z, yAxis: dims.yAxis || false }); if (!recommendation || !recommendation.primary) { alert('No machines found for the given dimensions'); return; } primary = recommendation.primary; considerations = recommendation.considerations; if (primary.series.id !== TOOLROOM_LATHE_SERIES_PATH || dims.yAxis) { nextStep = this.goToNextStep.bind(this); } else { alt = this.state.recommendedAlt = _.find(considerations, function (machine) { return machine.series.id === ST_SERIES_PATH; }); pri = this.state.recommendedPrimary = primary; if (pri.series.id === 'toolroom-lathe' && alt.series.id === 'st') { pri.h2hText = h2hText.TL; alt.h2hText = h2hText.ST; } else { pri.h2hText = ''; alt.h2hText = ''; } } } this.state.recommended.primary = primary; this.state.recommended.alt = considerations; nextStep(); }, goToNextStep: function () { var storeState = store.hydrate().getState(); var models = [this.state.recommended.primary].concat(this.state.recommended.alt).map(function (model) { return encodeSlingSelector(model.id); }); window.location = formatURI({ path: storeState.modelSelectPath, selectors: [models.join(',')] }); } }); })(); /* global haas, $, _, priceGroupPromise */ (function () { 'use strict'; var EVENT_CLICK = 'click'; var router = haas.router; var getSlingSelectors = haas.utils.getSlingSelectors; var store = haas.data.configuratorStore; var formatURI = haas.utils.formatURI; var Modal = haas.components.Modal; var QueryModel = { x: Number, y: Number, z: Number }; haas.components.ConfiguratorProvideAdditionalDimensions = haas.Component.create({ params: {}, state: {}, initialize: function () { var self = this; router.init(); Modal.load(); this.state.functionality = getSlingSelectors(0); this.params = router.getCoercedQuery(QueryModel); $.when(haas.region.priceGroupPromise).then(function(price_group){ haas.services.configurator.fetchMachines().then(function () { Modal.unload(); self.determineRenderer(); }); }); }, determineQuestionIsValid: function () { if (haas.wcm.isEditMode()) return true; var functionality = this.state.functionality; if (functionality === 'milling') { return this.determineMillingQuestionIsValid() } if (functionality === 'turning') { return this.determineTurningQuestionIsValid(); } return false; }, determineMillingQuestionIsValid: function () { var dims2x = { x: this.params.x * 2, y: this.params.y, z: this.params.z }; var recommendation = haas.services.configurator.getRecommendedMillingMachinesForDims(dims2x); return !!recommendation.primary; }, determineTurningQuestionIsValid: function () { // always show y axis question for turning path return true; }, renderQuestion: function () { this.refs.$output.html(this.templates.additionalDimsQuestion(this.state)); this.bindEvents(); }, bindEvents: function () { var self = this; if (this.state.functionality === 'turning') { this.$('.btn-continue').off(EVENT_CLICK).on(EVENT_CLICK, function (e) { e.preventDefault(); self.params.yAxis = self.$('input[name=yaxis]:checked').val() === 'true'; self.goToNextStep(); }); } if (this.state.functionality === 'milling') { this.$('.configurator-card').off(EVENT_CLICK).on(EVENT_CLICK, function (e) { e.preventDefault(); if ($(this).data('modifier') === 'multiple') { self.applyMultiplePieceModifier(self.params); } self.goToNextStep(); }); } }, applyMultiplePieceModifier: function (dims) { dims.x = dims.x * 2; return dims; }, goToNextStep: function () { var storeState = store.hydrate().getState(); var functionality = this.state.functionality; window.location = formatURI({ path: storeState.seriesSelectPath, selectors: [functionality], hash: '/', hashQuery: this.params }); }, determineRenderer: function () { if (!this.determineQuestionIsValid()) { return this.goToNextStep(); } this.renderQuestion(); } }); })(); /* global haas, _ */ (function () { 'use strict'; var logger = haas.LOGGER; haas.rules.conflictGroup = conflictGroup; function conflictGroup (activation) { var self = this; var option = activation.option; var options = activation.context.options; var associations = activation.context.associations; var nextContext; var peers = self.peers.filter(function (peer) { return !!_.find(options, {id: peer}) || !!_.find(associations, {id: peer}); }); var peerOptions = peers.map(function (peer) { return _.find(options, {id: peer}) || !!_.find(associations, {id: peer}); }); var optionInGroup = peers.indexOf(option.id) !== -1; if (!optionInGroup) return activation.cancel(haas.models.OptionRuleContext.CancelReasons.notInGroup); // find any peer options already selected var selectedPeerOptions = _.filter(peerOptions, {isSelected: true}); var selectedPeerOption =_.find(selectedPeerOptions, function(peerOption) {return peerOption.id !== option.id;} ); if (selectedPeerOption) { activation.setVars({blockedBy: Object.assign({}, selectedPeerOption)}); return activation.resolve(activation.context); } var nextOptions = options.slice(); var optState = _.find(nextOptions, {id: option.id}) || _.find(associations, {id: option.id}); // optState = Object.assign({}, optState); optState.isSelected = activation.isSelection; nextContext = Object.assign({}, activation.context, {options: nextOptions}); activation.flagChange(optState); return activation.resolve(nextContext); } })(); /* global haas, _ */ (function () { 'use strict'; haas.rules.defaultValue = defaultRule; function defaultRule (activation) { var options = activation.context.options; var associations = activation.context.associations; var automations = activation.context.automations; var option = activation.option; var nextOptions = options.slice(); var optState = _.find(nextOptions, {id: option.id}) || _.find(associations, {id: option.id}) || _.find(automations, {id: option.id}); optState.isSelected = activation.isSelection; var nextContext = Object.assign({}, activation.context, {options: nextOptions}); activation.flagChange(optState); return activation.resolve(nextContext); } })(); /* global haas, _ */ (function () { 'use strict'; let logger = haas.LOGGER; haas.rules.dependencyGroup = dependencyGroup; function dependencyGroup (activation) { let self = this; let CancelReasons = haas.models.OptionRuleContext.CancelReasons; let option = activation.option; let options = activation.context.options.concat(activation.context.associations).concat(activation.context.automations); let associations = activation.context.associations; let deselect = activation.isAuxiliary ? !option.parentIsSelected : !activation.isSelection; // get whole peer objects instead of just ids let dependentPeerGroup = options.filter(function (option) { return !!_.includes(self.peers, option.id); }); let optionInGroup = self.peers.indexOf(option.id) !== -1; let parentOpt = _.find(options, {id: this.parentOption}) || _.find(associations, {id: this.parentOption}); // Note: parentIsSelected value reflects parent's status at start of click // EXAMPLE: If a user is clicking a parent option to select it, // parentIsSelected === false let requiredByOptions = option.requiredBy ? options.filter((opt) => option.requiredBy.includes(opt.id)) : []; let requiredBySelected = _.some(requiredByOptions, (opt) => opt.isSelected); let parentIsSelected = requiredBySelected; let optionIsParent = option.id === self.parentOption; let nextOptions; // hack for existing 5AXD / 4AXD / 4TH-AXIS-RTY rules // until we can rewrite the ruleset; remove as soon as rewrite is done if (option.id === '5AXD' || option.id === '4AXD') { let hiddenPeer = _.find(options, {id:'4TH-AXIS-RTY'}); // 4TH-AXIS-RTY exists if (hiddenPeer) { // if option is 5AXD and 4TH-AXIS-RTY is already selected, just toggle 5AXD. if(option.id === '5AXD' && hiddenPeer.isSelected){ nextOptions = options.map(function (opt) { if (opt.id === option.id) { opt.isSelected = activation.isSelection; activation.flagChange(opt); } if (opt.id === '4AXD'){ opt.parentIsSelected = activation.isSelection; } return opt; }); nextOptions = nextOptions.filter(function(opt) { return opt.getFormattedDiscountedPrice; }); return activation.resolve(Object.assign({}, activation.context, {options: nextOptions})); } else if(option.id === '4AXD') { // otherwise just resolve with no changes, and let the peer group handle it. options = options.filter(function(opt) { return opt.getFormattedDiscountedPrice; }); return activation.resolve(Object.assign({}, activation.context, {options: options})); } } // otherwise, proceed as normal. } // if deselecting a standard option, cancel if (deselect && option.isStandard) { if ((!activation.isAuxiliary && option.isSelected)) { option.isSelected = true; return activation.cancel(CancelReasons.standardOption); } } // if selected option is a dependency if (!optionIsParent) { // if selected option not found in the peer group, cancel if (!optionInGroup) { option.isSelected = (!deselect && !activation.isAuxiliary); return activation.cancel(CancelReasons.notInGroup); } // if selected option is a dependency being deselected, // but the parent option is selected, // cancel because the selected parent requires the dependency if (parentIsSelected && deselect) { option.isSelected = true; return activation.cancel(CancelReasons.parentIsSelected); } // if selected option is not itself being deselected, but // is rather being checked as a part of an auxiliary rule, // do not deselect if it is standard if (deselect && activation.isAuxiliary && option.isSelected && option.isStandard) { option.isSelected = true; return activation.cancel(CancelReasons.standardOption); } // if the parent option doesn't exist, // or the parent option isn't selected, // just toggle the dependent option in question if (!parentOpt || !parentIsSelected) { nextOptions = options.map(function (opt) { if (opt.id === option.id) { opt.isSelected = (!deselect && !activation.isAuxiliary); // additional flags for use in modals, firing auxiliary rules opt.optionInGroup = optionInGroup; opt.parentIsSelected = false; opt.requiredBy = opt.requiredBy || []; activation.flagChange(opt); } return opt; }); nextOptions = nextOptions.filter(function(opt) { return opt.getFormattedDiscountedPrice; }); return activation.resolve(Object.assign({}, activation.context, {options: nextOptions})); } } // if option is parent, // option is being selected, // and un-selected child has blocking rules associated with it, // check to see if child's blocked peers are already selected. // If they are, cancel the activation because the child cannot be activated // due to peer conflict. // EXAMPLE: On GR-510, a user selects P-COOL, and then selects MIN QTY LUBE. // MIN QTY LUBE has a dependency of AAG, but P-COOL and AAG are incompatible. // In this case, check to see if P-COOL is selected. // If it is, cancel MIN QTY LUBE's activation and throw a modal // explaining the incompatibility. if (!deselect && !activation.isAuxiliary && optionIsParent && self.childrenWithBlockedRules.length !== 0) { let blockedSelectedPeers = []; _.forEach(dependentPeerGroup, function(peerObject) { // find any children that are not selected if (!peerObject.isSelected) { _.forEach(self.childrenWithBlockedRules, function(child) { // make sure they're actually in the blocked group if(child.options.indexOf(peerObject.id) !== -1){ _.forEach(child.rule.options, function(option) { // check to see if any of the blocked peers are activated if(option !== peerObject.id){ let selectedPeer = _.find(options, {id: option, isSelected: true}); if (!!selectedPeer){ blockedSelectedPeers.push(_.find(options, {id: option, isSelected: true})); } // TO-DO: Activate any child-peer rules for options } }); } }); } }); // if there are any activated, blocked peers, do not change any options, // cancel the activation and throw a modal. if (blockedSelectedPeers.length) { option.isSelected = false; activation.setVars({ childOptions: dependentPeerGroup, blockedBy: blockedSelectedPeers, messageId: 'childBlockedByPeer' }); return activation.cancel(CancelReasons.childBlockedByPeer); } } let dependencies = []; // if we've made it this far, and the parent is being selected/deselected, update parentIsSelected value. // this value needs to be set ahead of the loop below, // because the parent is not always ahead of the dependents in the option list. if (optionIsParent) { parentIsSelected = !deselect; } nextOptions = _.chain(options) .map(function (opt) { if (opt.id === option.id) { opt.isSelected = !deselect && !activation.isAuxiliary; activation.option = opt; activation.flagChange(opt); } // if the option is in the dependent peer group, that means it's a child/dependent // If it isn't the selected option, it may need to be selected/deselected in conjunction with the parent let inDependentGroup = !!_.find(dependentPeerGroup, {id:opt.id}); let requiredByOptions = opt.requiredBy ? options.filter((optItem) => opt.requiredBy.includes(optItem.id)) : []; let requiredBySelected = _.some(requiredByOptions, (optItem) => optItem.isSelected); if (inDependentGroup && opt.id !== option.id) { // if parent is being selected, // save dependent's initial selection value // so we can check if dependent option was already selected // before parent option was selected if (!deselect && optionIsParent){ opt.alreadySelected = !!opt.isSelected; } // additional flags for use in modals, firing auxiliary rules opt.optionInGroup = true; opt.parentIsSelected = parentIsSelected; // if parent is being deselected, // any dependent that is standard or already selected // should automatically remain selected. if (deselect && optionIsParent && !parentIsSelected || activation.isAuxiliary && optionIsParent) { opt.isSelected = (opt.isStandard || opt.alreadySelected) ? true : !deselect; } else { // otherwise, set dependent as selected/deselected if parent is selected/deselected, // and this is not an auxiliary rule opt.isSelected = (opt.isStandard) ? true : !deselect && !activation.isAuxiliary; } // no options currently have requiredBy arrays pre-set; // they're added here and are used by Auxiliary rules. opt.requiredBy = opt.requiredBy || []; let otherParents = opt.requiredBy.filter(function (optId) { return optId !== option.id; }); if (parentIsSelected && otherParents.length) { if (opt.isSelected) { if (opt.requiredBy.indexOf(option.id) === -1) { opt.requiredBy.push(option.id); } else { let index = opt.requiredBy.indexOf(option.id); _.pullAt(opt.requiredBy, index); } opt.price = opt.price === 0 ? 0 : self.priceOverride ? 0 : opt.constantPrice; activation.flagChange(opt); return opt; } } if (opt.isSelected) { if (opt.requiredBy.indexOf(option.id) === -1) { opt.requiredBy.push(option.id); } } else { let idx = opt.requiredBy.indexOf(option.id); _.pullAt(opt.requiredBy, idx); } if (deselect || activation.isAuxiliary) { opt.price = opt.constantPrice; } else { opt.price = self.priceOverride ? 0 : opt.constantPrice; } dependencies.push(opt.id); activation.flagChange(opt); } return opt; }) .value(); nextOptions = nextOptions.filter(function(opt) { return opt.getFormattedDiscountedPrice; }); return activation.resolve(Object.assign({}, activation.context, {options: nextOptions})); } })(); /* global haas, _ */ (function () { 'use strict'; let logger = haas.LOGGER; haas.rules.childPeerGroup = childPeerGroup; function childPeerGroup (activation) { let self = this; let CancelReasons = haas.models.OptionRuleContext.CancelReasons; let option = activation.option; let options = activation.context.options; let associations = activation.context.associations; let deselect = activation.isAuxiliary ? !option.parentIsSelected : !activation.isSelection; // get whole peer objects instead of just ids let dependentPeerGroup = options.filter(function (option) { return !!_.includes(self.peers, option.id); }); // check if a child of the parent is already selected. let alreadySelected = !!_.find(dependentPeerGroup, {isSelected: true}); let optionInGroup = self.peers.indexOf(option.id) !== -1; let parentOpt = _.find(options, {id: this.parentOption}) || _.find(associations, {id: this.parentOption}); // Note: parentIsSelected value reflects parent's status at start of click // EXAMPLE: If a user is clicking a parent option to select it, // parentIsSelected === false let requiredByOptions = option.requiredBy ? options.filter((opt) => option.requiredBy.includes(opt.id)) : []; let requiredBySelected = _.some(requiredByOptions, (opt) => opt.isSelected); let parentIsSelected = parentOpt && parentOpt.isSelected; let optionIsParent = option.id === self.parentOption; let nextOptions; if (!parentOpt) return activation.cancel(CancelReasons.notInGroup); // Hard-Coded Cancel Rule for HSK Tool Changers if (option.categoryUniqueName === 'tool_changer' && option.id.includes('HSK') && !deselect) { let selectedSpindle = options.find(opt => opt.categoryUniqueName === 'spindle' && opt.isSelected); if (!deselect && !selectedSpindle.id.includes('HSK')) { activation.setVars({ blockedBy: selectedSpindle, messageId: 'hskBlockedModal' }); return activation.cancel(CancelReasons.hskToolChangerBlocked); } if (deselect && selectedSpindle.id.includes('HSK')) { return activation.cancel(CancelReasons.parentIsSelected); } } // if deselecting a standard option, cancel if (deselect && option.isStandard && optionInGroup) { if ((!activation.isAuxiliary && option.isSelected) || (activation.isAuxiliary)){ option.isSelected = true; return activation.cancel(CancelReasons.standardOption); } } if (deselect && optionIsParent) { if (requiredBySelected) return activation.cancel(CancelReasons.parentIsSelected); } /**************************************************** * Handle Child Click * ****************************************************/ if (!optionIsParent) { // if selected option not parent and not in group, it doesn't apply to current machine, cancel if (!optionInGroup) { return activation.cancel(CancelReasons.notInGroup); } // if selected option is not itself being deselected, but // is rather being checked as a part of an auxiliary rule, // do not deselect if it is standard if (deselect && activation.isAuxiliary && option.isSelected && option.isStandard && optionInGroup) { option.isSelected = true; return activation.cancel(CancelReasons.standardOption); } // if the parent option doesn't exist, // or the parent option isn't selected, // just toggle the dependent option in question if (!parentOpt || !parentIsSelected ) { if (option.categoryUniqueName === 'tool_changer' && option.id.includes('HSK') && !deselect) { let selectedSpindle = options.find(opt => opt.categoryUniqueName === 'spindle' && opt.isSelected); // Hard Coded HSK Tool Changer Rules if (!deselect && !selectedSpindle.id.includes('HSK')) { activation.setVars({ blockedBy: selectedSpindle, messageId: 'hskBlockedModal' }); return activation.cancel(CancelReasons.hskToolChangerBlocked); } if (deselect && selectedSpindle.id.includes('HSK')) { return activation.cancel(CancelReasons.parentIsSelected); } } nextOptions = options.map(function (opt) { if (opt.id === option.id) { opt.isSelected = (!deselect && !activation.isAuxiliary); // additional flags for use in modals, firing auxiliary rules opt.optionInGroup = optionInGroup; opt.parentIsSelected = false; opt.requiredBy = (parentOpt) ? [parentOpt.id] : []; activation.flagChange(opt); } return opt; }); return activation.resolve(Object.assign({}, activation.context, {options: nextOptions})); } // if not deselect and there is a peer selected, deselect it, and select clicked option if (parentIsSelected && !deselect && alreadySelected) { nextOptions = options.map(function (opt) { let inDependentGroup = !!_.find(dependentPeerGroup, {id:opt.id}); if (opt.id === option.id) { opt.isSelected = true; opt.alreadySelected = true; opt.parentIsSelected = true; opt.requiredBy = (parentOpt) ? [parentOpt.id] : []; opt.price = self.priceOverride ? 0 : opt.constantPrice; activation.flagChange(opt); } else if (inDependentGroup) { opt.isSelected = false; opt.alreadySelected = false; opt.parentIsSelected = false; opt.price = opt.constantPrice; opt.requiredBy = (parentOpt) ? [parentOpt.id] : []; } return opt; }); return activation.resolve(Object.assign({}, activation.context, {options: nextOptions})); } // if selected option is a dependency being deselected, // but the parent option is selected, // cancel because the selected parent requires the dependency if (parentIsSelected && deselect) { option.isSelected = true; return activation.cancel(CancelReasons.parentIsSelected); } } /**************************************************** * Handle Parent Click * ****************************************************/ /*************************************************** * Handle Parent with Blocked Children * ***************************************************/ // NOTE : This was not updated for Child Peer Rules // if option is parent, // option is being selected, // and un-selected child has blocking rules associated with it, // check to see if child's blocked peers are already selected. // If they are, cancel the activation because the child cannot be activated // due to peer conflict. // EXAMPLE: On GR-510, a user selects P-COOL, and then selects MIN QTY LUBE. // MIN QTY LUBE has a dependency of AAG, but P-COOL and AAG are incompatible. // In this case, check to see if P-COOL is selected. // If it is, cancel MIN QTY LUBE's activation and throw a modal // explaining the incompatibility. if(!deselect && !activation.isAuxiliary && optionIsParent && self.childrenWithBlockedRules.length !== 0){ let blockedSelectedPeers = []; _.forEach(dependentPeerGroup, function(peerObject){ // find any children that are not selected if(!peerObject.isSelected){ _.forEach(self.childrenWithBlockedRules, function(child){ // make sure they're actually in the blocked group if(child.options.indexOf(peerObject.id) !== -1){ _.forEach(child.rule.options, function(option){ // check to see if any of the blocked peers are activated if(option !== peerObject.id){ let selectedPeer = _.find(options, {id: option, isSelected: true}); if (!!selectedPeer){ blockedSelectedPeers.push(_.find(options, {id: option, isSelected: true})); } } }); } }); } }); // if there are any activated, blocked peers, do not change any options, // cancel the activation and throw a modal. if(blockedSelectedPeers.length){ option.isSelected = false; activation.setVars({ childOptions: dependentPeerGroup, blockedBy: blockedSelectedPeers, messageId: 'childBlockedByPeer' }); return activation.cancel(CancelReasons.childBlockedByPeer); } } /*************************************************** * Normal Parent Handler * ***************************************************/ // if we've made it this far, and the parent is being selected/deselected, update parentIsSelected value. // this value needs to be set ahead of the loop below, // because the parent is not always ahead of the dependents in the option list. let addedOption = ''; let addedOptionPeers = []; let addedOptionId = null; let deselectedChildId = null; if (optionIsParent) { if (activation.isAuxiliary) parentIsSelected = requiredBySelected; if (!activation.isAuxiliary) parentIsSelected = !deselect; } nextOptions = _.chain(options) .map(function (opt) { // if the option is in the dependent peer group, that means it's a child/dependent // If it isn't the selected option, it may need to be selected/deselected in conjunction with the parent let inDependentGroup = !!_.find(dependentPeerGroup, {id:opt.id}); // If not the parent, or in dependent group, option isnt affected, just return if (opt.id !== option.id && !inDependentGroup) return opt; // if option is parent, then update its attributes if (opt.id === option.id) { opt.isSelected = !deselect; activation.option = opt; activation.flagChange(opt); } else { // no options currently have requiredBy arrays pre-set; // they're added here and are used by Auxiliary rules. opt.requiredBy = opt.requiredBy || []; let otherParents = opt.requiredBy.filter((optId) => optId !== option.id); // if parent is being deselected if (deselect) { // if parent is being deselected, // any dependent that is standard or previously selected should remain selected // other options should be deselected if (opt.isSelected) deselectedChildId = opt.id; opt.isSelected = opt.isStandard ? true : !deselect; let idx = opt.requiredBy.indexOf(option.id); _.pullAt(opt.requiredBy, idx); opt.price = opt.constantPrice; return opt; } // if parent is being selected and theres a child already selected, // then no children need to be selected else if (alreadySelected && !deselect) { // if parent is being selected, // save dependent's initial selection value // so we can check if dependent option was already selected // before parent option was selected opt.alreadySelected = !!opt.isSelected; addedOptionPeers.push(opt.name); return opt; } // if parent is being selected and theres no child selected else { // additional flags for use in modals, firing auxiliary rules opt.optionInGroup = true; opt.parentIsSelected = parentIsSelected; // update option selected value, rule is not auxiliary opt.isSelected = true; if (parentIsSelected && otherParents.length) { if (opt.isSelected) { if (opt.requiredBy.indexOf(option.id) === -1) { opt.requiredBy.push(option.id); } else { let index = opt.requiredBy.indexOf(option.id); _.pullAt(opt.requiredBy, index); } opt.price = opt.price === 0 ? 0 : self.priceOverride ? 0 : opt.constantPrice; activation.flagChange(opt); return opt; } } if (opt.requiredBy.indexOf(option.id) === -1) { opt.requiredBy.push(option.id); } if (activation.isAuxiliary) opt.price = opt.constantPrice; else opt.price = self.priceOverride ? 0 : opt.constantPrice; addedOption = opt.name; addedOptionId = opt.id; activation.flagChange(opt); alreadySelected = opt.isSelected; } } return opt; }) .value(); // Process the peer group rule of children on select or deselect try { let optionPeerRule = deselect ? haas.services.rules.rules.filter(rule => rule.type === 'peer-group').find(peerRule => peerRule.models.includes(activation.context.id) && peerRule.options.includes(deselectedChildId)) : haas.services.rules.rules.filter(rule => rule.type === 'peer-group').find(peerRule => peerRule.models.includes(activation.context.id) && peerRule.options.includes(addedOptionId)); if (optionPeerRule) { let optPeers = optionPeerRule.options; optPeers.forEach(peer => { if (addedOptionId) { if (!peer || peer === addedOptionId) return; let peerObj = nextOptions.find(opt => opt.id === peer); if (peerObj) { peerObj.isSelected = false; peerObj.alreadySelected = false; activation.flagChange(peerObj); } } else if (deselectedChildId) { if (!peer || peer === deselectedChildId) return; let peerObj = nextOptions.find(opt => opt.id === peer); if (peerObj && peerObj.isStandard) { peerObj.isSelected = true; peerObj.alreadySelected = true; activation.flagChange(peerObj); } } }); } } catch (e) { console.log(e); } if (addedOption.length > 0) { activation.setVars({ action: 'added', primaryOptionText: addedOption, secondaryOptionText: addedOptionPeers, multipleDependencies : true, messageId: 'prerequisiteChoiceModal' }); } return activation.resolve(Object.assign({}, activation.context, {options: nextOptions})); } })(); /* global haas, _ */ (function () { 'use strict'; var logger = haas.LOGGER; haas.rules.peerGroup = peerGroup; function peerGroup (activation) { var CancelReasons = haas.models.OptionRuleContext.CancelReasons; var self = this; var option = activation.option; var options = activation.context.options; var deselect = (!activation.isAuxiliary) ? !activation.isSelection : !activation.option.isSelected; var nextContext; var nextOptions; // get whole peer object, not just ID var peers = options.filter(function (option) { return (self.peers.indexOf(option.id) !== -1); }); // GATHER INFORMATION ABOUT OPTION AND ITS PEERS var optionInGroup = !!(_.find(peers, {id: option.id})); // locate any peers in the peer group that are already selected var selectedPeers = _.filter(peers, function(peer){ return (peer.isSelected === true && peer.id !== option.id); }); // Locate any selected peers that are required by selected, dependent parents // EXAMPLE: ON VF-6, SMTC-24 and SMTC-40 have a peer rule between them. // 30K-30T requires SMTC-24. If SMTC-40 is being selected, check to see if // SMTC-24 is among the selected peers, and if its parent (30K-30T) is currently selected. // If it is, it's required by its parent and shouldn't be deselected. var requiredPeers = _.filter(selectedPeers, function(peer){ return (peer.hasOwnProperty('requiredBy') && peer.requiredBy.length && peer.parentIsSelected); }); // is the only selected peer the option, itself? option.selfOnlySelectedPeer = (selectedPeers.length === 0 && selectedPeers.indexOf(option) === -1); // is the option required by a dependencyGroup rule, and its parent is selected? option.selfRequiredByParent = option.isSelected && option.hasOwnProperty('requiredBy') && option.requiredBy.length && option.parentIsSelected; // Hard-Coded Cancel Rule for HSK Tool Changers if (option.categoryUniqueName === 'tool_changer' && option.id.includes('HSK')) { let selectedSpindle = options.find(opt => opt.categoryUniqueName === 'spindle' && opt.isSelected); if (!deselect && !selectedSpindle.id.includes('HSK')) { activation.setVars({ blockedBy: selectedSpindle, messageId: 'hskBlockedModal' }); return activation.cancel(CancelReasons.hskToolChangerBlocked); } if (deselect && selectedSpindle.id.includes('HSK')) { return activation.cancel(CancelReasons.parentIsSelected); } } // hack for existing 5AXD / 4AXD / 4TH-AXIS-RTY rules // until we can rewrite the ruleset; remove as soon as rewrite is done if(option.id === '4AXD' || option.id === '4TH-AXIS-RTY') { var parent = _.find(options, {id: "5AXD"}); if (parent && parent.isSelected && !activation.isAuxiliary && !option.hasOwnProperty('alreadyPeerChecked') ) { var optionPeer = _.find(peers, function(peer){ return (peer.id !== option.id); }); // if 5AXD is selected, toggle the two like radio buttons // (they're both compatible but mutually exclusive, like a Live Tooling rule). // Check for machine has both 4AXD and 4TH-AXIS-RTY options, if not, skip if (optionPeer) { nextOptions = options.map(function (opt) { if (opt.id === option.id){ opt.isSelected = activation.isSelection; activation.flagChange(opt); } if (opt.id === optionPeer.id){ opt.isSelected = !activation.isSelection; activation.flagChange(opt); } return opt; }); return activation.resolve(Object.assign({}, activation.context, {options: nextOptions})); } } // otherwise proceed as usual } // REASONS TO CANCEL // if the option is not in the group if (!optionInGroup) { return activation.cancel(CancelReasons.notInGroup); } //if this is an auxiliary peer check, and the peer being checked is already selected, // and it has no selected peers and is not a deselect, cancel the peer check. if (activation.isAuxiliary && option.selfOnlySelectedPeer && !deselect) { return activation.cancel(CancelReasons.auxiliaryActivation); } // if deselecting a standard option, cancel if (deselect && option.isStandard) { if((!activation.isAuxiliary && option.isSelected) || (activation.isAuxiliary && !option.isSelected)){ option.isSelected = true; return activation.cancel(CancelReasons.standardOption); } } // Accommodate child-peer rules, cancel if option has a parent selected if (deselect && option.requiredBy) { var parentSelected = false; _.each(option.requiredBy, function(optId) { parentSelected = parentSelected || !!_.find(options, {id: optId, isSelected: true}); }); if (parentSelected) { option.isSelected = true; return activation.cancel(CancelReasons.parentIsSelected); } } // If the peer being selected has a peer that another option requires, // do not select this peer, and do not deselect the dependent option. // EXAMPLE: On VM-6, 30K-30T requires SMTC-24. SMTC-40 is a peer of SMTC-24. // If 30K-30T and SMTC-24 are both already selected, // and a user clicks on SMTC-40 to select it, // SMTC-24 should not be de-selected because it is required by 30K-30T, // and SMTC-40 should not be selected because its peer is both selected and required. if (!deselect && requiredPeers.length && !activation.isAuxiliary) { var requiredParents = []; _.forEach(requiredPeers, function(peer){ if (peer.requiredBy && peer.requiredBy.length) { _.forEach(peer.requiredBy, function (parent) { if (parent !== undefined && requiredParents.indexOf(parent) === -1) { var requiredParent = _.find(options, {id: parent, isSelected: true}); if(requiredParent) requiredParents.push(_.find(options, {id: parent, isSelected: true})); } }); } }); if (requiredParents.length > 0) { // cancel the activation and throw a modal. option.isSelected = false; activation.setVars({ parentOptions: _.uniq(requiredParents), // send only one of each parent in case there are multiples peerOptions: requiredPeers, messageId: 'peerRequiredByAnotherOption' }); return activation.cancel(CancelReasons.peerRequiredByAnotherOption); } } // if there's only one peer // (sometimes a machine is listed in a rule but does not have all options associated with the rule) if (peers.length < 2) { if (activation.isAuxiliary) { return activation.cancel(CancelReasons.auxiliaryActivation); } // just toggle option since it has no peers option.isSelected = !deselect; nextOptions = options.slice(); var optState = _.find(nextOptions, {id: option.id}); optState.isSelected = !deselect && !activation.isAuxiliary; nextContext = Object.assign({}, activation.context, {options: nextOptions}); activation.flagChange(optState); return activation.resolve(nextContext); } // OTHERWISE, CONTINUE WITH PEER GROUP RULE LOGIC nextOptions = options.map(function (opt) { if (!!(_.find(peers, {id: opt.id}))) { var prev = !!opt.isSelected; // STANDARD LOGIC: opt.isSelected = opt.id === option.id && !deselect && !activation.isAuxiliary; // EXCEPTIONS: // If an option is required by its parent, select it if(opt.id === option.id && option.selfRequiredByParent){ opt.isSelected = true; } // if an option's peer is being deselected, and the option is standard but not selected, // select the standard peer option // EXAMPLE: two peer spindles, one standard, one non-standard. // the non-standard spindle was selected, but is being deselected, // so we select the standard peer as default. if (deselect && opt.isStandard && option.id !== opt.id) { opt.isSelected = true; } if (prev !== opt.isSelected) { activation.flagChange(opt); } } return opt; }); nextContext = Object.assign({}, activation.context, {options: options}); nextContext.options = nextOptions; return activation.resolve(nextContext); } })(); /* global haas, _ */ (function () { 'use strict'; var logger = haas.LOGGER; haas.rules.standardOption = standardOption; function standardOption (activation) { var option = activation.option; var options = activation.context.options; if (activation.isAuxiliary) { return activation.cancel(haas.models.OptionRuleContext.CancelReasons.auxiliaryActivation); } var nextOpts = _.map(options, function (opt) { if (opt.id === option.id) { option.isSelected = true; option.selectedByStandardRule = true; activation.flagChange(opt); } return opt; }); var nextContext = Object.assign({}, activation.context, {options: options}); nextContext.options = nextOpts; return activation.resolve(nextContext); } })(); (function() { haas.rules.ruleUtilsObj = function(option, options, activation, deselect) { return { option : option, options : options, activation : activation, deselect: deselect, anyOptionsSelected : function(arr) { var selected = arr.map(this.optionIsSelected); return !_.every(selected); }, optionIsSelected : function(optionId) { var option = this.getOptionById(optionId, this.options); return option.isSelected; }, getOptionById : function(optionId) { return _.find(this.options, {id: optionId}); }, getOptionsByIds : function(ids) { return this.options.filter(function (opt) { return ids.indexOf(opt.id) !== -1; }); }, isStandardOption : function(id) { var opt = _.find(this.options, {id: id}); return opt ? opt.isStandard : false; }, selectStandardOption : function(ids) { var opts = this.getOptionsByIds(ids); var standardOpt = _.find(opts, {isStandard: true}); this.activation.flagChange(standardOpt); standardOpt.isSelected = true; }, deselectOption : function(optionId, isFree) { var option = this.getOptionById(optionId); if (!option) return; // if child was included for free, return child option's price // to its constant price if (isFree === true && option.constantPrice){ option.price = option.constantPrice; } this.activation.flagChange(option); option.isSelected = false; }, selectOption : function(optionId, isFree) { var option = this.getOptionById(optionId); if (!option) return; // if childr option is included for free, set its price to zero if (isFree === true){ option.price = 0; } this.activation.flagChange(option); option.isSelected = true; }, resolveWithContext : function() { return this.activation.resolve(Object.assign({}, this.activation.context, {options: this.options})); }, peerGroup : function(ids, isLiveTooling) { var self = this; var allIds = [this.option.id].concat(ids); if (self.deselect) { if (isLiveTooling) { var LT4K = this.getOptionById('LT-4K'); var selectedIDs = _.filter(ids, {isSelected:true}); if (LT4K !== undefined && LT4K.isSelected && selectedIDs.length === 0) { activation.setVars({ parentOption: LT4K, messageId: 'requiredChildModal' }); } else { this.deselectOption(self.option.id); this.selectStandardOption(allIds); } } else { this.deselectOption(self.option.id); this.selectStandardOption(allIds); } return this.resolveWithContext(); } this.getOptionsByIds(allIds).forEach(function (opt) { opt.isSelected = opt.id === self.option.id; }); return this.resolveWithContext(); } }; }; })(); /* global haas, _ */ (function () { 'use strict'; haas.rules.liveTooling = liveTooling; function liveTooling (activation) { var CancelReasons = haas.models.OptionRuleContext.CancelReasons; var option = Object.assign({}, activation.option); var options = activation.context.options.slice(); var deselect = !activation.isSelection; var currentModel = activation.context.id; // Initialize an object for the rule utils var ruleUtils = haas.rules.ruleUtilsObj(option, options, activation, deselect); /**************************** * Option Selectors * ****************************/ var BMT6512NLT = ruleUtils.getOptionById('BMT65-12-NLT'); var BMT6524NLT = ruleUtils.getOptionById('BMT65-24-NLT'); var BOT = ruleUtils.getOptionById('BOT'); var BOT10 = ruleUtils.getOptionById('BOT10'); var CABCOOL = ruleUtils.getOptionById('CABCOOL'); var LT4K = ruleUtils.getOptionById('LT-4K'); var LT6KUP = ruleUtils.getOptionById('LT-6K-UP'); var LTBMT6512 = ruleUtils.getOptionById('LT-BMT65-12'); var LTBMT6524 = ruleUtils.getOptionById('LT-BMT65-24'); var LTS1 = ruleUtils.getOptionById('LTS-1'); var PTS = ruleUtils.getOptionById('PTS'); var SO = ruleUtils.getOptionById('SO'); var subSpindleA25 = ruleUtils.getOptionById('SUB-SPDL-A2-5'); var VB10 = ruleUtils.getOptionById('VB10'); var VDI = ruleUtils.getOptionById('VDI'); var VDI10 = ruleUtils.getOptionById('VDI10'); var VB40 = ruleUtils.getOptionById('VB40'); /**************************** * Option Handler * ****************************/ var optionHandlerMap = { 'BMT65-12-NLT': function () { return ruleUtils.peerGroup(['BOT' , 'VDI', 'BMT65-24-NLT', 'LT-BMT65-12', 'LT-BMT65-24'], true); }, 'BMT65-24-NLT': function () { return ruleUtils.peerGroup(['BOT' , 'VDI', 'BMT65-12-NLT', 'LT-BMT65-12', 'LT-BMT65-24'], true); }, 'BOT': function () { if (LT4K !== undefined && LT4K.isSelected) { activation.setVars({ blockedBy: LT4K, messageId: 'blockedModal' }); return activation.resolve(activation.context); } if (LTBMT6512 !== undefined && LTBMT6512.isSelected) { activation.setVars({ blockedBy: LTBMT6512, messageId: 'blockedModal' }); return activation.resolve(activation.context); } if (LTBMT6524 !== undefined && LTBMT6524.isSelected) { activation.setVars({ blockedBy: LTBMT6524, messageId: 'blockedModal' }); return activation.resolve(activation.context); } if (LT6KUP !== undefined && LT6KUP.isSelected) { activation.setVars({ blockedBy: LT6KUP, messageId: 'blockedModal' }); return activation.resolve(activation.context); } if (subSpindleA25 !== undefined && subSpindleA25.isSelected) { activation.setVars({ blockedBy: subSpindleA25, messageId: 'blockedModal' }); return activation.resolve(activation.context); } // if BOT is not blocked, treat as peer group. if (BMT6512NLT !== undefined && BMT6524NLT !== undefined ) { return ruleUtils.peerGroup(['BMT65-12-NLT', 'BMT65-24-NLT', 'LT-BMT65-12', 'LT-BMT65-24', 'VDI'], true); } else { return ruleUtils.peerGroup(['LT-BMT65-12', 'LT-BMT65-24', 'VDI'], true); } }, 'BOT10': function () { if (currentModel !== "ST-10Y" && currentModel !== "ST-15Y"){ if (LT4K !== undefined && LT4K.isSelected) { activation.setVars({ blockedBy: LT4K, messageId: 'blockedModal' }); return activation.resolve(activation.context); } } if (LT6KUP !== undefined && LT6KUP.isSelected) { activation.setVars({ blockedBy: LT6KUP, messageId: 'blockedModal' }); return activation.resolve(activation.context); } if (subSpindleA25 !== undefined && subSpindleA25.isSelected) { activation.setVars({ blockedBy: subSpindleA25, messageId: 'blockedModal' }); return activation.resolve(activation.context); } return ruleUtils.peerGroup(['VB10', 'VDI10'], true); }, 'VB10': function () { if(['ST-10','ST-10Y','ST-15','ST-15Y'].indexOf(activation.context.id) !== -1) { if (LT4K !== undefined && LT4K.isSelected) { // log selection state so modal is not thrown // if this option was already selected before LT-4K VB10.alreadySelected = !deselect; } } if(deselect && subSpindleA25 !== undefined && subSpindleA25.isSelected){ activation.setVars({ parentOption: subSpindleA25 }); return activation.cancel(CancelReasons.parentIsSelected); } return ruleUtils.peerGroup(['BOT10', 'VDI10'], true); }, 'VDI': function () { if (LTBMT6512 !== undefined && LTBMT6512.isSelected) { if(deselect){ activation.setVars({ parentOption: LTBMT6512 }); return activation.cancel(CancelReasons.parentIsSelected); } } else if (LTBMT6524 !== undefined && LTBMT6524.isSelected) { if(deselect){ activation.setVars({ parentOption: LTBMT6524 }); return activation.cancel(CancelReasons.parentIsSelected); } } // if not blocked, treat as peer group if (BMT6512NLT !== undefined && BMT6524NLT !== undefined ) { return ruleUtils.peerGroup(['BOT', 'BMT65-12-NLT', 'BMT65-24-NLT', 'LT-BMT65-12', 'LT-BMT65-24'], true); } else { return ruleUtils.peerGroup(['BOT', 'LT-BMT65-12', 'LT-BMT65-24'], true); } }, 'VDI10': function () { if (subSpindleA25 !== undefined && subSpindleA25.isSelected) { activation.setVars({ blockedBy: subSpindleA25, messageId: 'blockedModal' }); return activation.resolve(activation.context); } else if (LT4K !== undefined && LT4K.isSelected) { if(deselect){ activation.setVars({ parentOption: LT4K }); return activation.cancel(CancelReasons.parentIsSelected); } } else { // log selection state so modal is not thrown // if this option was already selected before LT-4K VDI10.alreadySelected = !deselect; } return ruleUtils.peerGroup(['BOT10', 'VB10'], true); }, 'LT-4K': function () { var primaryOption; var secondaryOption; if (deselect) { // if this is a deselection: if (LT4K.isStandard) { return activation.cancel(CancelReasons.standardOption); } ruleUtils.deselectOption('LT-4K'); if(SO !== undefined && !SO.isStandard){ ruleUtils.deselectOption('SO', true); } if(LT6KUP !== undefined && LT6KUP.isSelected){ ruleUtils.deselectOption('LT-6K-UP'); } if(['ST-10','ST-10Y','ST-15','ST-15Y'].indexOf(activation.context.id) !== -1) { if (VDI10.isSelected || VB10.isSelected) { if(VDI10.isSelected && !VDI10.alreadySelected){ // deselect VDI10 if it was not selected primaryOption = VDI10; secondaryOption = VB10; ruleUtils.deselectOption('VDI10'); } if(VB10.isSelected && !VB10.alreadySelected && subSpindleA25 !== undefined && !subSpindleA25.isSelected ) { // deselect VB10 if it was not already selected, // UNLESS SUB-SPDL-A2-5 is selected, which requires VB10, so it should remain selected. primaryOption = VB10; secondaryOption = VDI10; ruleUtils.deselectOption('VB10'); } } } if(['ST-20','ST-25','ST-30','ST-35'].indexOf(activation.context.id) !== -1) { if(VDI !== undefined && VDI.isSelected && !VDI.alreadySelected){ // deselect VDI if it was not selected ruleUtils.deselectOption('VDI'); activation.setVars({ dependencyGroup: [VDI], messageId: 'prerequisiteModal', action: 'removed' }); // if VDI has been deselected, // Re-select standard option ruleUtils.selectOption('BOT'); } } if(activation.context.id === 'ST-10' || activation.context.id === 'ST-15'){ primaryOption = primaryOption || VB10; secondaryOption = secondaryOption || VDI10; if(!primaryOption.isSelected && !secondaryOption.isSelected && subSpindleA25 !== undefined && !subSpindleA25.isSelected){ activation.setVars({ action: 'removed', dependencyGroup: [SO], primaryOptionText: primaryOption.name, secondaryOptionText: [secondaryOption.name], multipleDependencies : true, messageId: 'prerequisiteChoiceModal' }); // if neither VDI10 or VB10 are selected, // and SUB-SPDL-A2-5 is not selected // Re-select standard option ruleUtils.selectOption('BOT10'); } } if(['ST-40','ST-40L','ST-45','ST-45L', 'ST-50', 'ST-55'].indexOf(activation.context.id) !== -1) { activation.setVars({ dependencyGroup: [SO], messageId: 'prerequisiteModal', action: 'removed' }); } return ruleUtils.resolveWithContext(); } // if this is a selection: ruleUtils.selectOption('LT-4K'); if(!SO.isSelected){ ruleUtils.selectOption('SO', true); } if (['ST-10','ST-10Y','ST-15','ST-15Y'].indexOf(activation.context.id) !== -1) { ruleUtils.deselectOption('BOT10'); if (VDI10.isSelected || VB10.isSelected) { return ruleUtils.resolveWithContext(); } if(VB10.isSelected){ VB10.alreadySelected = true; } else { VB10.alreadySelected = false; } ruleUtils.selectOption('VB10'); // On ST-10 or ST-15, clicking on LT-4K should bring up a popup that mentions both VB10 and VDI10. // VB10 should be selected by default. // LT-4K also requires SO. // On the ST-10Y or ST-15Y, SO is standard, as is LT-4K, so no popup is necessary; // VB10 and VDI10 should simply operate as a peer group // and all other options should remain selected. if(activation.context.id === 'ST-10' || activation.context.id === 'ST-15'){ primaryOption = VB10; secondaryOption = VDI10; activation.setVars({ action: 'added', dependencyGroup: [SO], primaryOptionText: primaryOption.name, secondaryOptionText: [secondaryOption.name], multipleDependencies : true, messageId: 'prerequisiteChoiceModal' }); } return ruleUtils.resolveWithContext(); } else if (['ST-20','ST-25','ST-30','ST-35'].indexOf(activation.context.id) !== -1) { ruleUtils.deselectOption('BOT'); if (VDI.isSelected) { return ruleUtils.resolveWithContext(); } if(VDI.isSelected){ VDI.alreadySelected = true; } else { VDI.alreadySelected = false; } ruleUtils.selectOption('VDI'); activation.setVars({ dependencyGroup: [VDI], messageId: 'prerequisiteModal', action: 'added' }); return ruleUtils.resolveWithContext(); } else { ruleUtils.deselectOption('BOT40'); ruleUtils.deselectOption('BOT50'); if (VB40.isSelected) { activation.setVars({ addOnText: SO.name, messageId: 'addonModal' }); } else{ ruleUtils.selectOption('VB40'); activation.setVars({ option: activation.option, addOnCostText: VB40.name, addOnNoCostText: SO.name, action: 'added', messageId: 'addonCostNoCostModal' }); } return ruleUtils.resolveWithContext(); } }, /*'SUB-SPDL-A2-5': function () { // SUB-SPDL-A2-5 requires CABCOOL at no additional cost. // SUB-SPDL-A2-5 requires VB10, but it costs normal amount // SUB-SPDL-A2-5 can only use VB10, and may not be used with VDI10 or BOT10 // VB10 may also be required by LT-4K // SUB-SPDL-A2-5 is incompatible with LTS-1 // SUB-SPDL-A2-5 is incompatible with PTS if(deselect){ deselectOption('SUB-SPDL-A2-5'); if (CABCOOL !== undefined && CABCOOL.alreadySelected !== true) { deselectOption('CABCOOL', true); } if (VB10 !== undefined && VB10.isSelected) { if(!VB10.alreadySelected && !LT4K.isSelected ){ // if VB10 was not already selected and LT-4K are selected, // deselect VB10 and re-select standard option deselectOption('VB10'); selectOption('BOT10'); } activation.setVars({ option: activation.option, addOnCostText: (VB10 !== undefined && !VB10.alreadySelected) ? VB10.name : 'false', addOnNoCostText: (CABCOOL !== undefined && !CABCOOL.alreadySelected) ? CABCOOL.name : 'false', action: (deselect) ? 'removed' : 'added', messageId: 'addonDeselectCostNoCostModal' }); } } else { if (LTS1 !== undefined && LTS1.isSelected) { activation.setVars({ blockedBy: LTS1, messageId: 'blockedModal' }); return activation.resolve(activation.context); } if (PTS !== undefined && PTS.isSelected) { activation.setVars({ blockedBy: PTS, messageId: 'blockedModal' }); return activation.resolve(activation.context); } selectOption('SUB-SPDL-A2-5'); if (CABCOOL !== undefined) { CABCOOL.alreadySelected = false; if (!CABCOOL.isSelected) { selectOption('CABCOOL', true); } else { CABCOOL.alreadySelected = true; } } if (VB10 !== undefined) { VB10.alreadySelected = false; if (!VB10.isSelected) { if (BOT10 !== undefined && BOT10.isSelected) { // if BOT10 is selected, deselect it. deselectOption('BOT10'); } else if (VDI10 !== undefined && VDI10.isSelected) { // if VDI10 exists, deselect it. deselectOption('VDI10'); } // if VB10 exists, select it. selectOption('VB10'); } else { // alreadySelected is used to show/hide parts of the modal VB10.alreadySelected = true; } activation.setVars({ option: activation.option, addOnCostText: (VB10 !== undefined && !VB10.alreadySelected) ? VB10.name : 'false', addOnNoCostText: (CABCOOL !== undefined && !CABCOOL.alreadySelected) ? CABCOOL.name : 'false', action: (deselect) ? 'removed' : 'added', messageId: 'addonCostNoCostModal' }); } } return resolveWithContext(); },*/ 'LT-6K-UP': function () { // LT-6K-UP is a speed upgrade for ALL live tooling options: LT-4K, LT-BMT65-12, and LT-BMT65-24. // – LT-4K + LT-6K-UP for ST-10/Y, ST-15/Y, ST-40/L, and ST-45/L. // – LT-BMT65-12 and LT-BMT65-24 for ST-20 through ST-35, including Y models, and DS-30Y // – You must select one of the live tooling options before selecting LT-6K-UP. // – If the base live tooling option (4000-rpm) is deselected, then LT-6K-UP should also be deselected. var primaryOption; var secondaryOption; if (deselect) { ruleUtils.deselectOption('LT-6K-UP'); return ruleUtils.resolveWithContext(); } else { ruleUtils.selectOption('LT-6K-UP'); if(!SO.isSelected){ ruleUtils.selectOption('SO', true); } if (LT4K !== undefined && !LT4K.isSelected){ // if LT4K is the only live tooling selection, select it // -- Deselect BOT10 (and don't allow it to be selected) // -- Select VB (and allow VDI to be selected as a peer) if((LTBMT6512 === undefined && LTBMT6524 === undefined) || (LTBMT6512 !== undefined && !LTBMT6512.isSelected && LTBMT6524!== undefined && !LTBMT6524.isSelected)) { ruleUtils.selectOption('LT-4K'); if (['ST-10','ST-15'].indexOf(activation.context.id) !== -1) { ruleUtils.deselectOption('BOT10'); if (VDI10.isSelected || VB10.isSelected) { return ruleUtils.resolveWithContext(); } if(VB10.isSelected) { VB10.alreadySelected = true; } else { VB10.alreadySelected = false; } ruleUtils.selectOption('VB10'); // On ST-10 or ST-15, // selecting LT-4K via LT-6K-UP // should bring up a popup that mentions both VB10 and VDI10. // VB10 should be selected by default. // LT-4K also requires SO. // On the ST-10Y or ST-15Y, SO is standard, as is LT-4K, so no popup is necessary; // VB10 and VDI10 should simply operate as a peer group // and all other options should remain selected. if(activation.context.id === 'ST-10' || activation.context.id === 'ST-15'){ primaryOption = VB10; secondaryOption = VDI10; activation.setVars({ action: 'added', dependencyGroup: [SO, LT4K], primaryOptionText: primaryOption.name, secondaryOptionText: [secondaryOption.name], multipleDependencies : true, messageId: 'prerequisiteChoiceModal' }); } // if LT-4K, AND LT-BMT65-12 AND LT-BMT65-24 are available, select LT-4K by default if(LTBMT6512 !== undefined && !LTBMT6512.isSelected && LTBMT6524!== undefined && !LTBMT6524.isSelected){ activation.setVars({ action: 'added', dependencyGroup: [SO], primaryOptionText: LT4K.name, secondaryOptionText: [LTBMT6512.name, LTBMT6524.name], multipleDependencies : false, messageId: 'prerequisiteChoiceModal' }); } return ruleUtils.resolveWithContext(); } else { ruleUtils.deselectOption('BOT40'); ruleUtils.deselectOption('BOT50'); if (VB40.isSelected && LT4K.isSelected) { activation.setVars({ addOnText: SO.name, messageId: 'addonModal' }); } if (VB40.isSelected && !LT4K.isSelected) { activation.setVars({ option: activation.option, addOnCostText: LT4K.name, addOnNoCostText: SO.name, action: 'added', messageId: 'addonCostNoCostModal' }); } else if (!VB40.isSelected && !LT4K.isSelected) { ruleUtils.selectOption('VB40'); activation.setVars({ option: activation.option, addOnCostText: LT4K.name + ' and ' + VB40.name, addOnNoCostText: SO.name, action: 'added', messageId: 'addonCostNoCostModal' }); } else{ ruleUtils.selectOption('VB40'); activation.setVars({ option: activation.option, addOnCostText: VB40.name, addOnNoCostText: SO.name, action: 'added', messageId: 'addonCostNoCostModal' }); } return ruleUtils.resolveWithContext(); } } } else if(LTBMT6512 !== undefined || LTBMT6524 !== undefined){ // if LT-4K is unavailable, but // LT-BMT65-12 AND LT-BMT65-24 are available, select LT-BMT65-12 by default if (['ST-20','ST-25','ST-30','ST-35'].indexOf(activation.context.id) !== -1) { ruleUtils.deselectOption('BOT'); } if(!LTBMT6512.isSelected && !LTBMT6524.isSelected){ ruleUtils.selectOption('LT-BMT65-12'); activation.setVars({ action: 'added', dependencyGroup: [SO], primaryOptionText: LTBMT6512.name, secondaryOptionText: [LTBMT6524.name], multipleDependencies : false, messageId: 'prerequisiteChoiceModal' }); } } return ruleUtils.resolveWithContext(); } }, 'BOT40': function () { return ruleUtils.peerGroup(['BOT50', 'VB40', 'LT-4K'], true); }, 'BOT50': function () { return ruleUtils.peerGroup(['BOT40', 'VB40', 'LT-4K'], true); }, 'VB40': function () { return ruleUtils.peerGroup(['BOT40', 'BOT50'], true); }, 'LT-BMT65-12': function () { var dependencyGroup = []; if(deselect){ ruleUtils.deselectOption('LT-BMT65-12'); if(LT6KUP.isSelected){ ruleUtils.deselectOption('LT-6K-UP'); dependencyGroup.push(LT6KUP); } if(!SO.isStandard){ ruleUtils.deselectOption('SO', true); dependencyGroup.push(SO); } if(dependencyGroup.length !== 0){ if(dependencyGroup.length === 2){ activation.setVars({ option: activation.option, addOnCostText: LT6KUP.name, addOnNoCostText: SO.name, action: 'removed', messageId: 'addonDeselectCostNoCostModal' }); } else { activation.setVars({ dependencyGroup: dependencyGroup, messageId: 'prerequisiteModal', action: 'removed' }); } } activation.setVars({ dependencyGroup: [SO], messageId: 'prerequisiteModal', action: 'removed' }); // select standard option if deselecting if (BOT !== undefined && !BOT.isSelected) { ruleUtils.selectOption('BOT'); } } else { // deselect any other peers if (BOT !== undefined && BOT.isSelected) { ruleUtils.deselectOption('BOT'); } if (LTBMT6524.isSelected) { ruleUtils.deselectOption('LT-BMT65-24'); } if(BMT6512NLT !== undefined && BMT6512NLT.isSelected){ ruleUtils.deselectOption('BMT65-12-NLT'); } if(BMT6524NLT !== undefined && BMT6524NLT.isSelected){ ruleUtils.deselectOption('BMT65-24-NLT'); } if(!SO.isSelected && !SO.isStandard ){ ruleUtils.selectOption('SO', true); activation.setVars({ addOnText: SO.name, messageId: 'addonModal' }); } ruleUtils.selectOption('LT-BMT65-12'); } return ruleUtils.resolveWithContext(); }, 'LT-BMT65-24': function () { var dependencyGroup = []; if(deselect){ ruleUtils.deselectOption('LT-BMT65-24'); if(LT6KUP.isSelected){ ruleUtils.deselectOption('LT-6K-UP'); dependencyGroup.push(LT6KUP); } if(!SO.isStandard){ ruleUtils.deselectOption('SO', true); dependencyGroup.push(SO); } if(dependencyGroup.length !== 0){ if(dependencyGroup.length === 2){ activation.setVars({ option: activation.option, addOnCostText: LT6KUP.name, addOnNoCostText: SO.name, action: 'removed', messageId: 'addonDeselectCostNoCostModal' }); } else { activation.setVars({ dependencyGroup: dependencyGroup, messageId: 'prerequisiteModal', action: 'removed' }); } } // select standard option if deselecting if (BOT !== undefined && !BOT.isSelected) { ruleUtils.selectOption('BOT'); } } else { // deselect any other peers if (BOT !== undefined && BOT.isSelected) { ruleUtils.deselectOption('BOT'); } if (LTBMT6512.isSelected) { ruleUtils.deselectOption('LT-BMT65-12'); } if(BMT6512NLT !== undefined && BMT6512NLT.isSelected){ ruleUtils.deselectOption('BMT65-12-NLT'); } if(BMT6524NLT !== undefined && BMT6524NLT.isSelected){ ruleUtils.deselectOption('BMT65-24-NLT'); } ruleUtils.selectOption('LT-BMT65-24'); if(!SO.isSelected && !SO.isStandard ){ ruleUtils.selectOption('SO', true); activation.setVars({ addOnText: SO.name, messageId: 'addonModal' }); } } return ruleUtils.resolveWithContext(); } }; return optionHandlerMap[option.id] ? optionHandlerMap[option.id]() : activation.cancel(CancelReasons.noHandler); } })(); /* global haas, _ */ (function () { 'use strict'; haas.rules.specialModelRules = specialModelRules; function specialModelRules (activation) { var CancelReasons = haas.models.OptionRuleContext.CancelReasons; var option = Object.assign({}, activation.option); var options = activation.context.options.slice(); var deselect = !activation.isSelection; var currentModel = activation.context.id; // Initialize an object for the rule utils var ruleUtils = haas.rules.ruleUtilsObj(option, options, activation, deselect); /**************************** * Option Selectors * ****************************/ var PalletPool = ruleUtils.getOptionById('PALLET POOL'); var SMTC3040T = ruleUtils.getOptionById('SMTC-30-40T'); var SMTC5040T = ruleUtils.getOptionById('SMTC-50-40T'); var SMTC10040T = ruleUtils.getOptionById('SMTC-100-40T'); var RJHT = ruleUtils.getOptionById('RJH-TOUCH'); /**************************** * Option Handler * ****************************/ var optionHandlerMap = { }; // return the rule for the option if available, else, cancel return optionHandlerMap[option.id] ? optionHandlerMap[option.id]() : activation.cancel(CancelReasons.noHandler); } })(); /* global haas, $, _ */ (function () { 'use strict'; var getMonthlyPaymentPrice = haas.utils.getMonthlyPaymentPrice; var formatCurrency = haas.utils.formatCurrency; var discountTypes = haas.constants.promotions.discounts.type; haas.models.Option = OptionModel; function OptionModel (props) { this.price = 0; Object.assign(this, props); /** * * @type {haas.models.Promotion} */ this.promotion = this.promotion || null; this.promotions = this.promotions || []; this.getFormattedPrice = function () { return formatCurrency(this.getPrice()); }; this.getMonthlyPaymentPrice = function (months) { return getMonthlyPaymentPrice(this.getPrice(), months); }; this.hasPromotion = function () { if (!this.promotion) return false; var promo = this.promotion; var validInRegion = _.find(promo.regions, function(region){ return region === haas.region.props.region }); var validForHfo = _.find(promo.hfoIds, function(hfo){ return hfo === haas.region.props.hfoid; }); var now = new Date(); return (promo.type === "option" || (promo.type === "order" && promo.discounts[0].type === discountTypes.PERCENT)) && (!!validInRegion || !!validForHfo) && now < promo.endDate && now > promo.startDate; }; this.getPrice = function () { return this.price; }; this.getActualPrice = function () { return this.hasPromotion() ? this.getDiscountedPrice() : this.getPrice(); }; /** * Get discounted option price, stacking promotion discounts if there are multiple * @returns {Number} */ this.getDiscountedPrice = function () { if (!this.promotion) { return this.getPrice(); } if (!this.promotions || this.promotions.length === 1) { return haas.utils.applyPromotionalDiscount(this.promotion, this.getPrice()); } var totalDiscount = 0; var self = this; // Stack promotion discounts if there are multiple this.promotions.forEach(function(promo) { var discountedPrice = haas.utils.applyPromotionalDiscount(promo, self.getPrice()); // Add the difference between the full price and the discountedPrice to the total discount totalDiscount += (self.getPrice() - discountedPrice); }); return this.getPrice() - totalDiscount; }; this.getFormattedDiscountedPrice = function () { return haas.utils.formatCurrency(this.getDiscountedPrice()); }; this.getSaleTagText = function () { if (!this.promotion) { return ''; } if (!this.promotions || this.promotions.length === 1) { return this.promotion.getSaleTagText(); } var totalDiscountValue = 0; var discountType = discountTypes.PERCENT; // default to percent discount this.promotions.forEach(function(promo) { var firstDiscount = promo.discounts[0]; // If there are any flat discounts, then don't actually consider a total discount value but instead just show the 'SALE' tag if (firstDiscount.type === discountTypes.FLAT) { discountType = discountTypes.FLAT; return; } totalDiscountValue += firstDiscount.value; }); return haas.models.Promotion.GetSaleTagText(discountType, totalDiscountValue); }; } })(); /* global haas, _ */ (function () { 'use strict'; var inchesToMM = haas.utils.inchesToMM; var genUID = haas.utils.genUID;// used for anchor nav var getMonthlyPaymentPrice = haas.utils.getMonthlyPaymentPrice; var Option = haas.models.Option; var content = haas.constants.content; var promotionTypes = haas.constants.promotions.type; var discountTypes = haas.constants.promotions.discounts.type; var promotionSpecificity = haas.constants.promotions.specificity; var encodeSlingSelector = haas.utils.encodeSlingSelector; var DEFAULT_IMAGE = { path: '/content/dam/haascnc/static/placeholder-image10.jpg', alt: 'Product Image' }; var ALL = 'ALL'; var NON_STANDALONE_CATEGORIES = ['rotaries-indexers', 'bar-feeder']; var ID_BAR_FEEDER = 'HAAS BAR FEEDER'; var ID_BAR_FEEDER_V2 = 'HAAS BAR FEEDER V2'; var ID_PREFIX_AUTO_PARTS_LOADER = 'APL-'; haas.models.Machine = HaasMachine; function HaasMachine (model, meta) { if (!model) return this; var self = this; meta = meta || {}; this.selectedOptions = []; this.selectedToolingParts = []; this.selectedToolingPackage = null; this.price = 0; this.regions = model.regions; this.isAutomation = !!meta.isAutomation; this.isAssociate = !!meta.isAssociate; var parent = meta.parent || null; this.promotions = _.filter(model.promotions || [], function(promotion) { // Get promotions applicable to the user's region or HFO if (promotion.parents.length > 0) { if (!self.isAssociate || !promotion.parents.includes(parent)) { haas.LOGGER.debug("Removing promotion because it does not meet the parent machine requirement: ", promotion); return false; } } var match = (promotion.regions.includes(haas.region.props.region) || promotion.hfoIds.includes(haas.region.props.hfoid)); if (!match) { return match; } if (haas.region.props.region !== 'CN') { return match; } return match; }); this.id = model.id; this.name = model.name; this.productDetailPage = model.product_detail_page; this.imagePath = model.image.path; this.imageAlt = model.image.alt; this.category = model.category.name; this.videoIds = model.video_ids || []; this.chinaVideoIds = model.china_video_ids || []; this.categoryId = model.category.id; this.series = model.series.name; this.seriesId = model.series.id; this.tagline = model.tagline; this.group = model.series.group; this.dims = model.dims; this._hasPackages = false; this.toolingPackages = null; if(model.hasOwnProperty('sapSpecs')){ this.sapSpecs = model.sapSpecs; } if(model.hasOwnProperty('categories')){ this.categories = model.categories; } this.getLocalizedPromotionMessage = function(promotion) { if (_.isEmpty(promotion)) { return ""; } var language = haas.utils.getLanguage(); if (!_.isEmpty(promotion.localizedMessages) && !_.isEmpty(promotion.localizedMessages[language])) { return promotion.localizedMessages[language]; } return ""; }; this.getLocalizedPdpMessages = function(promotion) { if (_.isEmpty(promotion)) { return ""; } var language = haas.utils.getLanguage(); if (!_.isEmpty(promotion.localizedPdpMessages) && !_.isEmpty(promotion.localizedPdpMessages[language])) { return promotion.localizedPdpMessages[language]; } return ""; }; this.getLocalizedPromoNotes = function(promotion) { if (_.isEmpty(promotion)) { return ""; } var language = haas.utils.getLanguage(); if (!_.isEmpty(promotion.localizedPromoNotes) && !_.isEmpty(promotion.localizedPromoNotes[language])) { return promotion.localizedPromoNotes[language]; } else if (!_.isEmpty(promotion.localizedPromoNotes) && !_.isEmpty(promotion.localizedPromoNotes['en'])) { // default to english return promotion.localizedPromoNotes['en']; } return ""; }; this.getToolingHierarchy = function(filteredToolingParts) { var self = this; var subOneCats = Array.from(new Set(filteredToolingParts.reduce(function(total, part) { return total.concat(part.subCatOne); }, []))); var toolingHierarchy = {}; // Create a part hierarchy, render tooling parts according to this heirarchy subOneCats.forEach(function(cat) { var parts = filteredToolingParts.filter(function(part) { return part.subCatOne === cat; }); var subTwoCats = Array.from(new Set(parts.reduce(function(total, part) { return part.subCatTwo.length ? total.concat(part.subCatTwo) : total; }, []))); toolingHierarchy[cat] = {}; if (!subTwoCats.length) { toolingHierarchy[cat].parts = parts; toolingHierarchy[cat].type = 'one'; } else { subTwoCats.forEach(function(cat2) { var sub2Parts = parts.filter(function(part) { return part.subCatTwo === cat2; }); var subThreeCats = []; var subTwoCatsWithSubThree = []; parts.filter(part => part.subCatThree.length).forEach(part => { if (!subThreeCats.includes(part.subCatThree)) subThreeCats.push(part.subCatThree); if (!subTwoCatsWithSubThree.includes(part.subCatTwo)) subTwoCatsWithSubThree.push(part.subCatTwo); }); if (subThreeCats.length && subTwoCatsWithSubThree.includes(cat2)) { toolingHierarchy[cat][cat2] = {}; subThreeCats.forEach(function(cat3) { var sub3Parts = sub2Parts.filter(function(part) { return part.subCatThree === cat3; }); toolingHierarchy[cat][cat2][cat3] = sub3Parts; toolingHierarchy[cat].type = 'long'; toolingHierarchy[cat][cat2].level = 'three-level'; }); } else if (subThreeCats.length) { toolingHierarchy[cat][cat2] = sub2Parts; toolingHierarchy[cat].type = 'long'; } else { toolingHierarchy[cat][cat2] = sub2Parts; toolingHierarchy[cat].type = 'short'; } }); } }); return toolingHierarchy; } this.hasDetails = function () { return NON_STANDALONE_CATEGORIES.indexOf(this.categoryId) === -1; }; this.hasPackages = function () { return this._hasPackages; }; this.loadPackages = function() { var self = this; return haas.services.optionPackage.fetchOptionPackages().then(function () { var optionPackages = haas.services.optionPackage.getPackagesForModel(self.id).filter(function (pkg) { return !(pkg.industries && pkg.industries.length); }); self._hasPackages = optionPackages && optionPackages.length; }); }; /** * @param {String} [type] promotion type defaults to {@link haas.constants.promotions.type.MACHINE} * @param {String} [specificity] promotion specificity (hfo or region) defaults to {@link haas.constants.promotions.specificity.REGION} */ this.hasPromotionOfSpecificity = function(type, specificity) { type = type || promotionTypes.MACHINE; specificity = specificity || promotionSpecificity.REGION; var now = new Date(); var promos = _.filter(this.promotions, function (promo) { if (specificity === promotionSpecificity.HFO) { var validForHfo = _.find(promo.hfoIds, function(hfo){ return hfo === haas.region.props.hfoid; }); return promo.type === type && validForHfo && now < promo.endDate && now > promo.startDate; } if (specificity === promotionSpecificity.REGION) { var validForRegion = _.find(promo.regions, function(region){ return region === haas.region.props.region; }); return promo.type === type && validForRegion && now < promo.endDate && now > promo.startDate; } return false; }); return promos.length > 0; }; /** * Check if configuration has an applicable promotion of the specified type. * If the type is {@link haas.constants.promotions.type.OPTION}, then check if there's an option promotion met by the configuration's * selected options. * @param {String} [type] promotion type defaults to {@link haas.constants.promotions.type.MACHINE} * @param {String} [specificity] promotion specificity (hfo or region) defaults to {@link haas.constants.promotions.specificity.REGION} * @returns {boolean} */ this.hasPromotion = function (type, specificity) { if (!this.promotions || !this.promotions.length) return false; var now = new Date(); type = type || promotionTypes.MACHINE; var promos = _.filter(this.promotions, function (promo) { // TODO: We've already filtered promotions by region and HFO when initializing. Do we need to filter by region and HFO again here? var validInRegion = _.find(promo.regions, function(region){ return region === haas.region.props.region }); var validForHfo = _.find(promo.hfoIds, function(hfo){ return hfo === haas.region.props.hfoid; }); var valid = false; if (specificity === promotionSpecificity.HFO) { valid = !!validForHfo; } else if (specificity === promotionSpecificity.REGION) { valid = !!validInRegion; } else { valid = (!!validInRegion || !!validForHfo); } return promo.type === type && valid && now < promo.endDate && now > promo.startDate; }); if (!promos.length) return false; if (type === promotionTypes.OPTION) { var self = this; var validPromosArr; var hfoSpecificPromos = _.filter(promos, function(promo) { return !_.isEmpty(promo.hfoIds); }); if (!_.isEmpty(hfoSpecificPromos)) { // If there are any HFO-specific option promos, then look at those only validPromosArr = hfoSpecificPromos.map(function (promo) { var selectedOptionIds = _.map(self.getSelectedOptions(), 'id'); var intersection = _.intersection(promo.options, selectedOptionIds); return !!intersection.length; }); } else { // Otherwise, look at any region-specific option promos validPromosArr = promos.map(function (promo) { var selectedOptionIds = _.map(self.getSelectedOptions(), 'id'); var intersection = _.intersection(promo.options, selectedOptionIds); return !!intersection.length; }); } return validPromosArr.indexOf(true) !== -1; } if (type === promotionTypes.TOOLING) { var self = this; var validPromosArr; var hfoSpecificPromos = _.filter(promos, function(promo) { return !_.isEmpty(promo.hfoIds); }); if (!_.isEmpty(hfoSpecificPromos)) { // If there are any HFO-specific option promos, then look at those only validPromosArr = hfoSpecificPromos.map(function (promo) { var selectedToolingIds = _.map(self.getSelectedToolingParts(), 'partId'); var intersection = _.intersection(promo.toolingParts, selectedToolingIds); return !!intersection.length; }); } else { // Otherwise, look at any region-specific option promos validPromosArr = promos.map(function (promo) { var selectedToolingIds = _.map(self.getSelectedToolingParts(), 'partId'); var intersection = _.intersection(promo.toolingParts, selectedToolingIds); return !!intersection.length; }); } return validPromosArr.indexOf(true) !== -1; } if (type === promotionTypes.TOOLING) { } return true; }; this.hasOrderPromotion = function() { return this.hasPromotion(promotionTypes.ORDER); }; this.hasFlatOrderPromotion = function() { return this.hasPromotion(promotionTypes.ORDER) && this.getOrderPromotion().discounts[0].type === discountTypes.FLAT; }; this.hasPercentageOrderPromotion = function() { return this.hasPromotion(promotionTypes.ORDER) && this.getOrderPromotion().discounts[0].type === discountTypes.PERCENT; }; this.hasToolingPackagePromo = function(packageName) { return this.getToolingPackagePromotions().find(tp => tp.toolingPackageName === packageName); }; this.hasMachinePromotionMessage = function() { return this.getMachinePromotionMessages().length > 0; }; this.hasOptionPromotionMessage = function() { // prevent duplicate promo messages if theres a order percentage promo return this.getOptionPromotionMessages().length > 0 && !this.getOrderPromotionMessages().length > 0; }; this.hasOrderPromotionMessage = function() { return this.getOrderPromotionMessages().length > 0; }; this.isBarFeeder = function() { return (this.id === ID_BAR_FEEDER || this.id === ID_BAR_FEEDER_V2); }; this.isAutoPartsLoader = function() { return (this.id && this.id.indexOf(ID_PREFIX_AUTO_PARTS_LOADER) === 0); }; this.hasSelectedOptions = function () { return !!this.getSelectedOptions().length; }; this.hasSelectedTooling = function () { return !!this.getSelectedToolingParts().length; }; /** * If there are applicable OptionPrice promotion, then calculate the total option price after taking any Option promotion discounts, and check * if the minimum required option price of the OptionPrice promotion is met. * @returns {boolean} */ this.meetsMinimumTotalOptionPrice = function () { var selectedOptions = this.getSelectedOptions(); var associate = !this.isAssociate ? _.find(this.associations, {isSelected: true}) : null; var automation = !this.isAutomation ? _.find(this.automations, {isSelected: true}) : null; var optionsPrice = _.sumBy(selectedOptions, function (opt) { return opt.getActualPrice(); }); var totalOptionPricePromos = this.getTotalOptionPricePromotions(); var meetsMinimum = false; if (totalOptionPricePromos.length > 0) { _.forEach(totalOptionPricePromos, function(totalOptionPricePromo) { var nonexcludedOptionsPrice = getTotalNonExcludedOptionsPrice(selectedOptions, totalOptionPricePromo, false); if (associate) { nonexcludedOptionsPrice += getTotalNonExcludedOptionsPrice(associate.getSelectedOptions(), totalOptionPricePromo, false); } if (automation) { nonexcludedOptionsPrice += getTotalNonExcludedOptionsPrice(automation.getSelectedOptions(), totalOptionPricePromo, false); } if (totalOptionPricePromo.discounts.length > 0) { var discount = totalOptionPricePromo.discounts[0]; // Look at first discount only discount.min_value = discount.min_value || 0; // Default min value to 0 if (discount.type === discountTypes.FLAT) { // If it's a flat discount, then take the Option Price discount only if total discounted total price of options excluding // any options excluded by the promotion is greater than the discount min value AND the current discounted total price of // all options is greater than the discount value if (nonexcludedOptionsPrice > discount.min_value && optionsPrice > discount.value) { meetsMinimum = true; return; } } else if (discount.type === discountTypes.PERCENT) { // If it's a percent discount, then take the Option Price discount only if total discounted total price of options // excluding any options excluded by the promotion is greater than the discount min value if (nonexcludedOptionsPrice > discount.min_value) { meetsMinimum = true; return; } } } }); } return meetsMinimum; }; // returns array of options filtered by sap category this.filterOptionsBySAPCategory = function (sapCategory) { return _.filter(this.options, {categoryUniqueName: sapCategory}); }; // returns the first option in a given sap category this.findOptionBySAPCategory = function (sapCategory) { return _.find(this.options, {categoryUniqueName: sapCategory}); }; // returns array of standard options filtered by sap category this.filterStandardOptionsBySAPCategory = function (sapCategory) { return _.filter(this.filterOptionsBySAPCategory(sapCategory), {isStandard: true}); }; // returns the first standard options in a given sap category this.findStandardOptionBySAPCategory = function (sapCategory) { return _.find(this.filterStandardOptionsBySAPCategory(sapCategory), {isStandard: true}); }; this.getStandardOptions = function () { return _.filter(this.options, {isStandard: true}); }; this.getAssociateById = function (associateId) { return _.find(this.associations, {id: associateId}); }; this.getAutomationById = function (automationId) { return _.find(this.automations, {id: automationId}); }; this.getLegacyOptions = function() { return this.legacyOptions || {}; }; this.getOrderSaleTagText = function () { var orderPromo = this.getOrderPromotion(); if (!orderPromo) return; return orderPromo.getSaleTagText(); }; this.getSaleTagText = function () { var machinePromo = this.getMachinePromotion(); if (!machinePromo) return; return machinePromo.getSaleTagText(); }; this.getOptionsSaleTagText = function () { // var optionPromos = this.getOptionPromotions(); // var optionPromo = optionPromos[optionPromos.length -1]; // // if (!optionPromo) return ''; // // return optionPromo.getSaleTagText(); return 'SALE'; }; this.getMachinePromotion = function () { // TODO: Are promotions sorted by discount already, so we're getting the last one here to get the one with best discount? // If there's an applicable HFO-specific machine promotion, return it var machinePromotion = _.findLast(this.promotions, function(promo) { return (promo.type === promotionTypes.MACHINE && !_.isEmpty(promo.hfoIds)); }); if (!_.isEmpty(machinePromotion)) { return machinePromotion; } // Otherwise, return any applicable region-specific machine promotion machinePromotion = _.findLast(this.promotions, function(promo) { return (promo.type === promotionTypes.MACHINE && !_.isEmpty(promo.regions)); }); return machinePromotion; }; this.getOptionPromotions = function (type) { // If there's any applicable HFO-specific option promotion(s), return those var optionPromotions = _.filter(this.promotions, function (promo) { if ((promo.type !== promotionTypes.OPTION && promo.type !== promotionTypes.OPTION_PRICE && !(promo.type === promotionTypes.ORDER && promo.discounts[0].type === discountTypes.PERCENT)) || _.isEmpty(promo.hfoIds)) return false; var firstDiscount = promo.discounts[0]; if (!firstDiscount) return false; if (!type) return true; return firstDiscount.type === type; }); if (!_.isEmpty(optionPromotions)) { return _.filter(optionPromotions, {type: promotionTypes.OPTION}); } // Otherwise, return any applicable HFO-specific option promotion(s) optionPromotions = _.filter(this.promotions, function (promo) { if ((promo.type !== promotionTypes.OPTION && promo.type !== promotionTypes.OPTION_PRICE && !(promo.type === promotionTypes.ORDER && promo.discounts[0].type === discountTypes.PERCENT)) || _.isEmpty(promo.regions)) return false; var firstDiscount = promo.discounts[0]; if (!firstDiscount) return false; if (!type) return true; return firstDiscount.type === type; }); return optionPromotions; }; this.getOrderPromotion = function () { // TODO: Are promotions sorted by discount already, so we're getting the last one here to get the one with best discount? // If there's an applicable HFO-specific order promotion, return it var orderPromotion = _.findLast(this.promotions, function(promo) { return (promo.type === promotionTypes.ORDER && !_.isEmpty(promo.hfoIds)); }); if (!_.isEmpty(orderPromotion)) return orderPromotion; // Otherwise, return any applicable region-specific order promotion orderPromotion = _.findLast(this.promotions, function(promo) { return (promo.type === promotionTypes.ORDER && !_.isEmpty(promo.regions)); }); return orderPromotion; }; this.getToolingPromotions = function (type) { // If there's any applicable HFO-specific option promotion(s), return those var toolingPromotions = _.filter(this.promotions, function (promo) { if ((promo.type !== promotionTypes.TOOLING && promo.type !== promotionTypes.TOOLING_PACKAGE) || _.isEmpty(promo.hfoIds)) return false; var firstDiscount = promo.discounts[0]; if (!firstDiscount) return false; if (!type) return true; return firstDiscount.type === type; }); // Otherwise, return any applicable HFO-specific option promotion(s) toolingPromotions = _.filter(this.promotions, function (promo) { if ((promo.type !== promotionTypes.TOOLING && promo.type !== promotionTypes.TOOLING_PACKAGE) || _.isEmpty(promo.regions)) return false; var firstDiscount = promo.discounts[0]; if (!firstDiscount) return false; if (!type) return true; return firstDiscount.type === type; }); return toolingPromotions; }; this.getToolingPackagePromotions = function (type) { // If there's any applicable HFO-specific option promotion(s), return those var toolingPromotions = _.filter(this.promotions, function (promo) { if ((promo.type !== promotionTypes.TOOLING_PACKAGE) || _.isEmpty(promo.hfoIds)) return false; var firstDiscount = promo.discounts[0]; if (!firstDiscount) return false; if (!type) return true; return firstDiscount.type === type; }); // Otherwise, return any applicable HFO-specific option promotion(s) toolingPromotions = _.filter(this.promotions, function (promo) { if (promo.type !== promotionTypes.TOOLING_PACKAGE || _.isEmpty(promo.regions)) return false; var firstDiscount = promo.discounts[0]; if (!firstDiscount) return false; if (!type) return true; return firstDiscount.type === type; }); return toolingPromotions; }; this.getTotalOptionPricePromotions = function (type) { // If there's any applicable HFO-specific option-price promotion(s), return those var optionPromotions = _.filter(this.promotions, function (promo) { if ((promo.type !== promotionTypes.OPTION && promo.type !== promotionTypes.OPTION_PRICE) || _.isEmpty(promo.hfoIds)) return false; var firstDiscount = promo.discounts[0]; if (!firstDiscount) return false; if (!type) return true; return firstDiscount.type === type; }); if (!_.isEmpty(optionPromotions)) { return _.filter(optionPromotions, {type: promotionTypes.OPTION_PRICE}); } // Otherwise, return any applicable HFO-specific option-price promotion(s) var optionPricePromotions = _.filter(this.promotions, function (promo) { if (promo.type !== promotionTypes.OPTION_PRICE || _.isEmpty(promo.regions)) return false; var firstDiscount = promo.discounts[0]; if (!firstDiscount) return false; if (!type) return true; return firstDiscount.type === type; }); return optionPricePromotions; }; this.getOrderDiscountPrice = function () { var orderPromo = this.getOrderPromotion(); if (!orderPromo) return this.price; return haas.utils.applyPromotionalDiscount(orderPromo, this.price); }; this.getDiscountedPrice = function () { var machinePromo = this.getMachinePromotion(); if (!machinePromo) return this.price; return haas.utils.applyPromotionalDiscount(machinePromo, this.price); }; this.getActualTotalPrice = function () { return this.hasPromotion() ? this.getDiscountedTotalPrice() : this.getTotalPrice(); }; this.getActualPrice = function () { return this.hasPromotion() ? this.getDiscountedPrice() : this.price; }; this.hasNonZeroDiscount = function() { if (this.hasPromotion() && this.getDiscountedPrice() !== this.price) return true; return false; } this.hasNonZeroOptionDiscount = function() { return this.getSelectedOptionsDiscountPrice() !== this.getSelectedOptionsPrice() || this.getSelectedToolingPartsDiscountPrice() !== this.getSelectedToolingPartsPrice(); } this.getSelectedToolingPartsPrice = function() { var totalPrice = 0; var selectedParts = this.getSelectedToolingParts(); var userRegion = haas.region.props.region; var userCurrency = haas.region.props.currency; totalPrice = selectedParts.reduce(function(total, part) { var partPrice = _.find(part.toolingRegion.prices, {plRegion: userRegion.toLowerCase(), currency: userCurrency.toLowerCase()}); var partTotal = partPrice ? partPrice.price * part.quantity : 0; return total + partTotal; }, totalPrice); return totalPrice; } this.getSelectedToolingPartsDiscountPrice = function () { if (!this.hasPromotion(promotionTypes.ORDER) && !this.hasPromotion(promotionTypes.TOOLING) && !this.hasPromotion(promotionTypes.TOOLING_PACKAGE)) return this.getSelectedToolingPartsPrice(); var totalPrice = 0; var selectedParts = this.getSelectedToolingParts(); var userRegion = haas.region.props.region; var userCurrency = haas.region.props.currency; var self = this; var orderPromo = this.getOrderPromotion(); totalPrice = selectedParts.reduce(function(total, part) { var partPrice = _.find(part.toolingRegion.prices, {plRegion: userRegion.toLowerCase(), currency: userCurrency.toLowerCase()}); var partTotal = partPrice ? partPrice.price * part.quantity : 0; var hasPromo = !!part.promotion; var toolingQty = part.quantity; var hasToolingPackage = self.selectedToolingPackage; var pkgPartNdx = hasToolingPackage ? self.selectedToolingPackage.toolingIDs.indexOf(part.partId) : -1; // prioritize package promos if (hasToolingPackage && pkgPartNdx > -1) { var tempTotal = 0; if (part.packagePrices[self.selectedToolingPackage.description]) { tempTotal = part.packagePrices[self.selectedToolingPackage.description] * self.selectedToolingPackage.toolingQtys[pkgPartNdx]; } else { tempTotal = self.selectedToolingPackage.toolingQtys[pkgPartNdx] * partPrice.price; } if (toolingQty > self.selectedToolingPackage.toolingQtys[pkgPartNdx]) { var remainingToolingQty = (toolingQty - self.selectedToolingPackage.toolingQtys[pkgPartNdx]); if (hasPromo) tempTotal += part.promotionPrice * remainingToolingQty; else tempTotal += partPrice.price * remainingToolingQty; } return total + tempTotal; } else if (hasPromo) return total + part.promotionPrice * part.quantity; return total + partTotal; }, totalPrice); return totalPrice; } this.getSelectedOptionsDiscountPrice = function () { if (!this.hasPromotion(promotionTypes.ORDER) &&!this.hasPromotion(promotionTypes.OPTION) && !this.hasPromotion(promotionTypes.OPTION_PRICE) && !this.hasSelectedAssociatePromotion() && !this.hasSelectedAutomationPromotion()) { return this.getSelectedOptionsPrice(); } var selectedOptions = this.getSelectedOptions(); var associate = !this.isAssociate ? _.find(this.associations, {isSelected: true}) : null; var automation = !this.isAutomation ? _.find(this.automations, {isSelected: true}) : null; var optionsPrice = _.sumBy(selectedOptions, function (opt) { return opt.getActualPrice(); }); var orderPromotion = this.getOrderPromotion(); if (orderPromotion) { let discount = orderPromotion.discounts[0]; // for flat discount, only show strikethrough on total price if (discount.type === discountTypes.FLAT) return this.getSelectedOptionsPrice(); else if (discount.type === discountTypes.PERCENT) return haas.utils.applyPromotionalDiscount(orderPromotion, this.getSelectedOptionsPrice()); } var totalOptionPricePromos = this.getTotalOptionPricePromotions(); if (totalOptionPricePromos.length) { if (totalOptionPricePromos.length > 1) { haas.LOGGER.warn("Multiple Total Option Price promotions apply.", totalOptionPricePromos); } _.forEach(totalOptionPricePromos, function(totalOptionPricePromo) { var nonexcludedOptionsPrice = getTotalNonExcludedOptionsPrice(selectedOptions, totalOptionPricePromo, false); if (associate) { nonexcludedOptionsPrice += getTotalNonExcludedOptionsPrice(associate.getSelectedOptions(), totalOptionPricePromo, false); } if (automation) { nonexcludedOptionsPrice += getTotalNonExcludedOptionsPrice(automation.getSelectedOptions(), totalOptionPricePromo, false); } if (totalOptionPricePromo.discounts.length > 0) { var discount = totalOptionPricePromo.discounts[0]; // Use first discount discount.min_value = discount.min_value || 0; // Default min value to 0 if (discount.type === discountTypes.FLAT) { // If it's a flat discount, then take the Option Price discount only if total discounted total price of options excluding // any options excluded by the promotion is greater than the discount min value AND the current discounted total price of // all options is greater than the discount value if (nonexcludedOptionsPrice > discount.min_value && optionsPrice > discount.value) { optionsPrice -= discount.value; } } else if (discount.type === discountTypes.PERCENT) { // If it's a percent discount, then take the Option Price discount based on the total price (non-discounted) of options // excluding any options excluded by the promotion, only if total discounted total price of options excluding any options // excluded by the promotion is greater than the discount min value if (nonexcludedOptionsPrice > discount.min_value) { var nonexcludedOptionsPriceFull = getTotalNonExcludedOptionsPrice(selectedOptions, totalOptionPricePromo, true); if (associate) { nonexcludedOptionsPriceFull += getTotalNonExcludedOptionsPrice(associate.getSelectedOptions(), totalOptionPricePromo, true); } if (automation) { nonexcludedOptionsPriceFull += getTotalNonExcludedOptionsPrice(automation.getSelectedOptions(), totalOptionPricePromo, true); } var discValue = nonexcludedOptionsPriceFull * (discount.value / 100); if (!!totalOptionPricePromo.maxValue) { // Max value cannot be 0 or negative var maxValue = totalOptionPricePromo.maxValue > 0 ? totalOptionPricePromo.maxValue : Infinity; // If the promotion has a max value and the calculated discount value exceeds it, then use the max value; // otherwise, use the calculated discount value discValue = discValue < maxValue ? discValue : maxValue; } optionsPrice -= discValue; } } } }); } // var flatPromos = this.getOptionPromotions(discountTypes.FLAT); // // if (!flatPromos.length) return optionsPrice; // // flatPromos.forEach(function (promo) { // optionsPrice -= promo.getDiscount().value; // }); if (this.isAssociate || this.isAutomation) return optionsPrice; var associate = _.find(this.associations, {isSelected: true}); var automation = _.find(this.automations, {isSelected: true}); if (associate) optionsPrice += associate.getActualPrice() + associate.getActualSelectedOptionsPrice(); if (automation) optionsPrice += automation.getActualPrice() + automation.getActualSelectedOptionsPrice(); return optionsPrice; }; this.getActualSelectedOptionsPrice = function () { if (!this.hasPromotion(promotionTypes.OPTION)) { return this.getSelectedOptionsPrice(); } return this.getSelectedOptionsDiscountPrice(); }; this.getFormattedSelectedOptionsDiscountedPrice = function() { return haas.utils.formatCurrency(this.getSelectedOptionsDiscountPrice()); }; /** * Get selected non-standard options * @returns {Option[]} */ this.getSelectedOptions = function () { return _.filter(this.options, {isSelected: true, isStandard: false}); }; this.getSelectedToolingParts = function () { return _.filter(this.toolingParts, {isSelected: true}); }; this.getDiscountedTotalPrice = function () { return this.getDiscountedPrice() + this.getSelectedOptionsDiscountPrice() + this.getSelectedToolingPartsDiscountPrice(); }; // returns formatted base price this.getFormattedPrice = function () { return haas.utils.formatCurrency(this.price); }; // returns formatted discount tooling price this.getFormattedDiscountedToolingPrice = function () { return haas.utils.formatCurrency(this.getSelectedToolingPartsDiscountPrice()); }; // returns formatted base price after machine level discounts have been applied this.getFormattedDiscountPrice = function () { if (!this.getDiscountedPrice()) return ''; return haas.utils.formatCurrency(this.getDiscountedPrice()); }; // returns formatted discount price + selected options this.getFormattedDiscountedTotalPrice = function () { return haas.utils.formatCurrency(this.getSelectedOptionsDiscountPrice() + this.getDiscountedPrice() + this.getSelectedToolingPartsDiscountPrice()); }; // returns formatted base price after order discounts have been applied this.getFormattedOrderDiscountPrice = function () { if (!this.getOrderDiscountPrice()) return ''; return haas.utils.formatCurrency(this.getOrderDiscountPrice()); }; // returns formatted order discount price + selected options this.getFormattedOrderDiscountedTotalPrice = function () { return haas.utils.formatCurrency(this.getSelectedOptionsDiscountPrice() + this.getOrderDiscountPrice() + this.getSelectedToolingPartsDiscountPrice()); }; // returns formatted total price with selected options, but without discounts applied this.getFormattedTotalPrice = function () { return haas.utils.formatCurrency(this.getTotalPrice()); }; this.getFormattedTotalPriceWithOptionDiscounts = function () { return haas.utils.formatCurrency(this.getTotalPriceWithOptionDiscounts()); }; this.getTotalPriceWithOptionDiscounts = function () { return this.getSelectedOptionsDiscountPrice() + this.price + this.getSelectedToolingPartsDiscountPrice(); }; // returns formatted total price including selected options and machine level discounts this.getFormattedActualTotalPrice = function () { return this.hasPromotion() ? this.getFormattedDiscountedTotalPrice() : this.getFormattedTotalPriceWithOptionDiscounts(); }; /** * Return localized machine promotion message list. If there are none, return empty array; * @return {String[]} */ this.getMachinePromotionMessages = function () { var machinePromotion = this.getMachinePromotion(); var messages = []; var message = this.getLocalizedPromotionMessage(machinePromotion); if (!_.isEmpty(message)) { messages.push(message); } return messages; }; /** * Return localized option promotion message list. If there are none, return empty array; * @return {String[]} */ this.getOptionPromotionMessages = function () { var self = this; var messages = []; var optionPromotions = self.getOptionPromotions(); var totalOptionPricePromotions = this.getTotalOptionPricePromotions(); _.forEach(optionPromotions, function(promo) { var message = self.getLocalizedPromotionMessage(promo); if (!_.isEmpty(message)) { messages.push(message); } }); _.forEach(totalOptionPricePromotions, function(promo) { var message = self.getLocalizedPromotionMessage(promo); if (!_.isEmpty(message)) { messages.push(message); } }); return messages; }; /** * Return localized order promotion message list. If there are none, return empty array; * @return {String[]} */ this.getOrderPromotionMessages = function () { var orderPromotion = this.getOrderPromotion(); var messages = []; var message = this.getLocalizedPromotionMessage(orderPromotion); if (!_.isEmpty(message)) { messages.push(message); } return messages; }; /** * Return localized machine promotion message. If there are multiple, return first. If there are none, return empty string; * @return {String} */ this.getMachinePromotionMessage = function () { var messages = this.getMachinePromotionMessages(); if (messages.length === 0) { return ""; } if (messages.length > 1) { haas.LOGGER.warn("The are multiple applicable machine promotions with messages:", messages, "Only the first will be shown."); } return messages[0]; }; /** * Return localized option promotion message. If there are multiple, return first. If there are none, return empty string; * @return {String} */ this.getOptionPromotionMessage = function () { var messages = this.getOptionPromotionMessages(); if (messages.length === 0) { return ""; } if (messages.length > 1) { haas.LOGGER.warn("The are multiple applicable option promotions with messages:", messages, "Only the first will be shown."); } return messages[0]; }; /** * Return localized order promotion message. If there are multiple, return first. If there are none, return empty string; * @return {String} */ this.getOrderPromotionMessage = function () { var messages = this.getOrderPromotionMessages(); if (messages.length === 0) { return ""; } if (messages.length > 1) { haas.LOGGER.warn("The are multiple applicable order promotions with messages:", messages, "Only the first will be shown."); } return messages[0]; }; /** * Check if any of the following conditions are met:
    * 1. the model has an applicable Option promotion AND the configuration has any required options selected, OR
    * 2. a selected associated machine has a promotion, OR
    * 3. the model has an applicable OptionPrice promotion AND the selected options in the configuration meet the minimum option price of the * promotion
    * @returns {boolean} */ this.shouldShowOptionPromotion = function () { var hasHfoSpecificOptionPromotions = this.hasPromotionOfSpecificity(promotionTypes.OPTION, promotionSpecificity.HFO) || this.hasPromotionOfSpecificity(promotionTypes.OPTION_PRICE, promotionSpecificity.HFO); if (hasHfoSpecificOptionPromotions) { return (this.hasPromotion(promotionTypes.OPTION, promotionSpecificity.HFO) && this.hasSelectedOptions()) || this.hasSelectedAssociatePromotion() || this.hasSelectedAutomationPromotion() || (this.hasPromotion(promotionTypes.OPTION_PRICE, promotionSpecificity.HFO) && this.meetsMinimumTotalOptionPrice()); } else { return (this.hasPromotion(promotionTypes.OPTION, promotionSpecificity.REGION) && this.hasSelectedOptions()) || this.hasSelectedAssociatePromotion() || this.hasSelectedAutomationPromotion() || (this.hasPromotion(promotionTypes.OPTION_PRICE, promotionSpecificity.REGION) && this.meetsMinimumTotalOptionPrice()); } }; this.shouldShowToolingPromotion = function () { return this.hasPromotion(promotionTypes.TOOLING) && this.hasSelectedTooling(); } this.hasSelectedAssociatePromotion = function () { var hasPromotionsArr = this.associations.filter(function (associate) { return associate.isSelected; }) .map(function (associate) { return associate.hasPromotion(); }); return hasPromotionsArr.indexOf(true) !== -1; }; this.hasSelectedAutomationPromotion = function () { var hasPromotionsArr = this.automations.filter(function (automation) { return automation.isSelected; }) .map(function (automation) { return automation.hasPromotion(); }); return hasPromotionsArr.indexOf(true) !== -1; }; // returns sum of prices for selected options this.getSelectedOptionsPrice = function () { var optionsPrice = _.chain(this.getSelectedOptions()) .map(function (option) { return option.addOnFor ? option.addOnPrice : option.price; }) .sum() .value(); if (this.isAssociate || this.isAutomation) return optionsPrice; var associate = _.find(this.associations, {isSelected: true}); var automation = _.find(this.automations, {isSelected: true}); if (associate) optionsPrice += associate.getTotalPrice(); if (automation) optionsPrice += automation.getTotalPrice(); return optionsPrice; }; // returns formatted sum of prices for selected options this.getFormattedSelectedOptionsPrice = function () { return haas.utils.formatCurrency(this.getSelectedOptionsPrice() + this.getSelectedToolingPartsPrice()); }; this.getFormattedSelectedOptionsDiscountPrice = function () { return haas.utils.formatCurrency(this.getSelectedOptionsDiscountPrice() + this.getSelectedToolingPartsDiscountPrice()); }; // returns numeric machine price + selected options and does not include any applied discounts this.getTotalPrice = function () { return this.getSelectedOptionsPrice() + this.price + this.getSelectedToolingPartsPrice(); }; this.getOptionCategoryDetails = function (categoryName) { var cat = _.find(model.categories, {name: categoryName}); if (!cat) return {}; return { id: cat.id, uid: cat.uid, name: cat.name, imagePath: cat.image.path, imageAlt: cat.image.alt, description: cat.description, longDescription: cat.description_long, productDetailPage: cat.product_detail_page, videoIds: cat.video_ids || [], chinaVideoIds: cat.china_video_ids || [] }; }; // returns estimated monthly price for base machine for a given number of months this.getMonthlyPaymentPrice = function (months) { return getMonthlyPaymentPrice(this.price, months); }; // returns formatted estimated monthly price for base machine for a given number of months this.getFormattedMonthlyPaymentPrice = function (months) { return haas.utils.formatCurrency(this.getMonthlyPaymentPrice(months)); }; // returns estimated monthly price for base machine + options for a given number of months // get optionModel.getActualPrice() returns promo price if available, normal price if not this.getMonthlyPaymentPriceWithOptions = function (months) { var optionsPriceSum = _.chain(this.selectedOptions) .map(function(opt) { return opt.getActualPrice(); }) .sum() .value(); // get Discounted Price returns normal price if no discount, so its safe to replace 'this.price' var totalPriceSum = this.getDiscountedPrice() + optionsPriceSum + this.getSelectedToolingPartsPrice(); return getMonthlyPaymentPrice(totalPriceSum, months); }; this.getMachineDiscountAmount = function () { return this.price - this.getDiscountedPrice(); }; this.getOptionsDiscountAmount = function () { return this.getSelectedOptionsPrice() - this.getSelectedOptionsDiscountPrice(); }; this.getToolingPartsDiscountAmount = function () { return this.getSelectedToolingPartsPrice() - this.getSelectedToolingPartsDiscountPrice(); }; this.getDiscounts = function () { var self = this; var calculatedToolingPromo = false; // getToolingPartsDiscountAmount will calculate both package and non-package discounts for tooling, combine into one discount return this.promotions.map(function (promo) { var discount = promo.discounts && promo.discounts.length ? promo.discounts[0] : {type: promotionTypes.MACHINE, value: 0}; var discountAmount = 0; if (promo.type === promotionTypes.MACHINE) { discountAmount = self.getMachineDiscountAmount(); } else if ((promo.type === promotionTypes.TOOLING || promo.type === promotionTypes.TOOLING_PACKAGE)) { if (!calculatedToolingPromo) { calculatedToolingPromo = true; discountAmount = self.getToolingPartsDiscountAmount(); } else { return { discount: 'dup-tooling-promo', type: 'flat', value: 0, discount_amount: 0 } } } else if (promo.type === promotionTypes.ORDER) { let totalPrice = self.price; let discount = promo.discounts[0]; if (discount.type === 'percent') { let discountToolingAmount = (self.getSelectedToolingPartsPrice() - self.getSelectedToolingPartsDiscountPrice()); let discountOptionsAmount = (self.getSelectedOptionsPrice() - self.getSelectedOptionsDiscountPrice()); let discountMachineAmount = totalPrice * (discount.value / 100); discountAmount = Number((discountMachineAmount + discountOptionsAmount + discountToolingAmount).toFixed(2)); } if (discount.type === 'flat') { discountAmount = discount.value; } return { discount: (promo.type === promotionTypes.TOOLING || promo.type === promotionTypes.TOOLING_PACKAGE) ? promotionTypes.TOOLING : promo.type, type: discount.type, value: discount.value, amount: discountAmount }; } else { discountAmount = self.getOptionsDiscountAmount(); } return { discount: (promo.type === promotionTypes.TOOLING || promo.type === promotionTypes.TOOLING_PACKAGE) ? promotionTypes.TOOLING : promo.type, type: discount.type, value: discount.value, discount_amount: discountAmount }; }); }; this._parsePrice = function (regions) { var machine = this; if (!regions || !regions.length) return {price: 0, currency: haas.region.props.currency}; var priceRegion = _.find(regions, {name: haas.region.props.region}); if (!priceRegion) { return; } return _.find(priceRegion.prices, function (priceDefinition) { return priceDefinition.currency === haas.region.props.currency || priceDefinition.currency === ALL; }); }; this._parseToolingParts = function(model) { var machine = this; var toolingParts = []; _.forEach(model.model_tooling_parts, function(part) { var partObj = part; partObj['isSelected'] = false; partObj['quantity'] = 0; toolingParts.push(partObj); }); return toolingParts; }; this._setToolingPackages = function(model) { return model.model_tooling_packages; }; this._parseOptions = function (model) { var machine = this; var ret = []; _.forEach(model.categories, function (category) { category.uid = genUID(); _.forEach(category.options, function (option) { option.image = option.image || DEFAULT_IMAGE; category.image = category.image || DEFAULT_IMAGE; var opt = { // option props id: option.id, uid: genUID(), // used for anchor nav name: option.name, description: option.description, longDescription: option.description_long, productDetailPage: option.product_detail_page, imagePath: option.image.path, imageAlt: option.image.alt, videoIds: option.video_ids, chinaVideoIds: option.china_video_ids, // category props category: category.name, categoryId: category.id, categoryUID: category.uid, categoryDescription: category.description, categoryLongDescription: category.description_long, categoryProductDetailPage: category.product_detail_page, categoryImagePath: category.image.path, categoryImageAlt: category.image.alt, categoryUniqueName : option.sap_char, categoryVideoIds: category.video_ids, categoryChinaVideoIds: category.china_video_ids, subgroup: option.subgroups && option.subgroups.length ? option.subgroups[0] : '' }; var priceEntry = machine._parsePrice(option.regions); // option not available for selected region if (!priceEntry) { return; } opt.price = priceEntry.price; opt.constantPrice = priceEntry.price; opt.isStandard = priceEntry.is_standard; ret.push(new Option(opt)); }); }); return ret; }; this._parseAutomation = function(model) { if (!model.associations || !model.associations.length) return []; var machineAutomations = model.associations.filter(function(associate) { return associate.model.category.id !== 'rotaries-indexers'; }); return machineAutomations.map(function(automation) { var promotions = haas.services.modelDetail.promotions; automation.model.promotions = []; promotions.forEach(function(promotion) { if (!promotion.models.length) return automation.model.promotions.push(promotion); if (promotion.models.indexOf(automation.model.id) === -1) return; automation.model.promotions.push(promotion); }); return new HaasMachine(automation.model, {isAutomation: true, parent: model.id}); }); } this._parseAssociations = function (model) { if (!model.associations || !model.associations.length) return []; var machineAssociations = model.associations.filter(function(associate) { return associate.model.category.id === 'rotaries-indexers'; }); return machineAssociations.map(function (associate) { var promotions = haas.services.modelDetail.promotions; associate.model.promotions = []; promotions.forEach(function (promotion) { // if array is empty, it applies to all models if (!promotion.models.length) return associate.model.promotions.push(promotion); if (promotion.models.indexOf(associate.model.id) === -1) return; associate.model.promotions.push(promotion); }); return new HaasMachine(associate.model, {isAssociate: true, parent: model.id}); }); }; this._parseLegacyOptions = function (model) { var legacyOptions = {}; if (!model.legacy_options || !model.legacy_options.length) return legacyOptions; _.forEach(model.legacy_options, function (legacyOption) { if (legacyOption.legacy_id) { var opt = { currentId: legacyOption.current_id, legacyId: legacyOption.legacy_id, hasReplacement: legacyOption.has_replacement }; if (legacyOption.current_option) { Object.assign(opt, { id: legacyOption.current_option.id, uid: genUID(), // used for anchor nav name: legacyOption.current_option.name, description: legacyOption.current_option.description, longDescription: legacyOption.current_option.description_long, productDetailPage: legacyOption.current_option.product_detail_page, imagePath: legacyOption.current_option.image.path, imageAlt: legacyOption.current_option.image.alt, videoIds: legacyOption.current_option.video_ids, chinaVideoIds: legacyOption.current_option.china_video_ids }); } legacyOptions[legacyOption.legacy_id] = opt; } }); return legacyOptions; }; // adds references to option promos on Option models this.applyOptionDiscounts = function () { var self = this; this.getOptionPromotions().forEach(function (promo) { if (promo.type === promotionTypes.OPTION || (promo.type === promotionTypes.ORDER && promo.discounts[0].type === discountTypes.PERCENT)) { if (!promo.options.length) { self.options.forEach(function (opt) { applyPromoToOption(opt, promo); }); return; } promo.options.forEach(function (optionId) { var option = _.find(self.options, {id: optionId}); applyPromoToOption(option, promo); }); } }); }; // adds references to tooling promos to Model Object this.applyToolingDiscounts = function () { var self = this; this.getToolingPromotions().forEach(function (promo) { if (promo.type === promotionTypes.TOOLING || promo.type === promotionTypes.TOOLING_PACKAGE) { promo.toolingParts.forEach(function (id) { var toolingPart = _.find(self.toolingParts, {partId: id}); applyPromoToTooling(toolingPart, promo); }); } }); }; this.postConstruct = function () { var priceEntry = this._parsePrice(model.regions); this.price = priceEntry ? priceEntry.price : 0; this.options = this._parseOptions(model); this.associations = this._parseAssociations(model); this.automations = this._parseAutomation(model); this.legacyOptions = this._parseLegacyOptions(model); this.toolingParts = this._parseToolingParts(model); this.toolingPackages = this._setToolingPackages(model); var language = haas.utils.getLanguage(); this.configureOptionsURL = _.template(content.configureOptionsURL)({language: language, model: encodeSlingSelector(this.name)}); this.midpointURL = _.template(content.midpointURL)({language: language, model: encodeSlingSelector(this.name)}); this.metricDims = { x: inchesToMM(model.dims.x), y: inchesToMM(model.dims.y), z: inchesToMM(model.dims.z) }; this.specs = _.mapKeys(model.specs, function (value, key) { return _.camelCase(key); }); if (this.isAssociate) { this.isSelected = !!model.isSelected; } this.applyOptionDiscounts(); this.applyToolingDiscounts(); return this; }; var self = this; self.postConstruct(); return self; } HaasMachine.create = function (model) { return new HaasMachine(model); }; // returns true if promo can be applied else false function applyPromoToOption (option, promo) { if (!option) return; var promoPrice = haas.utils.applyPromotionalDiscount(promo, option.price); if (promoPrice === option.getPrice()) { return false; } option.promotion = promo; // Keep track of all promotions applicable for the option rather than just using the last promotion, if this has been called multiple times option.promotions.push(promo); option.promotionPrice = promoPrice; return true; } // returns true if promo can be applied else false function applyPromoToTooling (toolingPart, promo) { if (!toolingPart) return; var userRegion = haas.region.props.region; var userCurrency = haas.region.props.currency; var toolingPrice = toolingPart.toolingRegion.prices.find(price => price.plRegion.toUpperCase() === userRegion && price.currency.toUpperCase() === userCurrency); var promoPrice = haas.utils.applyPromotionalDiscount(promo, toolingPrice.price); if (promoPrice === toolingPrice) { return false; } toolingPart.promotion = promo; // Keep track of all promotions applicable for the option rather than just using the last promotion, if this has been called multiple times if (!toolingPart.promotions) toolingPart.promotions = []; toolingPart.promotions.push(promo); if (promo.type === promotionTypes.TOOLING) toolingPart.promotionPrice = promoPrice; if (!toolingPart.hasOwnProperty('packagePrices')) toolingPart.packagePrices = {}; if (promo.type === promotionTypes.TOOLING_PACKAGE) toolingPart.packagePrices[promo.toolingPackageName] = promoPrice; return true; } /** * Get total price of selected options, excluding the promotion's excluded options (if any). By default, use the options' actual (discounted, if * applicable) prices; otherwise, if fullPrice is true, then use the options' full prices * @param {Option[]} selectedOptions - selected machine configuration options * @param {Promotion} promotion - Total Option Price promotion * @param {boolean} fullPrice - if true, use the full option price; otherwise use the actual price (apply any discounts available) */ function getTotalNonExcludedOptionsPrice(selectedOptions, promotion, fullPrice) { return _.sumBy(selectedOptions, function(opt) { // Don't count the price of options excluded by the promotion return promotion.excludedOptions.includes(opt.id) ? 0 : fullPrice ? opt.getPrice() : opt.getActualPrice(); }); } })(); /* global haas, $, _ */ (function () { 'use strict'; var logger = haas.LOGGER; haas.models.OptionRule = OptionRule; var RuleTypeHandlerMap = { 'peer-group': haas.rules.peerGroup, 'child': haas.rules.dependencyGroup, 'blocked': haas.rules.conflictGroup, 'standard': haas.rules.standardOption, 'defaultValue': haas.rules.defaultValue, 'live-tooling': haas.rules.liveTooling, 'child-peer-rule': haas.rules.childPeerGroup, 'special-model-rule' : haas.rules.specialModelRules }; // Salience determines activation order when multiple rules exist var RuleTypeSalienceMap = { 'special-model-rule' : 6, 'child-peer-rule': 4, 'peer-group': 3, 'child': 2, 'blocked': 5, 'standard': 1, 'defaultValue': 0 }; var HighPriorityFloor = RuleTypeSalienceMap.child; function OptionRule (props) { if (typeof props.activationHandler !== 'function') { throw new Error('activationHandler is required to construct an OptionRule'); } this.name = props.name; this.type = props.type; this.activationHandler = props.activationHandler || defaultActivationHandler; this.salience = props.salience || RuleTypeSalienceMap.defaultValue; this.peers = props.peers || []; this.priceOverride = props.priceOverride || false; this.peerGroupRequired = props.peerGroupRequired || false; this.parentOption = props.parentOption || null; this.regions = props.regions || []; this.activate = function (context) { return this.activationHandler(context); }; this.isPeerGroup = function () { return this.type === 'peer-group'; }; this.isBlocked = function () { return this.type === 'blocked'; }; this.isChild = function () { return this.type === 'child'; }; this.isChildPeer = function() { return this.type === 'child-peer-rule'; }; this.isSpecial = function() { return this.type === 'special-model-rule'; }; } OptionRule.create = function (props) { return new OptionRule(props); }; function defaultActivationHandler (activationContext, option) { logger.warn('Activation handler has not been implemented. Context:', activationContext, option); } OptionRule.TypeSalienceMap = RuleTypeSalienceMap; OptionRule.TypeHandlerMap = RuleTypeHandlerMap; OptionRule.HighPriorityFloor = HighPriorityFloor; })(); /* global haas, $, _ */ (function () { 'use strict'; var logger = haas.LOGGER; haas.models.OptionRuleContext = OptionRuleContext; var CancelReasons = { defaultValue: '', notInGroup: 'Option not in group', notParent: 'Option is not parent', parentIsSelected: 'Option parent is selected', parentNotSelected: 'Option parent is not selected', parentIsUnavailable: 'Machine does not have option\'s parent available', peersAreUnavailable: 'Machine has no peers associated with option', peerRequiredByAnotherOption: 'Option\'s peer is required by another option', standardOption: 'Option is standard', auxiliaryActivation: 'Activation was fired by a previous activation', noHandler: 'Option does not have an activation handler', childBlockedByPeer: 'Option\'s child is blocked by another option', hskToolChangerBlocked: 'HSK Tool Changer requires HSK Spindle' }; function OptionRuleContext (option, rule, context, isSelection, isAuxiliary) { this.option = option; this.rule = rule; this.context = context; this.isSelection = isSelection; // auxiliary rules are rules activated by another rule this.isAuxiliary = !!isAuxiliary; this.hasFired = false; this.resolved = false; this.cancelled = false; this.nextContext = null; this.changed = false; this.reason = ''; this.vars = {}; this.changedOptions = []; this.cancel = function (reason) { checkHasFired(this); this.hasFired = true; this.cancelled = true; this.reason = reason; this.nextContext = Object.assign({}, this.context); return this; }; this.resolve = function (nextContext) { checkHasFired(this); nextContext = nextContext || this.context; this.nextContext = nextContext; this.hasFired = true; this.resolved = true; return this; }; this.flagChange = function (option) { if (option.id !== this.option.id) { this.changedOptions.push(option); } this.changed = true; }; this.hasChanged = function () { return this.changed; }; this.setVars = function (obj) { Object.assign(this.vars, obj); }; this.getVars = function () { return this.vars; }; this.getChangedOptions = function () { return this.changedOptions.slice(); }; this.next = function () { return this.nextContext; }; this.isCancelled = function () { return this.cancelled; }; } OptionRuleContext.create = function (option, rule, salience) { return new OptionRuleContext(option, rule, salience); }; OptionRuleContext.CancelReasons = CancelReasons; function checkHasFired (context) { if (context.hasFired) { throw new Error('OptionRuleContext has already been activated'); } } })(); /* global haas, _, $ */ (function () { 'use strict'; var apiConstants = haas.constants.api; var OptionRule = haas.models.OptionRule; var PersistedCache = haas.utils.PersistedCache; var LIVE_TOOLING_OPTIONS = [ 'BMT65-12-NLT', 'BMT65-24-NLT', 'BOT', 'VDI', 'BOT10', 'VB10', 'VDI10', 'BOT40', 'BOT50', 'VB40', 'LT-BMT65-12','LT-BMT65-24', 'LT-4K', 'LT-6K-UP' //,'SUB-SPDL-A2-5' ]; var SPECIAL_MODEL_RULES = { }; haas.services.rules = { rules: [], cache: new PersistedCache('rules'), promise: Promise.resolve([]), fetchRules: function () { // if in memory, return if (this.rules.length) { return Promise.resolve(this.rules); } // else check localStorage cache var cached = this.cache.get(); if (cached) { this.rules = cached; return Promise.resolve(this.rules); } // else fetch this.promise = this._fetchRules(); return this.promise; }, _fetchRules: function () { var self = this; return $.getJSON(apiConstants.rules) .then(function (rules) { self.rules = rules; self.cache.set(rules); return rules; }); }, getSpecialModelRules: function (model_name) { return SPECIAL_MODEL_RULES[model_name]; }, getRulesForOption: function (option, context) { var self = this; var specialModelRules = self.getSpecialModelRules(context.id); if (!option) { return []; } if (LIVE_TOOLING_OPTIONS.indexOf(option.id) !== -1) { return [ OptionRule.create({ name: 'Live Tooling', type: 'live-tooling', activationHandler: OptionRule.TypeHandlerMap['live-tooling'], salience: 9 }) ]; } if (specialModelRules && specialModelRules.indexOf(option.id) !== -1) { return [ OptionRule.create({ name: 'Special Model Rule', type: 'special-model-rule', activationHandler: OptionRule.TypeHandlerMap['special-model-rule'], salience: OptionRule.TypeSalienceMap['special-model-rule'] }) ]; } var initialRules = _.chain(this.rules) .filter(function (rule) { switch (rule.type) { case 'peer-group': return rule.options.indexOf(option.id) !== -1; case 'blocked': return rule.options.indexOf(option.id) !== -1; case 'child': return rule.parent_option === option.id || rule.options.indexOf(option.id) !== -1; case 'child-peer-rule': return rule.parent_option === option.id || rule.options.indexOf(option.id) !== -1; case 'special-model-rule': return specialModelRules && specialModelRules.indexOf(option.id) !== -1; default: throw new Error('Unexpected rule type ' + rule.type); } }) .map(function (rule) { var handler = OptionRule.TypeHandlerMap[rule.type]; var salience = OptionRule.TypeSalienceMap[rule.type]; if (typeof handler !== 'function') { throw new Error('No activation handler available for rule type ' + rule.type); } return OptionRule.create({ name: rule.name, type: rule.type, activationHandler: handler, salience: salience, peers: rule.options, parentOption: rule.parent_option, priceOverride: rule.linked_free || rule.linked_free_child_peer, peerGroupRequired: rule.peer_group_required, regions: rule.regionList ? rule.regionList : [] }); }) .value(); var rules = []; initialRules.forEach(function (initialRule) { if (!initialRule.regions.length || initialRule.regions.includes(haas.region.props.region)) rules.push(initialRule); if (initialRule.type === 'child' || initialRule.type === 'child-peer-rule') { // check to see if any of the children have blocking rules // associated with them and attach that info to the rule. // Logic is handled in dependencyGroup.js initialRule.childrenWithBlockedRules = []; var children = initialRule.peers; var blockedRules = _.filter(self.rules, {type:'blocked'}); _.forEach(blockedRules, function (rule) { var childOptionsWithRules = _.intersection(children, rule.options); if(childOptionsWithRules.length){ initialRule.childrenWithBlockedRules.push({options: childOptionsWithRules, rule: rule}) } }); initialRule.childrenWithBlockedRules = _.uniq(initialRule.childrenWithBlockedRules); // left by Wes; may be useful in the future // auxiliaryRules.forEach(function (rule) { // rules.push(OptionRule.create({ // type: rule.type, // activationHandler: OptionRule.TypeHandlerMap[rule.type], // salience: OptionRule.TypeSalienceMap[rule.type], // peers: rule.options, // parentOption: rule.parent_option, // priceOverride: rule.linked_free, // peerGroupRequired: rule.peer_group_required // })); // }); } }); if (!rules.length) { if (option.isStandard) { var standardOptionRule = OptionRule.create({ type: 'standard', name: 'Standard Option', activationHandler: OptionRule.TypeHandlerMap.standard, salience: OptionRule.TypeSalienceMap.standard, applicableOptions: [option] }); rules.push(standardOptionRule); } else { var defaultRule = new OptionRule({ type: 'default', name: 'Default', activationHandler: OptionRule.TypeHandlerMap.defaultValue, salience: OptionRule.TypeSalienceMap, applicableOptions: [option] }); rules.push(defaultRule); } } return rules; }, getInstanceForModel: function (model) { var self = this; return self.fetchRules().then(function (rules) { return self._createInstance(model, rules); }); }, _createInstance: function (model, rules) { var filteredRules = _.filter(rules.slice(), function (rule) { return rule.models.indexOf(model.id) !== -1; }); var newInstance = Object.assign({}, this); newInstance.rules = filteredRules; newInstance.model = model; return newInstance; } }; })(); /* global haas, $, _ */ (function () { 'use strict'; var logger = haas.LOGGER; var EventEmitter = haas.events.EventEmitter; var OptionRuleContext = haas.models.OptionRuleContext; var OptionRule = haas.models.OptionRule; var rulesService = haas.services.rules; var Events = { activate: 'activate', cancelled: 'cancelled', resolved: 'resolved' }; haas.models.OptionRulesManager = OptionRulesManager; function OptionRulesManager (context) { var self = this; this.currentContext = context; this.emitter = new EventEmitter(); this.activations = []; this.rulesService = null; this.prevContext = Object.assign({}, context); this._canAddOption = true; this.getCanAddOption = function(){ return this._canAddOption; }; this.promise = rulesService.getInstanceForModel(context).then(function (instance) { self.rulesService = instance; }); this.getModelState = function (option, auxiliaryRule) { var isAuxiliary = !!auxiliaryRule; var initialContext = Object.assign({}, this.currentContext); var isSelection = !option.isSelected; var rules = this.getHighestPriorityRulesForOption(option); if (auxiliaryRule) { rules = rules.filter(function (rule) { return rule.type !== auxiliaryRule.type && rule.type !== 'blocked'; }); } var activation; var blockedRules = _.filter(rules.slice(), {type: 'blocked'}); var tmp = blockedRules.slice(); var blockedActivations = []; // blocked rules take first priority while (tmp.length) { var blockedRule = tmp.shift(); var act = self.activateRuleForOption(blockedRule, Object.assign({}, option), isSelection, isAuxiliary); blockedActivations.push(act); this.currentContext = act.next(); } // if any blocked rules actually block the option from being selected // return var unchangedBlockedActivations = _.filter(blockedActivations, {changed: false, cancelled: false}); if (unchangedBlockedActivations.length) { var firstBlocked = unchangedBlockedActivations[0]; // this option is now blocked this._canAddOption = false; // if option is blocked, it shouldn't be selected, even if the user clicked on it option.isSelected = false; this.emitter.emit(Events.resolved, firstBlocked, isAuxiliary); this.currentContext = Object.assign({}, initialContext); return initialContext; } rules = rules.filter(function (rule) { return rule.type !== 'blocked'; }); for (var i = 0; i < rules.length; i++) { var rule = rules[i]; activation = self.activateRuleForOption(rule, option, isSelection, isAuxiliary); if (!activation.hasChanged() && rule.isBlocked()) { break; } if (activation.isCancelled() && rule.isChild() && activation.reason === OptionRuleContext.CancelReasons.parentIsSelected) { break; } this.currentContext = activation.next(); // if the rule changed the context // run rules for the options changed by the last rule if (activation.hasChanged() && !isAuxiliary && (rule.isPeerGroup() || rule.isChild())) { var changedOpts = activation.getChangedOptions().filter(function (opt) { return opt.id !== activation.option.id; }); while (changedOpts.length) { var nextOption = changedOpts.shift(); var opt = _.find(this.currentContext.options, {id: nextOption.id}); if (!opt) { logger.warn('Option', nextOption.id, 'for auxiliary rule not found. Skipping...'); continue; } this.currentContext = this.getModelState(opt, rule); } } } return this.currentContext; }; this.activateRuleForOption = function (rule, option, isSelection, isAuxiliary) { var activationContext = new OptionRuleContext(option, rule, this.currentContext, isSelection, isAuxiliary); var activation = rule.activate(activationContext); this.saveActivation(activation); if (activation.cancelled) { this.emitter.emit(Events.cancelled, activation, isAuxiliary); } if (activation.resolved) { this.emitter.emit(Events.resolved, activation, isAuxiliary) } return activation; }; this.getHighestPriorityRulesForOption = function (option) { var rules = this.getRulesForOption(option, self.currentContext); var highPriorityRules = _.sortBy(rules, 'salience'); return highPriorityRules.reverse(); }; this.saveActivation = function (activation) { this.activations.push(activation); this.emitter.emit(Events.activate, activation, activation.isAuxiliary); }; this.listActivations = function () { return this.activations; }; this.getRulesForOption = function (option, context) { return this.rulesService.getRulesForOption(option, context) || []; }; } OptionRulesManager.getInstance = function (context) { return new OptionRulesManager(context); }; OptionRulesManager.Events = Events; })(); /* global haas, _, $, LZString */ (function () { 'use strict'; var encodeSlingSelector = haas.utils.encodeSlingSelector; var PersistedCache = haas.utils.PersistedCache; var modelDetailUrl = haas.constants.api.modelDetail; var urlTemplate = _.template(modelDetailUrl); var modelDetailSpecsUrl = haas.constants.api.modelDetailWithSpecs; var urlSpecsTemplate = _.template(modelDetailSpecsUrl); var Machine = haas.models.Machine; var ONE_HOUR = 1000 * 60 * 60; haas.services.modelDetail = { promotions: [], cache: new PersistedCache('modelDetail'), getModel: function (modelName) { var self = this; var language = haas.utils.getLanguage(); var url = this.getModelUrl(modelName, language); var modelLanguageName = modelName + '_' + language; var cached = this.cache.get(modelLanguageName); if (cached) return self.applyPromotions(cached.model).then(() => Machine.create(cached.model)); return $.getJSON(url).then(function (model) { var cacheDef = {expiration: new Date(Date.now() + ONE_HOUR), model: model}; self.cache.set(cacheDef, modelLanguageName); return self.applyPromotions(model).then(() => Machine.create(model)); }); }, getModelWithSpecs: function (modelName) { var self = this; var language = haas.utils.getLanguage(); var specs = 'Y'; var url = this.getModelUrlWithSpecs(modelName, language, specs); var modelLanguageName = modelName + '_' + language; var cached = this.cache.get(modelLanguageName); if (cached) { return this.applyPromotions(cached.model).then(function () { return Machine.create(cached.model); }); } return $.getJSON(url).then(function (model) { var cacheDef = {expiration: new Date(Date.now() + ONE_HOUR), model: model}; self.cache.set(cacheDef, modelLanguageName); return self.applyPromotions(model).then(function () { return Machine.create(model); }); }); }, applyPromotions: function (model) { var self = this; model.promotions = model.promotions || []; return haas.services.promotion.fetchPromotions().then(function (promotions) { self.promotions = promotions; promotions.forEach(function (promotion) { // if array is empty, there is an error in the promotion if (!promotion.models.length || promotion.models.indexOf(model.id) === -1) return; model.promotions.push(promotion); }); return promotions; }); }, fetchToolingParts: function (model) { return fetch(haas.constants.api.toolingBNP+'.json').then(res => res.json()).then(toolingParts => { model.model_tooling_parts = toolingParts; return toolingParts; }); }, getModelUrl: function (modelName, language) { return urlTemplate({language: language, model: encodeSlingSelector(modelName)}); }, getModelUrlWithSpecs: function (modelName, language, specs) { return urlSpecsTemplate({language: language, model: encodeSlingSelector(modelName), specs: specs}); } }; })(); /* global haas, $, _ */ (function () { 'use strict'; var createQuotePackagePath = haas.constants.api.createPackage; var postJSON = haas.utils.postJSON; haas.services.createPackage = { submit: function (pkg) { return postJSON(createQuotePackagePath, pkg); } }; })(); /* global haas, $, _ */ (function () { 'use strict'; var createQuoteServletPath = haas.constants.api.createQuote; var updateQuoteServletPath = haas.constants.api.updateQuote; var postJSON = haas.utils.postJSON; var postJSONAuthenticated = function(url, obj) { return $.when(haas.jwToken.jwtPromise).then(function (payload) { if (haas.jwToken.isValid(payload)) { var headers = { "Authorization": "Bearer " + haas.jwToken.getToken() }; return postJSON(url, obj, headers); } else { return {"success": false}; } }); }; haas.services.createQuote = { /** * * @param {Object} quote * @param {boolean} authenticated * @returns {*} */ submit: function (quote, authenticated) { if (authenticated) { return postJSONAuthenticated(createQuoteServletPath, quote); } return postJSON(createQuoteServletPath, quote); } }; haas.services.updateQuote = { submit: function (quote, authenticated) { if (authenticated) { return postJSONAuthenticated(updateQuoteServletPath, quote); } return postJSON(updateQuoteServletPath, quote); } }; })(); /** principal = <%=finalPrice%> - <%=downPayment%>; //alert( "final Amt "+principal); apr= apr / 100.0; var monthPayment = monthlyamortization2(principal, noOfMonths, apr, '<%=decimalSeparator%>'); function roundtopennies(n, decimalSeparator) { n = Math.round(n); pennies = n * 100; strpennies = "" + pennies; len = strpennies.length; return strpennies.substring(0, len - 2) + decimalSeparator + strpennies.substring(len - 2, len); } function monthly(principal, noOfMonths, apr, decimalSeparator) { rate = apr / 12; payments = noOfMonths; return roundtopennies(principal * rate / (1 - (1 / Math.pow(1 + rate, payments))), decimalSeparator); } function monthlyamortization2(principal, noOfMonths, apr, decimalSeparator) { var interestpayment; var principalpayment; var i; var payments = noOfMonths; var monthlyinterest = apr /12; var rndprincipal = roundtopennies(principal); var monthPayment = monthly(principal, noOfMonths, apr, decimalSeparator); return monthPayment; } */ /* global haas, $, _ */ (function () { 'use strict'; var PARAMETER_SERIAL_NUMBER = "serial"; var getSerialNumberConfigPath = haas.constants.api.getSerialNumberConfig; haas.services.serialNumberConfig = { /** * Get list of options from serial number * @param {string} serialNumber * @returns {*|PromiseLike<[] | never>} */ get: function(serialNumber) { var url = getSerialNumberConfigPath + "?" + PARAMETER_SERIAL_NUMBER + "=" + serialNumber; return $.getJSON(url).then(function (response) { return { model: response.e_model ? response.e_model : "", options: response.ot_options ? response.ot_options : [] }; }); } }; })(); /* global haas, $, _ */ (function () { 'use strict'; var PARAMETER_SERIAL_NUMBER = "serial"; var getSerialNumberOptionsPath = haas.constants.api.getSerialNumberOptions; haas.services.serialNumberOptions = { /** * Get list of options from serial number * @param {string} serialNumber * @returns {*|PromiseLike<[] | never>} */ get: function(serialNumber) { var url = getSerialNumberOptionsPath + "?" + PARAMETER_SERIAL_NUMBER + "=" + serialNumber; return $.getJSON(url).then(function (response) { if (response.d && response.d.results) { return response.d.results; } return []; }); } }; })(); /* global haas, $, _ */ (function () { 'use strict'; var DELIMITER_STREET = ", "; var SELECTOR_FORM = '.bp-form'; var SELECTOR_INPUT = '.bp-input'; var SELECTOR_SHARE_INPUT = '.bp-share-input'; var SELECTOR_SHARE_FORM = '.bp-share-form'; var SELECTOR_SHARE_MORE = '.bp-share-more'; var SELECTOR_ADD_ANOTHER = '.bp-share-another-btn'; var SELECTOR_ACCOUNT_FORM = '.bp-myHaas-form'; var SELECTOR_SUBMIT_BTN = '.btn-submit'; var SELECTOR_INPUT_WITH_VALIDATORS = '[data-validators]'; var SELECTOR_AUTOCOMPLETE = '#autocomplete'; var SELECTOR_REGION = '#Region'; var SELECTOR_COUNTRY = '#Country'; var SELECTOR_ADDRESS_FIELDS = '.address-fields'; var SELECTOR_CUSTOM_ADDRESS = '.custom-address'; var SELECTOR_FORM_EMAIL = '#email'; var SELECTOR_FORM_SIGNIN_LINK = '#myHaas-signin-link .myHaas-signin-btn'; var SELECTOR_FORM_SIGNIN_RETURN_LINK = '#myHaas-signin-link-return'; var SELECTOR_FORM_SIGNIN_PW = '#myHaas-signin-pw'; var SELECTOR_FORM_REG_PW = '#bp-MyHaas-reg-pw'; var SELECTOR_FORM_REG_CONFIRM_PW = '#bp-MyHaas-reg-confirm-pw'; var PROP_NAME = 'name'; var EVENT_BLUR = 'blur'; var EVENT_CLICK = 'click'; var EVENT_SUBMIT = 'submit'; var EVENT_CHANGE = 'change'; var EVENT_KEYUP = 'keyup'; var EVENT_KEYDOWN = 'keydown'; var EVENT_FOCUS = 'focus'; var nonZipCodeCountries = ['SA', 'EG', 'OM', 'QA', 'KW', 'BH', 'LB', 'AE', 'VN', 'CN']; var Modal = haas.components.Modal; var showValidationState = haas.utils.showValidationState; var validateInput = haas.utils.validateInput; var formModel = { customer: { company: '', email: '', first_name: '', last_name: '', phone: '' }, address: { city: '', country: '', post_code: '', region: '', street: '', additionalComments:'' }, recipients: [] }; var authFormModel = { customer: { id : '', first_name : '', last_name : '' } }; var BPFormBus = haas.bus.bpForm = haas.utils.Channel.create({ submitted: false, form: formModel, hideForm: true }); haas.components.BPForm = haas.Component.create({ vm: { model: null }, token: {}, numShareForms: 1, unsubOptionsBus: _.noop, initialize: function () { var form = this; $.when(haas.jwToken.jwtPromise).then(function (token) { form.token = token; form.unsubOptionsBus(); form.unsubOptionsBus = haas.bus.configuratorOptions.subscribe(function (nextState) { if (nextState.model) { form.vm.model = nextState.model; if (nextState.showForm) form.render(); if (nextState.submitForm) { form.submitForm(); } } }); }); }, getInputChangeHandler: function (form) { return function () { return form.validateInput($(this)); }; }, validateInput: function ($input) { var validation = validateInput($input); showValidationState(validation); return validation.isValid; }, serializeInputs: function () { var form = this; var $inputs = this.$(SELECTOR_INPUT).not(SELECTOR_SHARE_INPUT); var $shareForms = this.$(SELECTOR_SHARE_FORM); var tmp = {}; var inputsObj = _.assign({}, formModel); var authInputsObj = _.assign({}, authFormModel); $inputs.each(function () { var $input = $(this); var val = $input.val(); if ($input.is('[type=checkbox]')) { val = $input.prop('checked'); } var key = $input.prop(PROP_NAME); // Check if the input's val is not empty // NOTE: IE11 specific check for duplicate input fields erasing populated fields if (key && val && val.length > 0) { tmp[key] = val; } }); // check to see if user is logged in; // if so, submit form with information from token if(haas.jwToken.isValid(form.token)){ _.assign(authInputsObj.customer, { id : form.token.customerId, contact_id : form.token.contactId, first_name : form.token.firstName, last_name : form.token.lastName }); return authInputsObj; } else{ _.assign(inputsObj.customer, { company: tmp.company, email: tmp.email, first_name: tmp.first_name, last_name: tmp.last_name, phone: tmp.phone }); if(tmp.opt_status) { _.assign(inputsObj.customer, { opt_status: '01' }); } else if(inputsObj.customer.opt_status) { delete inputsObj.customer.opt_status; } _.assign(inputsObj.address, { city: tmp.city, country: tmp.country, post_code: tmp.post_code, region: tmp.region, street: tmp.address2 ? tmp.street + DELIMITER_STREET + tmp.address2 : tmp.street + DELIMITER_STREET, additionalComments: tmp.additionalComments }); inputsObj.include_specs = tmp.include_specs; // wipe recipients list to ensure accurate list inputsObj.recipients = []; $shareForms.each(function () { var $inputs = $(this).find(SELECTOR_SHARE_INPUT); var recipients = {}; $inputs.each(function () { var $input = $(this); recipients[$input.prop(PROP_NAME)] = $input.val(); }); // make sure the recipient has a populated email to avoid empty objects if (recipients.email && haas.utils.validateEmail(recipients.email)) { inputsObj.recipients.push(recipients); } }); return inputsObj; } }, duplicateRecipientForm: function (e) { if (e && e.preventDefault) e.preventDefault(); var $newForm = this.$(SELECTOR_SHARE_FORM).eq(0).clone(); this.numShareForms++; $newForm.find(SELECTOR_SHARE_INPUT).each(function () { var $input = $(this); $input.val(''); }); this.$(SELECTOR_SHARE_MORE).append($newForm); }, checkRegFields: function () { // True if > 0, if 0 then false var passwordFilled = !!$(SELECTOR_FORM_REG_PW).val().length || !!$(SELECTOR_FORM_REG_CONFIRM_PW).val().length; if (passwordFilled) { this.$(SELECTOR_FORM).data('status', 'register'); this.$('.btn-submit-default').addClass('hidden'); this.$('.btn-submit-signin').addClass('hidden'); this.$('.btn-submit-register').removeClass('hidden'); this.$(SELECTOR_FORM_REG_PW).attr('data-validators', 'required'); this.$(SELECTOR_FORM_REG_CONFIRM_PW).attr('data-validators', 'required'); } else { this.$(SELECTOR_FORM).data('status', 'skip'); this.$('.btn-submit-default').removeClass('hidden'); this.$('.btn-submit-signin').addClass('hidden'); this.$('.btn-submit-register').addClass('hidden'); this.$(SELECTOR_FORM_REG_PW).removeAttr('data-validators'); this.$(SELECTOR_FORM_REG_CONFIRM_PW).removeAttr('data-validators'); this.$(SELECTOR_FORM_REG_PW).parent().find('.error-output').empty(); this.$(SELECTOR_FORM_REG_CONFIRM_PW).parent().find('.error-output').empty(); } }, renderMyHaasSignIn: function () { // If signing in, unhide relevant fields + return button and hide all unneeded input fields + current button // Also empty registration pw fields to avoid status discrepancies $(SELECTOR_FORM).data('status', 'signin'); $('.myHaas-pw-row, #myHaas-signin-link-return').removeClass('hidden'); $('#address-form-group, #myHaas-signin-link, form .name-row, #share-label, .bp-share-more, .bp-share-another-btn').addClass('hidden'); this.$(SELECTOR_FORM_REG_PW).empty(); this.$(SELECTOR_FORM_REG_CONFIRM_PW).empty(); this.$('.btn-submit-default, .btn-submit-register').addClass('hidden'); this.$('.btn-submit-signin').removeClass('hidden'); $('#myHaas-signin-pw').attr('data-validators', 'required'); }, hideMyHaasSignIn: function () { // If returning from sign in, return form to default $(SELECTOR_FORM).data('status', 'skip'); $('.myHaas-pw-row, #myHaas-signin-link-return').addClass('hidden'); $('#address-form-group, #myHaas-signin-link, form .name-row, #share-label, .bp-share-more, .bp-share-another-btn').removeClass('hidden'); this.$('.btn-submit-signin, .btn-submit-register').addClass('hidden'); this.$('.btn-submit-default').removeClass('hidden'); $('#myHaas-signin-pw').removeAttr('data-validators'); }, validateForm: function () { var form = this; var $inputs = this.$(SELECTOR_INPUT_WITH_VALIDATORS).filter(':visible'); var validationStates = $inputs.map(function () { return form.validateInput($(this)); }); // blur all address fields to trigger field validations $(SELECTOR_INPUT).not(SELECTOR_FORM_REG_PW).not(SELECTOR_FORM_REG_CONFIRM_PW).blur(); return _.every(validationStates); }, submitForm: function (e) { if (e) e.preventDefault(); if (!this.validateForm()) return; var status = $(SELECTOR_FORM).data('status'); var self = this; haas.LOGGER.debug('FORM SUBMIT STATUS', status); // Include a check for login status here. if (status === 'signin') { var acc_email = $(SELECTOR_FORM_EMAIL).val(); var acc_pw = $(SELECTOR_FORM_SIGNIN_PW).val(); haas.services.fleetLoginService.post({"username":acc_email,"password":acc_pw}) .then(function (data) { haas.jwToken.setToken(data.token); }) .then(function(){ $.when(haas.jwToken.jwtPromise).then(function (token) { haas.LOGGER.debug('payload: ', token); self.token = token; BPFormBus.publish({submitted: true, form: self.serializeInputs(), hideForm : BPFormBus.hideForm }); }); }) .fail(function () { self.showErrorDialog('There was an issue logging into your MyHaas account. Verify that your email and password are correct and submit again.'); }); } if (status === 'register') { var acc_pw = $(SELECTOR_FORM_REG_PW).val(); var acc_confirm_pw = $(SELECTOR_FORM_REG_CONFIRM_PW).val(); var pw_req_pattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!"#$%&'()*+,-./:;<=>?@\[\]^_`{|}~])[A-Za-z\d!"#$%&'()*+,-./:;<=>?@\[\]^_`{|}~]{8,}$/g; var self = this; if (!acc_pw.match(pw_req_pattern) || !acc_pw.match(pw_req_pattern).length) { self.showErrorDialog('Password must be at least 8 characters and contain at least 1 number, upper case letter, lower case letter and special character'); return; } if (acc_pw !== acc_confirm_pw) { self.showErrorDialog('Please verify password fields match and submit again.'); return; } BPFormBus.publish({submitted: true, form: self.serializeInputs(), hideForm : BPFormBus.hideForm }); } if (status === 'skip') { BPFormBus.publish({submitted: true, form: this.serializeInputs(), hideForm : BPFormBus.hideForm }); } }, showErrorDialog: function (err) { Modal.open(_.template('

    {{=err}}

    ')({err: err})); }, revise: function () { BPFormBus.publish({hideForm: true}); return false; }, cancel: function () { Modal.open(this.templates.cancel()); $('.btn-close-modal').off(EVENT_CLICK).on(EVENT_CLICK, function (e) { e.preventDefault(); Modal.close(); }); return false; }, showContactFieldsHandler: function (self, override) { return function () { var val = ($(this).val() || '').trim(); if (!val && !override) return; self.$(SELECTOR_ADDRESS_FIELDS).removeClass('hidden'); self.$(SELECTOR_CUSTOM_ADDRESS).addClass('hidden'); if(override) { self.$(SELECTOR_AUTOCOMPLETE).addClass('hidden'); } }; }, handleCountryChange: function(self) { return function() { self.$(SELECTOR_REGION).parent().find('.error-output').empty(); self.$('#PostCode').parent().find('.error-output').empty(); if ($('#Region')[0].hasAttribute('disabled')) { $('#Region').data('validators', ''); } else { $('#Region').data('validators', 'required'); } // if new country val is ME, dont require post code if (nonZipCodeCountries.indexOf($('#Country').val()) > -1) { $('#PostCode').data('validators', ''); } else { $('#PostCode').attr('data-validators', 'required'); } }; }, disableAddressAutocomplete: function(e) { $('#autocomplete').attr('autocomplete', 'new-password'); }, disableAutocomplete: function() { if (!!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime)) { // for chrome $('input.bp-input').attr('autocomplete', 'new-password'); } else { // Non-chorme browsers $('input.bp-input').attr('autocomplete', 'off'); } }, handleEnterPress: function(e) { if (e.keyCode === 13) { // if item in google maps dropdown is selected, allow enter click if ($('.pac-item-selected').length) { $('#autocomplete').blur(); } else { event.preventDefault(); return false; } } }, bindEvents: function () { this.$(SELECTOR_INPUT).off(EVENT_BLUR).on(EVENT_BLUR, this.getInputChangeHandler(this)); this.$('#autocomplete').off(EVENT_CHANGE).on(EVENT_CHANGE, this.getInputChangeHandler(this)); this.$('#autocomplete').off(EVENT_FOCUS).on(EVENT_FOCUS, this.disableAddressAutocomplete.bind(this)); this.$(SELECTOR_ADD_ANOTHER).off(EVENT_CLICK).on(EVENT_CLICK, this.duplicateRecipientForm.bind(this)); this.$(SELECTOR_FORM).off(EVENT_SUBMIT).on(EVENT_SUBMIT, this.submitForm.bind(this)); this.$('.btn-revise-options').off(EVENT_CLICK).on(EVENT_CLICK, this.revise.bind(this)); this.$('.btn-cancel').off(EVENT_CLICK).on(EVENT_CLICK, this.cancel.bind(this)); this.$(SELECTOR_AUTOCOMPLETE).off(EVENT_BLUR).on(EVENT_BLUR, this.showContactFieldsHandler(this)); this.$(SELECTOR_CUSTOM_ADDRESS).off(EVENT_CLICK).on(EVENT_CLICK, this.showContactFieldsHandler(this, true)); this.$(SELECTOR_FORM_REG_PW).off(EVENT_KEYUP).on(EVENT_KEYUP, this.checkRegFields.bind(this)); this.$(SELECTOR_FORM_REG_PW).on(EVENT_BLUR, this.checkRegFields.bind(this)); this.$(SELECTOR_FORM_REG_CONFIRM_PW).off(EVENT_KEYUP).on(EVENT_KEYUP, this.checkRegFields.bind(this)); this.$(SELECTOR_FORM_REG_CONFIRM_PW).on(EVENT_BLUR, this.checkRegFields.bind(this)); this.$(SELECTOR_COUNTRY).off(EVENT_CHANGE).on(EVENT_CHANGE, this.handleCountryChange(this)); // Disabling Sign In from form, leaving in case it needs to be reimplemented // - Reimplementation note: jwt.setToken is the issue, its doing a cart owner check. Need to create setToken that bypasses that. // this.$(SELECTOR_FORM_SIGNIN_LINK).off(EVENT_CLICK).on(EVENT_CLICK, this.renderMyHaasSignIn.bind(this)); this.$(SELECTOR_FORM_SIGNIN_LINK).off(EVENT_CLICK).on(EVENT_CLICK, () => { window.location = '/ecommpartsstorefront/ecommparts/'+haas.utils.getLanguage()+'/login?referrer=aem'; }); this.$(SELECTOR_FORM_SIGNIN_RETURN_LINK).off(EVENT_CLICK).on(EVENT_CLICK, this.hideMyHaasSignIn.bind(this)); this.$(SELECTOR_INPUT).on(EVENT_KEYDOWN, this.handleEnterPress.bind(this)); this.$('#bp-form').on('autocompleteFilled', this.handleCountryChange(this)); }, render: function () { var self = this; this.refs.$output.html(this.templates.bpForm(this.vm)); this.bindEvents(); setTimeout(function () { // TODO: update this to avoid race condition, by replacing timeout with something more reliable haas.utils.initAutocomplete(); }, 500); // Disable Brower's autocomplete (will still allow google maps autocomplete for address this.disableAutocomplete(); } }); })(); /* global $, _, haas */ (function () { 'use strict'; var getSlingSelectors = haas.utils.getSlingSelectors; var getSlingSelectorMap = haas.utils.getSlingSelectorMap; var formatCurrency = haas.utils.formatCurrency; var eqHeight = haas.utils.eqHeight; var inchesToMM = haas.utils.inchesToMM; var OptionRulesManager = haas.models.OptionRulesManager; var Modal = haas.components.Modal; var modelDetailService = haas.services.modelDetail; var createPackageService = haas.services.createPackage; var createQuoteService = haas.services.createQuote; var updateQuoteService = haas.services.updateQuote; var quoteDetailsService = haas.services.quoteDetails; var serialNumberConfigService = haas.services.serialNumberConfig; var CLASS_SELECTED = 'selected'; var CLASS_HIDDEN = 'hidden'; var SELECTOR_CONFIGURATOR_OPTIONS = '.configurator-options'; var SELECTOR_CARD_GROUP = '.option-card-group'; var SELECTOR_CARD = '.model-option-card'; var SELECTOR_ASSOCIATE_CARD = '.associate-card'; var SELECTOR_ASSOCIATE_OPTION_CARD = '.associate-option-card'; var SELECTOR_AUTOMATION_CARD = '.automation-card'; var SELECTOR_AUTOMATION_OPTION_CARD = '.automation-option-card'; var SELECTOR_OPTION_DETAIL_LINK = '.option-detail-link'; var SELECTOR_SELECTED = '.selected'; var EVENT_DUPLICATE = '137'; var EVENT_CLICK = 'click'; var EVENT_RESIZE = 'resize'; var DATA_OPTION = 'option'; var SLIDE_TOGGLE_SPEED = 300; // Special identifier for options that are always selected, but have a price (Haas Delivered) // Initialized in setInitialSelectedOptions() var specialOptions = ['INSTALLATION']; var formBus = haas.bus.bpForm; var regionBus = haas.bus.region; var myQuotesUri = '#'; var defaultAmortizationSchedule = _.find(haas.constants.AMORTIZATION_SCHEDULES, {defaultValue: true}); var optionsBus = haas.bus.configuratorOptions = haas.utils.Channel.create({ model: null, categories: null, showForm: false, submitForm: false, submitPackage: false, newQuote: false, quote: null, promptUmcCdfPopup: false }); haas.components.ConfiguratorOptions = haas.Component.create({ vm: { startCase: _.startCase, model: null, categories: null, numCols: 4, showOptionIds: false, optionRulesManager: null, formatCurrency: formatCurrency, inchesToMM: inchesToMM, months: defaultAmortizationSchedule.months }, isExpandAll: false, isToolingExpandAll: false, lastScrollTop: 0, loading: true, initialized: false, associateOptionsShown: false, automationOptionsShown: false, selectors: [], toolingHierarchy: {}, preconfiguredPackageJSON: {}, unsubFormBus: _.noop, unsubOptionsBus: _.noop, unsubRegionBus:_.noop, triggeredByUmcCdfModal: false, slickConfig: { infinite: true, slidesToShow: 1, slidesToScroll: 1, dots: true, adaptiveHeight: false, draggable: true }, initialize: function () { var self = this; myQuotesUri = $(SELECTOR_CONFIGURATOR_OPTIONS).data('myquotes-uri'); $.when(haas.region.priceGroupPromise).then(function(price_group) { Object.assign(self.vm, optionsBus.state); // set global func to display option ids for debugging window.toggleOptionIds = function () { self.vm.showOptionIds = !self.vm.showOptionIds; haas.LOGGER.info(self.vm.showOptionIds ? 'Enabling' : 'Disabling' + ' option id display'); self.render(); }; self.unsubRegionBus(); self.unsubRegionBus = regionBus.subscribe(self.onRegionChange.bind(self)); self.unsubOptionsBus(); self.unsubOptionsBus = optionsBus.subscribe(self.onVMUpdate.bind(self)); self.unsubFormBus(); self.unsubFormBus = formBus.subscribe(self.onFormSubmit.bind(self)); var quoteId = self.getCurrentQuote(); var serialNumber = self.getCurrentSerial(); if (quoteId) { $.when(self.applyCurrentQuote()).then(function(applyQuoteObj){ var quotePayload = null; if (applyQuoteObj) { self.vm.model = applyQuoteObj.nextModelState; quotePayload = applyQuoteObj.quote; } haas.bus.configuratorOptionsHeader.publish({model: self.vm.model}); var categories = self.getCategories(self.vm.model.options); self.finishApplyConfiguration(categories, quotePayload); }); } else if (serialNumber) { $.when(self.applyCurrentSerial()).then(function(applySerialObj){ haas.LOGGER.debug('Received Legacy Options Payload: ', applySerialObj.legacyOptions); if (applySerialObj) { self.vm.model = applySerialObj.nextModelState; } if (applySerialObj.legacyOptions.length) { self.showLegacyOptionsModal(applySerialObj.legacyOptions, applySerialObj.currentOptions); } haas.bus.configuratorOptionsHeader.publish({model: self.vm.model}); var categories = self.getCategories(self.vm.model.options); self.finishApplyConfiguration(categories); }); } else { var modelName = self.getCurrentModel(); if (!modelName) return haas.LOGGER.warn('No model name was supplied'); self.fetchModelDetails(modelName) .then(function (model) { var categories = self.getCategories(model.options); self.initORMandTracking(model); self.applyCurrentPackage().then(function(nextModelState){ self.vm.model = nextModelState; haas.bus.configuratorOptionsHeader.publish({model: self.vm.model}); self.finishApplyConfiguration(categories); }); }); } $(window).on(EVENT_RESIZE, self.onWindowResize.bind(self)); }); }, setFinancingOptions: function() { var self = this; $.when(haas.region.priceGroupPromise).then(function(price_group) { console.log(price_group.hfoid); if (price_group.hfoid !== '0') { haas.LOGGER.debug('SETTING FINANCING RATES CONFIG OPTIONS'); haas.services.dealerFinancingService.getPrograms(price_group.hfoid).then(function(programs){ if (programs.length && programs[0].monthAndRateOptions) { self.vm.months = _.find(programs[0].monthAndRateOptions, {defaultValue: true}).months; } }); } }); }, getCategories: function(options) { return _.chain(options) .groupBy('category') .mapValues(function (optionGroup) { return _.sortBy(optionGroup, function (option) { return option.isStandard ? -1 : 1; }); }) .value(); }, /** * Call this function after finishing applying a package configuration, quote configuration, or serial number options configuration * @param categories * @param [quotePayload] */ finishApplyConfiguration: function(categories, quotePayload) { var self = this; if (quotePayload) { optionsBus.publish({model: self.vm.model, categories: categories, quote: quotePayload}); } else { optionsBus.publish({model: self.vm.model, categories: categories}); } //TODO: refactor - hack to pre-select associated model, ie. rotary if(self.vm.model.defaultAssociate) { var associateCard = $(".associate-card[data-associate='" + self.vm.model.defaultAssociate + "']"); self.onAssociateCardClick({ currentTarget : associateCard }); var associate = _.filter(haas.bus.configuratorOptionsHeader.state.model.selectedOptions, function(option) { return option.isAssociate; })[0]; self.vm.model.defaultAssociate = null; if(self.vm.model.defaultAssociateOptions && self.vm.model.defaultAssociateOptions.length) { self.vm.model.defaultAssociateOptions.forEach(function (option) { var associateOptionCard = $(".associate-option-card[data-option='" + option + "']"); var optionObj = _.find(associate.options, {id: option}); // For onRegionChange, if option is selected, toggle so that its not deselected after click if (optionObj.isSelected) { optionObj.isSelected = false; } self.onAssociateOptionCardClick({ currentTarget : associateOptionCard }); }); } self.vm.model.defaultAssociateOptions = null; } if (haas.debug) { self.debugOptionRulesManager(); } self.initRulesMessaging(); }, initORMandTracking: function(model) { var self = this; self.vm.model = model; haas.orm = self.optionRulesManager = OptionRulesManager.getInstance(self.vm.model); haas.analytics.trackProduct('category', model.category); haas.analytics.trackProduct('series', model.series); haas.analytics.trackProduct('model', model.name); haas.analytics.trackSubStep('choose-options'); haas.LOGGER.debug('Fetched model:', model); }, updateORM: function(model) { var self = this; haas.orm = self.optionRulesManager = OptionRulesManager.getInstance(model); if (haas.debug) { self.debugOptionRulesManager(); } self.initRulesMessaging(); }, initializeBuildPackageMode: function() { if(this.getIsBuildPackageMode()) { haas.bus.configuratorOptionsHeader.publish({buildPackageMode: true}); $('.btn-exit-build-package-mode').show(); } else { $('.btn-build-package-mode').show(); } }, setInitialSelectedOptions: function () { var model = this.vm.model; model.selectedOptions = _.filter(model.options, {isStandard: true}); // Check for Standard Options or Special Options (always selected) model.options.forEach(function (option) { option.isSelected = !!option.isStandard || specialOptions.includes(option.id); }); }, debugOptionRulesManager: function () { this.optionRulesManager.emitter.subscribe(OptionRulesManager.Events.cancelled, function (activation, skipSelect) { haas.LOGGER.debug('ORM: Activation cancelled for option ' + activation.option.id + '. Rule: ' + activation.rule.name + ' (' + activation.rule.type + '). Reason: ' + activation.reason + '. IsSelected: ' + activation.option.isSelected + '. isAuxiliary: ' + activation.isAuxiliary + '. Skip: ' + skipSelect); }); this.optionRulesManager.emitter.subscribe(OptionRulesManager.Events.resolved, function (activation, skipSelect) { haas.LOGGER.debug('ORM: Activation resolved for option ' + activation.option.id + '. Rule: ' + activation.rule.name + ' (' + activation.rule.type + '). IsSelected: ' + activation.option.isSelected + '. isAuxiliary: ' + activation.isAuxiliary + '. Skip: ' + skipSelect + '.'); }); }, initRulesMessaging: function () { this.optionRulesManager.emitter.subscribe(OptionRulesManager.Events.resolved, this.onResolveRule.bind(this)); this.optionRulesManager.emitter.subscribe(OptionRulesManager.Events.cancelled, this.onCancelRule.bind(this)); }, onResolveRule: function (activation) { const self = this; var messageHTML = '', children; switch (activation.rule.type) { case 'child': children = activation.getChangedOptions(); if (!children || !children.length) return; // check to see if children were added by parents, // or were selected prior to parent selection var preSelectedChildren = _.filter(children, { alreadySelected:true }); var standardSelectedChildren = _.filter(children, { isSelected:true, isStandard:true }); if (activation.option.isSelected) { // only throw addOn or prerequisite modal if children were added by parent, // and not already pre-selected if (preSelectedChildren.length !== activation.rule.peers.length){ if (activation.rule.priceOverride) { // priceOverride AND child not selected AND child not standard messageHTML = this.templates.addonModal({ addOnText: haas.utils.arrayToText(_.map(_.filter(children, {alreadySelected:false}), 'name')), addOns: _.filter(children, {alreadySelected:false}), option: activation.option }); } else { messageHTML = this.templates.prerequisiteModal({ optionAction : 'added', optionsText: haas.utils.arrayToText(_.map( _.filter(children, {alreadySelected:false}), 'name')), option: activation.option, triggeredByUmcCdf: self.triggeredByUmcCdfModal, selectingCdf: activation.option.id === 'CDF CONVEYOR' ? true : false }); } } } else { // only throw addOn deselect or prerequisite modal if all children are not standard // i.e., standard children should not be deselected by parent if (standardSelectedChildren.length !== activation.rule.peers.length && preSelectedChildren.length !== activation.rule.peers.length) { if (activation.rule.priceOverride) { // priceOverride AND all children not pre-selected AND all children not standard messageHTML = this.templates.addonDeselectModal({ addOnText: haas.utils.arrayToText(_.map(_.filter(children, {isStandard:false, alreadySelected:false}), 'name')), addOns: _.filter(children, {isStandard:false, alreadySelected:false}), option: activation.option }); } else { messageHTML = this.templates.prerequisiteModal({ optionAction: 'removed', optionsText: haas.utils.arrayToText(_.map( _.filter(children, {isStandard:false, alreadySelected:false}), 'name')), option: activation.option, triggeredByUmcCdf: false, selectingCdf: false }); } } break; } break; case 'blocked': var blockedBy = activation.vars.blockedBy; if (blockedBy) { messageHTML = this.templates.blockedModal({ option: activation.option, blockedBy: blockedBy }); } break; case 'peer-group': break; case 'child-peer-rule': if (activation.vars.messageId === 'prerequisiteChoiceModal') { messageHTML = this.templates.prerequisiteChoiceModal({ multipleDependencies: activation.vars.multipleDependencies, optionAction: activation.vars.action, optionsText: '', option: activation.option, primaryOptionText: activation.vars.primaryOptionText, secondaryOptionText: activation.vars.secondaryOptionText }); } break; case 'special-model-rule': if (activation.vars.messageId === 'prerequisiteModal') { messageHTML = this.templates.prerequisiteModal({ optionAction: activation.vars.action, optionsText: haas.utils.arrayToText(_.map(activation.vars.dependencyGroup, 'name')), option: activation.option }); } else if (activation.vars.messageId === 'prerequisiteChoiceModal') { messageHTML = this.templates.prerequisiteChoiceModal({ multipleDependencies: activation.vars.multipleDependencies, optionAction: activation.vars.action, optionsText: haas.utils.arrayToText(_.map(activation.vars.dependencyGroup, 'name')), option: activation.option, primaryOptionText: activation.vars.primaryOptionText, secondaryOptionText: activation.vars.secondaryOptionText }); } else if (activation.vars.messageId === 'blockedModal') { messageHTML = this.templates.blockedModal({ option: activation.option, blockedBy: activation.vars.blockedBy }); } break; case 'live-tooling': if (!activation.vars.messageId) return; if (activation.vars.messageId === 'addonModal') { messageHTML = this.templates.addonModal({ addOnText: activation.vars.addOnText, option: activation.option }); } if (activation.vars.messageId === 'prerequisiteModal') { messageHTML = this.templates.prerequisiteModal({ optionAction: activation.vars.action, optionsText: haas.utils.arrayToText(_.map(activation.vars.dependencyGroup, 'name')), option: activation.option }); } else if (activation.vars.messageId === 'prerequisiteChoiceModal') { messageHTML = this.templates.prerequisiteChoiceModal({ multipleDependencies: activation.vars.multipleDependencies, optionAction: activation.vars.action, optionsText: haas.utils.arrayToText(_.map(activation.vars.dependencyGroup, 'name')), option: activation.option, primaryOptionText: activation.vars.primaryOptionText, secondaryOptionText: activation.vars.secondaryOptionText }); } else if (activation.vars.messageId === 'blockedModal') { messageHTML = this.templates.blockedModal({ option: activation.option, blockedBy: activation.vars.blockedBy }); } else if (activation.vars.messageId === 'requiredChildModal') { messageHTML = this.templates.requiredChildModal({ parentOption: activation.vars.parentOption }); } else if (activation.vars.messageId === 'addonCostNoCostModal') { messageHTML = this.templates.addonCostNoCostModal({ option: activation.option, addOnCostText: activation.vars.addOnCostText, addOnNoCostText : activation.vars.addOnNoCostText, optionAction : activation.vars.action }); }else if (activation.vars.messageId === 'addonDeselectCostNoCostModal') { messageHTML = this.templates.addonDeselectCostNoCostModal({ option: activation.option, addOnCostText: activation.vars.addOnCostText, addOnNoCostText: activation.vars.addOnNoCostText, optionAction: activation.vars.action }); } break; } if (messageHTML) { Modal.open(messageHTML); if (self.triggeredByUmcCdfModal) { let umcCdfFinishQuoteButton = document.querySelector('.haas-modal #umc-cdf-finish-quote'); if (umcCdfFinishQuoteButton) { umcCdfFinishQuoteButton.onclick = () => { $.when(haas.jwToken.jwtPromise).then(function (token) { let submitBPForm = haas.jwToken.isValid(token); Modal.close(); optionsBus.publish({ showForm: !submitBPForm, submitForm: submitBPForm, newQuote: true }); }); } } self.triggeredByUmcCdfModal = false; } } }, onCancelRule: function (activation) { var CancelReasons = haas.models.OptionRuleContext.CancelReasons; var messageHTML = ''; if (activation.rule.type === 'child') { if (activation.reason === CancelReasons.parentIsSelected) { var parentOpt = _.find(activation.context.options, {id: activation.rule.parentOption}) || _.find(activation.context.associations, {id: activation.rule.parentOption}); messageHTML = this.templates.requiredChildModal({ parentOption: parentOpt || {}, option: activation.option }); } if (activation.vars.messageId === 'childBlockedByPeer') { messageHTML = this.templates.childBlockedByPeerModal({ parentOption: activation.option, childOptionText: haas.utils.arrayToText(_.map(activation.vars.childOptions, 'name')), blockedByText: haas.utils.arrayToText(_.map(activation.vars.blockedBy, 'name')) }); } } if (activation.rule.type === 'peer-group') { if (activation.vars.messageId === 'peerRequiredByAnotherOption') { messageHTML = this.templates.requiredPeerModal({ option: activation.option, peerOptionText: haas.utils.arrayToText(_.map(activation.vars.peerOptions, 'name')), parentOptionText: haas.utils.arrayToText(_.map(activation.vars.parentOptions, 'name')) }); } if (activation.vars.messageId === 'hskBlockedModal') { messageHTML = this.templates.hskBlockedModal({ blockedBy: activation.vars.blockedBy }); } } if (activation.rule.type === 'child-peer-rule') { if (activation.reason === CancelReasons.parentIsSelected) { var parentOpt = _.find(activation.context.options, {id: activation.rule.parentOption}) || _.find(activation.context.associations, {id: activation.rule.parentOption}); messageHTML = this.templates.requiredChildModal({ parentOption: parentOpt || {}, option: activation.option }); } if (activation.vars.messageId === 'hskBlockedModal') { messageHTML = this.templates.hskBlockedModal({ blockedBy: activation.vars.blockedBy }); } } if (activation.rule.type === 'special-model-rule') { if (activation.reason === CancelReasons.parentIsSelected) { messageHTML = this.templates.requiredChildModal({ parentOption: activation.vars.parentOption, option: activation.option }); } } if (activation.rule.type === 'live-tooling' && activation.reason === CancelReasons.parentIsSelected) { messageHTML = this.templates.requiredChildModal({ parentOption: activation.vars.parentOption, option: activation.option }); } if (messageHTML) { Modal.open(messageHTML); } }, replacedModalCheck : function(option) { var replaced = this.getReplacedOptionsForOption(option); if (replaced.length && option.isSelected) { var replacedIds = _.map(replaced, 'id'); haas.LOGGER.debug('Replaced', replacedIds.length, 'options for', option.id + ':', replacedIds.join(', ')); Modal.open(this.templates.replacedOptionModal({ replacedText: haas.utils.arrayToText(_.map(replaced, 'name')), replaced: replaced, option: option })); } }, prerequisiteModalCheck : function(option) { var prerequisites = this.getPrerequisiteOptions(option); if(prerequisites.length){ var targetTemplate = this.templates.prerequisiteModal; var targetAction = option.isSelected ? 'added' : 'removed'; Modal.open(targetTemplate({ optionAction : targetAction, optionsText: haas.utils.arrayToText(_.map(prerequisites, 'name')), option: option })); } }, addOnModalCheck : function(option) { // TODO: fix standard options var addOns = this.getAddOnsForOption(option); var deselectAddons = !option.isSelected; if (addOns.length) { this.showStandardAddOnModal.call(this, option, addOns, deselectAddons); } }, showStandardAddOnModal : function(option, addOns, deselectAddons){ var addOnIds = _.map(addOns, 'id'); var targetTemplate = deselectAddons ? this.templates.addonDeselectModal : this.templates.addonModal; haas.LOGGER.debug('Adding', addOns.length, 'options for', option.id + ':', addOnIds.join(', ')); Modal.open(targetTemplate({ addOnText: haas.utils.arrayToText(_.map(addOns, 'name')), addOns: addOns, option: option })); }, showLegacyOptionsModal : function(legacyOptions, currentOptions) { var legacyOpsList = legacyOptions.slice(); var currentOpsList = currentOptions.slice(); Modal.open(this.templates.addonLegacyOptionsModal({ legacyList: legacyOpsList, currentList: currentOpsList })); }, setNumCols: function () { var prev = this.vm.numCols; if (haas.device.display.isLargeDesktop()) { this.vm.numCols = 4; } else { this.vm.numCols = 3; } if (prev !== this.vm.numCols) { this.render(); } }, onWindowResize: function () { this.setNumCols(); }, fetchModelDetails: function (modelName) { return modelDetailService.getModel(modelName); }, getCurrentQuote: function () { var selectorMap = getSlingSelectorMap(); var quote = selectorMap[haas.constants.slingSelectors.QUOTE]; return quote ? quote : null; }, getCurrentSerial: function () { var selectorMap = getSlingSelectorMap(); var serial = selectorMap[haas.constants.slingSelectors.SERIAL]; return serial ? serial : null; }, getCurrentModel: function () { var selectors = this.selectors = getSlingSelectors(); return selectors[0]; }, getCurrentPackage: function () { var selectors = this.selectors = getSlingSelectors(); return selectors.length == 2 && this.getIsBuildPackageMode() ? '' : selectors[1]; }, getIsDuplicateQuote: function () { var selectors = haas.utils.getSlingSelectors(); return selectors.indexOf(haas.constants.slingSelectors.DUPLICATE) > -1; }, getIsBuildPackageMode: function () { var selectors = this.selectors = getSlingSelectors(); return _.includes(selectors, 'package'); }, applyCurrentPackage: function () { var self = this; var packageTitle = this.getCurrentPackage(); let urlObject = new URL(window.location.href); let preconfiguredPackagePath = urlObject.searchParams.get('preconfiguredPackagePath'); haas.orm = self.optionRulesManager = OptionRulesManager.getInstance(self.vm.model); // Default Machine Init, just setting standard options if (!packageTitle && !preconfiguredPackagePath) { this.setInitialSelectedOptions(); return self.optionRulesManager.promise.then(function () { var nextOptionsState = self.vm.model.options.slice(); var selectedOptions = _.filter(self.vm.model.options, {isSelected: true}); self.loading = false; self.vm.model = Object.assign({}, self.vm.model, { options: nextOptionsState, selectedOptions: selectedOptions }); return self.vm.model; }); } // New Implementation of Packages if (preconfiguredPackagePath) { return fetch(haas.constants.api.getPackageWithURL(preconfiguredPackagePath)).then(res => res.json()).then(packageData => { let packageOptionIDs = packageData.options ? packageData.options.split('&&') : []; let packageOptions = _.filter(self.vm.model.options, (option) => packageOptionIDs.indexOf(option.id) !== -1); let packageToolingJSON = packageData.tooling_qty ? JSON.parse(packageData.tooling_qty) : {}; for (const toolingKey in packageToolingJSON) { packageToolingJSON[toolingKey] = Number(packageToolingJSON[toolingKey]); } self.preconfiguredPackageJSON = packageData; self.preconfiguredPackageJSON.tooling_qty = packageToolingJSON; if (self.preconfiguredPackageJSON.toolingOptionNames && self.preconfiguredPackageJSON.toolingOptionNames.length) { self.preconfiguredPackageJSON.toolingOptionNames = self.preconfiguredPackageJSON.toolingOptionNames.split('&&'); } else { self.preconfiguredPackageJSON.toolingOptionNames = []; } if (self.preconfiguredPackageJSON.optionNames && self.preconfiguredPackageJSON.optionNames.length) { self.preconfiguredPackageJSON.optionNames = self.preconfiguredPackageJSON.optionNames.split('&&'); } else { self.preconfiguredPackageJSON.optionNames = []; } return self.optionRulesManager.promise.then(function () { let nextOptionsState = self.vm.model.options.slice(); self.loading = false; haas.LOGGER.debug('Applying option package:', packageData); // Apply Package Options packageOptions.forEach(opt => { let optionState = _.find(nextOptionsState, {id: opt.id}); if (!optionState) { haas.LOGGER.debug('Skipped unavailable option:', opt.id); return; } // TODO (eventually): restructure/clone getModelState to accept multiple options // TODO: Will also be used for saved configurations self.vm.model = self.optionRulesManager.getModelState(opt); if (optionState.isStandard) { haas.LOGGER.debug('Skipped standard option:', opt.id); } else { haas.LOGGER.debug('Added option:', opt.id); } }); let selectedOptions = _.filter(self.vm.model.options, {isSelected: true}); self.vm.model = Object.assign({}, self.vm.model, { options: nextOptionsState, selectedOptions: selectedOptions }); return self.vm.model; }); }); } // Old Implementation of Packages packageTitle = decodeURIComponent(packageTitle); return haas.services.optionPackage.fetchOptionPackages().then(function () { var model = self.getCurrentModel(); var machineOptionPackages = haas.services.optionPackage.getPackagesForModel(model); var selectedOptionPackage = _.find(machineOptionPackages, {title: packageTitle}); var selectedPackageOptionIds = _.map(selectedOptionPackage.options, 'id'); var selectedPackageOptions = _.filter(self.vm.model.options, function (option) { return selectedPackageOptionIds.indexOf(option.id) !== -1; }); var nextOptionsState = self.vm.model.options.slice(); haas.LOGGER.debug('Applying option package:', selectedOptionPackage.title); return self.optionRulesManager.promise.then(function() { self.loading = false; _.forEach(selectedPackageOptions, function (option) { var optionState = _.find(nextOptionsState, {id: option.id}); if (!optionState) { haas.LOGGER.debug('Skipped unavailable option:', option.id); return; } // TODO (eventually): restructure/clone getModelState to accept multiple options // TODO: Will also be used for saved configurations self.vm.model = self.optionRulesManager.getModelState(option); if (optionState.isStandard) { haas.LOGGER.debug('Skipped standard option:', option.id); } else { haas.LOGGER.debug('Added option:', option.id); } }); var selectedOptions = _.filter(self.vm.model.options, {isSelected: true}); self.vm.model = Object.assign({}, self.vm.model, { defaultAssociate: selectedOptionPackage.machineAssociation, defaultAssociateOptions: selectedOptionPackage.machineAssociationOptions, options: nextOptionsState, selectedOptions: selectedOptions }); return self.vm.model; }); }); }, /** * Apply current quote from quote={bid} Sling selector in URL * @returns {*|PromiseLike|Promise} * { * nextModelState: self.vm.model - Haas model object * quote: payload - quote payload JSON object * } */ applyCurrentQuote: function () { var self = this; var quoteId = self.getCurrentQuote(); return quoteDetailsService.get(quoteId) .then(function(quote) { var modelName = quote.model; var payload = quote.payload || {}; if (!modelName) { modelName = self.getCurrentModel(); if (modelName.indexOf(haas.constants.slingSelectors.QUOTE) === 0) modelName = null; if (!modelName) { haas.LOGGER.warn('No model id included in quote'); return new Promise(function(resolve, reject) { resolve({ nextModelState: {}, quote: {} }); }); } } return self.fetchModelDetails(modelName) .then(function (model) { self.initORMandTracking(model); var selectedQuoteOptionIds = []; if (quote.included) { var included = quote.included.split(","); if (included.length > 0) { selectedQuoteOptionIds = selectedQuoteOptionIds.concat(included); } } if (quote.options) { var options = quote.options.split(","); if (options.length > 0) { selectedQuoteOptionIds = selectedQuoteOptionIds.concat(options); } } var selectedQuoteOptions = _.filter(self.vm.model.options, function (option) { return selectedQuoteOptionIds.indexOf(option.id) !== -1; }); var nextOptionsState = self.vm.model.options.slice(); haas.LOGGER.debug('Applying options from quote:', quoteId, quote); return self.optionRulesManager.promise .then(function() { self.loading = false; _.forEach(selectedQuoteOptions, function (option) { var optionState = _.find(nextOptionsState, {id: option.id}); if (!optionState) { haas.LOGGER.debug('Skipped unavailable option:', option.id); return; } // TODO (eventually): restructure/clone getModelState to accept multiple options // TODO: Will also be used for saved configurations self.vm.model = self.optionRulesManager.getModelState(option); if (optionState.isStandard) { haas.LOGGER.debug('Skipped standard option:', option.id); } else { haas.LOGGER.debug('Added option:', option.id); } }); var selectedOptions = _.filter(self.vm.model.options, {isSelected: true}); var defaultAssociate = null; var defaultAssociateOptions = []; var machines = payload.machines; if (machines && machines.length > 1) { for (var i = 1; i < machines.length; i++) { var machine = machines[i]; haas.LOGGER.debug('Adding associated machine ' + machine.model + ' with options: ', machine.options); if (machine.model) { if (!defaultAssociate) { defaultAssociate = machine.model; } } if (machine.options) { var options = machine.options.split(","); if (options.length > 0) { defaultAssociateOptions = defaultAssociateOptions.concat(options); } } } } self.vm.model = Object.assign({}, self.vm.model, { defaultAssociate: defaultAssociate, defaultAssociateOptions: defaultAssociateOptions, options: nextOptionsState, selectedOptions: selectedOptions }); return { nextModelState: self.vm.model, quote: payload } }); }); }); }, /** * Apply current serial from serial={serial number} Sling selector in URL * @returns {*|PromiseLike} * nextModelState: self.vm.model - Haas model object */ applyCurrentSerial: function () { var self = this; var serialNumber = self.getCurrentSerial(); return serialNumberConfigService.get(serialNumber) .then(function(config) { var modelName = config.model; var options = config.options; if (!modelName) { modelName = self.getCurrentModel(); if (modelName.indexOf(haas.constants.slingSelectors.SERIAL) === 0) modelName = null; if (!modelName) { haas.LOGGER.warn('No model id included in serial number config'); return new Promise(function(resolve, reject) { resolve({}); }); } } return self.fetchModelDetails(modelName) .then(function (model) { self.initORMandTracking(model); if (!options || options.length === 0) { haas.LOGGER.warn("Missing options from config for serial number: " + serialNumber); } var selectedSerialOptionIds = _.filter(options, function(option) { return !!(option.charact_value); }).map(function(option) { return option.charact_value; }); // initialize options with standard options var selectedSerialOptions = self.vm.model.getStandardOptions(); // Apply options from serial number, filter out legacy options _.filter(self.vm.model.options, function (option) { return selectedSerialOptionIds.indexOf(option.id) !== -1; }).map(function(option){ selectedSerialOptions.push(option); }); // This gathers the names of legacy options that can be used for option replacement var legacyOptionIds = _.difference(selectedSerialOptionIds, selectedSerialOptions.map(function(option) { return option.id; })); // Get the option objects of the legacy options var legacyOptions = _.filter(options, function(option) { return (legacyOptionIds.indexOf(option.charact_value) !== -1 && option.charact_name !== 'TOOLING_TAPER' && option.charact_name !== 'INCH_OR_METRIC'); }); haas.LOGGER.debug('All skipped Options: ', legacyOptions); // Object to hold successfully replaced legacy options for modal var replacedOptions = { 'legacy': [], 'current': [] }; // For every legacy option, find its replacement and push it to the selectedSerialOptions legacyOptions.map(function(option) { var legacyOptionIndex = option.charact_value; var modelLegacyOptions = self.vm.model.legacyOptions; var legacyOptionObj = modelLegacyOptions[legacyOptionIndex]; haas.LOGGER.debug(legacyOptionObj); // if the legacy option is documented, and has a replacement, try to add to selected options if (legacyOptionObj && legacyOptionObj.hasReplacement) { var replacementOption = _.find(self.vm.model.options, {'id' : legacyOptionObj.currentId}); replacedOptions.legacy.push(option.value_txt); // if machine currently has the option, add to selected options if (replacementOption) { replacedOptions.current.push(replacementOption.name); selectedSerialOptions.push(replacementOption); } else { // if not, then skip but display to user replacedOptions.current.push('none'); } } else if (legacyOptionObj && !legacyOptionObj.hasReplacement) { // legacy option is documented and doesnt have a replacement, skip but display to user replacedOptions.legacy.push(option.value_txt); replacedOptions.current.push('none'); } }); // remove duplicate options selectedSerialOptions = _.uniq(selectedSerialOptions); var nextOptionsState = self.vm.model.options.slice(); haas.LOGGER.debug('Applying options from serial number:', serialNumber, selectedSerialOptionIds); return self.optionRulesManager.promise .then(function() { self.loading = false; _.forEach(selectedSerialOptions, function (option) { var optionState = _.find(nextOptionsState, {id: option.id}); if (!optionState) { haas.LOGGER.debug('Skipped unavailable option:', option.id); return; } // TODO (eventually): restructure/clone getModelState to accept multiple options // TODO: Will also be used for saved configurations self.vm.model = self.optionRulesManager.getModelState(option); if (optionState.isStandard) { haas.LOGGER.debug('Skipped standard option:', option.id); } else { haas.LOGGER.debug('Added option:', option.id); } }); var selectedOptions = _.filter(self.vm.model.options, {isSelected: true}); var defaultAssociate = null; var defaultAssociateOptions = []; self.vm.model = Object.assign({}, self.vm.model, { defaultAssociate: defaultAssociate, defaultAssociateOptions: defaultAssociateOptions, options: nextOptionsState, selectedOptions: selectedOptions }); // legacyOptions -> names of unsupported options for modal display return { nextModelState: self.vm.model, legacyOptions: replacedOptions.legacy, currentOptions: replacedOptions.current }; }); }); }); }, getSelectedAssociate : function () { var selectedAssociate = haas.bus.configuratorOptionsHeader.state.model.associations.filter(function(option) { return option.isSelected; }); return selectedAssociate.length ? selectedAssociate[0] : {}; }, onVMUpdate: function (nextState) { Object.assign(this.vm, nextState); if (nextState.promptUmcCdfPopup) { this.renderUmcCdfPopup(); return; } else if (nextState.showForm) { this.showForm(); return; } else if (nextState.submitPackage) { this.submitPackage(); return; } this.render(); }, renderUmcCdfPopup: function() { let self = this; $.when(haas.jwToken.jwtPromise).then(function (token) { let submitBPForm = haas.jwToken.isValid(token); const modalTemplate = self.templates.umcCdfModal; setTimeout(() => { optionsBus.publish({ promptUmcCdfPopup: false }) }, 100); document.querySelector('body').classList.remove('cursor-wait'); Modal.open(modalTemplate()); document.querySelector('.umc-cdf-modal #skip-and-finish').onclick = () => { Modal.close(); optionsBus.publish({ showForm: !submitBPForm, submitForm: submitBPForm, newQuote: true }); } document.querySelector('.umc-cdf-modal #add-and-finish').onclick = () => { const cdfOptionCard = document.querySelector('.option-card[data-option="CDF CONVEYOR"]'); self.triggeredByUmcCdfModal = true; cdfOptionCard.click(); } }); }, onRegionChange: function () { // If regionChange fired before state is initialized just skip function // Should only happen if a V-Model is chosen for Build and Price if (!('vm' in this)) { return; } var self = this; var modelName = self.getCurrentModel(); var selectedOptions = _.filter(self.vm.model.options, {isSelected: true}); var selectedAssociate = self.getSelectedAssociate(); var selectedAssociateOptions = _.filter(selectedAssociate.options, {isSelected: true}) || []; // get updated version of model with new region pricing self.fetchModelDetails(modelName) .then(function (model) { // get new categories with new region pricing var categories = self.getCategories(model.options); // assign previous version to new version and get new instance of orm using new model self.initORMandTracking(model); // make an array of the option ids we're keeping and collect their options from the // new option model, as though they were a package var keepSelectedOptionIds = _.map(selectedOptions, 'id'); var keepSelectedOptions = _.filter(self.vm.model.options, function (option) { return keepSelectedOptionIds.indexOf(option.id) !== -1; }); var keepSelectedAssociate = _.find(self.vm.model.associations, {id: selectedAssociate.id}); var keepSelectedAssociateOptionIds = _.map(selectedAssociateOptions, 'id'); var keepSelectedAssociateOptions = []; if (keepSelectedAssociate) { keepSelectedAssociateOptions = _.filter(keepSelectedAssociate.options, function (option) { return keepSelectedAssociateOptionIds.indexOf(option.id) !== -1; }); } var nextOptionsState = self.vm.model.options.slice(); var nextAssociatesState = self.vm.model.associations.slice(); self.optionRulesManager.promise.then(function() { var keptSelectedOptions = []; var keptAssociate = null; var keptAssociateOptions = []; _.forEach(keepSelectedOptions, function (option) { var optionState = _.find(nextOptionsState, {id: option.id}); if (!optionState) { haas.LOGGER.debug('Skipped unavailable option:', option.id); return; } self.vm.model = self.optionRulesManager.getModelState(option); if (optionState.isStandard) { haas.LOGGER.debug('Skipped standard option:', option.id); } else { haas.LOGGER.debug('Added option:', option.id); } }); keptSelectedOptions.push.apply(keptSelectedOptions, _.filter(self.vm.model.options, {isSelected: true })); // if associate selected, send it and its selected options to new model if (keepSelectedAssociate) { var associateState = _.find(nextAssociatesState, {id: keepSelectedAssociate.id}); if (!associateState) { haas.LOGGER.debug('Skipped unavailable associate:', keepSelectedAssociate.id); } else { haas.LOGGER.debug('Added associate:', keepSelectedAssociate.id); keptAssociate = associateState.id; var nextAssociateOptionsState = associateState.options; _.forEach(keepSelectedAssociateOptions, function(option) { var optionState = _.find(nextAssociateOptionsState, {id: option.id}); if (!optionState) { haas.LOGGER.debug('Skipped unavailable associate option:', option.id); return; } if (optionState.isStandard) { haas.LOGGER.debug('Skipped standard option:', option.id); } else { haas.LOGGER.debug('Added option:', option.id); } optionState.isSelected = true; }); keptAssociateOptions = _.filter(associateState.options, {isSelected: true}); keptAssociateOptions = _.map(keptAssociateOptions, function(opt) { return opt.id; }); } } haas.LOGGER.debug('kept options', keptSelectedOptions); self.vm.model = Object.assign({}, self.vm.model, { defaultAssociate: keptAssociate, defaultAssociateOptions: keptAssociateOptions, options: nextOptionsState, selectedOptions: keptSelectedOptions }); haas.bus.configuratorOptionsHeader.publish({model: self.vm.model}); optionsBus.publish({model: self.vm.model, categories: categories}); self.finishApplyConfiguration(categories); }).then(function(){ self.renderSelectedOptions(); self.renderOptionPrices(); }); }); }, setCardHeights: function () { var configurator = this; var $groups = this.$(SELECTOR_CARD_GROUP); $groups.each(function () { var $this = $(this); var $cards = $this.find(SELECTOR_CARD); var rows = _.chunk($cards, configurator.vm.numCols); rows.forEach(function (row) { eqHeight($(row)); }); }); }, getOptionFromCardElem: function (card) { var $card = $(card); var optionId = $card.data(DATA_OPTION); var associateId = $card.data('associate'); var automationId = $card.data('automation'); var associate = _.find(this.vm.model.associations, {id: associateId}); var automation = _.find(this.vm.model.automations, {id: automationId}); if (!optionId && associate) { return associate; } if (!optionId && automation) { return automation; } if ($card.hasClass('associate-option-card')) { return _.find(associate.options, {id: optionId}); } if ($card.hasClass('automation-option-card')) { return _.find(automation.options, {id: optionId}); } return _.find(this.vm.model.options, {id: optionId}); }, getCardElemForOption: function (option) { return this.$('[data-' + DATA_OPTION + '="' + option.id + '"]'); }, loadModal: function() { Modal.load(); document.querySelector('body').classList.add('cursor-wait'); }, unloadModal: function() { if (haas.bus.modal.state.loading) Modal.unload(); document.querySelector('body').classList.remove('cursor-wait'); }, getCardClickHandler: function (self, cardElem) { var option = self.getOptionFromCardElem(cardElem); self.addOption(option); var selectedOptions = _.filter(self.vm.model.options, {isSelected: true}); var $associateCard = self.$(SELECTOR_ASSOCIATE_CARD + SELECTOR_SELECTED); var $automationCard = self.$(SELECTOR_AUTOMATION_CARD + SELECTOR_SELECTED); if ($associateCard.length) { var associate = _.find(self.vm.model.associations, {id: $associateCard.data('associate')}); var associateOpts = _.filter(associate.options, function (opt) { return opt.isSelected || opt.isStandard; }); associateOpts.unshift(associate); selectedOptions = selectedOptions.concat(associateOpts); } if ($automationCard.length) { var automation = _.find(self.vm.model.automations, {id: $automationCard.data('automation')}); var automationOpts = _.filter(automation.options, function (opt) { return opt.isSelected || opt.isStandard; }); automationOpts.unshift(automation); selectedOptions = selectedOptions.concat(automationOpts); } var model = Object.assign({}, self.vm.model, { selectedOptions: selectedOptions, selectedToolingParts: haas.bus.configuratorOptionsHeader.state.model.selectedToolingParts }); haas.bus.configuratorOptionsHeader.publish({model: model}); self.renderSelectedOptions(); self.render(); self.unloadModal(); }, onAssociateOptionCardClick: function (e) { var $card = $(e.currentTarget); var optionId = $card.data('option'); var self = this; var selectedOptions = _.filter(this.vm.model.options, {isSelected: true}); var associateId = $card.data('associate'); var automationId = $card.data('automation'); var associate = associateId ? _.find(this.vm.model.associations, {id: associateId}) : automationId ? _.find(this.vm.model.automations, {id: automationId}) : null; var associateType = associateId ? 'associate' : automationId ? 'automation' : null; var option = _.find(associate.options, {id: optionId}); if (option.categoryUniqueName === 'bar_install') { Modal.open(this.templates.requiredChildModal({ parentOption: associate })); return; } if (!option.isStandard) { option.isSelected = !option.isSelected; } var selectedAssociateOptions = _.filter(associate.options, function (opt) { return opt.isSelected || opt.isStandard; }); selectedOptions = selectedOptions.concat(associate).concat(selectedAssociateOptions); if (associateType === 'associate') { var $automationCard = self.$(SELECTOR_AUTOMATION_CARD + SELECTOR_SELECTED); if ($automationCard.length) { var automation = _.find(self.vm.model.automations, {id: $automationCard.data('automation')}); var automationOpts = _.filter(automation.options, function (opt) { return opt.isSelected || opt.isStandard; }); automationOpts.unshift(automation); selectedOptions = selectedOptions.concat(automationOpts); } } else if (associateType === 'automation') { var $associateCard = self.$(SELECTOR_ASSOCIATE_CARD + SELECTOR_SELECTED); if ($associateCard.length) { var associateObj = _.find(self.vm.model.associations, {id: $associateCard.data('associate')}); var associateOps = _.filter(associateObj.options, function (opt) { return opt.isSelected || opt.isStandard; }); associateOps.unshift(associateObj); selectedOptions = selectedOptions.concat(associateOps); } } var model = Object.assign({}, this.vm.model, { selectedOptions: selectedOptions, selectedToolingParts: haas.bus.configuratorOptionsHeader.state.model.selectedToolingParts }); haas.bus.configuratorOptionsHeader.publish({model: model}); this.renderSelectedOptions(); switch (associateType) { case 'associate': self.renderAssociateOptions(associate, true); break; case 'automation': self.renderAutomationOptions(associate, true); break; default: break; } }, renderSelectedOptions: function() { // for each selectedOption, if it doesn't have the "selected" class, // add the selected class $('.option-card').removeClass('selected'); _.forEach(haas.bus.configuratorOptionsHeader.state.model.selectedOptions, function(element){ var element_selector = ".option-card[data-option='"+element.id+"']"; $(element_selector).addClass('selected'); }); var selectedAssociates = haas.bus.configuratorOptionsHeader.state.model.associations.filter(function(opt) { return opt.isSelected; }); if (selectedAssociates.length) { var element_selector = ".associate-card[data-associate='"+selectedAssociates[0].id+"']"; $(element_selector).addClass('selected'); } var selectedAutomations = haas.bus.configuratorOptionsHeader.state.model.automations.filter(function(opt) { return opt.isSelected; }); if (selectedAutomations.length) { var element_selector = ".automation-card[data-automation='"+selectedAutomations[0].id+"']"; $(element_selector).addClass('selected'); } }, addOption: function (option) { var model = this.optionRulesManager.getModelState(option); if (this.optionRulesManager.getCanAddOption()){ optionsBus.publish({model: model}); } }, mapToString:function(objectArray){ haas.LOGGER.log( _.map(objectArray, 'id').join() ); }, handleDialog: function (option) { this.addOnModalCheck.call(this, option); this.replacedModalCheck.call(this, option); this.prerequisiteModalCheck.call(this,option); }, handlePrompt: function () { }, getAddOnsForOption: function (option) { return _.filter(this.vm.model.options, {addOnFor: option.id}); }, getReplacedOptionsForOption: function (option) { return _.filter(this.vm.model.options, {replacedBy: option.id}); }, getPrerequisiteOptions: function (option) { var prerequisiteOptionIds = option.rules.PREREQUISITES.includes; return _.filter(this.vm.model.options, function(optionItem){ return _.includes(prerequisiteOptionIds, optionItem.id); }); }, getOptionDetailClickHandler: function (configurator) { return function (e) { e.stopPropagation(); e.preventDefault(); var $card = $(this).parents(SELECTOR_CARD); if (!$card.length) $card = $(this).parents(SELECTOR_ASSOCIATE_CARD); if (!$card.length) $card = $(this).parents(SELECTOR_ASSOCIATE_OPTION_CARD); if (!$card.length) $card = $(this).parents(SELECTOR_AUTOMATION_CARD); if (!$card.length) $card = $(this).parents(SELECTOR_AUTOMATION_OPTION_CARD); var option = configurator.getOptionFromCardElem($card); // pass region to temporarily disable videos for options in CN var modalVM = { option: option, formatCurrency: formatCurrency, region: haas.region.props.region }; Modal.open(configurator.templates.optionDetails(modalVM)); Modal.emitter.subscribeOnce('load', function () { $('.option-detail-modal-carousel').slick(configurator.slickConfig); $('.option-detail-modal-carousel').slick('goTo', 0); }); }; }, getSelectedOptions: function () { var $selected = this.$(SELECTOR_CARD + SELECTOR_SELECTED); var selectedIds = _.map($selected, function (elem) { return $(elem).data(DATA_OPTION); }); return this.vm.model.options.filter(function (option) { return selectedIds.indexOf(option.id) !== -1; }); }, showForm: function () { var self = this; $.when(haas.jwToken.jwtPromise).then(function (token) { console.log('=> form shown!'); // check to see if user is logged in; // if not, show the form. Otherwise, auto-submit // and skip to thank you page without showing initial form. // this.refs.$actionBar.addClass(CLASS_HIDDEN); self.refs.$output.addClass(CLASS_HIDDEN); self.refs.$successOutput.addClass(CLASS_HIDDEN); self.refs.$form.removeClass(CLASS_HIDDEN); haas.utils.resetCurrentMenuScroll(); haas.analytics.trackSubStep('contact-information'); try {window._satellite.track("baq-step");} catch (e) {} }); }, createNewQuote: function() { $.when(haas.jwToken.jwtPromise).then(function (token) { var submitBPForm = haas.jwToken.isValid(token); optionsBus.publish({showForm: !submitBPForm, submitForm: submitBPForm, newQuote: true }); }); }, hideForm: function () { if (this.refs.$actionBar) { this.refs.$actionBar.removeClass(CLASS_HIDDEN); } this.$('.configurator-options-form').addClass(CLASS_HIDDEN); this.$('.component-output').removeClass(CLASS_HIDDEN); optionsBus.publish({showForm: false}); }, setGoToTopPosition: function () { var offsetHeight = $('.configurator-action-bar').outerHeight(); var offset = haas.device.display.isMobile() ? 10 : 20; $('.gototop').css('bottom', offsetHeight + offset); }, onFormSubmit: function (formState) { console.log('=======> form submitted!'); if (formState.hideForm) { this.hideForm(); return; } if (!formState.submitted) return; var self = this; var machines = this.buildMachinesPayload(); var configuratorData = Object.assign({ machines: machines }, formState.form); console.log(configuratorData); var campaignInfo = haas.analytics.getCampaignInfo(); if (!_.isEmpty(campaignInfo)) { Object.assign(configuratorData, { "campaign": { "utm_info": encodeURIComponent(campaignInfo) } }); } // If there is a promo and it has a note, send it with the B&P payload if (self.vm.model.promotions.length) { let promoNotes = []; self.vm.model.promotions.forEach(promo => { if (promo.promoNote.length) promoNotes.push(self.vm.model.getLocalizedPromoNotes(promo)); }); // if multiple promos w/ notes, only send the first note if (promoNotes.length) { Object.assign(configuratorData, { "notes": promoNotes[0] }); } } // If it is a preconfigured package, add note from package instead if (Object.keys(self.preconfiguredPackageJSON).length) { if (self.preconfiguredPackageJSON.quoteNotes && self.preconfiguredPackageJSON.quoteNotes.length) { Object.assign(configuratorData, { "notes": self.preconfiguredPackageJSON.quoteNotes }); } } haas.LOGGER.debug('Submitting Quote: ', configuratorData); this.showLoadingDialog(); var quoteId = this.getCurrentQuote(); var newQuote = haas.bus.configuratorOptions.state.newQuote; // If the quote ID selector is NOT present (or the quote ID value is empty), then create a new quote // If the quote ID selector is present AND the "duplicate" selector is NOT present, then update the existing quote // If the quote ID selectors is present and the "duplicate" selector is present, then create a new quote (with duplicate-quote flag) if (quoteId && !newQuote) { Object.assign(configuratorData, { "bid": quoteId }); $.when(haas.jwToken.jwtPromise).then(function (userData) { if (haas.jwToken.isValid(userData)) { updateQuoteService.submit(configuratorData, true) .done(function (res) { if (typeof res === 'string') { res = JSON.parse(res); } if (!res.success) { return handleError('There was an issue processing your request. Please verify the information entered and try again.', res); } // self.refs.$form.addClass(CLASS_HIDDEN); // self.showSuccessDialog(); // instead of showing success dialog, // take authenticated users directly to their quotes page window.location.replace(myQuotesUri); }) .fail(handleError); } else { updateQuoteService.submit(configuratorData, false) .done(function (res) { if (typeof res === 'string') { res = JSON.parse(res); } if (!res.success) { return handleError('There was an issue processing your request. Please verify the information entered and try again.', res); } self.refs.$form.addClass(CLASS_HIDDEN); self.showSuccessDialog(false); }) .fail(handleError); } }); } else { $.when(haas.jwToken.jwtPromise).then(function (userData) { if (haas.jwToken.isValid(userData)) { if (self.getIsDuplicateQuote()) { // If this is a duplicate quote rather than just a new quote, send flag to authenticated create quote endpoint configuratorData["event_id"] = EVENT_DUPLICATE; } createQuoteService.submit(configuratorData, true) .done(function (res) { if (typeof res === 'string') { res = JSON.parse(res); } if (!res.success) { return handleError('There was an issue processing your request. Please verify the information entered and try again.', res); } // self.refs.$form.addClass(CLASS_HIDDEN); // self.showSuccessDialog(); // instead of showing success dialog, // take authenticated users directly to their quotes page window.location.replace(myQuotesUri); }) .fail(handleError); } else { createQuoteService.submit(configuratorData, false) .then(function (res) { var form_status = $('.bp-form').data('status'); if (typeof res === 'string') { res = JSON.parse(res); } if (!res.success) { return handleError('There was an issue processing your request. Please verify the information entered and try again.', res); } self.refs.$form.addClass(CLASS_HIDDEN); haas.LOGGER.debug(res); if (form_status === 'register') { return res; } else { self.showSuccessDialog(false); } }) .then(function(reg_res){ if (reg_res) { if (!reg_res.data) { return handleError('There was an issue processing your request. Please verify the information entered and try again.', reg_res); } var SELECTOR_FORM_EMAIL = '#email'; var SELECTOR_FORM_PW = '#bp-MyHaas-reg-pw'; var form_firstname = $('#first_name').val(); var form_lastname = $('#last_name').val(); var form_phone = $('#phone').val(); var form_street = $('#street').val(); var form_city = $('#City').val(); var form_region = $('#Region').val(); var form_postcode = $('#PostCode').val(); var form_country = $('#Country').val(); var form_company = $('#company').val(); var acc_email = $(SELECTOR_FORM_EMAIL).val(); var acc_pw = $(SELECTOR_FORM_PW).val(); var cust_num = reg_res.data.sap_customer_id; // add leading zeros to customer number (SAP Requirement) cust_num = cust_num.split(''); while (cust_num.length < 10) { cust_num.unshift('0'); } cust_num = cust_num.join(''); var registration_json = { "customerNumber":cust_num, "customerName":form_company, "email":acc_email, "password":acc_pw, "title":"0002", "firstName":form_firstname, "lastName":form_lastname, "houseNumber":form_street.split(' ')[0], "streetName":form_street.split(' ').splice(1).join(' '), "city":form_city, "region":form_country+'-'+form_region, "postalCode":form_postcode, "country":form_country, "cellNumber":form_phone, "languageIsoCode":haas.utils.getLanguage(), "callerSystemId":"MyNewHaas", "comments":"Created from AEM" }; haas.LOGGER.debug('registering account with: ', registration_json); haas.services.fleetRegistrationService.post(registration_json).then(function(payload) { haas.LOGGER.debug('registration payload', payload); if (payload.contactId) { self.showSuccessDialog('success'); } else { // registration failed haas.LOGGER.debug(payload.responseText); if (payload.messageCode === 'EMAIL_EXISTS') { self.showSuccessDialog('dupEmail'); } else { self.showSuccessDialog('failed'); } } }) .fail(function(){ haas.LOGGER.warn(err); self.showSuccessDialog(false); }); } }) .fail(handleError); } }); } function handleError (err, res) { if (err) { haas.LOGGER.warn(err); if (res) haas.LOGGER.info(res); Modal.unload(); self.showForm(); self.showErrorDialog(err); } } }, submitPackage: function() { var self = this; var cancelEvent = function() { $('#edit-package').on(EVENT_CLICK, function() { Modal.unload(); }); }; var submitPackageEvents = function() { cancelEvent(); $('#packageForm').on('submit', function(e) { e.preventDefault(); self.showLoadingDialog(); var payload = { title: $(this).find('#packageTitle').val(), machines: self.buildMachinesPayload() }; createPackageService.submit(payload) .done(function (res) { Modal.unload(); var packageSuccessEvents = function() { cancelEvent(); }; //build author edit link to package var modalModel = { //lovely hack, for some reason, the template ingest scrapes attribute placeholders. packageEditUrl:'EDIT GENERATED PACKAGE' }; Modal.prompt(self.templates.packageSuccessModal(modalModel), packageSuccessEvents); }) .fail(function (err, res) { if (err) { haas.LOGGER.warn(err.responseJSON); Modal.unload(); self.showErrorDialog(err.responseJSON.error.message); } }) }); }; Modal.prompt(this.templates.submitPackageModal(), submitPackageEvents); haas.bus.configuratorOptions.publish({submitPackage: false}); }, buildMachinesPayload: function() { var model = this.vm.model; var language = haas.utils.getLanguage().toUpperCase(); var primaryMachine = { model: model.id, included: _.chain(model.options).filter({price: 0, isSelected: true}).map('id').value().join(), options: _.chain(model.options).filter(function (option) { return option.isSelected && option.price > 0; }).map('id').value().join(), machine_language: language, machine_region: haas.region.props.region, machine_currency: haas.region.props.currency, machine_hfo_id: haas.region.props.hfoid, tooling_qty : haas.bus.configuratorOptionsHeader.state.model.selectedToolingParts, //TODO: remove discounts discounts: model.getDiscounts() }; var secondaryMachine; var $associateCard = this.$(SELECTOR_ASSOCIATE_CARD + SELECTOR_SELECTED); if ($associateCard.length) { var associate = _.find(this.vm.model.associations, {id: $associateCard.data('associate')}); secondaryMachine = { model: associate.id, included: _.chain(associate.options).filter({price: 0, isSelected: true}).map('id').value().join(), options: _.chain(associate.options).filter(function (option) { return option.isSelected && option.price > 0; }).map('id').value().join(), machine_language: language, machine_region: haas.region.props.region, machine_currency: haas.region.props.currency, machine_hfo_id: haas.region.props.hfoid }; } var machines = [primaryMachine]; if (secondaryMachine) { machines.push(secondaryMachine); } var automationMachine; var $automationCard = this.$(SELECTOR_AUTOMATION_CARD + SELECTOR_SELECTED); if ($automationCard.length) { var automation = _.find(this.vm.model.automations, {id: $automationCard.data('automation')}); automationMachine = { model: automation.id, included: _.chain(automation.options).filter({price: 0, isSelected: true}).map('id').value().join(), options: _.chain(automation.options).filter(function (option) { return option.isSelected && option.price > 0; }).map('id').value().join(), machine_language: language, machine_region: haas.region.props.region, machine_currency: haas.region.props.currency, machine_hfo_id: haas.region.props.hfoid }; } var machines = [primaryMachine]; if (secondaryMachine) { machines.push(secondaryMachine); } if (automationMachine) { machines.push(automationMachine); } return machines; }, showLoadingDialog: function () { Modal.load(); }, showSuccessDialog: function (isRegistration) { Modal.unload(); this.refs.$successOutput.removeClass(CLASS_HIDDEN).html(this.templates.successModal({registration: isRegistration})); // $('.configurator-options-header').addClass(CLASS_HIDDEN); // $('.progress-indicator').addClass(CLASS_HIDDEN); this.bindSuccessDialogEvents(); haas.analytics.trackSubStep('form-complete'); try {window._satellite.track("baq-complete");} catch (e) {} }, bindSuccessDialogEvents: function () { var self = this; $('.edit-machine').off(EVENT_CLICK).on(EVENT_CLICK, function (e) { e.preventDefault(); self.refs.$successOutput.addClass(CLASS_HIDDEN); self.refs.$output.removeClass(CLASS_HIDDEN); $('.configurator-options-header').removeClass(CLASS_HIDDEN); $('.progress-indicator').removeClass(CLASS_HIDDEN); // self.refs.$actionBar.removeClass(CLASS_HIDDEN); }); }, showErrorDialog: function (err) { Modal.open(_.template('

    {{=err}}

    ')({err: err})); }, onSubgroupClick: function (e) { var $target = $(e.currentTarget); var $subgroupHeading = $target.parents('.subgroup-heading'); var $subgroup = $target.parents('.option-subgroup'); if ($target.hasClass('global-subgroup-name')) { $subgroup = $('.option-subgroup[data-subgroup="'+ $subgroupHeading.data('subgroup') +'"]'); $subgroupHeading.find('.subgroup-name-wrapper').toggleClass('closed'); } var $subgroupWrapper = $subgroup.find('.subgroup-wrapper'); $subgroupWrapper.slideToggle(SLIDE_TOGGLE_SPEED); }, onAssocGroupClick: function (e) { var $target = $(e.currentTarget); var $subgroup = $target.parents('.associations-group'); var $subgroupWrapper = $subgroup.find('.associateOptionsContainer'); $subgroupWrapper.slideToggle(SLIDE_TOGGLE_SPEED); $target.find('.header-collapse-icon').toggleClass('rotate'); }, onAutomGroupClick: function (e) { var $target = $(e.currentTarget); var $subgroup = $target.parents('.automations-group'); var $subgroupWrapper = $subgroup.find('.automationOptionsContainer'); console.log($target, $subgroup, $subgroupWrapper); $subgroupWrapper.slideToggle(SLIDE_TOGGLE_SPEED); $target.find('.header-collapse-icon').toggleClass('rotate'); }, onHeaderClick: function (e) { var $target = $(e.currentTarget); var $parentContainer = $target.parents('.option-group-container'); var $optionCardGroup = $parentContainer.find('.option-card-group'); $optionCardGroup.slideToggle(SLIDE_TOGGLE_SPEED); $target.find('.header-collapse-icon').toggleClass('rotate'); }, onToolingHeaderClick: function(e) { var $parentContainer = $($(e.target).parents('.option-group-container')[0]); $parentContainer.find('> .option-card-group').slideToggle(); $parentContainer.find('> .option-group-banner .header-collapse-icon').toggleClass('rotate'); }, expandCollapseAll: function () { this.$('.expand-collapse-btn').toggleClass('active'); if (this.isExpandAll) { this.$('.option-group-container .option-card-group:not(#tooling-container .option-card-group)').slideUp(SLIDE_TOGGLE_SPEED); this.$('.associateOptionsContainer').slideUp(SLIDE_TOGGLE_SPEED); this.$('.header-collapse-icon:not(#tooling-container .header-collapse-icon)').removeClass('rotate'); this.isExpandAll = false; } else { this.$('.option-group-container .option-card-group:not(#tooling-container .option-card-group)').slideDown(SLIDE_TOGGLE_SPEED); this.$('.associateOptionsContainer').slideDown(SLIDE_TOGGLE_SPEED); this.$('.header-collapse-icon:not(#tooling-container .header-collapse-icon)').addClass('rotate'); this.isExpandAll = true; } }, toolingExpandCollapseAll: function () { this.$('.tooling-expand-collapse-txt').toggleClass('active'); if (this.isToolingExpandAll) { document.querySelectorAll('#tooling-cat-container .option-card-group').forEach(group => { group.style.display = 'none' }); this.$('#tooling-cat-container .header-collapse-icon').removeClass('rotate'); this.isToolingExpandAll = false; } else { document.querySelectorAll('#tooling-cat-container .option-card-group').forEach(group => { group.style.display = 'block' }); this.$('#tooling-cat-container .header-collapse-icon').addClass('rotate'); this.isToolingExpandAll = true; } }, onPageScroll: function () { var DATA_SUBGROUP = 'subgroup'; var FIXED_CLASS = 'fixed-subgroup'; var $subgroups = $('.option-subgroup'); var $globalHeading = $('.global-subgroup-heading'); var topPos = $('.configurator-options-header-wrapper').height(); var subHeadingHeight = $globalHeading.height(); var topPosWithSubHeading = topPos + subHeadingHeight; var $inPosSubgroups = $subgroups.filter(function () { return haas.utils.isInViewPort($(this), topPos); }); var $inPosSubgroup = $inPosSubgroups.eq(0); var $nextSubGroup = $inPosSubgroups.eq(1); var nextSubOffset = $nextSubGroup.offset(); var windowScrollTop = $(window).scrollTop(); if (windowScrollTop < haas.tmp.currentMenuOffset) { //$('.configurator-header-wrapper').removeClass('sticky'); } if (nextSubOffset) nextSubOffset = nextSubOffset.top; var inPosOffset = $inPosSubgroup.find('.subgroup-heading').offset(); if ((this.$currentSubgroup && $inPosSubgroup.data(DATA_SUBGROUP) !== this.$currentSubgroup.data(DATA_SUBGROUP)) || (inPosOffset && inPosOffset.top >= topPos)) { this.removeGlobalSubgroupHeader(); } if ($inPosSubgroup.length && $inPosSubgroup.data('subgroup') !== 'undefined' && $inPosSubgroup.find('.subgroup-heading').offset().top - windowScrollTop <= topPos) { if (!$inPosSubgroup.hasClass(FIXED_CLASS)) { this.setGlobalSubgroupHeader($inPosSubgroup); this.$currentSubgroup = $inPosSubgroup; } } if ($nextSubGroup.length && nextSubOffset <= topPosWithSubHeading && nextSubOffset >= topPos) { var diff = topPosWithSubHeading - nextSubOffset; // $globalHeading.css('top', topPos - diff); } else { // $globalHeading.css('top', ''); } }, setGlobalSubgroupHeader: function ($subgroup) { var HEADING_SUFFIX = ' '; var subgroupName = $subgroup.data('subgroup'); var $heading = $('.global-subgroup-heading'); var topPos = $('.configurator-options-header-wrapper').height(); $('.global-subgroup-name-text').html(subgroupName + HEADING_SUFFIX); $heading .removeClass('invisible') .data('subgroup', subgroupName) .css('top', topPos + 'px'); if ($subgroup.find('.subgroup-name-wrapper').hasClass('closed')) { $heading.find('.subgroup-name-wrapper').addClass('closed'); } else { $heading.find('.subgroup-name-wrapper').removeClass('closed'); } }, removeGlobalSubgroupHeader: function () { $('.global-subgroup-name-text').html(''); $('.global-subgroup-heading').addClass('invisible').data('subgroup', ''); }, onAutomationCardClick: function (e) { var self = this; var $card = $(e.currentTarget); var id = $card.data('automation'); var automation = _.find(this.vm.model.automations, {id: id}); var model; this.$(SELECTOR_AUTOMATION_CARD + SELECTOR_SELECTED).removeClass(CLASS_SELECTED); this.vm.model.automations.forEach(function (model) { if (model.id !== automation.id) { model.isSelected = false; } }); self.addOption(automation); var selectedOptions = _.filter(this.vm.model.options, {isSelected: true}); if (automation.isSelected) { var automationOptions = []; automation.options.forEach(function (opt) { if (opt.isStandard) opt.isSelected = true; if (opt.isSelected) automationOptions.push(opt); if ((automation.id === 'HAAS BAR FEEDER' || automation.id === 'HAAS BAR FEEDER V2') && opt.categoryUniqueName === 'bar_install') { var existing = _.find(automationOptions, {categoryUniqueName: 'bar_install'}); if (!existing) { automationOptions.push(opt); } } }); automationOptions.unshift(automation); selectedOptions = selectedOptions.concat(automationOptions); var $associateCard = self.$(SELECTOR_ASSOCIATE_CARD + SELECTOR_SELECTED); if ($associateCard.length) { var associate = _.find(self.vm.model.associations, {id: $associateCard.data('associate')}); var associateOpts = _.filter(associate.options, function (opt) { return opt.isSelected || opt.isStandard; }); associateOpts.unshift(associate); selectedOptions = selectedOptions.concat(associateOpts); } $card.addClass(CLASS_SELECTED); model = Object.assign({}, this.vm.model, { selectedOptions: selectedOptions, selectedToolingParts: haas.bus.configuratorOptionsHeader.state.model.selectedToolingParts }); haas.bus.configuratorOptionsHeader.publish({model: model}); // on associate change, reinitialize options if (!e.shown) { this.automationOptionsShown = false; } this.renderAutomationOptions(automation, true); } else { _.remove(selectedOptions, {categoryUniqueName: 'bar_install'}); var $associateCard = self.$(SELECTOR_ASSOCIATE_CARD + SELECTOR_SELECTED); if ($associateCard.length) { var associate = _.find(self.vm.model.associations, {id: $associateCard.data('associate')}); var associateOpts = _.filter(associate.options, function (opt) { return opt.isSelected || opt.isStandard; }); associateOpts.unshift(associate); selectedOptions = selectedOptions.concat(associateOpts); } model = Object.assign({}, this.vm.model, { selectedOptions: selectedOptions, selectedToolingParts: haas.bus.configuratorOptionsHeader.state.model.selectedToolingParts }); haas.bus.configuratorOptionsHeader.publish({model: model}); this.renderAutomationOptions(false, true); } self.renderSelectedOptions(); }, onAssociateCardClick: function (e) { var self = this; var $card = $(e.currentTarget); var id = $card.data('associate'); var associate = _.find(this.vm.model.associations, {id: id}); var model; this.$(SELECTOR_ASSOCIATE_CARD + SELECTOR_SELECTED).removeClass(CLASS_SELECTED); this.vm.model.associations.forEach(function (model) { if (model.id !== associate.id) { model.isSelected = false; } }); self.addOption(associate); var selectedOptions = _.filter(this.vm.model.options, {isSelected: true}); if (associate.isSelected) { var associateOptions = []; associate.options.forEach(function (opt) { if (opt.isStandard) opt.isSelected = true; if (opt.isSelected) associateOptions.push(opt); if ((associate.id === 'HAAS BAR FEEDER' || associate.id === 'HAAS BAR FEEDER V2') && opt.categoryUniqueName === 'bar_install') { var existing = _.find(associateOptions, {categoryUniqueName: 'bar_install'}); if (!existing) { associateOptions.push(opt); } } }); associateOptions.unshift(associate); selectedOptions = selectedOptions.concat(associateOptions); var $automationCard = self.$(SELECTOR_AUTOMATION_CARD + SELECTOR_SELECTED); if ($automationCard.length) { var automation = _.find(self.vm.model.automations, {id: $automationCard.data('automation')}); var automationOpts = _.filter(automation.options, function (opt) { return opt.isSelected || opt.isStandard; }); automationOpts.unshift(automation); selectedOptions = selectedOptions.concat(automationOpts); } $card.addClass(CLASS_SELECTED); model = Object.assign({}, this.vm.model, { selectedOptions: selectedOptions, selectedToolingParts: haas.bus.configuratorOptionsHeader.state.model.selectedToolingParts }); haas.bus.configuratorOptionsHeader.publish({model: model}); // on associate change, reinitialize options if (!e.shown) { this.associateOptionsShown = false; } this.renderAssociateOptions(associate, true); } else { _.remove(selectedOptions, {categoryUniqueName: 'bar_install'}); var $automationCard = self.$(SELECTOR_AUTOMATION_CARD + SELECTOR_SELECTED); if ($automationCard.length) { var automation = _.find(self.vm.model.automations, {id: $automationCard.data('automation')}); var automationOpts = _.filter(automation.options, function (opt) { return opt.isSelected || opt.isStandard; }); automationOpts.unshift(automation); selectedOptions = selectedOptions.concat(automationOpts); } model = Object.assign({}, this.vm.model, { selectedOptions: selectedOptions, selectedToolingParts: haas.bus.configuratorOptionsHeader.state.model.selectedToolingParts }); haas.bus.configuratorOptionsHeader.publish({model: model}); this.renderAssociateOptions(false, true); } self.renderSelectedOptions(); }, renderAutomationOptions: function (automation, fireModal) { var $out = this.$('.automation-options'); if (!automation) { // set associate options boolean to false on deselect this.automationOptionsShown = false; $out.html(''); return; } if (automation.id === 'HAAS BAR FEEDER' || automation.id === 'HAAS BAR FEEDER V2') { var installKit = _.find(automation.options, {categoryUniqueName: 'bar_install'}); installKit.isSelected = true; if(fireModal){ Modal.open(this.templates.prerequisiteModal({ optionAction : 'added', optionsText: installKit.name, option: automation })); } } var categories = _.groupBy(automation.options, 'category'); // only push out html on first render if (!this.automationOptionsShown) { $out.html(this.templates.automationOptions({ automation: automation, categories: categories, // helpers numCols: this.vm.numCols, months: this.vm.months, formatCurrency: formatCurrency, showOptionIds: this.vm.showOptionIds })); } // set associate boolean to true after first render this.automationOptionsShown = true; this.postRender(); }, renderAssociateOptions: function (associate, fireModal) { var $out = this.$('.associate-options'); if (!associate) { // set associate options boolean to false on deselect this.associateOptionsShown = false; $out.html(''); return; } if (associate.id === 'HAAS BAR FEEDER' || associate.id === 'HAAS BAR FEEDER V2') { var installKit = _.find(associate.options, {categoryUniqueName: 'bar_install'}); installKit.isSelected = true; if(fireModal){ Modal.open(this.templates.prerequisiteModal({ optionAction : 'added', optionsText: installKit.name, option: associate })); } } var categories = _.groupBy(associate.options, 'category'); // only push out html on first render if (!this.associateOptionsShown) { $out.html(this.templates.associateOptions({ associate: associate, categories: categories, // helpers numCols: this.vm.numCols, months: this.vm.months, formatCurrency: formatCurrency, showOptionIds: this.vm.showOptionIds })); } // set associate boolean to true after first render this.associateOptionsShown = true; this.postRender(); }, showCategoryVideos: function (e) { var self = this; var $link = $(e.currentTarget); var videoIds = $link.data('videos').split(','); Modal.open(this.templates.categoryDetails({videoIds: videoIds})); Modal.emitter.subscribeOnce('load', function () { $('.option-detail-modal-carousel').slick(self.slickConfig); $('.option-detail-modal-carousel').slick('goTo', 0); }); }, bindToolingEvents: function() { this.$('#tooling-container .option-group-banner:not(#tooling-container > .option-group-container > .option-group-banner)').off(EVENT_CLICK).on(EVENT_CLICK, this.onToolingHeaderClick.bind(this)); this.$('.bnp-ecomm-part').off(EVENT_CLICK).on(EVENT_CLICK, this.onToolingCardClick.bind(this)); this.$('.bnp-ecomm-part > .option-detail-link').off(EVENT_CLICK).on(EVENT_CLICK, this.onToolingDetailsClick.bind(this)); this.$('.bnp-ecomm-part #quantity').off("change").on("change", this.onToolingQuantityChange.bind(this)); this.$('#tooling-expand-collapse-btn').off(EVENT_CLICK).on(EVENT_CLICK, this.toolingExpandCollapseAll.bind(this)); }, bindEvents: function () { let _self = this; this.$(SELECTOR_CARD).off(EVENT_CLICK).on(EVENT_CLICK, (e) => { _self.loadModal(); setTimeout(() => { _self.getCardClickHandler(_self, e.currentTarget); }, 200); }); this.$(SELECTOR_ASSOCIATE_CARD).off(EVENT_CLICK).on(EVENT_CLICK, this.onAssociateCardClick.bind(this)); this.$(SELECTOR_AUTOMATION_CARD).off(EVENT_CLICK).on(EVENT_CLICK, this.onAutomationCardClick.bind(this)); this.$(SELECTOR_ASSOCIATE_OPTION_CARD).off(EVENT_CLICK).on(EVENT_CLICK, this.onAssociateOptionCardClick.bind(this)); this.$(SELECTOR_AUTOMATION_OPTION_CARD).off(EVENT_CLICK).on(EVENT_CLICK, this.onAssociateOptionCardClick.bind(this)); this.$(SELECTOR_OPTION_DETAIL_LINK).off(EVENT_CLICK).on(EVENT_CLICK, this.getOptionDetailClickHandler(this)); $('.mobile-next-btn:not(.btn-new-quote)').off(EVENT_CLICK).on(EVENT_CLICK, this.showForm.bind(this)); $('.mobile-next-btn.btn-new-quote').off(EVENT_CLICK).on(EVENT_CLICK, this.createNewQuote.bind(this)); // $('.btn-next').off(EVENT_CLICK).on(EVENT_CLICK, this.showForm.bind(this)); $('.subgroup-name').off(EVENT_CLICK).on(EVENT_CLICK, this.onSubgroupClick.bind(this)); $('.option-group-container .option-group-banner:not(#tooling-container > .option-group-container > .option-group-banner)').off(EVENT_CLICK).on(EVENT_CLICK, this.onHeaderClick.bind(this)); $($('.associations-group .option-group-banner')[0]).off(EVENT_CLICK).on(EVENT_CLICK, this.onAssocGroupClick.bind(this)); $($('.automations-group .option-group-banner')[0]).off(EVENT_CLICK).on(EVENT_CLICK, this.onAutomGroupClick.bind(this)); this.$('.expand-collapse-btn').off(EVENT_CLICK).on(EVENT_CLICK, this.expandCollapseAll.bind(this)); this.$('.category-video-link').off(EVENT_CLICK).on(EVENT_CLICK, this.showCategoryVideos.bind(this)); this.bindToolingEvents(); this.unbindSpecialOptions(); var pageScrollHandler = this.onPageScroll.bind(this); $(window).off('scroll', pageScrollHandler).on('scroll', pageScrollHandler); }, unbindSpecialOptions: function() { specialOptions.forEach(function(opId) { $("[data-option='"+opId+"'").off(EVENT_CLICK); }) }, renderTemplate: function (template) { this.refs.$output.html(template(this.vm)); }, getSaleHTML : function(saleTagText, discountedPrice, defaultPrice) { return "
    " + "" + saleTagText + "" + " " + "" + discountedPrice + "" + "
    " + defaultPrice + "
    " + "
    "; }, getDefaultPriceHTML : function (defaultPrice){ return "
    " + defaultPrice + "
    "; }, renderOptionPrices: function () { // gather all options and associates var machine_options = []; var machine_associates = []; var machine_associate_options = []; var self = this; _.forEach(haas.bus.configuratorOptionsHeader.state.model.options, function(option) { machine_options.push(option.id); if (!option.isStandard) { var currentPrice; if (option.hasPromotion()) { currentPrice = option.getDiscountedPrice(); if (currentPrice) { $(".option-card[data-option='"+option.id+"']").find('.option-price').replaceWith( self.getSaleHTML( option.getSaleTagText(), option.getFormattedDiscountedPrice(), option.getFormattedPrice())); } else { $(".option-card[data-option='"+option.id+"']").find('.option-price').replaceWith("
    /mo"); } else { $(".option-card[data-option='"+option.id+"']").find('.option-monthly-price').html(monthlyPrice); } } else { currentPrice = option.getPrice(); $(".option-card[data-option='"+option.id+"']").find('.option-price').replaceWith(self.getDefaultPriceHTML(option.getFormattedPrice())); var monthlyPrice = haas.utils.formatCurrency(option.getMonthlyPaymentPrice(haas.bus.configuratorOptionsHeader.state.selectedAmortizationSchedule.months)); if (monthlyPrice) { $(".option-card[data-option='"+option.id+"']").find('.option-monthly-price').html(monthlyPrice + "/mo"); } else { $(".option-card[data-option='"+option.id+"']").find('.option-monthly-price').html(monthlyPrice); } } } }); _.forEach(haas.bus.configuratorOptionsHeader.state.model.associations, function(associate){ machine_associates.push(associate.id); var currentPrice; if (associate.hasPromotion()) { currentPrice = associate.getDiscountedPrice(); $(".associate-card[data-associate='"+associate.id+"']").find('.option-price').replaceWith( self.getSaleHTML( associate.getSaleTagText(), associate.getFormattedDiscountPrice(), associate.getFormattedPrice())); var monthlyPrice = haas.utils.formatCurrency(haas.utils.getMonthlyPaymentPrice(currentPrice, haas.bus.configuratorOptionsHeader.state.selectedAmortizationSchedule.months)); $(".associate-card[data-associate='"+associate.id+"']").find('.option-monthly-price').html(monthlyPrice + "/mo"); } else { $(".associate-card[data-associate='"+associate.id+"']").find('.option-price').replaceWith(self.getDefaultPriceHTML(associate.getFormattedPrice())); var monthlyPrice = haas.utils.formatCurrency(associate.getMonthlyPaymentPrice(haas.bus.configuratorOptionsHeader.state.selectedAmortizationSchedule.months)); $(".associate-card[data-associate='"+associate.id+"']").find('.option-monthly-price').html(monthlyPrice + "/mo");} }); // check if associate is selected var selected_associate = haas.bus.configuratorOptionsHeader.state.model.associations.filter(function(option) { return option.isSelected; })[0]; if (selected_associate) { machine_associate_options = selected_associate.options; _.forEach(machine_associate_options, function(associate_option) { if (!associate_option.isStandard) { if (associate_option.hasPromotion()) { $(".associate-option-card[data-associate='"+selected_associate.id+"'][data-option='"+associate_option.id+"']").find('.option-price').replaceWith( self.getSaleHTML( associate_option.getSaleTagText(), associate_option.getFormattedDiscountedPrice(), associate_option.getFormattedPrice())); var monthlyPrice = haas.utils.formatCurrency(haas.utils.getMonthlyPaymentPrice(associate_option.getDiscountedPrice(), haas.bus.configuratorOptionsHeader.state.selectedAmortizationSchedule.months)); $(".associate-option-card[data-option='"+associate_option.id+"']").find('.option-monthly-price').html(monthlyPrice + "/mo"); } else { $(".associate-option-card[data-associate='"+selected_associate.id+"'][data-option='"+associate_option.id+"']").find('.option-price').replaceWith( self.getDefaultPriceHTML(associate_option.getFormattedPrice())); var monthlyPrice = haas.utils.formatCurrency(associate_option.getMonthlyPaymentPrice(haas.bus.configuratorOptionsHeader.state.selectedAmortizationSchedule.months)); $(".associate-option-card[data-option='"+associate_option.id+"']").find('.option-monthly-price').html(monthlyPrice + "/mo"); } } }); } }, isToolingPackageValid: function(toolingPackage, selectedToolingParts) { if (!toolingPackage) return false; for (let i = 0; i < toolingPackage.toolingIDs.length; i++) { if (!selectedToolingParts[toolingPackage.toolingIDs[i]] || selectedToolingParts[toolingPackage.toolingIDs[i]] < toolingPackage.toolingQtys[i]) return false; } return true; }, pushSelectedToolingOptions: function(optToolingPackage) { var self = this; var toolingParts = self.vm.model.toolingParts; var selectedToolingIds = []; var selectedToolingOptions = {}; var currentSelectedToolingPackage = optToolingPackage ? optToolingPackage : haas.bus.configuratorOptionsHeader.state.model.selectedToolingPackage ? haas.bus.configuratorOptionsHeader.state.model.selectedToolingPackage : null; $('.bnp-ecomm-part:not(.selected) #quantity').val(0); Array.from($('.bnp-ecomm-part.selected')).forEach(function(part) { var partId = $(part).attr('id'); var partQty = Number($(part).find('#quantity :selected').val()); _.filter(toolingParts, {partId: partId})[0].quantity = partQty; selectedToolingIds.push(partId); selectedToolingOptions[partId] = partQty; }); _.forEach(toolingParts, function(part) { part.isSelected = selectedToolingIds.indexOf(part.partId) > -1; }); var model = Object.assign({}, this.vm.model, { selectedOptions: haas.bus.configuratorOptionsHeader.state.model.selectedOptions, selectedToolingParts: selectedToolingOptions, selectedToolingPackage: self.isToolingPackageValid(currentSelectedToolingPackage, selectedToolingOptions) ? optToolingPackage : null }); self.vm.model.selectedToolingPackage = self.isToolingPackageValid(currentSelectedToolingPackage, selectedToolingOptions) ? optToolingPackage : null haas.bus.configuratorOptionsHeader.publish({model: model}); }, onToolingQuantityChange: function(e) { let $toolingCard = $($(e.target).parents('.bnp-ecomm-part')[0]); let toolingId = $toolingCard ? $toolingCard[0].id : null; let isHighlightedKit = $toolingCard ? $toolingCard[0].classList.contains('bnp-highlighted-ecomm-part') : false; if (!$toolingCard.hasClass('selected')) $toolingCard.addClass('selected'); if (Number($toolingCard.find('#quantity :selected').val()) === 0) $toolingCard.removeClass('selected'); if (toolingId) { if (isHighlightedKit) { let normalEntry = document.querySelector('#tooling-container .bnp-ecomm-part[id="'+toolingId+'"]'); if (normalEntry) $(normalEntry).find('#quantity').val($toolingCard.find('#quantity').val()); } else { let highlightedEntry = document.querySelector('#highlighted-tooling-section .bnp-ecomm-part[id="'+toolingId+'"]'); if (highlightedEntry) $(highlightedEntry).find('#quantity').val($toolingCard.find('#quantity').val()); } } this.renderToolingPartPrices(); this.pushSelectedToolingOptions(); }, selectToolingPackage: function (toolingPkg) { const toolingCards = Array.from(document.querySelectorAll('.bnp-ecomm-part')); const partQuantities = Array.from(document.querySelectorAll('.part-qty-input')); for (let i = 0; i < toolingPkg.toolingIDs.length; i++) { try { let toolingCard = toolingCards.find(card => card.id === toolingPkg.toolingIDs[i]); let qtyElem = partQuantities.find(elem => elem.dataset.partId === toolingPkg.toolingIDs[i]); let qty = qtyElem && qtyElem.value ? Number(qtyElem.value) : 0; if (qty > 0 && !toolingCard.classList.contains('selected')) toolingCard.classList.add('selected'); toolingCard.querySelector('select').value = qty; } catch (e) { console.warn('Could not find tooling card for part: ' + toolingPkg.toolingIDs[i]); } } this.renderToolingPartPrices(); this.pushSelectedToolingOptions(toolingPkg); }, onToolingCardClick: function(e) { if ($(e.target).is('#quantity') || $(e.target).is('.quantity-container')) return; let $toolingCard = $(e.target).hasClass('bnp-ecomm-part') ? $(e.target) : $($(e.target).parents('.bnp-ecomm-part')[0]); let toolingId = $toolingCard ? $toolingCard[0].id : null; let isHighlightedKit = $toolingCard ? $toolingCard[0].classList.contains('bnp-highlighted-ecomm-part') : false; let isWcProduct = $toolingCard ? $toolingCard[0].classList.contains('wc-ecomm-part') : false; $toolingCard.toggleClass('selected'); if (!Number($toolingCard.find('#quantity :selected').val())) { $toolingCard.find('#quantity').val('1'); } if (toolingId) { if (isHighlightedKit) { let normalEntry = document.querySelector('#tooling-container .bnp-ecomm-part[id="'+toolingId+'"]'); if (normalEntry) { $(normalEntry).toggleClass('selected'); $(normalEntry).find('#quantity').val($toolingCard.find('#quantity').val()); } } else if (isWcProduct) { let normalEntry = document.querySelector('#tooling-container .bnp-ecomm-part[id="'+toolingId+'"]'); if (normalEntry) { $(normalEntry).toggleClass('selected'); $(normalEntry).find('#quantity').val($toolingCard.find('#quantity').val()); } } else { let highlightedEntry = document.querySelector('#highlighted-tooling-section .bnp-ecomm-part[id="'+toolingId+'"]'); let wcEntry = document.querySelector('#winners-circle-section .wc-ecomm-part[id="'+toolingId+'"]'); if (highlightedEntry) { $(highlightedEntry).toggleClass('selected'); $(highlightedEntry).find('#quantity').val($toolingCard.find('#quantity').val()); } if (wcEntry) { $(wcEntry).toggleClass('selected'); $(wcEntry).find('#quantity').val($toolingCard.find('#quantity').val()); } } } this.pushSelectedToolingOptions(); }, onToolingDetailsClick: function(e) { let self = this; e.stopPropagation(); e.preventDefault(); let partId = $($(e.target).parents('.bnp-ecomm-part')[0]).attr('id'); let partObj = self.vm.model.toolingParts.filter(function(part) { return part.partId === partId; })[0]; let userRegion = haas.region.props.region; let userCurrency = haas.region.props.currency; Modal.open(self.templates.toolingPartDetails({ part: partObj, sku: partId, isWcProduct: partId.toLowerCase().includes('winner') })); let userPriceElem = document.querySelector('.option-detail-modal #tooling-details-price-container span[data-currency="'+userCurrency+'"]'); console.log(userRegion, userCurrency, userPriceElem); userPriceElem.innerHTML = haas.utils.formatCurrency(Number(userPriceElem.dataset.price)); userPriceElem.style.display = 'inline-block'; }, renderToolingPartPrices: function() { var userRegion = haas.region.props.region; var userCurrency = haas.region.props.currency; $('.bnp-ecomm-part').add('.bnp-highlighted-ecomm-part').each(function(ndx, part) { var partPriceObj = $(part).find('.part-price').filter(function(ndx, priceObj) { var $price = $(priceObj); return $price.attr('data-currency').toUpperCase() === userCurrency.toUpperCase(); }); // if it doesnt have a price, just exit. if (!partPriceObj[0]) return; var relevantQuantity = $(part).find('#quantity :selected').val() > 0 ? $(part).find('#quantity :selected').val() : 1; var partPriceValue = Number($(partPriceObj[0]).attr('data-value')) * relevantQuantity; var partPromoPrice = $(partPriceObj[0]).attr('data-promoprice').length ? Number($(partPriceObj[0]).attr('data-promoprice')) * relevantQuantity : -1; if (partPromoPrice > -1) { $(part).find('.tooling-promo-price-span').html(haas.utils.formatCurrency(partPromoPrice)); $(part).find('.price-strike').html(haas.utils.formatCurrency(partPriceValue)); } else { $(part).find('.option-price').html(haas.utils.formatCurrency(partPriceValue)); } }); }, initToolingHeirarchy: function() { let self = this; this.toolingHierarchy = this.vm.model.getToolingHierarchy(self.vm.model.toolingParts); // Hide the "Work in Progress" and "Tooling Packages" tooling items if (this.toolingHierarchy.work_in_progress) delete this.toolingHierarchy.work_in_progress; if (this.toolingHierarchy.tooling_packages) delete this.toolingHierarchy.tooling_packages; }, renderWinnersCirclePart: function() { let self = this; let winnersCirclePart = self.vm.model.toolingParts.find(part => part.partId.toLowerCase().includes('winner')); let winnersCircleContainer = document.querySelector('#winners-circle-section #wc-tooling-container'); let partTemplate = self.templates.singleToolingPartTemplate; if (winnersCirclePart) { winnersCircleContainer.innerHTML += partTemplate({ parts: [winnersCirclePart] }); document.querySelector('#winners-circle-section').style.display = ''; } }, renderHighlightedToolingParts: function() { let self = this; let highlightedToolingIDs = []; let highlightedToolingImgs = []; let parsedToolingPackages = []; if (haas.bus.configuratorOptionsHeader.state.model.id === 'UMC-350HD') { const umc350HighlightedOptionIDs = ['75MM AIR VISE-AUTO', 'ZERO PNT KIT-AUTO']; const umc350HighlightedToolingIDs = ['08-1758']; try { let umc350HighlightedOptionObjs = umc350HighlightedOptionIDs.map(hlOptId => haas.bus.configuratorOptionsHeader.state.model.options.find(opt => opt.id === hlOptId)); umc350HighlightedToolingIDs.forEach(hpID => { try { let toolingObj = self.vm.model.toolingParts.find(part => part.partId === hpID); document.querySelector('#highlighted-tooling-container').innerHTML += self.templates.highlightedToolingPartTemplate({ part: toolingObj }); } catch (e) { console.warn('Error adding part: ', hpID); console.warn(e); } }); umc350HighlightedOptionObjs.forEach(hlOpt => { document.querySelector('#highlighted-tooling-container').innerHTML += self.templates.highlightedOptionTemplate({ option: hlOpt, formatCurrency: formatCurrency, months: this.vm.months }); }); document.querySelector('#highlighted-tooling-section #default-hl-txt').style.display = 'none'; document.querySelector('#highlighted-tooling-section #highlighted-tooling-subtext').style.display = 'none'; document.querySelector('#highlighted-tooling-section #umc-350-hl-txt').style.display = 'block'; document.querySelector('#highlighted-tooling-section').style.display = 'block'; } catch (e) { console.warn('Error Building UMC 350HD Highlighted Options'); console.warn(e); } } else { _.forEach(self.vm.model.toolingPackages, (packageObj) => { let toolingPackage = {}; if (packageObj.workMaterial && packageObj.workMaterial.length) return; if (packageObj.currency !== haas.region.props.currency) return; try { toolingPackage = packageObj; packageObj.toolingIDs.forEach(id => { try { let partLongDescription = self.vm.model.toolingParts.find(part => part.partId === id).longDescription; let partImageID = self.vm.model.toolingParts.find(part => part.partId === id).imageId; if (!toolingPackage.toolingNames) toolingPackage.toolingNames = []; if (!toolingPackage.imageIDs) toolingPackage.imageIDs = []; toolingPackage.toolingNames.push(partLongDescription); toolingPackage.imageIDs.push(partImageID); } catch (e) { console.warn('Error: Skipping Part ID: ', id); console.warn(e); } }); parsedToolingPackages.push(toolingPackage); } catch (e) { console.error('Error: Skipping Tooling Package: ', packageObj); console.error(e); } }); parsedToolingPackages.forEach(pkg => { highlightedToolingIDs = highlightedToolingIDs.concat(pkg.toolingIDs); highlightedToolingImgs = highlightedToolingImgs.concat(pkg.imageIDs); }); if (highlightedToolingIDs.length) { document.querySelector('#highlighted-tooling-section').style.display = 'block'; } highlightedToolingIDs.forEach(hpID => { try { let toolingObj = self.vm.model.toolingParts.find(part => part.partId === hpID); document.querySelector('#highlighted-tooling-container').innerHTML += self.templates.highlightedToolingPartTemplate({ part: toolingObj }); } catch (e) { console.warn('Error adding part: ', hpID); console.warn(e); } }); } }, renderToolingParts: function() { // this is basically a SPA, will re-render eachtime // reinit selectable tooling before rendering if (!Object.keys(this.toolingHierarchy).length) this.initToolingHeirarchy(); let self = this; let subCatOneKeys = Object.keys(this.toolingHierarchy); var $toolingContainer = $('#tooling-cat-container'); let toolingRegions = ['US', 'GL', 'SE', 'IN', 'HE', 'ME', 'MX']; let region = haas.region.props.region; if (!toolingRegions.includes(region)) $('#tooling-container').hide(); $toolingContainer.empty(); if (!subCatOneKeys.length) { $('#tooling-container').addClass('hidden'); } else { $('#tooling-container').removeClass('hidden'); } subCatOneKeys.forEach(function(key) { var type = self.toolingHierarchy[key]['type']; if (type === 'one') { var toolingTemplate = self.templates.toolingPartsTemplate({ type: type, catOneKey: key.replace(/-/g, ' ').replace(/_/g, ' '), catTwoObjs: self.toolingHierarchy[key].parts }); $toolingContainer.append(toolingTemplate); } if (type === 'long') { var toolingTemplate = self.templates.toolingPartsTemplate({ type: type, catOneKey: key.replace(/-/g, ' ').replace(/_/g, ' '), catTwoObjs: self.toolingHierarchy[key] }); $toolingContainer.append(toolingTemplate); } if (type === 'short') { var toolingTemplate = self.templates.toolingPartsTemplate({ type: type, catOneKey: key.replace(/-/g, ' ').replace(/_/g, ' '), catTwoObjs: self.toolingHierarchy[key] }); $toolingContainer.append(toolingTemplate); } }); self.renderToolingPartPrices(); self.bindToolingEvents(); }, renderLoading: function () { this.refs.$output.html(haas.constants.loadingTmpl); }, render: function () { var browserIE = false || !!document.documentMode; let self = this; if (this.loading) { return this.renderLoading(); } else if (!this.initialized){ $.when(haas.region.priceGroupPromise).then((pl) => { // fetch and set model tooling parts before rendering spa fetch(haas.constants.api.toolingBNP+'.json').then(res => res.json()) .then(toolingParts => { let userCurrency = pl.currency; // for parts that end with "a", like 08-0002a, replace lowercase "a" with "A" for correct image toolingParts.filter(part => { return part.imageId && part.partId && part.partId.endsWith('a'); }).forEach(part => { part.partId = part.partId.replace('a', 'A'); part.imageId = part.imageId.replace('a/hero', 'A/hero'); }); self.vm.model.toolingParts = toolingParts.filter(part => part.toolingRegion.prices.some(price => price.currency.toUpperCase() === userCurrency)); self.updateORM(self.vm.model); // hard codeded category renames self.vm.model.toolingParts.forEach(part => { if (part.subCatOne === 'er_collet') part.subCatOne = 'er_collets_&_chucks'; if (part.subCatTwo === 'er_collet_kits') part.subCatTwo = 'er_collets'; if (part.subCatTwo === 'er_collet_kits_only') part.subCatTwo = 'er_collet_sets_&_accessories'; if (part.subCatTwo === 'spindle_taper_cleane') part.subCatTwo = 'spindle_taper_cleaner'; }); // apply order promotions to tooling if (self.vm.model.hasPercentageOrderPromotion()) { let promo = self.vm.model.getOrderPromotion(); self.vm.model.toolingParts.forEach(toolingPart => { let toolingPrice = toolingPart.toolingRegion.prices.find(price => price.currency.toUpperCase() === userCurrency); let promoPrice = haas.utils.applyPromotionalDiscount(promo, toolingPrice.price); if (promoPrice === toolingPrice) return false; if (promo.excludedToolingParts.some(excludedPart => excludedPart.toLowerCase() === toolingPart.partId.toLowerCase())) return false; toolingPart.promotion = promo; // Keep track of all promotions applicable for the option rather than just using the last promotion, if this has been called multiple times if (!toolingPart.promotions) toolingPart.promotions = []; toolingPart.promotions.push(promo); toolingPart.promotionPrice = promoPrice; }); } haas.bus.configuratorOptionsHeader.publish({model: self.vm.model}); }).then(() => { self.renderTemplate(this.templates.optionGroups); if (haas.region.props.country === 'US') self.renderWinnersCirclePart(); self.renderHighlightedToolingParts(); self.renderToolingParts(); self.initialized = true; // on initial render, expand forced selected options specialOptions.forEach(function(optionId) { $("[data-option='"+optionId+"']").parents('.option-card-group').slideDown(); }); // If it is a pre-configured package AND has tooling, then apply pre-selected tooling if (Object.keys(self.preconfiguredPackageJSON).length) { if (self.preconfiguredPackageJSON.tooling_qty && Object.keys(self.preconfiguredPackageJSON.tooling_qty).length) { for (const toolingId in self.preconfiguredPackageJSON.tooling_qty) { let normalEntry = document.querySelector('#tooling-container .bnp-ecomm-part[id="'+toolingId+'"]'); let highlightedEntry = document.querySelector('#highlighted-tooling-section .bnp-ecomm-part[id="'+toolingId+'"]'); if (toolingId) { if (normalEntry) { normalEntry.classList.add('selected'); normalEntry.querySelector('#quantity').value = self.preconfiguredPackageJSON.tooling_qty[toolingId]; } if (highlightedEntry) { normalEntry.classList.add('selected'); highlightedEntry.querySelector('#quantity').value = self.preconfiguredPackageJSON.tooling_qty[toolingId]; } } self.renderToolingPartPrices(); self.pushSelectedToolingOptions(); } } } // initialize the tooling heirarchy console.log("Initializing the Model:", haas.bus.configuratorOptionsHeader.state.model); self.renderSelectedAssociateAndOptions(); self.renderOptionPrices(); self.postRender(); if (Object.keys(self.preconfiguredPackageJSON).length) { Modal.open(self.templates.preconfiguredPackageModal({ optionNames: self.preconfiguredPackageJSON.optionNames, toolingNames: self.preconfiguredPackageJSON.toolingOptionNames })); } }); }); } else { self.renderSelectedAssociateAndOptions(); self.renderOptionPrices(); self.postRender(); } }, renderSelectedAssociateAndOptions: function () { var $associateCard = this.$(SELECTOR_ASSOCIATE_CARD + SELECTOR_SELECTED); if ($associateCard.length) { var associate = _.find(this.vm.model.associations, {id: $associateCard.data('associate')}); this.renderAssociateOptions(associate, false); } else { this.renderAssociateOptions(false, false); } }, postRender: function () { this.bindEvents(); this.setNumCols(); /* this.setCardHeights(); */ this.setGoToTopPosition(); this.initializeBuildPackageMode(); this.onPageScroll(); } }); })(); /* global $, _, haas, priceGroupPromise */ (function () { 'use strict'; var formatCurrency = haas.utils.formatCurrency; var AMORTIZATION_SCHEDULES = haas.constants.AMORTIZATION_SCHEDULES.slice(); var DEFAULT_DOWN_PAYMENT = haas.constants.DEFAULT_DOWN_PAYMENT; var TEXT_VIEW_DETAILS = 'DETAILS'; var TEXT_CLOSE_DETAILS = 'CLOSE'; var EVENT_CLICK = 'click'; var EVENT_RESIZE = 'resize'; var EVENT_CHANGE = 'change'; var PAYMENTCONTAINER = '.header-financing'; var SELECTOR_VIEW_DETAILS_LINK = '.configurator-header-details-link'; var SELECTOR_DETAILS = '.configurator-header-details-flyout'; var SELECTOR_DETAILS_CONTAINER = '.configurator-header-details'; var SELECTOR_FLYOUT_CAT = '.flyout-category'; var SELECTOR_PAYMENT_SELECT = '.configurator-monthly-payment-select'; var SELECTOR_CARD_FINANCING = '.option-monthly-price'; var DATA_UID = 'uid'; var defaultAmortizationSchedule = _.find(AMORTIZATION_SCHEDULES, {defaultValue: true}); var initialVM = { model: null, selectedOptions: [], selectedToolingParts: {}, detailsLinkText: TEXT_VIEW_DETAILS, showDetails: false, totalMonthlyPayment: 0, selectedAmortizationSchedule: Object.assign({}, defaultAmortizationSchedule), amortizationSchedules: AMORTIZATION_SCHEDULES, downPaymentPercentage: DEFAULT_DOWN_PAYMENT, buildPackageMode: false }; var regionBus = haas.bus.region; var bus = haas.bus.configuratorOptionsHeader = haas.utils.Channel.create(initialVM); haas.components.ConfiguratorOptionsHeader = haas.Component.create({ vm: initialVM, headerIsInitialized: false, headerBaseComponent: null, hfoHasFinancingRates: false, viewHelpers: { formatCurrency: formatCurrency }, unsubscribeBus: _.noop, unsubRegionBus:_.noop, initialize: function () { var self = this; $.when(haas.region.priceGroupPromise).then(function(price_group) { self.unsubscribeBus(); self.unsubscribeBus = bus.subscribe(self.onBusUpdate.bind(self)); self.unsubRegionBus(); self.unsubRegionBus = regionBus.subscribe(self.onRegionChange.bind(self)); self.setFinancingOptions(); $(window).on(EVENT_RESIZE, self.render.bind(self)); }); }, setFinancingOptions: function() { var self = this; $.when(haas.region.priceGroupPromise).then(function(price_group) { if (price_group.hfoid !== '0') { haas.LOGGER.debug('SETTING FINANCING RATES HEADER', price_group.hfoid); haas.services.dealerFinancingService.getPrograms(price_group.hfoid).then(function(programs){ if (programs.length && programs[0].monthAndRateOptions) { self.hfoHasFinancingRates = true; self.vm.amortizationSchedules = programs[0].monthAndRateOptions; bus.publish({amortizationSchedules: self.vm.amortizationSchedules}); self.vm.selectedAmortizationSchedule = _.find(programs[0].monthAndRateOptions, {defaultValue: true}) || programs[0].monthAndRateOptions[programs[0].monthAndRateOptions.length - 1]; bus.publish({selectedAmortizationSchedule: self.vm.selectedAmortizationSchedule}); self.vm.downPaymentPercentage = programs[0].defaultDownpaymentPercentage / 100; bus.publish({downPaymentPercentage: self.vm.downPaymentPercentage}); } }); } }); }, updateFinancingOptionsForTesting: function() { var self = this; haas.LOGGER.debug('HFO CHANGED TO: ', haas.region.props.hfoid); haas.LOGGER.debug('SETTING FINANCING RATES HEADER'); haas.services.dealerFinancingService.getPrograms(haas.region.props.hfoid).then(function(programs){ if (programs.length && programs[0].monthAndRateOptions) { self.hfoHasFinancingRates = true; self.vm.amortizationSchedules = programs[0].monthAndRateOptions; bus.publish({amortizationSchedules: self.vm.amortizationSchedules}); self.vm.selectedAmortizationSchedule = _.find(programs[0].monthAndRateOptions, {defaultValue: true}); bus.publish({selectedAmortizationSchedule: self.vm.selectedAmortizationSchedule}); self.vm.downPaymentPercentage = programs[0].defaultDownpaymentPercentage / 100; bus.publish({downPaymentPercentage: self.vm.downPaymentPercentage }); haas.bus.configuratorOptions.publish({months: self.vm.selectedAmortizationSchedule.months}); } }); }, onBusUpdate: function (nextState) { var self = this; $.when(haas.region.priceGroupPromise).then(function(price_group) { Object.assign(self.vm, nextState); if (nextState.model) { self.vm.model = nextState.model; self.vm.selectedOptions = nextState.model.selectedOptions; self.vm.selectedOptionCategoryTotals = _.chain(self.vm.selectedOptions) .groupBy('category') .map(function (options, categoryName) { var firstOption = options[0]; // if opt group is an associated machine, display the machine name if (firstOption instanceof haas.models.Machine) { categoryName = firstOption.name; } return { category: categoryName, uid: firstOption.categoryUID, price: _.chain(options) .map(function (option) { return option.addOnFor ? option.addOnPrice : option.price; // return option.getActualPrice(); }) .reduce(function (total, n) { return total + n; }) .value() }; }) .value(); // only reveal financing options if user is in the US if(self.hfoHasFinancingRates || haas.region.props.region === "US"){ self.vm.totalMonthlyPayment = nextState.model.getMonthlyPaymentPriceWithOptions(self.vm.selectedAmortizationSchedule.months); } } self.render(); }); }, initializeBuildPackageMode: function() { $('.btn-primary.btn-continue.btn-next').hide(); $('.btn-package').show(); }, onRegionChange: function () { haas.LOGGER.log('rerendering configurator options header on region change'); // region change render is triggered in configuratorOptions.js }, getVM: function () { return Object.assign({}, this.vm, this.viewHelpers); }, onViewDetailsClick: function (e) { e.preventDefault(); if (this.vm.showDetails) { bus.publish({ detailsLinkText: TEXT_VIEW_DETAILS, showDetails: false }); return; } bus.publish({ detailsLinkText: TEXT_CLOSE_DETAILS, showDetails: true }); }, positionDetailsFlyout: function () { var $container = this.$(SELECTOR_DETAILS_CONTAINER); var $flyout = this.$(SELECTOR_DETAILS); var containerWidth = $container.width(); var flyoutWidth = $flyout.width(); var diff = (containerWidth - flyoutWidth) / 2; $flyout.css('left', diff); this.setDetailsFlyoutOverflow(); }, setDetailsFlyoutOverflow: function () { var $flyout = this.$(SELECTOR_DETAILS); var $flyoutBody = $flyout.find('.flyout-body'); var $actionBar = $('.configurator-action-bar'); var offset = $flyoutBody.offset(); var actionBarOffset = $actionBar.offset(); if (!offset || !actionBarOffset) return; var flyoutBottomY = offset.top + $flyout.height(); if (flyoutBottomY >= actionBarOffset.top) { var bodyHeight = $flyoutBody.height(); var diff = flyoutBottomY - actionBarOffset.top; var nextHeight = bodyHeight - diff; $flyoutBody .css('overflow-y', 'scroll') .css('height', nextHeight); } }, scrollToCategory: function () { var uid = $(this).find('.flyout-category').data(DATA_UID); var $elem = $('#' + uid); // Expand options on scrollToCategory $elem.parents('.option-group-container').find('.option-card-group').slideDown(); if ($elem.length) $elem[0].scrollIntoView({block: 'center'}); }, updateMonthlyAmortizationSchedule: function (_self) { var months = + this.$(SELECTOR_PAYMENT_SELECT).val(); _self.vm.selectedAmortizationSchedule = _.find(_self.vm.amortizationSchedules, {months: months}); bus.publish({selectedAmortizationSchedule: _self.vm.selectedAmortizationSchedule}); haas.bus.configuratorOptions.publish({months: months}); }, getSaleHTML : function(saleTagText, discountedPrice, defaultPrice) { return "
    " + "" + saleTagText + "" + " " + "" + discountedPrice + "" + "
    " + defaultPrice + "
    " + "
    "; }, getDefaultPriceHTML : function (defaultPrice){ return "
    " + defaultPrice + "
    "; }, renderOptionPrices: function (self) { // gather all options and associates var machine_options = []; var machine_associates = []; var machine_associate_options = []; _.forEach(haas.bus.configuratorOptionsHeader.state.model.options, function(option) { machine_options.push(option.id); if (!option.isStandard) { var currentPrice; if (option.hasPromotion()) { currentPrice = option.getDiscountedPrice(); if (currentPrice) { $(".option-card[data-option='"+option.id+"']").find('.option-price').replaceWith( self.getSaleHTML( option.getSaleTagText(), option.getFormattedDiscountedPrice(), option.getFormattedPrice())); } else { $(".option-card[data-option='"+option.id+"']").find('.option-price').replaceWith("
    /mo"); } else { $(".option-card[data-option='"+option.id+"']").find('.option-monthly-price').html(monthlyPrice); } } else { currentPrice = option.getPrice(); $(".option-card[data-option='"+option.id+"']").find('.option-price').replaceWith(self.getDefaultPriceHTML(option.getFormattedPrice())); var monthlyPrice = haas.utils.formatCurrency(option.getMonthlyPaymentPrice(haas.bus.configuratorOptionsHeader.state.selectedAmortizationSchedule.months)); if (monthlyPrice) { $(".option-card[data-option='"+option.id+"']").find('.option-monthly-price').html(monthlyPrice + "/mo"); } else { $(".option-card[data-option='"+option.id+"']").find('.option-monthly-price').html(monthlyPrice); } } } }); _.forEach(haas.bus.configuratorOptionsHeader.state.model.associations, function(associate){ machine_associates.push(associate.id); var currentPrice; if (associate.hasPromotion()) { currentPrice = associate.getDiscountedPrice(); $(".associate-card[data-associate='"+associate.id+"']").find('.option-price').replaceWith( self.getSaleHTML( associate.getSaleTagText(), associate.getFormattedDiscountPrice(), associate.getFormattedPrice())); var monthlyPrice = haas.utils.formatCurrency(haas.utils.getMonthlyPaymentPrice(currentPrice, haas.bus.configuratorOptionsHeader.state.selectedAmortizationSchedule.months)); $(".associate-card[data-associate='"+associate.id+"']").find('.option-monthly-price').html(monthlyPrice + "/mo"); } else { $(".associate-card[data-associate='"+associate.id+"']").find('.option-price').replaceWith(self.getDefaultPriceHTML(associate.getFormattedPrice())); var monthlyPrice = haas.utils.formatCurrency(associate.getMonthlyPaymentPrice(haas.bus.configuratorOptionsHeader.state.selectedAmortizationSchedule.months)); $(".associate-card[data-associate='"+associate.id+"']").find('.option-monthly-price').html(monthlyPrice + "/mo");} }); // check if associate is selected var selected_associate = haas.bus.configuratorOptionsHeader.state.model.associations.filter(function(option) { return option.isSelected; })[0]; if (selected_associate) { machine_associate_options = selected_associate.options; _.forEach(machine_associate_options, function(associate_option) { if (!associate_option.isStandard) { if (associate_option.hasPromotion()) { $(".associate-option-card[data-associate='"+selected_associate.id+"'][data-option='"+associate_option.id+"']").find('.option-price').replaceWith( self.getSaleHTML( associate_option.getSaleTagText(), associate_option.getFormattedDiscountedPrice(), associate_option.getFormattedPrice())); var monthlyPrice = haas.utils.formatCurrency(haas.utils.getMonthlyPaymentPrice(associate_option.getDiscountedPrice(), haas.bus.configuratorOptionsHeader.state.selectedAmortizationSchedule.months)); $(".associate-option-card[data-option='"+associate_option.id+"']").find('.option-monthly-price').html(monthlyPrice + "/mo"); } else { $(".associate-option-card[data-associate='"+selected_associate.id+"'][data-option='"+associate_option.id+"']").find('.option-price').replaceWith( self.getDefaultPriceHTML(associate_option.getFormattedPrice())); var monthlyPrice = haas.utils.formatCurrency(associate_option.getMonthlyPaymentPrice(haas.bus.configuratorOptionsHeader.state.selectedAmortizationSchedule.months)); $(".associate-option-card[data-option='"+associate_option.id+"']").find('.option-monthly-price').html(monthlyPrice + "/mo"); } } }); } }, bindEvents: function () { var self = this; this.$(SELECTOR_VIEW_DETAILS_LINK).off(EVENT_CLICK).on(EVENT_CLICK, this.onViewDetailsClick.bind(this)); $(SELECTOR_FLYOUT_CAT).each(function(){ $(this).parent().off(EVENT_CLICK).on(EVENT_CLICK, self.scrollToCategory); }); $('.configurator-monthly-payment-select').off('change').on('change', () => { self.updateMonthlyAmortizationSchedule(self); self.renderOptionPrices(self); }); $(window).off('haas-hfo-changed').on('haas-hfo-changed', self.updateFinancingOptionsForTesting.bind(self)); $.when(haas.jwToken.jwtPromise).then(function (token) { var loggedIn = haas.jwToken.isValid(token); // // TO-DO: Create Intermediate step between btn click and show form. Allows user to add tooling package. // // If on a quote page, render specific buttons, else render 'Finish My Quote' Button if (self.getCurrentQuote()) { if (loggedIn) { // If authenticated, only one button appears and will perform different actions depending on flow $('.btn-continue.btn-next.btn-new-quote').addClass('hidden'); // If not duplciated if (!self.isDuplicateQuote()) { $('.btn-continue.btn-next.btn-edit-quote:not(.btn-reverse, .btn-new-quote)').removeClass('hidden').off(EVENT_CLICK).on(EVENT_CLICK, self.showForm.bind(self)); } else if (self.isDuplicateQuote()) { // In Duplicate flow, make button create new quote $('.btn-continue.btn-next.btn-edit-quote:not(.btn-reverse, .btn-new-quote)').removeClass('hidden').off(EVENT_CLICK).on(EVENT_CLICK, self.createNewQuote.bind(self)); // create new quote button } } else { $('.btn-continue.btn-next.btn-new-quote:visible').off(EVENT_CLICK).on(EVENT_CLICK, self.showForm.bind(self)); } } else { let hasCdfConveyer = self.vm.model.options.find(opt => opt.id === 'CDF CONVEYOR') ? true : false; let cdfConveyerSelected = self.vm.selectedOptions.find(opt => opt.id === 'CDF CONVEYOR') ? true : false; // was originally for umcs only, but now for anymachine with cdf. TO-DO: Rename to just cdf popup if (hasCdfConveyer && !cdfConveyerSelected) { $('.btn-continue.btn-next:not(.btn-reverse, .btn-new-quote)').off(EVENT_CLICK).on(EVENT_CLICK, self.promptUmcCdfPopup.bind(self)); // create new quote button } else { $('.btn-continue.btn-next:not(.btn-reverse, .btn-new-quote)').off(EVENT_CLICK).on(EVENT_CLICK, self.showForm.bind(self)); // create new quote button } } }); // Event Handler for Haas Delivered Price Modal Button $.when(haas.region.priceGroupPromise).then(function(payload) { // Maintainance: If more regions require this message, add pl region below if (payload.region === "FR") { var $haasDeliveredButton = $('.haas-delivered-message.bnp-msg button'); var modalHeight = $(window).height() * .80 + 'px'; var modalWidth = Math.min($(window).width() * .90, 1000) + 'px'; var pdfSource = '/content/dam/haascnc/assets/haas-delivered/fr/HaasDeliveredFrance_' + $('html').attr('lang') + '.pdf'; $haasDeliveredButton.on('click', function() { haas.components.Modal.open(' -1; }, renderTemplate: function (template) { this.refs.$output.html(template(this.getVM())); }, renderLoading: function () { this.refs.$output.html(''); }, render: function () { var self = this; if (!self.vm.model) { return self.renderLoading(); } self.renderTemplate(self.templates.header); if(self.vm.buildPackageMode) { self.initializeBuildPackageMode(); } self.bindEvents(); if (!self.headerIsInitialized) { self.headerBaseComponent = haas.components.registerComponent('ConfiguratorHeader', self.$element); self.headerIsInitialized = true; haas.utils.scrollToTarget($('#configurator-sticky-wrapper'), 5, 1); } else { self.headerBaseComponent.render(); } // only reveal financing options if user is in the US if (self.hfoHasFinancingRates || haas.region.props.region === "US") { $(PAYMENTCONTAINER).removeClass('hidden'); $(SELECTOR_CARD_FINANCING).removeClass('hidden'); } else { $(SELECTOR_CARD_FINANCING).addClass('hidden'); } } }); })(); /* global haas, $, _ */ (function () { 'use strict'; haas.models.OptionPackage = OptionPackageModel; function OptionPackageModel (props) { Object.assign(this, props); props.features = props.features || []; this.features = props.features; this.getPriceForMachine = function (machineName) { var self = this; var machinePackage = _.find(self.machines, {name: machineName}); if (!machinePackage) return; var priceDef = _.find(machinePackage.prices, {region: haas.region.props.region, currency: haas.region.props.currency}); if (!priceDef) priceDef = _.find(machinePackage.total_price, {region: haas.region.props.region}); if (!priceDef) return; return priceDef.price; }; this.hasPromotionForMachine = function (modelId) { var machine = _.find(this.machines, function (machine) { return machine.id === modelId && !!machine.promotion; }); return !!machine; }; this.hasOptionPromotionForMachine = function (modelId) { var self = this; var machine = _.find(this.machines, function (machine) { return machine.id === modelId; }); if (!machine) return false; if (machine.option_promotion_price && machine.option_promotion_price.length) { var promo = _.find(machine.option_promotion_price, {region: haas.region.props.region}); if (promo) return true; } return false; }; this.getDiscountedPriceForPackage = function (pkg, price) { if (!pkg.promotion) return; return haas.utils.formatCurrency(this.machine.promotion.getDiscountedPriceForModel(this.machine.id, this.getNumericPrice())); }; this.getOptionsPrice = function (machineName, isPromo) { var self = this; var priceProp = 'option_price'; var optionPriceProp = isPromo ? 'option_promotion_price' : priceProp; var machinePackage = _.find(this.machines, {name: machineName}); if (!machinePackage) return; var priceDef = _.find(machinePackage[optionPriceProp], {region: haas.region.props.region, currency:haas.region.props.currency }); if (!priceDef && isPromo) { priceDef = _.find(machinePackage[priceProp], {region: haas.region.props.region, currency:haas.region.props.currency}); } if (!priceDef) return; return priceDef.price; }; } })(); /* global haas, $, _ */ (function () { 'use strict'; var packagesURL = haas.constants.api.optionPackages; var urlTemplate = _.template(packagesURL); var OptionPackage = haas.models.OptionPackage; var PersistedCache = haas.utils.PersistedCache; haas.services.optionPackage = { cache: new PersistedCache('option_packages'), optionPackages: [], fetchOptionPackages: function (noCache) { noCache = !!noCache; // if packages in memory return them if (this.optionPackages.length && !noCache) return Promise.resolve(this.optionPackages); // if packages in localStorage return them var language = haas.utils.getLanguage(); var packages = this.cache.get(language); if (packages) { this.optionPackages = packages; return Promise.resolve(packages); } // else fetch return this._fetchOptionPackages(language); }, getPackagesForModel: function (modelId) { return _.chain(this.optionPackages) .filter(function (optionPackage) { return !!_.find(optionPackage.machines, {id: modelId}); }) .map(function (optionPackage) { return new OptionPackage(optionPackage); }) .value(); }, _fetchOptionPackages: function (language) { var self = this; return $.getJSON(urlTemplate({language: language})).then(function (optionPackages) { self.optionPackages = optionPackages; self.cache.set(optionPackages, language); return optionPackages; }); } }; })(); /* global $, haas, _, priceGroupPromise */ (function () { 'use strict'; var hidePageChrome = haas.utils.hidePageChrome; //var enableFullscreen = haas.utils.enableFullscreen; var Modal = haas.components.Modal; var resetScroll = haas.utils.resetCurrentMenuScroll; var optionPackageService = haas.services.optionPackage; var TYPE_FUNCTION = 'function'; var EVENT_CLICK = 'click'; var CLASS_SELECTED = 'selected'; var CLASS_ACTIVE = 'active'; var CLASS_HIDDEN = 'hidden'; var SELECTOR_CARD = '.configurator-card'; var SELECTOR_SELECTED = '.' + CLASS_SELECTED; var SELECTOR_CONTINUE = '.btn-continue:not(.btn-reverse)'; var SELECTOR_VIEW_DETAILS = '.view-details-link'; var DATA_URL = 'url'; var DATA_ACTION = 'action'; var getSlingSelectors = haas.utils.getSlingSelectors; var encodeSlingSelector = haas.utils.encodeSlingSelector; var regionBus = haas.bus.region; haas.components.ConfiguratorMidpoint = haas.Component.create({ vm: { selection: {}, optionPackages: [], optionPackageChunks: [], loadingPackages: false, formatNumber: haas.utils.formatNumber, formatCurrency: haas.utils.formatCurrency, // used in html encodeSlingSelector: encodeSlingSelector }, unsubRegionBus:_.noop, unsubRegionOptionBus :_.noop, currentStep: 0, initialize: function () { var midpoint = this; var selectors = getSlingSelectors(); var model = selectors[0]; $.when(haas.region.priceGroupPromise).then(function(price_group) { midpoint.unsubRegionBus(); midpoint.unsubRegionBus = regionBus.subscribe(midpoint.onRegionChange.bind(midpoint)); haas.services.modelDetail.getModel(model) .then(function (model) { haas.LOGGER.debug(model); midpoint.vm.selection = model; midpoint.vm.selection.loadPackages().then(function() { midpoint.vm.standardOptions = _.groupBy(model.getStandardOptions(), 'categoryUniqueName'); midpoint.render(); haas.analytics.trackProduct('category', model.category); haas.analytics.trackProduct('series', model.series); haas.analytics.trackProduct('model', model.name); haas.analytics.trackSubStep('your-machine'); }); }); haas.utils.bindDynamicLinks(); }); }, onRegionChange: function () { var self = this; haas.services.modelDetail.getModel(self.vm.selection.name) .then(function (model) { self.vm.selection = model; self.vm.standardOptions = _.groupBy(model.getStandardOptions(), 'categoryUniqueName'); self.renderModelSummary(); }); haas.LOGGER.log('rerendering configurator midpoint on region change'); }, setGoToTopPosition: function () { var offsetHeight = $('.configurator-action-bar').outerHeight(); var offset = haas.device.display.isMobile() ? 10 : 20; $('.gototop').css('bottom', offsetHeight + offset); }, renderTemplate: function (template) { if (typeof template !== TYPE_FUNCTION) { throw new Error('Cannot render template ' + template); } this.refs.$output.html(template(this.vm)); resetScroll(); }, getCardClickHandler: function (configurator) { return function selectCard () { configurator.toggleSelectedCardClass(this); configurator.handleConfigureOptionsAction(); }; }, toggleSelectedCardClass: function (cardElem) { if ($(cardElem).is('.horizontal-card')) return; var $selectedCard = this.getSelectedCard(); var $cardElem = $(cardElem); if ($selectedCard === $cardElem) return; $selectedCard.removeClass(CLASS_SELECTED); $cardElem.toggleClass(CLASS_SELECTED); var cardsAreSelected = !!this.getSelectedCard().length; if (cardsAreSelected) { this.$(SELECTOR_CONTINUE).addClass(CLASS_ACTIVE); this.$(SELECTOR_CONTINUE).prop('disabled', false); } else { this.$(SELECTOR_CONTINUE).removeClass(CLASS_ACTIVE); this.$(SELECTOR_CONTINUE).prop('disabled', true); } }, bindDynamicLinks: function () { // fix for sightly removing a tag due to template href var HREF = 'href'; var $link = this.$('.dynamic-link'); var href = this.$('.dynamic-link').data(HREF); $link.attr(HREF, href); }, renderModelSummary: function () { this.currentStep = 6; this.renderTemplate(this.templates.midpoint); this.bindModelSummaryEvents(); this.bindDynamicLinks(); // this.refs.$packageBackButton.addClass(CLASS_HIDDEN); // this.refs.$backButton.removeClass(CLASS_HIDDEN); }, showMachineOverview: function (e) { if (e && typeof e.preventDefault === 'function') { e.preventDefault(); } Modal.open(this.templates.machineOverview(this.vm)); }, bindModelSummaryEvents: function () { this.$(SELECTOR_CARD).off(EVENT_CLICK).on(EVENT_CLICK, this.getCardClickHandler(this)); this.$(SELECTOR_CONTINUE).off(EVENT_CLICK).on(EVENT_CLICK, this.handleConfigureOptionsAction.bind(this)); this.$(SELECTOR_VIEW_DETAILS).off(EVENT_CLICK).on(EVENT_CLICK, this.showMachineOverview.bind(this)); }, handleConfigureOptionsAction: function () { var $selectedCard = this.getSelectedCard(); var url = $selectedCard.data(DATA_URL); var action = $selectedCard.data(DATA_ACTION); if (url) { this.configureOptions(url); } var isValid = action || url; if (action) { if (action === 'showPackages') { this.loadOptionPackages(); } if (action === 'showOverview') { this.showMachineOverview(); } } }, configureOptions: function (url) { if (url) { window.location.href = url; } }, getSelectedCard: function () { return this.$(SELECTOR_CARD + SELECTOR_SELECTED); }, loadOptionPackages: function () { var self = this; self.unsubRegionOptionBus(); self.unsubRegionOptionBus = regionBus.subscribe(self.onRegionChangeOptionPackage.bind(self)); self.vm.loadingPackages = true; self.renderLoading(); optionPackageService.fetchOptionPackages().then(function () { self.vm.loadingPackages = false; self.vm.optionPackages = optionPackageService.getPackagesForModel(self.vm.selection.id).filter(function (pkg) { return !(pkg.industries && pkg.industries.length); }); self.vm.optionPackageChunks = _.chunk(self.vm.optionPackages, 3); self.renderOptionPackages(); }); }, onRegionChangeOptionPackage: function () { var self = this; optionPackageService.fetchOptionPackages().then(function () { self.vm.optionPackages = optionPackageService.getPackagesForModel(self.vm.selection.id).filter(function (pkg) { return !(pkg.industries && pkg.industries.length); }); self.vm.optionPackageChunks = _.chunk(self.vm.optionPackages, 3); self.renderOptionPackages(); }); haas.LOGGER.log('rerendering configurator midpoint Option Packages on region change'); }, bindOptionPackagesEvents: function () { this.$(SELECTOR_CARD).off(EVENT_CLICK).on(EVENT_CLICK, this.getCardClickHandler(this)); this.$(SELECTOR_CONTINUE).off(EVENT_CLICK).on(EVENT_CLICK, this.goToOptionPackage.bind(this)); }, goToOptionPackage: function () { var url = this.$(SELECTOR_CARD + SELECTOR_SELECTED).data(DATA_URL); if (url) { window.location.href = url; } }, renderOptionPackages: function () { this.renderTemplate(this.templates.optionPackages); this.bindOptionPackagesEvents(); // this.refs.$packageBackButton.removeClass(CLASS_HIDDEN); // this.refs.$backButton.addClass(CLASS_HIDDEN); var self = this; }, renderLoading: function () { this.refs.$output.html(haas.constants.loadingTmpl); }, render: function () { if (!this.vm.selection.name) { this.renderLoading(); } else { this.renderModelSummary(); haas.utils.scrollToTarget($('#configurator-sticky-wrapper'), 5, 1); } this.setGoToTopPosition(); } }); })(); /* global haas, $, _, priceGroupPromise */ (function () { 'use strict'; var Modal = haas.components.Modal; var INDUSTRY_DISPLAY_COUNT = 4; var DISPLAY_COUNT = 3; var DISPLAY_COUNT_MOBILE = 1; var SCROLL_COUNT = 1; var CLASS_SELECTED = 'selected'; var CLASS_ACTIVE = 'active'; var SELECTOR_FILTER = '.industry-filter'; var SELECTOR_SELECTED = '.' + CLASS_SELECTED; var SELECTOR_CARD = '.configurator-card'; var SELECTOR_CONTINUE = '.btn-continue:not(.btn-reverse)'; var SELECTOR_CAROUSEL = '.configurator-carousel'; var EVENT_CLICK = 'click'; var DATA_INDUSTRY = 'industry'; var DATA_URL = 'url'; var regionBus = haas.bus.region; haas.components.IndustryConfigurations = haas.Component.create({ vm: { loading: true, packages: [], packageChunks: [], industries: [], industryChunks: [], filters: [], selectedIndustry: null, encodeSlingSelector: haas.utils.encodeSlingSelector }, unsubRegionBus:_.noop, slickConfig: { infinite: true, slidesToShow: DISPLAY_COUNT, slidesToScroll: SCROLL_COUNT, dots: true, adaptiveHeight: true, draggable: false }, initialize: function () { var self = this; return $.when(haas.region.priceGroupPromise).then(function(price_group) { self.unsubRegionBus(); self.unsubRegionBus = regionBus.subscribe(self.onRegionChange.bind(self)); self.industryConfigPackageService = haas.services.industryConfigPackage; self.industryConfigPackageService.fetch() .then(function (industryPackages) { self.vm.loading = false; self.setPackages(industryPackages); return self.industryConfigPackageService.getIndustries(); }) .then(function (industries) { self.setIndustries(industries); self.vm.selectedIndustry = self.vm.filters[0]; self.render(); }); setTimeout(function () { if (haas.device.display.isMobile() || haas.device.display.isTablet()) { self.slickConfig.slidesToShow = DISPLAY_COUNT_MOBILE; self.slickConfig.adaptiveHeight = false; } }); window._satellite.track('baq-step'); haas.analytics.trackBAQType('Industry'); }); }, onRegionChange: function () { haas.LOGGER.log('rerender on region change!'); var self = this; haas.LOGGER.log('rerendering configurator industry on region change'); self.industryConfigPackageService = self.industryConfigPackageService || haas.services.industryConfigPackage; self.industryConfigPackageService.fetch() .then(function (industryPackages) { self.setPackages(industryPackages); return self.industryConfigPackageService.getIndustries(); }) .then(function (industries) { self.setIndustries(industries); self.vm.selectedIndustry = self.vm.filters[0]; self.render(); }); }, setIndustries: function (industries) { this.vm.industries = industries; this.vm.industryChunks = _.chunk(industries, INDUSTRY_DISPLAY_COUNT); this.vm.filters = industries; }, setPackages: function (packages) { this.vm.packages = packages; this.vm.packageChunks = _.chunk(packages, DISPLAY_COUNT); }, filterIndustries: function (industry) { var self = this; haas.services.industryConfigPackage.filterIndustryPackages([industry]) .then(function (packages) { self.setPackages(packages); self.render(); }); }, toggleSelectedCardClass: function (cardElem) { var $selectedCard = this.getSelectedCard(); var $cardElem = $(cardElem); if ($selectedCard === $cardElem) return; $selectedCard.removeClass(CLASS_SELECTED); $cardElem.toggleClass(CLASS_SELECTED); var cardsAreSelected = !!this.getSelectedCard().length; if (cardsAreSelected) { this.$(SELECTOR_CONTINUE).addClass(CLASS_ACTIVE); this.$(SELECTOR_CONTINUE).prop('disabled', false); } else { this.$(SELECTOR_CONTINUE).removeClass(CLASS_ACTIVE); this.$(SELECTOR_CONTINUE).prop('disabled', true); } }, getSelectedCard: function () { return this.$(SELECTOR_CARD + SELECTOR_SELECTED).filter(':visible'); }, getCardClickHandler: function (self) { return function selectCard () { var $this = $(this); var functionality = $this.data(DATA_URL); self.toggleSelectedCardClass(this); if (functionality) { self.vm.functionality = functionality; } }; }, selectOptions: function () { var $card = this.getSelectedCard(); var url = $card.data(DATA_URL); if(!url){ this.showValidationModal(); return; } window.location.href = url; }, showValidationModal : function(){ Modal.open(this.templates.validationModal({ })); }, setGoToTopPosition: function () { var offsetHeight = $('.configurator-action-bar').outerHeight(); var offset = haas.device.display.isMobile() ? 10 : 20; $('.gototop').css('bottom', offsetHeight + offset); }, bindEvents: function () { var self = this; this.$(SELECTOR_FILTER).off(EVENT_CLICK).on(EVENT_CLICK, function () { var $this = $(this); var industry = $this.data(DATA_INDUSTRY); if ($this.hasClass(CLASS_SELECTED)) { return; } self.vm.selectedIndustry = industry; self.filterIndustries(industry); }); this.$(SELECTOR_CARD).off(EVENT_CLICK).on(EVENT_CLICK, this.getCardClickHandler(this)); this.$(SELECTOR_CONTINUE).off(EVENT_CLICK).on(EVENT_CLICK, this.selectOptions.bind(this)); }, renderLoading: function () { this.refs.$output.html(haas.constants.loadingTmpl); }, render: function () { if (this.vm.loading) { return this.renderLoading(); } this.refs.$output.html(this.templates.industryConfigs(this.vm)); var self = this; haas.utils.nextTick(function () { self.$(SELECTOR_CAROUSEL).slick(self.slickConfig); }); this.bindEvents(); } }); })(); /* global haas, $, _, waypoints.js */ (function () { 'use strict'; haas.components.ConfiguratorHeader = haas.Component.create({ render: function () { // set up sticky header // using dom as opposed to jQuery because of race condition around $(document).ready if(document.getElementById('configurator-sticky-wrapper') !== null && document.getElementById('configurator-sticky-nav') !== null){ var wrapperID = 'configurator-sticky-wrapper'; var targetID = 'configurator-sticky-nav'; haas.utils.sticky(wrapperID, targetID); $('.page').addClass('fullscreen-config'); } else { haas.LOGGER.log('Error: sticky header could not be set up.') } } }); })(); /* global haas, $, _, priceGroupPromise */ (function () { 'use strict'; var Modal = haas.components.Modal; var SELECTOR_CARD = '.configurator-card'; var SELECTOR_EQ_HEIGHT = '.eq-height'; var router = haas.router; var regionBus = haas.bus.region; haas.components.ConfiguratorExpertModeSeries = haas.Component.create({ vm: { functionality: 'Milling', machines: [], seriesList: [] }, unsubRegionBus:_.noop, initialize: function () { var self = this; var query = router.getQuery(); this.vm.category = query.category; $.when(haas.region.priceGroupPromise).then(function(price_group) { Modal.load(); self.unsubRegionBus(); self.unsubRegionBus = regionBus.subscribe(self.onRegionChange.bind(self)); haas.services.configurator.fetchMachines().then(function (machines) { Modal.unload(); self.vm.machines = machines; self.vm.standardMachines = haas.services.configurator.standardMachines; var functionality = self.vm.functionality = haas.services.configurator.getFunctionalityForCategory(self.vm.category); var category = _.find(self.vm.machines[functionality], { id: self.vm.category }); self.vm.seriesList = _.chunk(category.series, 3); self.render(); }); }); }, onRegionChange: function () { var self = this; haas.LOGGER.log('rerendering configurator expert mode series on region change'); haas.services.configurator.fetchMachines().then(function (machines) { self.render(); }); }, bindDynamicLinks: function () { this.$('.dynamic-link').each(function () { var $this = $(this); var href = $this.data('href'); if (!$this.data('series-id') && $this.data('product-id')) $this.attr('href', $this.data('bnp-href')); else $this.attr('href', href); }); }, render: function () { if (!this.vm.seriesList.length) { return; } this.refs.$output.html(this.templates.series(this.vm)); this.bindDynamicLinks(); } }); })(); /* global haas, $, _ */ (function () { 'use strict'; var Modal = haas.components.Modal; var SELECTOR_CARD = '.configurator-card'; var SELECTOR_EQ_HEIGHT = '.eq-height'; var router = haas.router; var regionBus = haas.bus.region; haas.components.ConfiguratorExpertModeModel = haas.Component.create({ vm: { functionality: 'Milling', standardMachines: [], encodeSlingSelector: haas.utils.encodeSlingSelector }, unsubRegionBus:_.noop, initialize: function () { var self = this; var query = router.getQuery(); this.vm.category = query.category; this.vm.seriesId = query.series; Modal.load(); $.when(haas.region.priceGroupPromise).then(function(price_group) { haas.services.configurator.fetchMachines().then(function (machines) { Modal.unload(); self.vm.standardMachines = haas.services.configurator.standardMachines; self.unsubRegionBus(); self.unsubRegionBus = regionBus.subscribe(self.onRegionChange.bind(self)); var filteredModels = self.vm.filteredModels = self.vm.standardMachines.filter(function (machine) { return machine.series.id === self.vm.seriesId; }); self.vm.groups = _.groupBy(filteredModels, 'group'); self.vm.getClassificationGroups = function (machines) { return haas.services.configurator.getClassificationGroups(machines); }; self.vm.getMinPriceMachine = function (machines) { var availableMachines = _.filter(machines, function (m) { return m.isAvailable(); }); return _.minBy(availableMachines, function (m) { return m.getPrice(); }); }; self.render(); }); }); }, onRegionChange: function () { var self = this; haas.LOGGER.log('rerendering configurator expert mode model on region change'); haas.services.configurator.fetchMachines().then(function (machines) { self.render(); }); }, bindDynamicLinks: function () { this.$('.dynamic-link').each(function () { var $this = $(this); var href = $this.data('href'); $this.attr('href', href); }); }, render: function () { if (!this.vm.standardMachines.length) { return; } this.refs.$output.html(this.templates.model(this.vm)); this.bindDynamicLinks(); } }); })(); // /* global haas, $, _ */ // (function () { // 'use strict'; // var Modal = haas.components.Modal; // // var EVENT_CLICK = 'click'; // // var CLASS_SELECTED = 'selected'; // var CLASS_HIDDEN = 'hidden'; // var CLASS_ACTIVE = 'active'; // // var SELECTOR_CARD = '.configurator-card'; // var SELECTOR_SELECTED = '.' + CLASS_SELECTED; // var SELECTOR_CONTINUE = '.btn-continue:not(.btn-reverse)'; // var SELECTOR_CATEGORY_CARD = '.category-card'; // var SELECTOR_EQ_HEIGHT = '.eq-height'; // // var DATA_CATEGORY = 'category'; // var DATA_SERIES = 'series'; // var DATA_MODEL = 'model'; // var DATA_URL = 'url'; // // var eqHeight = haas.utils.eqHeight; // var getSlingSelectors = haas.utils.getSlingSelectors; // // var CATEGORY_VM_IMG = '/etc/clientlibs/haascnc/images/configurator/CARD_VM_ICO.png'; // var CATEGORY_HM_IMG = '/etc/clientlibs/haascnc/images/configurator/CARD_HM_ICO.png'; // var CATEGORY_LATHES_IMG = '/etc/clientlibs/haascnc/images/configurator/CARD_LATHE_ICO.png'; // // var progressBus = haas.bus.configuratorProgress; // // var stepName = "category"; // // haas.components.ConfiguratorExpertModeCategory = haas.Component.create({ // vm: { // category: null, // series: null, // seriesList: [], // machines: null, // standardMachines: [], // // // view helper functions // inchesToMM: haas.utils.inchesToMM // }, // // currentStep: 0, // // stepHistory: [0], // // isPreconfigured: false, // // initialize: function () { // var configurator = this; // haas.bus.machines.subscribe(function (nextState) { // if (nextState.machines && !_.isEmpty(nextState.machines)) { // configurator.vm.machines = nextState.machines; // configurator.vm.standardMachines = nextState.standardMachines; // configurator.render(); // } // }); // }, // // renderPreviousStep: function () { // var lastStepIndex = this.stepHistory.length - 2; // var lastStep = this.stepHistory[lastStepIndex]; // // this.stepHistory = this.stepHistory.slice(0, lastStepIndex); // // switch (lastStep) { // default: // case 0: // progressBus.goBack(); // this.returnToBaseConfigurator(); // this.renderChooseCategory(); // break; // // case 1: // progressBus.goBack(); // this.renderChooseCategory(); // break; // // case 2: // progressBus.goBack(); // this.renderChooseSeries(); // break; // // case 3: // progressBus.goBack(); // this.renderChooseModel(); // break; // } // }, // // returnToBaseConfigurator: function () { // haas.events.configurator.emit('hideExpertMode'); // }, // // getCardClickHandler: function (configurator) { // return function selectCard() { // var $this = $(this); // var category = $this.data(DATA_CATEGORY); // var series = $this.data(DATA_SERIES); // var model = $this.data(DATA_MODEL); // // configurator.toggleSelectedCardClass(this); // // configurator.vm.categoryImagePath = $this.data('img') || ''; // // console.log('click', $this.data(), stepName); // // if (category) { // configurator.vm.category = category; // } // // if (series) { // configurator.vm.series = series; // } // // if (model) { // configurator.vm.model = model; // } // // switch (stepName) { // case "category": // configurator.renderChooseSeries(); // break; // case "series": // configurator.renderChooseModel(); // break; // case "model": // configurator.goToMidpoint(); // break; // } // // }; // }, // // toggleSelectedCardClass: function (cardElem) { // var $selectedCard = this.getSelectedCard(); // var $cardElem = $(cardElem); // // if ($selectedCard === $cardElem) return; // // $selectedCard.removeClass(CLASS_SELECTED); // $cardElem.toggleClass(CLASS_SELECTED); // // var cardsAreSelected = !!this.getSelectedCard().length; // // if (cardsAreSelected) { // this.$(SELECTOR_CONTINUE).addClass(CLASS_ACTIVE); // this.$(SELECTOR_CONTINUE).prop('disabled', false); // } else { // this.$(SELECTOR_CONTINUE).removeClass(CLASS_ACTIVE); // this.$(SELECTOR_CONTINUE).prop('disabled', true); // } // }, // // showValidationModal: function () { // if (this.isPreconfigured) return; // Modal.open(this.templates.validationModal({})); // }, // // getSelectedCard: function () { // return this.$(SELECTOR_CARD + SELECTOR_SELECTED); // }, // // renderTemplate: function (template) { // this.refs.$output.html(template(this.vm)); // // haas.utils.resetScroll(); // }, // // renderChooseCategory: function () { // this.currentStep = 1; // this.stepHistory.push(this.currentStep); // // stepName = "category"; // // progressBus.advance(); // this.renderTemplate(this.templates.category); // this.bindChooseCategoryEvents(); // }, // // bindChooseCategoryEvents: function () { // this.$(SELECTOR_CONTINUE).off(EVENT_CLICK).on(EVENT_CLICK, this.renderChooseSeries.bind(this)); // this.$(SELECTOR_CARD).off(EVENT_CLICK).on(EVENT_CLICK, this.getCardClickHandler(this)); // }, // // setCategoryImagePath: function () { // if (!this.vm.categoryImagePath) { // if (this.vm.category === 'Vertical Mills') { // this.vm.categoryImagePath = CATEGORY_VM_IMG; // } else if (this.vm.category === 'Horizontal Mills') { // this.vm.categoryImagePath = CATEGORY_HM_IMG; // } else if (this.vm.category === 'Lathes') { // this.vm.categoryImagePath = CATEGORY_LATHES_IMG; // } else { // this.vm.categoryImagePath = CATEGORY_VM_IMG; // } // } // }, // // setGoToTopPosition: function () { // var offsetHeight = $('.configurator-action-bar').outerHeight(); // var offset = haas.device.display.isMobile() ? 10 : 20; // $('.gototop').css('bottom', offsetHeight + offset); // }, // // renderChooseSeries: function () { // stepName = "series"; // this.currentStep = 2; // this.stepHistory.push(this.currentStep); // progressBus.advance(); // // this.setCategoryImagePath(); // // var functionality = haas.services.configurator.getFunctionalityForCategory(this.vm.category); // // if (!functionality) { // functionality = 'Milling'; // } // // this.vm.functionality = functionality; // // var category = _.find(this.vm.machines[functionality], { name: this.vm.category }); // this.vm.seriesList = _.chunk(category.series, 3); // // this.renderTemplate(this.templates.series); // this.bindChooseSeriesEvents(); // this.setEQHeights(); // }, // // bindChooseSeriesEvents: function () { // this.$(SELECTOR_CONTINUE).off(EVENT_CLICK).on(EVENT_CLICK, this.renderChooseModel.bind(this)); // this.$(SELECTOR_CARD).not(SELECTOR_CATEGORY_CARD).off(EVENT_CLICK).on(EVENT_CLICK, this.getCardClickHandler(this)); // }, // // setEQHeights: function () { // this.$(SELECTOR_EQ_HEIGHT).each(function () { // eqHeight($(this).find(SELECTOR_CARD)); // }); // }, // // renderChooseModel: function () { // this.currentStep = 3; // this.stepHistory.push(this.currentStep); // stepName = "model"; // // progressBus.advance(); // // this.setCategoryImagePath(); // // var functionality = this.vm.functionality; // if (!functionality) { // functionality = this.vm.functionality = haas.services.configurator.getFunctionalityForSeries(this.vm.series); // } // // var category = _.find(this.vm.machines[functionality], { name: this.vm.category }); // var series = _.find(category.series, { name: this.vm.series }); // // var filteredModels = this.vm.filteredModels = this.vm.standardMachines.filter(function (machine) { // return !!_.find(series.details, { id: machine.id }); // }); // // this.vm.groups = _.groupBy(filteredModels, 'group'); // this.vm.getClassificationGroups = function (machines) { // return haas.services.configurator.getClassificationGroups(machines); // }; // // this.vm.getMinPriceMachine = function (machines) { // return _.minBy(machines, function (m) { return m.getPrice(); }); // }; // // this.renderTemplate(this.templates.model); // this.bindChooseModelEvents(); // this.setEQHeights(); // // // this.$('.collapse-section').slideUp(); // }, // // bindChooseModelEvents: function () { // this.$(SELECTOR_CONTINUE).off(EVENT_CLICK).on(EVENT_CLICK, this.goToMidpoint.bind(this)); // this.$(SELECTOR_CARD).not(SELECTOR_CATEGORY_CARD).off(EVENT_CLICK).on(EVENT_CLICK, this.getCardClickHandler(this)); // // this.$('.expert-mode-group-name').off(EVENT_CLICK).on(EVENT_CLICK, function () { // // $(this).next('.collapse-section').slideToggle(); // // }); // }, // // goToMidpoint: function () { // var url = $(SELECTOR_CARD + SELECTOR_SELECTED).filter(':visible').data(DATA_URL); // // if (!url) { // this.showValidationModal(); // return; // } // // window.location.href = url; // }, // // renderLoading: function () { // this.refs.$output.html(haas.constants.loadingTmpl); // }, // // determinePreconfiguredState: function () { // var service = haas.services.configurator; // var selectors = getSlingSelectors(); // // if (service.loading) { // service.promise // .then(doDeterminPreconfiguredState.bind(this), function (err) { // Modal.open(_.template('

    There was an error loading our machines.

    Start Over')({ err: err })); // }); // } else { // doDeterminPreconfiguredState.call(this); // } // // function doDeterminPreconfiguredState() { // if (!selectors.length) { // return this.renderChooseCategory(); // } // // this.isPreconfigured = true; // $('.expert-mode-back-btn').addClass(CLASS_HIDDEN); // // var category = selectors[0]; // var series = selectors[1]; // // this.vm.category = category; // // if (!series) { // progressBus.advance(); // haas.LOGGER.debug('Got preconfigured category', category + '.', 'Advancing to choose series.'); // return this.renderChooseSeries(); // } // // progressBus.advance(); // progressBus.advance(); // haas.LOGGER.debug('Got preconfigured category', category, 'and series', series + '.', 'Advancing to choose model.'); // // this.vm.series = series; // this.renderChooseModel(); // } // }, // // bindGlobalEvents: function () { // $('.expert-mode-back-btn').off(EVENT_CLICK).on(EVENT_CLICK, this.renderPreviousStep.bind(this)); // }, // // render: function () { // if (!this.vm.machines) return this.renderLoading(); // this.determinePreconfiguredState(); // this.setGoToTopPosition(); // this.bindGlobalEvents(); // } // }); // })(); /* global haas, $, _, THREE */ (function () { 'use strict'; var MAX_SIZE = 150; var TRANSFORM = 'transform'; var WIDTH = 'width'; var HEIGHT = 'height'; var PX = 'px'; var ROTATE_FRONT = 'rotateY(0deg)'; var ROTATE_BACK = 'rotateX(90deg)'; var ROTATE_RIGHT = 'rotateY(90deg)'; var ROTATE_LEFT = 'rotateY(-90deg)'; var bus = haas.bus.shape3d = haas.utils.Channel.create({ width: 10, depth: 10, height: 10 }); haas.components.Box3d = haas.Component.create({ dimensions: { width: bus.state.width, depth: bus.state.depth, height: bus.state.height }, renderedDimensions: { width: MAX_SIZE, depth: MAX_SIZE, height: MAX_SIZE }, maxSize: MAX_SIZE, unsubscribeBus: function nooop () {}, initialize: function () { this.unsubscribeBus(); this.unsubscribeBus = bus.subscribe(this.onDimensionsChange.bind(this)); }, onDimensionsChange: function (nextDims) { this.renderedDimensions = this.calculateDimensions(nextDims); Object.assign(this.dimensions, nextDims); this.renderCube(); }, renderCube: function () { var width = this.renderedDimensions.width; var depth = this.renderedDimensions.depth; var height = this.renderedDimensions.height; this.refs.$front .css(TRANSFORM, ROTATE_FRONT + this.getTranslation(depth / 2)) .css(WIDTH, width + PX) .css(HEIGHT, height + PX); this.refs.$back .css(TRANSFORM, ROTATE_BACK + this.getTranslation(depth / 2)) .css(WIDTH, width + PX) .css(HEIGHT, depth + PX); this.refs.$right .css(TRANSFORM, ROTATE_RIGHT + this.getTranslation(width - (depth / 2))) .css(WIDTH, depth + PX) .css(HEIGHT, height + PX); this.refs.$left .css(TRANSFORM, ROTATE_LEFT + this.getTranslation(depth / 2)) .css(WIDTH, depth + PX) .css(HEIGHT, height + PX); this.refs.$box .css(WIDTH, width + PX) .css(HEIGHT, height + PX) .css('margin-top', (this.maxSize / 2) - (height / 2) + 50 + PX); }, getTranslation: function (px) { return ' translateZ(' + px + 'px)'; }, calculateDimensions: function (dims) { var box = this; var newDims = {}; var maxValue = Math.max(dims.width, dims.depth, dims.height); var delta = this.maxSize / maxValue; _.forEach(dims, function (value, key) { if (value === maxValue) { newDims[key] = box.maxSize; } else { newDims[key] = value * delta; } }); return newDims; } }); })(); /* global haas, $, _ */ (function () { 'use strict'; var MAX_SIZE = 150; var SELECTOR_SLICE = '.cylinder-slice'; var bus = haas.bus.shape3d; haas.components.Cylinder3d = haas.Component.create({ maxSize: MAX_SIZE, dimensions: { len: bus.state.width, diameter: bus.state.depth }, slices: [], initialize: function () { bus.subscribe(this.onBusUpdate.bind(this)); }, onBusUpdate: function (nextState) { if (nextState.width !== this.dimensions.len) { this.dimensions.len = nextState.width; } if (nextState.depth !== this.dimensions.diameter) { this.dimensions.diameter = nextState.depth; } this.render(); }, sliceTmpl: '
    ', buildSlices: function () { var dims = this.calculateDimensions(this.dimensions); var numSlices = dims.len; var slicesHtmlList = []; var template = _.template(this.sliceTmpl); for (var i = 0; i <= Math.floor(numSlices); i++) { slicesHtmlList.push(template({translatePx: i, diameter: dims.diameter})); } return slicesHtmlList; }, _animateSlices: function () { var component = this; var slicesHtmlList = this.buildSlices(); var newLen = slicesHtmlList.length; var prevLen = this.$(SELECTOR_SLICE).length; var maxTickRate = 1000 / 30; var frame, interval; if (prevLen === newLen) { return; } if (prevLen < newLen) { frame = prevLen; interval = setInterval(function () { if (frame < newLen) { component.refs.$slices.append(slicesHtmlList[frame]); frame++; } else { clearInterval(interval); } }, maxTickRate); return; } if (prevLen > newLen) { frame = 0; interval = setInterval(function () { if (frame < (prevLen - newLen)) { component.$(SELECTOR_SLICE).last().remove(); frame++; } else { clearInterval(interval); } }, maxTickRate); } }, calculateDimensions: function (dims) { var box = this; var newDims = {}; var maxValue = Math.max(dims.len, dims.diameter); var delta = this.maxSize / maxValue; _.forEach(dims, function (value, key) { if (value === maxValue) { newDims[key] = box.maxSize; } else { newDims[key] = value * delta; } }); return newDims; }, render: function () { this.refs.$slices.html(this.buildSlices().join('')); } }); })(); /* global haas, $, _, priceGroupPromise */ (function () { 'use strict'; var EVENT_KEYUP = 'keyup input'; var EVENT_CHANGE = 'change'; var EVENT_CLICK = 'click'; var CLASS_ACTIVE = 'active'; var SELECTOR_CONTINUE = '.btn-continue:not(.btn-reverse):visible'; var SELECTOR_ERRORS = '.errors.error-output'; var ATTR_DISABLED = 'disabled'; var MILLING = 'milling'; var TURNING = 'turning'; var METRIC = 'metric'; var INCHES = 'inches'; var registerComponent = haas.components.registerTransientComponentElement; var configuratorStore = haas.data.configuratorStore; var configuratorService = haas.services.configurator; var shape3dBus = haas.bus.shape3d; var validateInput = haas.utils.validateInput; var isTruthy = haas.utils.isTruthy; var zerosPresent = false; var Modal = haas.components.Modal; function applyMultiplePieceModifier(dims) { dims.width = dims.width * 2; return dims; } haas.components.ConfiguratorDimensionsForm = haas.Component.create({ state: {}, initialize: function () { this.state = configuratorStore.hydrate().getState(); configuratorService = haas.services.configurator; haas.tmp.unitsContext = INCHES; $.when(haas.region.priceGroupPromise).then(function(price_group) { configuratorService.fetchMachines().then(function () { Modal.unload(); }); }); }, enableContinue: function ($btn) { $btn.addClass(CLASS_ACTIVE); $btn.attr(ATTR_DISABLED, false); }, disableContinue: function ($btn) { $btn.removeClass(CLASS_ACTIVE); $btn.attr(ATTR_DISABLED, true); }, validateStepForm: function($formElem){ var self = this; var $formInputs = $formElem.find('input[type=text]').filter(':visible'); self.zerosPresent = false; return _.every($formInputs, function(item) { var $item = $(item); if ($item.val() === "0") { self.zerosPresent = true; } return self.validateInput($item); }); }, validateInput: function ($input) { var validation = validateInput($input); this.showValidationState(validation); return validation.isValid; }, showValidationState: function (validation) { if (validation.isValid && !this.zerosPresent) { this.$(SELECTOR_ERRORS).html(''); } else if(this.zerosPresent){ this.$(SELECTOR_ERRORS).html(haas.utils.validatorMessages.numberNoZero()); }else { this.$(SELECTOR_ERRORS).html(_.find(validation.messages, isTruthy)); } }, getInputChangeHandler: function (self) { return function () { var $this = $(this); var value = Number($this.val()); var valid = self.validateInput($this); var $currentContinueBtn = self.$(SELECTOR_CONTINUE + ':visible'); if (!valid) { self.disableContinue($currentContinueBtn); return; } var dim = $this.attr('name'); var update = {}; update[dim] = value; var isFormComplete = self.validateStepForm($('.configurator-step-2-form')); shape3dBus.publish(update); if (!isFormComplete) { self.disableContinue($currentContinueBtn); return; } var hasMatchingMachines = self.validateMatchingMachines(); if (!hasMatchingMachines) { self.disableContinue($currentContinueBtn); self.$(SELECTOR_ERRORS).text(self.data.errorcopy); return; } self.enableContinue($currentContinueBtn); }; }, getInputs: function () { var units = this.$('.radio-btn:checked').val(); var values = { functionality: this.state.functionality, x: Number(this.$('.input-width').val()), z: Number(this.$('.input-height').val()), y: 0 }; if (this.state.functionality === MILLING) { values.y = Number(this.$('.input-depth').val()); } if (units === METRIC) { values.x = configuratorService.convertMMToInches(values.x); values.z = configuratorService.convertMMToInches(values.z); values.y = configuratorService.convertMMToInches(values.y); } return values; }, validateMatchingMachines: function () { var dims = this.dimensions = this.getInputs(); if (this.state.functionality === TURNING) { var turningMachinesWithY = configuratorService.getRecommendedTurningMachinesForDims({ x: dims.x, z: dims.z, yAxis: true }); var turningMachinesWithoutY = configuratorService.getRecommendedTurningMachinesForDims({ x: dims.x, z: dims.z, yAxis: false }); configuratorStore.transition(function (next) { next.showProvideAdditionalDimensions = !!turningMachinesWithY; }); return !!turningMachinesWithoutY; } else if (this.state.functionality === MILLING) { var millingMachines = configuratorService.getRecommendedMillingMachinesForDims({ x: dims.x, y: dims.y, z: dims.z }); var dims2x = applyMultiplePieceModifier(Object.assign({}, dims)); var machines2x = configuratorService.getRecommendedMillingMachinesForDims({ x: dims2x.x, y: dims2x.y, z: dims2x.z }); configuratorStore.transition(function (next) { next.showMultiplePieceSelector = !!machines2x.primary; }); return !!millingMachines.primary; } }, onStep2ContinueClick: function (e) { var dims = this.dimensions = this.dimensions || this.getInputs(); if (e && e.preventDefault) e.preventDefault(); var query = this.state.functionality === MILLING ? { x: dims.x, y: dims.y, z: dims.z } : { x: dims.x, z: dims.z }; var nextState = configuratorStore.getState(); var nextPath = ( nextState.showProvideAdditionalDimensions || nextState.showMultiplePieceSelector) ? this.state.additionalDimensionsPath : this.state.selectSeriesPath; window.location = haas.utils.formatURI({ path: nextPath, selectors: [this.state.functionality], hash: '/', hashQuery: query }); }, bindEvents: function () { var $inputFields = $('.configurator-input input'); $inputFields.off(EVENT_KEYUP).on(EVENT_KEYUP, this.getInputChangeHandler(this)); this.$(SELECTOR_CONTINUE).off(EVENT_CLICK).on(EVENT_CLICK, this.onStep2ContinueClick.bind(this)); this.$('.radio-btn').off(EVENT_CHANGE).on(EVENT_CHANGE, function (e) { haas.tmp.unitsContext = $(e.target).val(); }); }, render: function () { Modal.load(); if (this.state.functionality === "turning") { registerComponent(this.$('.cylinder-3d')); } else { registerComponent(this.$('.box-3d')); } this.bindEvents(); } }); })(); /* global haas, $, _, priceGroupPromise */ (function () { 'use strict'; var EVENT_CLICK = 'click'; var EVENT_RESIZE = 'resize'; var SELECTOR_CARD = '.configurator-card'; var SELECTOR_SECONDARY_CARD = '.configurator-card:not(.horizontal-card)'; var store = haas.data.configuratorStore; var getSlingSelectors = haas.utils.getSlingSelectors; var encodeSlingSelector = haas.utils.encodeSlingSelector; var decodeSlingSelector = haas.utils.decodeSlingSelector; var Modal = haas.components.Modal; var regionBus = haas.bus.region; haas.components.ConfiguratorCompareModels = haas.Component.create({ state: { recommended: { primary: {}, alt: [] } }, unsubRegionBus:_.noop, machines: [], dims: {}, initialize: function () { var self = this; Object.assign(this.state, store.hydrate().getState()); $.when(haas.region.priceGroupPromise).then(function(price_group) { self.unsubRegionBus(); self.unsubRegionBus = regionBus.subscribe(self.onRegionChange.bind(self)); Modal.load(); haas.services.configurator.fetchMachines().then(function (machines) { self.machines = machines; Modal.unload(); self.renderModels(); }); }); }, onRegionChange: function () { var self = this; haas.LOGGER.log('rerendering configurator compare models on region change'); haas.services.configurator.fetchMachines().then(function (machines) { self.machines = machines; self.renderModels(); }); }, bindEvents: function () { var self = this; this.$(SELECTOR_CARD).filter(':visible').off(EVENT_CLICK).on(EVENT_CLICK, function (e) { e.preventDefault(); var data = $(this).data(); self.state.selection = _.find(haas.services.configurator.standardMachines, {name: data.name}); self.navigateToMachine(); }); this.$('.primary-details').off(EVENT_CLICK).on(EVENT_CLICK, this.showModelDetails.bind(this)); }, navigateToMachine: function () { window.location = haas.utils.formatURI({ path: this.state.midpointPath, selectors: [encodeSlingSelector(this.state.selection.id)] }); }, showModelDetails: function (e) { e.preventDefault(); e.stopPropagation(); var self = this; Modal.load(); haas.services.modelDetail.getModel(this.state.recommended.primary.name) .then(function (model) { Modal.unload(); Modal.open(self.templates.machineOverview({ standardOptions: _.groupBy(model.getStandardOptions(), 'categoryUniqueName'), selection: model })); }); }, renderModels: function () { var modelIds = getSlingSelectors(0).split(',').map(function (id) { return decodeSlingSelector(id); }); var models = modelIds.map(function (id) { return haas.services.configurator.getModelById(id); }); this.state.recommended.primary = models[0]; this.state.recommended.alt = models.slice(1); this.refs.$output.html(this.templates.compareModels(this.state)); this.bindEvents(); } }); })(); /* global haas, _, $ */ (function () { 'use strict'; var SELECTOR_CARD = '.configurator-card'; var EVENT_CLICK = 'click'; var KEY_VAL_SEPARATOR = ':'; var KEY_VAL_DELIMETER = ','; var nextTick = haas.utils.nextTick; var store = haas.data.configuratorStore; haas.components.ConfiguratorCardGroup = haas.Component.create({ initialize: function () { console.log('configurator card', this); }, bindEvents: function () { this.$(SELECTOR_CARD).off(EVENT_CLICK).on(EVENT_CLICK, this.getCardClickHandler(this)); }, getCardClickHandler: function (self) { return function () { var $this = $(this); var event = $this.data('event'); var payload = $this.data('payload'); var nextStepPath = $this.data('nextpath'); var eventHandler = self.getEventHandler(event); if (typeof eventHandler === 'function') { eventHandler.call(self, self.parsePayload(payload)); } self.handleNextStep(nextStepPath); }; }, getEventHandler: function (event) { var eventHandlerMap = { trackFunctionality: this.trackFunctionality.bind(this) }; return eventHandlerMap[event]; }, trackFunctionality: function (payload) { store.transition(function (nextState) { nextState.functionality = payload.functionality; return nextState; }); }, handleNextStep: function (path) { if (!path) return; var functionality = store.getState().functionality; window.location = path + '.' + functionality + '.html'; }, parsePayload: function (payload) { var payloadObj = {}; payload.split(KEY_VAL_DELIMETER).map(function (keyVal) { keyVal = keyVal.trim(); var keyValArr = keyVal.split(KEY_VAL_SEPARATOR); payloadObj[keyValArr[0]] = keyValArr[1]; }); return payloadObj; }, render: function () { this.bindEvents(); } }); })(); /* global haas */ (function () { "use strict"; haas.data.machineRecommendations = { milling: [ { "x": 16, "xMax": 14.4, "y": 12, "yMax": 10.8, "z": 10, "zMax": 5, "primary": "sminimill", "considerations": [ "VF-2", "TM-1", "VF-2SS" ] }, { "x": 20, "xMax": 18, "y": 16, "yMax": 14.4, "z": 14, "zMax": 7, "primary": "sminimill2", "considerations": [ "UMC-750", "minimill2", "VF-2" ] }, { "x": 30, "xMax": 27, "y": 20, "yMax": 18, "z": 16, "zMax": 8, "primary": "TM-1P", "considerations": [ "TM-2", "VF-2", "UMC-750" ] }, { "x": 40, "xMax": 36, "y": 16, "yMax": 14.4, "z": 16, "zMax": 8, "primary": "TM-2P", "considerations": [ "TM-3", "VF-4", "UMC-750" ] }, { "x": 30, "xMax": 27, "y": 16, "yMax": 14.4, "z": 20, "zMax": 10, "primary": "VF-2SS", "considerations": [ "VF-2", "UMC-750", "VF-4" ] }, { "x": 50, "xMax": 45, "y": 20, "yMax": 18, "z": 25, "zMax": 12.5, "primary": "VF-4SS", "considerations": [ "VF-4", "UMC-750", "VF-6/40" ] }, { "x": 64, "xMax": 57.6, "y": 32, "yMax": 28.8, "z": 30, "zMax": 15, "primary": "VF-6SS", "considerations": [ "VF-6/40", "VF-7/40", "VF-8/40" ] }, { "x": 84, "xMax": 75.6, "y": 32, "yMax": 28.8, "z": 30, "zMax": 15, "primary": "VF-7/40", "considerations": [ "VF-8/40", "VF-9/40", "VF-10/40" ] }, { "x": 64, "xMax": 57.6, "y": 40, "yMax": 36, "z": 30, "zMax": 15, "primary": "VF-8/40", "considerations": [ "VF-9/40", "VF-10/40", "VF-11/40" ] }, { "x": 84, "xMax": 75.6, "y": 40, "yMax": 36, "z": 30, "zMax": 15, "primary": "VF-9/40", "considerations": [ "VF-10/40", "VF-11/40", "VF-12/40" ] }, { "x": 120, "xMax": 108, "y": 32, "yMax": 28.8, "z": 30, "zMax": 15, "primary": "VF-10/40", "considerations": [ "VF-11/40", "VF-12/40", "GR-510" ] }, { "x": 120, "xMax": 108, "y": 40, "yMax": 36, "z": 30, "zMax": 15, "primary": "VF-11/40", "considerations": [ "VF-12/40", "GR-510", "GR-712" ] }, { "x": 150, "xMax": 135, "y": 32, "yMax": 28.8, "z": 30, "zMax": 15, "primary": "VF-12/40", "considerations": [] } ], turning: [ { "x": 8, "z": 30, "yAxis": false, "primary": "TL-1", "considerations": [ "TL-2", "ST-10", "ST-15" ] }, { "x": 10, "z": 48, "yAxis": false, "primary": "TL-2", "considerations": [ "ST-20", "ST-30", "ST-35" ] }, { "x": 6, "z": 16, "yAxis": false, "primary": "ST-10", "considerations": [ "ST-15", "ST-20", "CL-1" ] }, { "x": 8, "z": 16, "yAxis": false, "primary": "ST-15", "considerations": [ "ST-10", "ST-20", "ST-25" ] }, { "x": 10, "z": 21, "yAxis": false, "primary": "ST-25", "considerations": [ "ST-30", "ST-35", "DS-30Y" ] }, { "x": 12, "z": 26, "yAxis": false, "primary": "ST-35", "considerations": [ "ST-30", "ST-40", "ST-45" ] }, { "x": 15, "z": 44, "yAxis": false, "primary": "ST-45", "considerations": [ "ST-40", "ST-45L", "ST-50" ] }, { "x": 15, "z": 80, "yAxis": false, "primary": "ST-45L", "considerations": [ "ST-45", "ST-50", "ST-55" ] }, { "x": 24, "z": 80, "yAxis": false, "primary": "ST-55", "considerations": [ "ST-50", "ST-45L", "ST-45" ] }, { "x": 6, "z": 16, "yAxis": true, "primary": "ST-10Y", "considerations": [ "ST-15Y", "ST-20Y", "CL-1" ] }, { "x": 8, "z": 16, "yAxis": true, "primary": "ST-15Y", "considerations": [ "ST-10Y", "ST-20Y", "ST-25Y" ] }, { "x": 10, "z": 21, "yAxis": true, "primary": "ST-25Y", "considerations": [ "ST-20Y", "DS-30Y" ] }, { "x": 12, "z": 23, "yAxis": true, "primary": "ST-35Y", "considerations": [ "ST-30Y", "DS-30Y" ] } ], headToHeadText: { MM_VF: { MM: [ '

    Best combination of value and performance in the industry.

    ', '
      ', '
    • Compact footprint and work envelope
    • ', '
    • Industry-standard 40-taper spindle
    • ', '
    • Great for 1-off and prototype work
    • ', '
    ' ].join(''), VF: [ '

    Full-featured CNC with many options to choose from.

    ', '
      ', '
    • Most popular vertical mill in the world
    • ', '
    • Ideal for multiple setup or multiple part runs
    • ', '
    • High performance features and options
    • ', '
    ' ].join('') }, TM_VF: { TM: [ '

    Affordable, easy to use mill with size flexibility.

    ', '
      ', '
    • Easy to learn interface
    • ', '
    • Affordable yet capable
    • ', '
    • No G-Code knowledge required
    • ', '
    ' ].join(''), VF: [ '

    Full-featured CNC with many options to choose from.

    ', '
      ', '
    • Most popular vertical mill in the world
    • ', '
    • Ideal for multiple setup or multiple part runs
    • ', '
    • High performance features and options
    • ', '
    ' ].join('') }, TL_ST: { TL: [ '

    Affordable, easy to use lathe with size flexibility.

    ', '
      ', '
    • Easy to learn interface
    • ', '
    • Affordable yet capable
    • ', '
    • No G-Code knowledge required
    • ', '
    ' ].join(''), ST: [ '

    Full-featured CNC with many options to choose from.

    ', '
      ', '
    • Best value turning center in the industry
    • ', '
    • Standard automatic tool changer
    • ', '
    • High performance CNC lathe
    • ', '
    ' ].join('') } } }; })(); /* global haas, $, _ */ (function () { 'use strict'; var PersistedCache = haas.utils.PersistedCache; var discountTypes = haas.constants.promotions.discounts.type; haas.models.Promotion = Promotion; haas.services.promotion = { cache: new PersistedCache('promotions'), promotions: null, rawPromotions: null, fetchPromotions: function () { var promotions = this.rawPromotions || this.cache.get(); if (promotions) { this.promotions = promotions.map(function (promotion) { return new Promotion(promotion); }); this.promise = Promise.resolve(this.promotions); return this.promise; } this.promise = this._fetch(); return this.promise; }, _fetch: function () { var self = this; return $.getJSON(haas.constants.api.promotions) .then(function (promotions) { this.promotions = promotions.map(function (promotion) { return new Promotion(promotion); }); this.rawPromotions = promotions; self.cache.set(promotions); return this.promotions; }); } }; /** * If it is a flat discount, then return 'SALE'. * Otherwise, if it is a percent discount, then return the percentage followed by '% OFF' * @param {String} discountType * @param {Number} discountValue * @returns {String} */ Promotion.GetSaleTagText = function(discountType, discountValue) { if (discountType === discountTypes.PERCENT) { return discountValue + '% OFF'; } else { return 'SALE'; } }; function Promotion (props) { var self = this; this.type = props.type_string; this.discounts = props.discounts; this.maxValue = props.max_value; this.startDate = _parseDateTime(props.start_date); this.endDate = _parseDateTime(props.end_date); this.models = props.models; this.options = props.options; // List of option IDs this.excludedOptions = props.excluded_options || []; // List of option IDs excluded by promotion this.associations = props.associations || []; // List of required associate machines for the promotion to be applied this.requireAllAssociations = props.require_all_associations || false; // If true, then all of the above required associate machines must be selected for the promotion to be applied this.parents = props.parents || []; // List of required parent machines (main machine in configuration, i.e., not associate machines) for the promotion to be applied this.regions = props.regions; this.hfoIds = props.hfo_ids || []; // HFO IDs /** @type {string} */ this.currency = props.currency || null; this.message = props.message; // English message this.localizedMessages = props.localizedMessages; this.localizedPdpMessages = props.localizedPdpMessages; this.localizedPromoNotes = props.localizedPromoNotes; this.promoNote = props.promoNote; this.pcCode = props.pc_code; this.excludedToolingParts = props.excluded_tooling_parts || []; this.toolingParts = props.tooling_parts || []; this.toolingPackageName = props.tooling_package_name || ''; this.getDiscountedPriceForModel = function (modelId, modelPrice) { if (this.models.indexOf(modelId) === -1) return; return haas.utils.applyPromotionalDiscount(this, modelPrice); }; this.getSaleTagText = function () { var firstDiscount = this.discounts[0]; return Promotion.GetSaleTagText(firstDiscount.type, firstDiscount.value); }; this.getDiscount = function () { return this.discounts[0]; }; this.isCurrencySpecific = function() { return this.currency != null && this.currency.length > 0; }; /** * Use for China (CN) region only. * Check if the promotion is applicable for the currency, if: * 1) the promotion is not currency-specific AND the [first] discount is a percent discount * (since we cannot apply a flat discount without knowing if the currency is USD or CNY), * OR * 2) the promotion is specific to the price's currency. * Otherwise, the promotion is not applicable * @param currency {string} * @return {boolean} */ this.isApplicableForCurrency = function(currency) { // TODO: which discount: best or first? var discount = this.discounts.length > 0 ? this.discounts[0] : null; if (!this.isCurrencySpecific() && discount != null && discount.type === discountTypes.PERCENT) { return true; } return currency === this.currency; }; } function _parseDateTime (dt) { if (!dt) return; var DASH = '/'; var COLON = ':'; var SPACE = ' '; var dateTime = dt.dateTime; var offset = dt.offset; var zone = dt.zone; var d = dateTime.date; var t = dateTime.time; return new Date([d.month, DASH, d.day, DASH, d.year, SPACE, t.hour, COLON, t.minute, COLON, t.second, SPACE, zone.totalSeconds / 60 / 60].join('')); } })(); /* global haas, $, _ */ (function () { 'use strict'; var formatCurrency = haas.utils.formatCurrency; var inchesToMM = haas.utils.inchesToMM; var encodeSlingSelector = haas.utils.encodeSlingSelector; haas.models.MachineStandard = MachineStandardModel; function MachineStandardModel (props) { Object.assign(this, props); this.mx = inchesToMM(this.x); this.my = inchesToMM(this.y); this.mz = inchesToMM(this.z); var language = haas.utils.getLanguage(); this.configureOptionsURL = _.template(haas.constants.content.configureOptionsURL)({language: language, model: encodeSlingSelector(this.name)}); this.midpointURL = _.template(haas.constants.content.midpointURL)({language: language, model: encodeSlingSelector(this.name)}); this.getPrice = function () { var priceDef = _.find(this.total_price, {region: haas.region.props.region, currency: haas.region.props.currency }); if (!priceDef) { priceDef = _.find(this.prices, {region: haas.region.props.region, currency: haas.region.props.currency }); } if (!priceDef) return; return priceDef.price; }; this.getDiscountedPrice = function () { return this.discountedPrice; }; this.getFormattedDiscountPrice = function () { return formatCurrency(this.getDiscountedPrice()); }; this.hasPromotion = function () { if (!this.promotion) return false; var validInRegion = _.find(this.promotion.regions, function(region){ return region === haas.region.props.region }); var now = new Date(); return !!this.promotion && !!validInRegion && this.promotion.startDate < now && this.promotion.endDate > now; }; this.isAvailable = function () { return !!this.getPrice(); }; this.getFormattedPrice = function () { return formatCurrency(this.getPrice()); }; this.getImperialDims = function () { return this.dim_formatted_string; }; this.getMetricDims = function () { return this.dim_formatted_string_metric; }; } })(); /* global haas, _, $ */ (function () { 'use strict'; // percentage of a machine's w/d/h that fits a part var WIDTH_DEPTH_TOLERANCE = 0.9; var HEIGHT_TOLERANCE = 0.5; var INCH_AS_MM = 0.0393701; var MILLING = haas.constants.modelUtils.MILLING; var TURNING = haas.constants.modelUtils.TURNING; var MODEL_LIST_URL = haas.constants.api.modelList; var urlTemplate = _.template(MODEL_LIST_URL); var recs = haas.data.machineRecommendations; var MachineStandard = haas.models.MachineStandard; var PersistedCache = haas.utils.PersistedCache; var encodeSlingSelector = haas.utils.encodeSlingSelector; var content = haas.constants.content; haas.services.configurator = { cache: new PersistedCache('machines'), machines: null, standardMachines: [], configuratorPromise: null, machinePromise: null, promotionPromise : haas.services.promotion.fetchPromotions(), loading: true, fetchMachines: function () { var self = this; var language = haas.utils.getLanguage(); var machines = this.machines || this.cache.get(language); if (machines) { self.machines = machines; self.standardMachines = self._parseMachinesList(machines); self.configuratorPromise = $.when(self.promotionPromise).then(function (promotions) { self.applyPromotions(promotions); return machines; }); return self.configuratorPromise; } else{ self.machinePromise = self._fetchMachines(language); self.configuratorPromise = $.when(self.machinePromise, self.promotionPromise).then(function(machines, promotions) { self.applyPromotions(promotions); return machines; }); return self.configuratorPromise; } }, getMachines: function () { return machines; }, getModelById: function (id) { return _.find(this.standardMachines, {id: id}); }, determineDimsRotation: function (dims) { var newDims = Object.assign(dims); var tmp; if (newDims.y > newDims.x) { tmp = +newDims.x; newDims.x = +newDims.y; newDims.y = tmp; } return newDims; }, getRecommendedMillingMachinesForDims: function (dims) { var self = this; dims = this.determineDimsRotation(dims); var recommendationDef = _.find(recs.milling, function (rec) { return dims.x <= rec.xMax && dims.y <= rec.yMax && dims.z <= rec.zMax; }); if (!recommendationDef) return {primary: null, considerations: []}; haas.tmp.currentRecommendation = recommendationDef; var primaryMachine = _.find(this.standardMachines, function(standardMachine){ return standardMachine.id.toLowerCase() === recommendationDef.primary.toLowerCase(); }); var considerations = _.map(recommendationDef.considerations, function (id) { return _.find(self.standardMachines, {id: id}); }); var recommendedMachines = { primary: primaryMachine, considerations: considerations }; haas.tmp.currentRecommendedMachines = recommendedMachines; return recommendedMachines; }, getRecommendedTurningMachinesForDims: function (dims) { var self = this; var recommendationDef = _.find(recs.turning, function (rec) { return dims.x <= rec.x && dims.z <= rec.z && dims.yAxis === rec.yAxis; }); if (!recommendationDef) return; var primaryMachine = _.find(this.standardMachines, {id: recommendationDef.primary}); var considerations = _.map(recommendationDef.considerations, function (id) { return _.find(self.standardMachines, {id: id}); }); return { primary: primaryMachine, considerations: considerations }; }, getClassificationGroups: function (machines) { var classifications = []; machines.forEach(function (machine) { machine.classifications.forEach(function (classification) { var existing = _.find(classifications, {name: classification}); if (!existing) { classifications.push({ name: classification, machines: [new MachineStandard(machine)] }); } else { existing.machines.push(new MachineStandard(machine)); } }); }); return classifications; }, convertMMToInches: function (mm) { return haas.utils.mmToInches(mm); }, _parseMachinesList: function (machinesList) { var machines = []; _.forEach(machinesList, function (categories, functionality) { _.forEach(categories, function (category) { _.forEach(category.series, function (series) { _.forEach(series.details, function (model) { var props = Object.assign({}, model, { functionality: functionality, category: { id: category.id, name: category.name, description: category.description, longDescription: category.description_long, imagePath: category.image_path, imageAlt: category.image_alt }, series: { id: series.id, name: series.name, path: series.path, description: series.description, longDescription: series.description_long, imagePath: series.image_path, imageAlt: series.image_alt } }); machines.push(new MachineStandard(props)); }); }); }); }); return machines; }, getFunctionalityForCategory: function (categoryId) { var sampleMachine = _.find(this.standardMachines, function (machine) { return machine.category.id === categoryId; }); if (!sampleMachine) return; return sampleMachine.functionality; }, getFunctionalityForSeries: function (seriesName) { var sampleMachine = _.find(this.standardMachines, function (machine) { return machine.series.name === seriesName; }); if (!sampleMachine) return; return sampleMachine.functionality; }, applyPromotions: function (promotions) { var self = this; //TODO: remove promotion from machine at this point if promotion is not valid in region? promotions.forEach(function (promotion) { self.standardMachines.forEach(function (machine) { if (promotion.models.indexOf(machine.id) === -1) return; machine.promotion = promotion; machine.discountedPrice = haas.utils.applyPromotionalDiscount(promotion, machine.getPrice()); }); }); }, _fetchMachines: function (language) { var service = this; return $.getJSON(urlTemplate({language: language})).then(function (models) { if (haas.utils.isServiceError(models)) { return Promise.reject(new Error('Unable to load machine list')); } return $.when(service.promotionPromise).then(function (promotions) { service.loading = false; service.machines = models; service.standardMachines = service._parseMachinesList(models); service.cache.set(models, language); service.applyPromotions(promotions); return service.machines; }); }); } }; })(); /* global haas, $, _ */ (function () { 'use strict'; var formatCurrency = haas.utils.formatCurrency; haas.models.IndustryConfigPackage = IndustryConfigPackageModel; function IndustryConfigPackageModel (machine, industry, props) { this.machine = machine; this.industry = industry; this.title = props.title; this.description = props.description; this.bgImagePath = props.bgImagePath; this.navTitle = props.navTitle; this.options = props.options; this.features = props.features; this.machine.prices = this.machine.prices || []; this.isAvailable = function () { return !!this._getPriceDefForUserRegion(); }; this.getNumericPrice = function () { var priceDef = this._getPriceDefForUserRegion(); if (!priceDef) return; return priceDef.price; }; this.getNumericModelPrice = function () { var priceDef = this._getPriceDefForUserRegion('model_price'); if (!priceDef) return; return priceDef.price; }; this.getPrice = function () { var price = this.getNumericPrice(); if (!price) return; return formatCurrency(price); }; this.getDiscountedPrice = function () { if (!this.machine.promotion) return this.getPrice(); var def = this._getPriceDefForUserRegion('total_promotion_price'); if (!def) return; return formatCurrency(def.price); }; this.hasPromotion = function () { var def = this._getPriceDefForUserRegion('total_promotion_price'); if (!def) return; if(def){ var now = new Date(); return !!this.machine.promotion && now < this.machine.promotion.endDate && now > this.machine.promotion.startDate; } }; this._getPriceDefForUserRegion = function (priceKey) { priceKey = priceKey || 'total_price'; return _.find(this.machine[priceKey], {region: haas.region.props.region, currency: haas.region.props.currency}); }; } })(); /* haas, $, _ */ (function () { var IndustryConfigPackage = haas.models.IndustryConfigPackage; haas.services.industryConfigPackage = { packages: [], parsedPackages: [], fetch: function () { var self = this; return this._getPackages().then(function (packages) { self.packages = packages; self.parsedPackages = self._parsePackages(packages).filter(function (pkg) { return pkg.isAvailable(); }); return self.applyPromotions().then(function () { return self.parsedPackages; }); }); }, applyPromotions: function () { var self = this; return haas.services.promotion.fetchPromotions() .then(function (promotions) { promotions.forEach(function (promotion) { self.parsedPackages.forEach(function (pkg) { if (promotion.models.indexOf(pkg.machine.id) === -1) return; pkg.machine.promotion = promotion; pkg.machine.discountedPrice = promotion.getDiscountedPriceForModel(pkg.machine.id, pkg.getNumericPrice()); }); }); }); }, filterIndustryPackages: function (industries) { industries = industries || []; return this._getParsedPackages().then(function (packages) { return packages.filter(function (pkg) { return industries.indexOf(pkg.industry) !== -1; }); }); }, getIndustries: function () { return this._getPackages().then(this._getIndustriesFromPackages.bind(this)); }, _getIndustriesFromPackages: function (packages) { var industries = []; packages.forEach(function (pkg) { pkg.industries.forEach(function (industry) { if (industries.indexOf(industry) === -1) { industries.push(industry); } }); }); return industries; }, _getPackages: function () { if (!this.packages.length) { return haas.services.optionPackage.fetchOptionPackages(); } return Promise.resolve(this.packages); }, _getParsedPackages: function () { var self = this; if (!this.parsedPackages.length) { return haas.services.optionPackage.fetchOptionPackages() .then(function (packages) { return self._parsePackages(packages); }); } return Promise.resolve(this.parsedPackages); }, _parsePackages: function (packages) { var parsedPackages = []; packages.forEach(function (pkg) { pkg.industries.forEach(function (industry) { pkg.machines.forEach(function (machine) { var industryConfigPackage = new IndustryConfigPackage(machine, industry, pkg); parsedPackages.push(industryConfigPackage); }); }); }); return parsedPackages; } }; })(); (function() { haas.components.ComponentSlider = haas.Component.create({ initialize: function() { $('.slideshow-container').each(function() { let $slideshowContainer = $(this); let slideIndex = 0; let slides = $(this).children(".mySlides"); let dots = $(this).children('.dots').children(".dot"); let transitionTime = parseInt($(this).attr('data-timebetween') * 1000); $slideshowContainer.children('.dots').children('.dot').on('click', function(e) { e.stopImmediatePropagation(); let dotIndex = parseInt($(this).attr('data-show')); slideIndex = parseInt($(this).attr('data-show')); $(this).parents('.dots').siblings(".mySlides").hide(); $(this).parents('.dots').siblings(".mySlides").eq(dotIndex).fadeIn(); $(this).siblings('.dot').removeClass('active'); $(this).addClass('active'); }) $(this).children('.prev').on('click', function() { slideIndex--; if (slideIndex > (slides.length - 1)) { slideIndex = -1 } if (slideIndex < -1) {slideIndex = slides.length - 2} console.log('CURRENT INDEX', slideIndex); $(this).siblings(".mySlides").eq(slideIndex + 1).hide(); $(this).siblings('.mySlides').eq(slideIndex).fadeIn(); $(this).siblings('.dots').children('.dot').eq(slideIndex + 1).removeClass('active'); $(this).siblings('.dots').children('.dot').eq(slideIndex).addClass('active'); }) $(this).children('.next').on('click', function() { slideIndex++; if (slideIndex > (slides.length - 1)) {slideIndex = 0} if (slideIndex < -1) {slideIndex = slides.length - 2} console.log('CURRENT INDEX', slideIndex); $(this).siblings('.mySlides').eq(slideIndex - 1).hide(); $(this).siblings('.mySlides').eq(slideIndex).fadeIn(); $(this).siblings('.dots').children('.dot').eq(slideIndex - 1).removeClass('active'); $(this).siblings('.dots').children('.dot').eq(slideIndex).addClass('active'); }) slides[slideIndex].style.display = "block"; dots[slideIndex].className += " active"; if($(this).attr('data-autotransition')) { console.log('AUTO TRANSITION ENABLED!'); setInterval(function(){ console.log('TRANSITION TIME', transitionTime); console.log('INDEX NOW', slideIndex + 1); slideIndex++; if (slideIndex > (slides.length - 1)) {slideIndex = 0} if (slideIndex < -1) {slideIndex = slides.length - 2} $slideshowContainer.children('.mySlides').eq(slideIndex - 1).hide(); $slideshowContainer.children('.mySlides').eq(slideIndex).fadeIn(); $slideshowContainer.children('.dots').children('.dot').eq(slideIndex - 1).removeClass('active'); $slideshowContainer.children('.dots').children('.dot').eq(slideIndex).addClass('active'); }, transitionTime); } }) } }); })(); /* global haas, $, _, priceGroupPromise */ // TODO: This page should be hooked up to the RegionBus so that its prices will update dynamically on region change. //clear menu function clearModelmachine2() { $("#modelSelector").val("none").change(); haas.compareMachines.removeLoadingGif('machine2'); } function clearModelmachine3() { $("#modelSelector2").val("none").change(); $('#comparePage').removeClass('hasMachine3'); haas.compareMachines.removeLoadingGif('machine3'); } $(function() { if($('#comparePage').length) { haas.compareMachines.init($('#comparePage').data('categorymodels')); } }); (function () { 'use strict'; var haas = window.haas || {}; var Modal = haas.components.Modal; var modelDetailService = haas.services.modelDetail; var quoteDetailsService = haas.services.quoteDetails; var comparableQuotesService = haas.services.comparableQuotes; var OptionRulesManager = haas.models.OptionRulesManager; var $comparePage = $('#comparePage'); haas.compareMachines = { init: function (category_models) { var self = this; var mode = haas.compareMachines.constants.mode.MACHINE; // default mode, compare machines self.quoteText = "Quote"; $.when(haas.region.priceGroupPromise).then(function(price_group) { mode = $comparePage.data('mode'); self.quoteText = $comparePage.data('quote'); // check to see if the mode is for comparing quotes if (mode === haas.compareMachines.constants.mode.QUOTE) { // hide quote header $('.compare').html(''); // build selector list self.category_models = category_models; haas.compareMachines.buildSelectList('.modelSelector', haas.region.props.region); // Set unit of measurement before rendering machines self.configureSystem(haas.compareMachines.constants.SAE); self.configureEvents(); // build the quotes from the slings haas.compareMachines.buildQuotesFromSlings(category_models); } else { // if not, populate as usual from machines in sling selector // build selector list self.category_models = category_models; haas.compareMachines.buildSelectList('.modelSelector', haas.region.props.region); self.configureEvents(); self.configureSystem(haas.compareMachines.constants.SAE); haas.compareMachines.configureModelStandardFeatures(self.constants.MACHINE_1, $comparePage.data('standardfeatures'), haas.region.props.region); haas.compareMachines.configureModelSpecs(self.constants.MACHINE_1, $comparePage.data('specs')); haas.compareMachines.configureModelBapLink(self.constants.MACHINE_1, $comparePage.data('id')); haas.compareMachines.clearMachine(self.constants.MACHINE_2); haas.compareMachines.clearMachine(self.constants.MACHINE_3); } }); }, constants: { BASE_PRICE: $comparePage.attr('data-base-price'), BUILD_OPTIONS: $comparePage.attr('data-build-options'), HAS_PROMOTION: 'has-promotion', PRICE: 'price', MODEL_SELECTOR_1: 'modelSelector', MODEL_SELECTOR_2: 'modelSelector2', MACHINE_1: 'machine1', MACHINE_2: 'machine2', MACHINE_3: 'machine3', MAX_MACHINES: 3, METRIC: 'metric', NATEXT: $comparePage.data('natext'), NONE: 'none', ROTARIES: $comparePage.attr('data-rotaries'), SAE: 'sae', SLING_SELECTOR_QUOTE : 'quote', SLING_SELECTOR_QUOTE1 : 'quote1', SLING_SELECTOR_QUOTE2 : 'quote2', SLING_SELECTOR_QUOTE3 : 'quote3', YOUR_PRICE: $comparePage.attr('data-your-price'), VMODEL_DISCLAIMER: $comparePage.attr('data-vModelDisclaimer'), mode : { MACHINE: "MACHINE", QUOTE: "QUOTE" } }, buildSelectList: function (selector, current_region) { $(selector).each(function () { var default_value = $(this).data('defaulttext'); $(this).find('option').remove(); $(this).append(''); }); $.each(this.category_models, function (id, val) { var val_split = val.split(';'); var name = val_split[0]; var regions = val_split[1].split('|'); if (regions.indexOf(current_region) > -1) { $(selector).append($('').attr('value', id).text(name)); } }); }, buildQuotesFromSlings: function(category_models){ var self = this; self.comparableQuoteDetailList = []; self.comparableQuotesMap = {}; // map of quote ID string to quote details object // check to see if there are quotes self.checkSlingForQuotes(); // if so, build machines from quote IDs if (!_.isEmpty(self.quoteMap)) { var language = haas.utils.getLanguage(); // quote slings may not be in correct order, so slot them manually var quoteMap = self.quoteMap; var machineQuoteArray = []; if (quoteMap.hasOwnProperty(self.constants.SLING_SELECTOR_QUOTE1)) { machineQuoteArray.push({ machineName: self.constants.MACHINE_1, quoteId: quoteMap[self.constants.SLING_SELECTOR_QUOTE1] }); } if (quoteMap.hasOwnProperty(self.constants.SLING_SELECTOR_QUOTE2)) { machineQuoteArray.push({ selector: self.constants.MODEL_SELECTOR_1, machineName: self.constants.MACHINE_2, quoteId: quoteMap[self.constants.SLING_SELECTOR_QUOTE2] }); } // if there's a quote3 but no quote 2, slot quote 3 into the second column if (quoteMap.hasOwnProperty(self.constants.SLING_SELECTOR_QUOTE3)) { if (!quoteMap.hasOwnProperty(self.constants.SLING_SELECTOR_QUOTE2)) { machineQuoteArray.push({ selector: self.constants.MODEL_SELECTOR_1, machineName: self.constants.MACHINE_2, quoteId: quoteMap[self.constants.SLING_SELECTOR_QUOTE3] }); } else { // otherwise, slot quote 3 into third column machineQuoteArray.push({ selector: self.constants.MODEL_SELECTOR_2, machineName: self.constants.MACHINE_3, quoteId: quoteMap[self.constants.SLING_SELECTOR_QUOTE3] }); } } // add loading images _.forEach(machineQuoteArray, function (thisMachine) { self.addLoadingGif(thisMachine.machineName); }); console.log("## machineQuoteArray: ", machineQuoteArray); // Wait for the authorization promise $.when(haas.jwToken.jwtPromise).then(function () { // Get comparable quotes from service comparableQuotesService.get(quoteMap[self.constants.SLING_SELECTOR_QUOTE1], null, language) .then(function(quotes) { var comparableQuotes = quotes; console.log("## comparableQuotes: ", comparableQuotes); if (!comparableQuotes || comparableQuotes.length === 0) { haas.LOGGER.info("No comparable quotes"); return new Promise(function(resolve, reject) { resolve(); }); } // Get list of comparable quote summaries, in order to get comparable quote IDs var comparableQuoteIds = []; _.forEach(comparableQuotes, function(quoteSummary) { var quoteId = quoteSummary.baq_id; if (quoteId) { comparableQuoteIds.push(quoteId); } }); // Get list of comparable quote details and store locally for ease of use $.when(quoteDetailsService.getList(comparableQuoteIds)).then(function(quoteDetailsList) { console.log("## quoteDetailsList: ", quoteDetailsList); self.comparableQuoteDetailList = quoteDetailsList; _.forEach(self.comparableQuoteDetailList, function(quoteDetail) { self.comparableQuotesMap[quoteDetail.id] = quoteDetail; }); console.log("## comparableQuotesMap: ", self.comparableQuotesMap); self.prependQuotesToSelectList('.modelSelector'); _.forEach(machineQuoteArray, function (thisMachine) { if (thisMachine.selector) { $('#' + thisMachine.selector).val(thisMachine.quoteId); } thisMachine.quoteDetail = self.comparableQuotesMap[thisMachine.quoteId]; if (!thisMachine.quoteDetail) { // this quote cannot be compared or is unavailable // TODO: render error message? } else { // build each quoted machine (and rotary, if machine has one) self.buildQuotedMachinesAndRotaries(thisMachine, thisMachine.quoteDetail); } }); // set up metric/sae radio buttons self.configureEvents(); self.configureSystem(haas.compareMachines.constants.SAE); }); }); }); } else { // TODO: handle case where the mode is for comparing quotes, but only a model selector is used? } }, checkSlingForQuotes: function() { // look in url for presence of sling quotes (.quote1=13011.quote2=13015.html) var selectorMap = haas.utils.getSlingSelectorMap(); var quoteMap = {}; if(selectorMap && selectorMap.length !== 0){ var selectorArray = [ haas.compareMachines.constants.SLING_SELECTOR_QUOTE1, haas.compareMachines.constants.SLING_SELECTOR_QUOTE2, haas.compareMachines.constants.SLING_SELECTOR_QUOTE3 ]; // get just the quote values out of the sling selectors, in case there are extra // non-quote slings quoteMap = _.pick(selectorMap, selectorArray); //remove null values quoteMap = _.forEach(quoteMap, function(){ for(var quote in quoteMap){ if (quoteMap[quote] === null || quoteMap[quote] === '' || quoteMap[quote] === undefined){ delete quoteMap[quote]; } } }); } haas.compareMachines.quoteMap = quoteMap; }, prependQuotesToSelectList: function(selector, current_region) { var self = this; if (!self.comparableQuoteDetailList || self.comparableQuoteDetailList.length === 0) { return; } $(selector).each(function () { var $this = $(this); var default_value = $this.data('defaulttextquote'); var html = ""; html += ''; _.forEach(self.comparableQuoteDetailList, function(quoteDetail) { if (quoteDetail) { var value = quoteDetail.id; var payload = quoteDetail.payload; var text; if (payload) { text = payload.quote_name; if (!text) text = payload['quote-name']; } if (!text) { // multiply timestamp by 1000 to get epoch time in ms var quoteDate = new Date(quoteDetail.timestamp * 1000); // if date is invalid, only pass model, else include date if (isNaN(quoteDate.getTime())) { text = quoteDetail.model; } else { text = quoteDetail.model + " (" + quoteDate.toLocaleDateString() + ")"; } } html += ''; } }); html += '