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);