$ready(function() { console.log("product finder running") 'use strict'; var $; $ = J; window.ProductFinder = {}; /* 設定 */ ProductFinder.Config = { updateDelay: 1000, fadeInDuration: 100, mainVisualFadeInDuration: 600, useFixPng: $.browser.msie && parseInt($.browser.version, 10) < 8 }; /* テキスト入力監視 */ ProductFinder.TextObserver = (function() { function TextObserver(selector) { var _this = this; this.callbacks = $.Callbacks(); $(selector).on('change keyup paste', function(event) { return _this.handle(event); }); } TextObserver.prototype.handle = function(event) { var $element, currentValue, previousValue; $element = $(event.currentTarget); currentValue = $element.val(); previousValue = $element.data('previous-value'); if (((previousValue == null) && currentValue !== '') || ((previousValue != null) && previousValue !== currentValue)) { $element.data('previous-value', currentValue); this.callbacks.fire(); } }; return TextObserver; })(); /* フォーム */ ProductFinder.Form = (function() { function Form() { this.callbacks = $.Callbacks(); this.$tabId = $('#product_finder_query input[name="tid"]'); this.textObserver = this.initializeTextObserver(); this.$solutionTree = this.initializeSolutionTree(); this.$specFilters = this.initializeSpecFilters(); this.$tabFilters = this.initializeTabFilters(); } Form.prototype.getTabId = function() { return this.$tabId.val(); }; Form.prototype.initializeTextObserver = function() { var textObserver, _this = this; textObserver = new ProductFinder.TextObserver('#price_filter input[type="text"]'); textObserver.callbacks.add(function() { return _this.callbacks.fire(); }); return textObserver; }; Form.prototype.initializeSolutionTree = function() { var $solutionTree, matches, node, _i, _len, _this = this; $solutionTree = $('#solution_filter input[type="checkbox"]'); for (_i = 0, _len = $solutionTree.length; _i < _len; _i++) { node = $solutionTree[_i]; matches = /\bsolution-medium-category-(\d+)\b/.exec(node.className); $(node).data('solution-medium-category-id', matches[1]); } $solutionTree.change(function(event) { return _this.updateSolutionTree(event); }); return $solutionTree; }; Form.prototype.updateSolutionTree = function(event) { var $element, checked, solutionMediumCategoryId; $element = $(event.currentTarget); checked = $element.prop('checked'); solutionMediumCategoryId = $element.data('solution-medium-category-id'); if ($element.hasClass('solution-medium-category')) { if (!checked) { this.$solutionTree.filter('.solution-small-category.solution-medium-category-' + solutionMediumCategoryId).prop('checked', checked).trigger('pf:change'); } } else if ($element.hasClass('solution-small-category')) { if (checked) { this.$solutionTree.filter('.solution-medium-category.solution-medium-category-' + solutionMediumCategoryId).prop('checked', checked).trigger('pf:change'); this.$solutionTree.filter('.solution-small-category.solution-medium-category-' + solutionMediumCategoryId).not($element).prop('checked', !checked).trigger('pf:change'); } } this.callbacks.fire(); }; Form.prototype.initializeSpecFilters = function() { var $specFilters, _this = this; $specFilters = $('#spec_filter input').filter('[type="checkbox"], [type="radio"]'); $specFilters.change(function() { return _this.callbacks.fire(); }); return $specFilters; }; Form.prototype.initializeTabFilters = function() { var $tabFilters, _this = this; $tabFilters = $('#tab_filter input[type="checkbox"]'); $tabFilters.change(function() { return _this.callbacks.fire(); }); return $tabFilters; }; Form.prototype.reset = function() { $('#price_filter input[type="text"]').val(''); $('#solution_filter input[type="checkbox"]').prop('checked', false).trigger('pf:change'); $('#spec_filter input').filter('[type="checkbox"], [type="radio"]').prop('checked', false).trigger('pf:change'); $('#tab_filter input[type="checkbox"]').prop('checked', false).trigger('pf:change'); this.callbacks.fire(true); return this; }; Form.prototype.clearPriceMin = function() { $('#price_filter input[name="price_min"]').val(''); this.callbacks.fire(true); return this; }; Form.prototype.clearPriceMax = function() { $('#price_filter input[name="price_max"]').val(''); this.callbacks.fire(true); return this; }; Form.prototype.clearSolution = function(id) { this.$solutionTree.filter("[value=\"" + id + "\"]").click().change(); this.callbacks.fire(true); return this; }; Form.prototype.clearSpecFilter = function(id) { this.$specFilters.filter("[value=\"" + id + "\"]").prop('checked', false).change(); this.callbacks.fire(true); return this; }; return Form; })(); /* 外観 */ ProductFinder.Appearance = (function() { function Appearance() { this.checkboxes = this.initializeCheckboxes(); this.radiobuttons = this.initializeRadiobuttons(); } Appearance.prototype.initializeCheckboxes = function() { var checkbox; return (function() { var _i, _len, _ref, _results; _ref = $('#product_finder_query input[type="checkbox"]'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { checkbox = _ref[_i]; _results.push(new ProductFinder.Appearance.Checkbox(checkbox)); } return _results; })(); }; Appearance.prototype.initializeRadiobuttons = function() { var radiobutton; return (function() { var _i, _len, _ref, _results; _ref = $('#product_finder_query input[type="radio"]'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { radiobutton = _ref[_i]; _results.push(new ProductFinder.Appearance.Radiobutton(radiobutton)); } return _results; })(); }; return Appearance; })(); /* チェックボックス */ ProductFinder.Appearance.Checkbox = (function() { function Checkbox(checkbox) { var _this = this; this.$checkbox = $(checkbox); this.$image = $(document.createElement('span')); this.$image.attr('class', 'product_finder_checkbox'); this.update(); this.$checkbox.closest('label').click(function(event) { return _this.clicked(event); }); this.$checkbox.on('change pf:change', function() { return _this.update(); }); this.$checkbox.hide(); this.$checkbox.after(this.$image); } Checkbox.prototype.clicked = function(event) { event.preventDefault(); return this.$checkbox.prop('checked', !this.$checkbox.prop('checked')).change(); }; Checkbox.prototype.update = function() { if (this.$checkbox.prop('checked')) { return this.$image.removeClass('product_finder_checkbox_off').addClass('product_finder_checkbox_on'); } else { return this.$image.removeClass('product_finder_checkbox_on').addClass('product_finder_checkbox_off'); } }; return Checkbox; })(); /* ラジオボタン */ ProductFinder.Appearance.Radiobutton = (function() { function Radiobutton(radiobutton) { var $form, _this = this; this.$radiobutton = $(radiobutton); $form = this.$radiobutton.closest('form'); this.$siblings = $form.find('input[type="radio"][name="' + this.$radiobutton.attr('name') + '"]'); this.$image = $(document.createElement('span')); this.$image.attr('class', 'product_finder_radiobutton'); this.update(); this.$radiobutton.closest('label').click(function(event) { return _this.clicked(event); }); this.$radiobutton.on('change pf:change', function() { return _this.updateAll(); }); this.$radiobutton.on('pf:update-radiobutton', function() { return _this.update(); }); this.$radiobutton.hide(); this.$radiobutton.after(this.$image); } Radiobutton.prototype.clicked = function(event) { event.preventDefault(); return this.$radiobutton.prop('checked', !this.$radiobutton.prop('checked')).change(); }; Radiobutton.prototype.updateAll = function() { return this.$siblings.trigger('pf:update-radiobutton'); }; Radiobutton.prototype.update = function() { if (this.$radiobutton.prop('checked')) { return this.$image.removeClass('product_finder_radiobutton_off').addClass('product_finder_radiobutton_on'); } else { return this.$image.removeClass('product_finder_radiobutton_on').addClass('product_finder_radiobutton_off'); } }; return Radiobutton; })(); /* コントローラー */ ProductFinder.Controller = (function() { function Controller() { var _this = this; this.fixPngReady = false; this.updateDelayId = null; this.$mainVisuals = this.initializeMainVisuals(); this.$addition = $('#product_finder_addition'); this.$resultWrapper = $('.product_finder_contents #main, .solutions .product_finder_contents .choice'); this.form = new ProductFinder.Form(); this.form.callbacks.add(function(immediately) { if (immediately == null) { immediately = false; } return _this.formChanged(immediately); }); this.appearance = new ProductFinder.Appearance(); this.request = null; this.updateMainVisual(); this.update(); } Controller.prototype.initializeMainVisuals = function() { var $mainVisuals, _this = this; $mainVisuals = $('#main_visual .main_visual_item'); if (ProductFinder.Config.useFixPng) { $script.ready('jquery.belatedPNG.0.0.4a', function() { var $img; if (_this.fixPngReady) { return; } _this.fixPngReady = true; $img = $mainVisuals.filter(':visible').find('img'); if (!$img.prop('vmlInitiated')) { return $img.fixPng(); } }); } return $mainVisuals; }; Controller.prototype.formChanged = function(immediately) { var delay, _this = this; if (this.updateDelayId != null) { clearTimeout(this.updateDelayId); } this.hideResult(); this.updateMainVisual(); delay = immediately ? 0 : ProductFinder.Config.updateDelay; this.updateDelayId = setTimeout(function() { _this.updateDelayId = null; return _this.update(); }, delay); }; Controller.prototype.updateMainVisual = function() { var $img, $mainVisual, mainVisualClass, tabId; tabId = this.form.getTabId(); mainVisualClass = tabId === '' ? 'tab-0' : 'tab-' + tabId; $mainVisual = this.$mainVisuals.filter('.' + mainVisualClass); if (!$mainVisual.is(':visible')) { this.$mainVisuals.hide(); if (ProductFinder.Config.useFixPng) { $mainVisual.show(); if (this.fixPngReady) { $img = $mainVisual.find('img'); if (!$img.prop('vmlInitiated')) { $img.fixPng(); } } } else { $mainVisual.fadeIn(ProductFinder.Config.mainVisualFadeInDuration); } } return this; }; Controller.prototype.update = function() { var $form, _this = this; if (this.request != null) { this.request.abort(); } this.hideResult(); $form = $('#product_finder_query'); this.request = $.get($form.prop('action'), $form.serializeArray()).success(function(data) { var $result; $result = $('#product_finder_result'); $result.html(data); $result.find('a img').not('.none').on({ mouseover: function() { return $(this).stop(true, false).animate({ opacity: 0.5 }, { duration: 0, queue: true }); }, mouseout: function() { return $(this).stop(true, false).animate({ opacity: 1 }, { duration: 0, queue: true }); } }); if (typeof Compare !== "undefined" && Compare !== null) { if (window.first) { $('li.checkbox').trigger('custom'); } else { window.compara = new Compare(); window.first = true; $('ul#tab_filter li.active a').trigger('customFilterInit'); } } var showResult = _this.showResult(); // ProductFinder より下にあるページ内リンクに URL で直接遷移した場合に上手くスクロールしてくれない対応 // e.g. // 遷移先 URL が /solutions/medical/or.html#contact の場合、ProductFinder 構築前にページ内リンクで // 移動してしまうのでお問い合わせの位置にスクロール出来ていない // その為、コンテツが全て読み込まれた後に再度スクロール位置を変更する _this.hashScroll(); return showResult; }); return this; }; Controller.prototype.hideResult = function() { this.$addition.detach(); this.$resultWrapper.hide(); $('#product_finder_loading').show(); return this; }; Controller.prototype.showResult = function() { $('#product_finder_loading').hide(); this.$addition.appendTo(this.$resultWrapper).show(); this.$resultWrapper.fadeIn(ProductFinder.Config.fadeInDuration); return this; }; Controller.prototype.reset = function() { this.form.reset(); return this; }; Controller.prototype.clearPriceMin = function() { this.form.clearPriceMin(); return this; }; Controller.prototype.clearPriceMax = function() { this.form.clearPriceMax(); return this; }; Controller.prototype.clearSolution = function(id) { this.form.clearSolution(id); return this; }; Controller.prototype.clearSpecFilter = function(id) { this.form.clearSpecFilter(id); return this; }; // ProductFinder より下にあるページ内リンクに URL で直接遷移した場合に上手くスクロールしてくれない対応 // e.g. // 遷移先 URL が /solutions/medical/or.html#contact の場合、ProductFinder 構築前にページ内リンクで // 移動してしまうのでお問い合わせの位置にスクロール出来ていない // その為、コンテツが全て読み込まれた後に再度スクロール位置を変更する Controller.prototype.hashScroll = function() { if (typeof this.isDoHashScroll !== "undefined") return; this.isDoHashScroll = true; // ページ内リンクのハッシュを取得 var hash = window.location.hash.replace('#', ''); // ProductFinder の TOP からの位置 var product_finder_contents_position = $('.product_finder_contents').offset().top; // ハッシュが指定されいる場合 if (hash != '') { // ハッシュが指定されいる場合 var target = $('#' + hash); if (target.length < 1) target = $('a[name="'+hash+'"]').parent(); if (target.length) { var p = $(target).offset().top; // ProductFinder より下にあるページ内リンクの場合 if (product_finder_contents_position < p) { // スクロール位置を再度変更 var $header = $('header'); if ($header.length > 0) p -= $header.height(); $('html,body').animate({ scrollTop: p }, 'slow'); } } } }; return Controller; })(); /* 初期化処理 */ $(function() { window.productFinder = new ProductFinder.Controller(); }); });