2011-09-09 11 views
2

我正在使用jQuery UI自動填充小部件與AJAX,並注意到以下問題。jquery ui自動完成沒有關閉選項菜單,如果沒有焦點時,AJAX返回

背景:爲了用戶能夠專注於自動完成,並獲得選擇不輸入任何東西,我用的是焦點事件:

autoComp.focus(function() { $(this).autocomplete("search", "");}

然而,這將產生以下效果:當用戶點擊,正在發送ajax請求。在等待響應時,用戶會在其他地方點擊並自動填充模糊。但只要響應返回,即使自動完成沒有焦點,選項菜單也會彈出。爲了讓它消失,用戶必須在內部點擊一下,並再次在自動完成之外點擊,這有點煩人。

任何想法如何防止這種情況?

編輯:我解決了這個非常醜陋的方式,通過構建另一個知道元素ID的中介函數,並且此函數使用ID調用ajax函數,成功時檢查元素的焦點並返回null if它沒有專注。這非常難看,我仍然在尋找替代品。

編輯#2:試圖按照Wlliam的建議做,仍然無法正常工作.. xhr在模糊時未定義。 this關鍵字存在一些問題,如果我在自動完成之外編寫getTags函數,可能會有不同的含義?

this.autocomplete = $('.tab#'+this.id+' #tags').autocomplete({ 
    minLength: 0, 
    autoFocus: true, 
    source: getTags, 
    select: function(e, obj) { 
     tab_id = $(this).parents('.tab').attr('id'); 
     tabs[tab_id].addTag(obj.item.label, obj.item.id, false); 
     $(this).blur(); // This is done so that the options menu won't pop up again. 
     return false; // This is done so that the value will not stay in the input box after selection. 
    }, 
    open: function() {}, 
    close: function() {} 
}); 
$('.tab#'+this.id+' #tags').focus(function() { 
    $(this).autocomplete("search", ""); 
}); 
$('.tab#'+this.id+' #tags').blur(function() { 
    console.log('blurring'); 
    var xhr = $(this).data('xhr'); // This comes out undefined... :(
    if (xhr) { 
     xhr.abort(); 
    }; 
    $(this).removeClass('ui-autocomplete-loading'); 
}); 

,這是getTags功能複製到源關鍵字:

 function getTags(request, response) 
     { 
      console.log('Getting tags.'); 
      $(this).data('xhr', $.ajax({ 
       url: '/rpc', 
       dataType: 'json', 
       data: { 
        action: 'GetLabels', 
        arg0: JSON.stringify(request.term) 
       }, 
       success: function(data) { 
        console.log('Tags arrived:'); 
        tags = []; 
        for (i in data) { 
         a = {} 
         a.id = data[i]['key']; 
         a.label = data[i]['name']; 
         tags.push(a); 
        } 
        response(tags); 
       } 
      })); 
      console.log($(this).data('xhr')); 
     } 

回答

4

我認爲你需要使用回調選項爲source,以終止Ajax請求。從自動完成構件的概述報價:

回調有兩個參數:

  • 的請求對象,與所謂的「術語」的單一屬性,它 指的是價值目前在文本輸入。例如,當 用戶在城市字段中輸入「new yo」時,自動完成詞將 等於「new yo」。
  • 響應回調,期望一個參數包含 向用戶建議的數據。這個數據應該根據 提供的術語進行過濾,並且對於簡單的本地數據(帶有 標籤/值/兩個屬性的字符串數組或對象數組),可以採用上述 中描述的任何格式。提供自定義 源回調來處理請求期間的錯誤非常重要。即使您遇到錯誤,您也必須始終調用響應回調 。這 確保小部件始終具有正確的狀態。

在你的情況下,它可能會看起來像如下:

$("#autoComp").autocomplete({ 
    source: function(request, response) { 
     var searchString = request.term; 

     // ajax call to remote server, perhaps filtered with searchString 
     $(this).data('xhr', $.ajax({ 
      ... 
      success: function(data) { 
       ... 
       // pass back the data filtered by searchString 
       response(filteredList); 
      } 
     })); 
    }, 
    minLength: 0, 
    focus: function() { 
     $(this).autocomplete("search"); 
    } 
}) 
// cancel the request when user click away from the input box 
.blur(function() { 
    var xhr = $(this).data('xhr'); 
    if (xhr) xhr.abort(); 
}); 
+0

我不知道,jquery對象可以存儲相關數據,所以這是一個好主意。不過,我有一個由自動完成加載類進行的加載動畫。如果我按照自己的方式做事,我必須自己去除課程?這有問題嗎? – Uri

+0

「自動完成加載類正在加載動畫」是什麼意思?使用回調作爲源只會給你更多的靈活性,所以我不認爲這會阻礙你提供動畫。你能用一些代碼更新你的答案嗎? –

+0

自動完成自動添加可用於添加加載指示的「ui-autocomplete-loading」類(用於加載期間)。一旦ajax返回,它會自動刪除它。如果你放棄它,我假設你必須用另一行代碼刪除它,對吧? – Uri

1

我解決此問題得到了通過使用Open event。如果在下拉列表打開時輸入沒有焦點,我只需關閉它即可。

$("#autoComp").autocomplete({ 
    open: function() { 
    if ($(this).is(':not(:focus)')) { 
     $(this).autocomplete('close'); 
    } 
    }, 
    source: function(request, response) { 
    ... 
    } 
}); 
相關問題