var wordCompleteClass = function(){ var lastKeyword = ''; //最終検索文字列または最終補完文字列 //ブラウザ判定 var isWin9X = (navigator.appVersion.toLowerCase().indexOf('windows 98')+1); var isIE = (navigator.appName.toLowerCase().indexOf('internet explorer')+1?1:0); var isOpera = (navigator.userAgent.toLowerCase().indexOf('opera')+1?1:0); var isSafari = (navigator.appVersion.toLowerCase().indexOf('safari')+1?1:0); var isFirefox = (navigator.userAgent.toLowerCase().indexOf('firefox')+1?1:0); var isKonqueror = (navigator.userAgent.toLowerCase().indexOf('Konqueror')+1?1:0); var isChrome = (navigator.userAgent.toLowerCase().indexOf('chrome')+1?1:0); if (isOpera) isIE = false; //各コントロールのID var completeWordId = "completeWord"; //キーワード入力フォーム var completeAreaId ="completeArea"; //補完リストの親領域 var completeListAreaId = "completeListArea"; //補完リストのdiv var completeListBackId = "completeListBack"; //補完リストの背景iframe(透過を防ぐ為) var completeListResultsId = "completeListResults"; //補完リスト候補一覧 var completeListResultId = "completeListResult"; //補完リスト候補 var completeLabelId = "completeLabel"; //ーワード入力フォームのラベル var paramName = ''; //補完候送信パラメータ名 var requestUrl = ''; //補完候補取得先URL var min = 2; //検索実行を行う最小の文字数 var idNumber = ''; var wordListIndex = 0; var wordListLength = 0; var isWordComplete = false; //補完リストが起動中かを示すフラグ var isLabel = false; //ラベルが存在するか var isSearch = false; //補完検索を起動したか var tmpKeyword = ''; var KeywordTimeID = ''; var TimeID = ''; var TimeID2 = ''; var i = 0; var fixLeft = null;//微調整パラメータ(横) var fixTop = null;//微調整パラメータ(縦) var fixWidth = null;//微調整パラメータ(幅) var completeWordOnchangeScript = ""; var completeWord = null; var completeArea = null; var completeLabel = null; //初期設定 this.init = function (url,param,number,searchmin,other){ paramName = param; requestUrl = url; if(arguments.length > 2){ if(number > 0){ idNumber = number; completeWordId = completeWordId + idNumber; completeAreaId = completeAreaId + idNumber; completeListAreaId = completeListAreaId + idNumber; completeListBackId = completeListBackId + idNumber; completeLabelId = completeLabelId + idNumber; } if(searchmin > 0){ min = searchmin; } if(other){ if(other.left > 0){ fixLeft = other.left; } if(other.top > 0){ fixTop = other.top; } if(other.width > 0){ fixWidth = other.width; } } } completeWord = document.getElementById(completeWordId); completeArea = document.getElementById(completeAreaId); completeWord.onkeydown = function(event){return completeListOnKeydown(event);} // completeWord.onkeyup = function(){completeListGet(this.value);} completeArea.innerHTML = '' + '' + '
' ; completeListSizeSet(completeWord,document.getElementById(completeListAreaId).style); completeListSizeSet(completeWord,document.getElementById(completeListBackId).style); if(completeWord.title.length > 0 || !!document.getElementById(completeLabelId)){ var text = getElementPos(completeWord); if(completeWord.title.length > 0){ //テキストボックス上にラベルを表示する(入力ヒント) var label = document.createElement("label"); label.id = completeLabelId; label.innerHTML = completeWord.title; completeArea.appendChild(label); } completeLabel = document.getElementById(completeLabelId); completeLabel.className = "completeLabel"; completeLabel.style.position = "absolute"; completeLabel.style.margin = "-3px 0 1px -"+(completeWord.offsetWidth+2) + "px"; // completeLabel.style.top = text.y + 'px'; // completeLabel.style.left = text.x + 'px'; completeLabel.onclick = function(){ completeWord.focus(); this.style.display = 'none'; } if(completeWord.value.length > 0){ completeLabel.style.display = 'none'; }else{ completeLabel.style.display = ''; } completeWord.onfocus= function(){ keywordGet();//確定前の日本語文字列も取得する場合 completeLabel.style.display = 'none'; } completeWord.onblur = function(){ completeWordIdOnblur(); if(completeWord.value.length < 1){ completeLabel.style.display = ''; } } isLabel = true; }else{ completeWord.onfocus= function(){keywordGet();}//確定前の日本語文字列も取得する場合 completeWord.onblur = function(){completeWordIdOnblur();} } //onchangeイベントがついている場合、このイベントの処理を取得し、onchangeイベントを抑制する if(completeWord.onchange){ completeWordOnchangeScript = String(completeWord.onchange).replace(/\n/g,""); completeWord.onchange = ""; if(completeWordOnchangeScript.match(/function.*{(.*)}/gi)){ completeWordOnchangeScript = RegExp.$1; }else{ completeWordOnchangeScript = ""; } } } //キーボード・マウス以外から強制的に文字列を変更された場合用 this.onchange = function (){ isSearch = true; completeListOnClick(completeWord.value); } // this.resize = function (number){ if(document.getElementById(completeListAreaId)){ completeListSizeSet(completeWord,document.getElementById(completeListAreaId).style); completeListSizeSet(completeWord,document.getElementById(completeListBackId).style); completeLabel.style.margin = "-3px 0 1px -"+(completeWord.offsetWidth+2) + "px"; } } //結果表示エリアのサイズ設定 function completeListSizeSet(base,update){ // if(fixLeft > 0){ // update.left = fixLeft+'px'; // }else{ // update.left = getElementPos(base).x+'px'; // } // // if(fixTop > 0){ // update.top = fixTop+'px'; // }else{ // update.top = (base.offsetHeight + getElementPos(base).y - 1)+'px'; // } if(fixWidth > 0){ update.width = fixWidth+'px'; }else{ if(base.offsetWidth > 0){ if(isIE){ update.width = (base.offsetWidth-2) +'px'; }else{ update.width = (base.offsetWidth-2) +'px'; } }else{ update.width = '0px'; } } } //指定要素の座標取得 function getElementPos(elem){ var obj = new Object(); do { obj.x = (!obj.x) ? elem.offsetLeft : obj.x + elem.offsetLeft; obj.y = (!obj.y) ? elem.offsetTop : obj.y + elem.offsetTop; } while((elem = elem.offsetParent) != null); return {x:obj.x, y:obj.y }; } //確定前の日本語文字列も取得して、検索実行する function keywordGet() { tmpKeyword = document.getElementById(completeWordId).value; KeywordTimeID = setTimeout(keywordGet, 100); completeListGet(tmpKeyword); } //補完リスト検索実行 function completeListGet(keyword){ //検索文字列が変更された場合のみ if(keyword != lastKeyword && keyword.length >= min){ getResponsebody(completeListSet,'&'+paramName+ '=' + encodeURI(keyword),'POST',requestUrl,true,completeListAreaId); isSearch = true; }else if(keyword.length < min){ //completeListHide(); eval(completeWordOnchangeScript); } lastKeyword = keyword; } //補完リストセット function completeListSet(oj,id){ var response = oj.responseText.split("\n"); var html = ''; document.getElementById(completeListAreaId).innerHTML = html; var idlength = 0; wordListLength = response.length; for(i=1;i<=wordListLength;i++){ idlength = document.getElementById(completeListResultId+idNumber+"_"+i).length; document.getElementById(completeListResultId+idNumber+"_"+i).onclick = function(){completeListOnClick(this.innerHTML);} document.getElementById(completeListResultId+idNumber+"_"+i).onmouseover = function(){completeListOnSelect(this.name);} } document.getElementById(completeListAreaId).style.width = (maxlength * 10) + 'px'; document.getElementById(completeListBackId).style.width = (maxlength * 10) + 'px'; completeListShow(); } //選択した補完文字列をセットする function completeListOnClick(text){ var completeWord = document.getElementById(completeWordId); lastKeyword = text; completeWord.value = text; //キーワード入力フォームにonchangeイベントが指定されてる場合は実行する //※javascriptで変更された場合はonchangeイベントが発生しない為 completeWordOnchange(); completeListHide(); } //選択中の補完文字列を検知する function completeListOnSelect(tmp_listindex){ tmp_listindex = parseInt(tmp_listindex); if(wordListLength >= tmp_listindex && 0 < tmp_listindex){ wordListIndex = tmp_listindex; }else if(wordListLength < tmp_listindex){ wordListIndex = 1; }else{ wordListIndex = wordListLength; } for(i=1;i<=wordListLength;i++){ if(i == wordListIndex){ //選択状態のスタイルに変更する document.getElementById(completeListResultsId+idNumber+"_"+i).className = 'select'; document.getElementById(completeListResultId+idNumber+"_"+i).className = 'select'; }else{ document.getElementById(completeListResultsId+idNumber+"_"+i).className = ''; document.getElementById(completeListResultId+idNumber+"_"+i).className = ''; } } } //別のコントロールにフォーカスが移った時の処理 function completeWordIdOnblur(){ if(KeywordTimeID){ clearTimeout(KeywordTimeID); } //Firefoxとクロームはonblur中別のイベント(今回の場合は選択した候補をセットする処理)が発生しなくなる為、時間を置いて非表示にする if(isFirefox || isChrome){ TimeID=setTimeout(function(){completeListHide();},300); TimeID2=setTimeout(function(){completeWordOnchange();},300); }else{ //フォーカスが検索結果リスト上にある場合は、テキストボックスに挿入処理を行った後に非表示にする為、ここでは非表示にしない if(document.activeElement.id.indexOf(completeListResultId) > -1){ }else{ completeListHide(); completeWordOnchange(); } } } //表示処理 function completeListShow(){ wordListIndex = 0; isWordComplete = true; document.getElementById(completeListAreaId).style.display = 'inline'; document.getElementById(completeListBackId).style.display = 'inline'; document.getElementById(completeListBackId).style.height = document.getElementById(completeListAreaId).offsetHeight + "px"; } //非表示&終了処理 function completeListHide(){ if(TimeID){ clearTimeout(TimeID); } isWordComplete = false; document.getElementById(completeListAreaId).style.display = 'none'; document.getElementById(completeListBackId).style.display = 'none'; } if('undefined' !== typeof document.addEventListener && 'undefined' === typeof document.activeElement){ document.addEventListener('focus', function (e) { e.currentTarget.activeElement = e.target; }, true); } //キーが押された際、キーのよってカーソルの移動及び補完実行を行う function completeListOnKeydown(e) { if(isWordComplete){ var move = 0; var tmp_listindex = 0; if(getkeycode(e) == 38){//up move = 1; }else if(getkeycode(e) == 40){//down move = 2; }else if(getkeycode(e) == 13){//enter completeListOnClick(document.getElementById(completeListResultId+idNumber+"_"+wordListIndex).innerHTML); return false; } if(move){ if(move == 2){ tmp_listindex = wordListIndex + 1; }else if(move == 1){ tmp_listindex = wordListIndex - 1; } completeListOnSelect(tmp_listindex); } }else{ if(getkeycode(e) == 40){ lastKeyword = ""; completeListGet(document.getElementById(completeWordId).value); } } } function getkeycode(e){ if(document.all){ return event.keyCode; } else if(document.getElementById){ return (e.keyCode!=0)?e.keyCode:e.charCode; } else if(document.layers){ return e.which; } } //文字列がセットされた際の処理 function completeWordOnchange(){ if(isSearch){ if(TimeID2){ clearTimeout(TimeID2); } eval(completeWordOnchangeScript); isSearch = false; } } //非同期通信 function getResponsebody(callback,data,method,fileURL,async ,id){ var oj = null; //XMLHttpRequestオブジェクト生成 if(window.ActiveXObject){ try{ oj = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e){ try{ oj = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e2){ oj = null; } } }else if(window.XMLHttpRequest){ oj = new XMLHttpRequest(); }else{ oj = null; } if( oj == null ){ return null; } //Konquerorはonloadが不安定 if(isOpera || isSafari || isFirefox){ oj.onload = function () { callback(oj,id) } }else{ oj.onreadystatechange = function () { if (oj.readyState == 4){ callback(oj,id); } } } if(isFirefox){ oj.overrideMimeType("text/plain; charset=shift_jis"); } oj.open( method,fileURL,async); if(method == 'POST'){ if(!isOpera){ oj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); } } oj.send(data); } }