fd300eea27c25f14eeadd10ce1d5691f8fd7ed63166f88c951e3daa40e220fcb

Source Code:

(function() {
  $(function() {
/***********************************************
 * Local Variables
 ***********************************************/
    var localstr  = '';
    var localidx  = null;
    var locallist = [];
    var frmSearch = $('form#frmSearch');
    var searchbox = $('input#searchstr');
    var suggests  = $('div#suggest');
    var suggestList = [];
    var suggestHighlightClass = 'suggest_word_highlight';

    // support suggest
    var perhapsRank = 0;
    var perhapsNodeCnt  = 0;
    var perhapsList = [];
    var perhapsLink = $('.i3-perhaps-link');

/***********************************************
 * Event List
 ***********************************************/
    // lost focus
    searchbox.bind('blur', function(){
      setTimeout(function(){
        // 初期化
        setLocalVariables();
        setSuggestHtmlDefault();
      }, 500);
    });

    // key typing
    searchbox.bind('keyup', function(evt){
      var code = evt.keyCode;

      // サジェストワードのハイライトを初期化
      // ワードサジェストのみセレクタ、サービスサジェストは上下キーハイライトなし
      $('#suggest > .suggest-list').removeClass(suggestHighlightClass);

      // keycode check => request
      if (code != 40 && code != 38) {
        var str  = searchbox.val();
        // local value compare
        if (localstr == str) {
          // nochange
          return;
        }
        else {
          // text changed
          if (str.length == 0) {
            return setSuggestHtmlDefault();
          }
          else {
            // update local value and make suggest
            return setSuggest(localstr = str);
          }
        }
      }
      else{

        if( !locallist ) return;
        if( locallist.length == 0 ) return;

        localidx = calcSuggestWordIdxOnUpAndDownKey(code, localidx, locallist);

        $("#suggest > .suggest-list:eq("+localidx+")").addClass(suggestHighlightClass);

        // set text
        if( varExisits(localidx) && varExisits(locallist[localidx]) ){
          searchbox.val(locallist[localidx].word);
        }
      }
    });

    // search box submit handler
    frmSearch.bind('submit', function(e, current){

      var data = suggestList,
          form = $(this);

      // 再実効しない。
      form.unbind('submit');

      // 上下キーでの選択時の処理
      if(varExisits(localidx) && varExisits(locallist[localidx])){
        // 送信する前に変更があった場合は
        if(locallist[localidx].word == searchbox.val()){
          current = locallist[localidx];
        }
      }

      // トラッキング送信
      if(current !== undefined){
        try{
          i3SuggestSend(current, data, 'click', function(){
            form.submit();
          });
          return false;
        }catch(e){
          console.log('tracking error.');
        }
      }

      form.submit();
    });
/***********************************************
 * Common Functions
 ***********************************************/
    var setLocalVariables = function(){
      localstr  = '';
      localidx  = null;
      locallist = [];
    };

    var setSuggestHtmlDefault = function(){
      // トラッキングするデータリストをリセット
      suggestList = [];
      // DOMの削除
      suggests.children().remove();
      return updateSuggestDisplay();
    };

    var updateSuggestDisplay = function(){
      if (suggests.children().length == 0) {
        // DOMの非表示化
        return suggests.attr('style', 'display: none');
      }
      else {
        return suggests.attr('style', '');
      }
    }

    // i3 tracking data send
    var i3SuggestSend = function(set, adds, event, callback){
        if(typeof i3 === "function"){
            var type = 'suggest',
                tracker = [event, '_', type].join('');

            // トラッカーの生成
            i3('create', tracker);

            // 検索ワードの情報を格納
            i3(tracker + '.set', type, set);

            for(var i = 0; i < adds.length; i++){
              // サジェストで表示されたものを格納
              i3(tracker + '.add', type, adds[i]);
            }

            // ログの送信
            if(typeof callback === 'function'){
              i3(tracker + '.send', event, type, callback);
            }else{
              i3(tracker + '.send', event, type);
            }
        }else{
            if(typeof callback === 'function'){
              callback();
            }
        }
    }

    // 上下キーで移動する際の現在位置を計算する
    var calcSuggestWordIdxOnUpAndDownKey = function(code, currentidx, locallist){

      if( code == 40 ) {
        currentidx = (currentidx != null) ? currentidx + 1 : 0;
      }
      if( code == 38 ) {
        currentidx = (currentidx != null) ? currentidx - 1 : locallist.length - 1;
      }
      currentidx %= locallist.length;

      // 最上位の項目位置でupの場合、最上位の項目へ移動
      if( currentidx < 0 ) currentidx += locallist.length;

      return currentidx;
    }

/***********************************************
 * Main Function
 ***********************************************/
    var setSuggest = function(text){
      var url = requestUrl(text);
      if (!url) { return; }

      $.ajax({
        url     : url,
        cache   : true,
        dataType: 'jsonp',
        jsonp   : 'jsoncallback',
        error   : function (json) { return ajaxError(json, url); },
        success : function (json) { return ajaxSuccess(json, text); }
      });
    };

    // make request url
    var requestUrl = function(text){
      // get domin
      var domain = location.hostname;
      switch (true) {
        case (/dmm\.com$/.test(domain)):
          domain = 'www.dmm.com';
          break;
        case (/dmm\.co\.jp$/.test(domain)):
          domain = 'www.dmm.co.jp';
          break;
        default:
          return null;
      }

      // url
      var url = [
        location.protocol,
        '//',
        domain,
        '/search/-/assist/ajax-suggest/=/q=' + encodeURIComponent(text) + '/'
      ].join('');
      return url;
    }

    // error process
    var ajaxError = function(json, url){
      console.log({request: url, err: json});
      return setSuggestHtmlDefault();
    };

    // success process
    var ajaxSuccess = function (resjson, text) {
      // window text, requested text compare
      if (searchbox.val() != text) {
        // if not equal => overwrite by other request response
        return ;
      }
      else {
        localidx = null;
        // set default suggest area
        setSuggestHtmlDefault();

        // response is array => old type
        if (jQuery.isArray(resjson)) {
          setSuggestHtmlByArray(resjson);
        }
        // response is string => JSON parse
        else if (typeof resjson === 'string' || resjson instanceof String) {
          setSuggestHtmlByObject(JSON.parse(resjson));
        }
        // response is object => JSON data
        else if (typeof resjson === 'object' || resjson instanceof Object) {
          setSuggestHtmlByObject(resjson);
        }
        // other => illegal data
        else {
          return;
        }

        i3SuggestSend({word: searchbox.val()}, suggestList, 'show');

        return updateSuggestDisplay();
      }
    };

    var normalize = function( val ){
        if (typeof val === 'string') {
            return val;
        }else {
            return '';
        }
    }

    var varExisits = function( val ){
        if ( val !== undefined && val !== null ) {
            return true;
        }else {
            return false;
        }
    }

/***********************************************
 * HTML Node Make Functions
 ***********************************************/
    var setSuggestHtmlByArray = function(resjson){
      setWordSuggestNode(resjson);
    };

    var setSuggestHtmlByObject = function(resjson){
      // display key order priority
      var configs = {
            services  : setServiceSuggestNode,
//            categories: setCategorySuggestNode,
            words     : setWordSuggestNode
          };

      // Loop for configs size
      for (var confkey in configs) {
        // early return check
        if (!resjson[confkey]) { continue; }

        var process   = configs[confkey],
            jsonlist  = resjson[confkey];
        process(jsonlist);
      }
    };

/***********************************************
 * Node Make Functions
 ***********************************************/
    var setServiceSuggestNode = function(jsonlist) {
      var selector = $('select[name="category"] option:selected');
      // search service is all check
      if (!(selector.val() == '' || selector.val() == 'all')) {
        return;
      }
      // searchbox text length check
      else if (searchbox.val().length < 2) {
        return;
      }
      else {
        var basenode = $('<div>').attr('class', 'txt-suggest__service');

        for (var idx=0; idx<jsonlist.length; idx++) {
          var data    = jsonlist[idx],
              detail  = data.detail,
              suggest = {
                suggest_rank: idx + 1,
                suggest_uid: normalize(data.uid),
                suggest_word: normalize(data.suggest_word),
                suggest_type: 'service_suggest',
                suggest_category: normalize(data.service_ja)
              },
              node    = $('<div>').attr('class', 'suggest-list')
                .append(
                  $('<a>')
                    .attr('href', detail.url)
                    .attr('data-uid', suggest.suggest_uid)
                    .bind('click',function(){
                      // i3 send
                      for(var i = 0; suggestList.length > i; i++){
                        if($(this).attr('data-uid') == suggestList[i].suggest_uid){
                          var current = suggestList[i],
                              set = {
                                rank: current.suggest_rank,
                                word: current.suggest_word,
                                uid: current.suggest_uid,
                                type: current.suggest_type,
                                category: current.suggest_category
                              },
                              url = $(this).attr('href');
                          i3SuggestSend(set, suggestList, 'click', function(){
                        	  location.href = url;
                          });
                          return false;
                        }
                      }
                    })
                    .text(data.suggest_word)
                    .append(
                      $('<span>').text(data.service_ja)
                    )
                );
          basenode.append(node);

          suggestList.push(suggest);

        }
        if (jsonlist.length > 0) {
          suggests.append(basenode);
        }
      }
    };

    // TODO ph.2
    var setCategorySuggestNode = function(jsonlist) {
    };

    var setWordSuggestNode = function(jsonlist) {
      locallist = [];
      for (var idx=0; idx<jsonlist.length; idx++) {
        var data = jsonlist[idx],
            rank = idx + 1,
            uid = normalize(data.uid);

        if(data instanceof Object){
          word = normalize(data.suggest_word);
        }else{
          word = data;
        }

        var node = $('<div>').attr('class', 'suggest-list').append($('<span>').text(word));

        // add locallist, suggestlist
        var suggest = {
          rank: rank,
          uid:  uid,
          word: word,
          type: 'word_suggest'
        }
        locallist.push(suggest);
        suggestList.push({
            suggest_rank: suggest.rank,
            suggest_uid:  suggest.uid,
            suggest_word: suggest.word,
            suggest_type: suggest.type
        });

        suggests.append(
          // word suggest click handler
          node.bind('click', function(){
            searchbox.val($(this).text());
            for(var i = 0; locallist.length > i; i++){
              if($(this).text() == locallist[i].word){
                // submit
                frmSearch.trigger('submit',  locallist[i]);
                return false;
              }
            }
            // submit
            frmSearch.submit();
          })
        );
      }
    };
  /***********************************************/


  /***********************************************
   * suggest support
   ***********************************************/
    perhapsLink.each(function(){
      var uid = $(this).attr('data-uid'),
          word = $(this).children('.i3-perhaps-word').text(),
          category = $(this).children('.i3-perhaps-category').text(),
          url = $(this).attr('href');
      if(varExisits(uid)){
        perhapsRank++;
        var perhaps = {
          uid: normalize(uid),
          rank: perhapsRank,
          word: normalize(word),
          category: normalize(category),
          type: "service_assist_suggest"
        };
        perhapsList.push({
          suggest_uid: perhaps.uid,
          suggest_rank: perhaps.rank,
          suggest_word: perhaps.word,
          suggest_category: perhaps.category,
          suggest_type: perhaps.type
        });

        $(this).click(function(){
          i3SuggestSend(perhaps, perhapsList, 'click', function(){
            location.href = url;
          });
          return false;
        });
      }

      perhapsNodeCnt++;
      if(perhapsLink.length == perhapsNodeCnt){
        i3SuggestSend({
        		word: searchbox.val(),
        		type: "service_assist_suggest"
        	}, perhapsList, 'show');
      }

    });
  /***********************************************/
  });
}).call(this);