透過jQueryUI 實現輸入框的自動完成
4年沒碰前端了,遇到了需求還是得跳下去改...
1.先確認這次的需求
- User輸入框輸入時必須出現自動完成的選項,給User選擇
- 自動完成的資料來源來自後端API,且會依照User當下輸入的值做查詢
- API有訪問頻率的限制
- User上下選擇選項時不可以更改輸入框的內容,按下enter時才可更改
- User按下enter選定選項後,停止跳出自動完成選單
- 自動完成的選項不需要過濾User輸入的內容,API拿到什麼就列出什麼
- User上下選擇選項時,不可刷新清單
2.以上是陸續被反映的問題跟需求...有的是連貫的因果關係,不過還是一併列出
3.直接貼出程式碼,一一確認需求
// ctrl: $("#text")
function autocomplete(ctrl) {
// 先定義方法,後面才會用到
let oldKeyword;
let newVar = function () {
// 每次進入時檢查是否有改變值,若無則直接離開不做事
const keyword = ctrl.val();
if (keyword === oldKeyword)
{
return;
}
// 紀錄這次新的值
oldKeyword = keyword;
// 向後端API取得資料
$.ajax({
type: 'POST',
url: "Autocomplete.aspx", //WebForm...
data: {method: "get", keyword: keyword},
datatype: "json",
success: (response) => {
const items = JSON.parse(response);
// 需求之一,不要過濾內容
ctrl.autocomplete("option", "source", function (request, response) {
response(items);
});
// 前面更新source後,jQuery-ui只有在觸發改變時才會跳出自動完成選單,這邊直接強制他做一次查詢,跳出選單
ctrl.autocomplete("search");
},
error: (ex, a, b) => {
console.log(b)
},
});
};
let interval;
// 當User聚焦在輸入框,加入timer每一段時間更新一次清單
// 若用keydown之類的觸發,會超過API的訪問頻率
ctrl.focus(() => {
// 先初始化輸入框的自動完成
ctrl.autocomplete({
source: [],
// 只要有輸入一個字就允許跳出選單
minLength: 1,
// 當User選到其中一個選項(enter或是滑鼠點擊)時,把timer拔掉
select: function (event, ui) {
clearInterval(interval);
},
// 當User上下移動選項時,不改變輸入框的內容
focus: function(event, ui){
event.preventDefault();
}
});
// 設定一個timer,每兩秒去更新一次選單
interval = setInterval(() => {
newVar();
}, 2000);
});
// User離開聚焦後,把timer拔掉
ctrl.focusout(() => {
clearInterval(interval)
});
}
4.說明都寫在程式碼內了,快樂結束XD
以上絕對不是最好也不是0 Bug的寫法,但是應付目前的需求是足夠的...
歡迎大大們提供建議改善這段程式碼 XD