2010-07-21 43 views
11

我有很多麻煩,使jQuery的自動填充小工具爲我工作。我正在使用來自服務器的鍵/值對列表。jQuery UI自動完成與混合文本/ ID搜索

我有以下要求:

如果用戶從窗口小部件選擇一個值,我想ID傳遞給服務器。

如果用戶沒有選擇一個值並輸入原始文本,或者修改了一個已經被選中的值,我想要清除ID字段,並且只是將原始文本發送到服務器。

假設someAjaxFunction返回自動填充小部件期望的對象數組:{label:label, value:key}

起初我設置自動完成構件像這樣:

$(input).autocomplete({ 
    source: sourceFunction, 
    minLength: 1 
}); 

改變選擇,甚至通過將鼠標懸停在項目中的一個改變了$(輸入)參考下面的鍵文本框中的文本,而不是標籤。從用戶交互的角度來看,這是非常不可取的 - 事實上,我正在研究這個問題的原因是因爲我正在構建的站點的用戶一直對他們輸入的文本感到困惑,似乎它們變成了隨機數字!

我添加了一個隱藏字段下的文本框中並實施的select()和焦點()事件,以掩飾,像這樣的ID:

$(input).autocomplete({ 
    source: sourceFunction, 
    minLength: 1 
    focus: function(event, ui) { 
     $(idField).val(ui.item.value); 
     $(this).val(ui.item.label); 
     return false; 
    }, 
    select: function(event, ui) { 
     $(idField).val(ui.item.value); 
     $(this).val(ui.item.label); 
     return false; 
    }, 
    minLength: 1 
}); 

這種運作良好,當用戶被粘到由自動完成下拉菜單提供的腳本。該ID隱藏並正確提交給服務器。不幸的是,如果用戶想要在框中輸入一些自由格式的文本並根據該值進行搜索,則ID字段不會重置,並且之前選擇的ID將被提交給服務器。這也相當混亂。

jQuery UI自動完成文檔列出change事件,並指出ui參數的item屬性將設置爲所選項目。我想我可以重置按鍵上隱藏的ID字段,並重新填充ID如果自動完成更改。不幸的是,除了按鍵事件捕獲了一大堆按鍵,不應該重置ID,事件中的事件(這是管理文本框中的文本所必需的)中的語句阻止change事件具有UI .item正確分配。

所以現在我被卡住了 - 我真的不知道還有什麼我可以嘗試使小部件支持功能,它似乎應該默認支持。要麼這個過程比它本該更復雜,要麼我錯過了一些非常明顯的東西。我挑選了所有可用的事件和所有的例子,並且空手而歸。事實上,即使jQuery UI頁面上的「自定義數據和顯示」示例也會遇到這個問題。

我可以在服務器端添加一些黑客來掩蓋這一點,但我真的希望能夠在客戶端級別做到這一點。

我還希望堅持jQuery UI自動填充小部件,而不是切換到另一個。

+0

對不起,我可以澄清一些事情嗎?至少有一個問題是,如果用戶輸入具有相應ID的值,或者如果用戶沒有對應的值時輸入的任何內容,則希望ID框填充* *相關的​​ID - 正確/不正確的? – Stephen 2010-07-27 13:49:39

+0

那麼,如果文本框中的文本被設置爲與自動完成提供的選項不對應的內容,我只希望隱藏的ID字段爲空。 – Shabbyrobe 2010-07-27 14:27:37

回答

2

我在做自動完成的方式是創建一個包含輸入的容器div。當我選擇一個元素時,我將一個包含span的鏈接添加到容器中,然後隱藏輸入框。

鏈接和跨度的樣式使它看起來像一個按鈕,帶有一個X,並具有一個單擊事件處理程序以從DOM中移除條目,清除隱藏的字段,並在單擊時重新顯示輸入框。所以,當一個項目被選中:

<div class="container"> 
    <a href="#"><span>Selected Item</span></a> 
    <input id="myautocomplete" type="text" /> 
    <input type="hidden" name="myvalue" value="1" /> 
    </div> 

當未選擇一個項目:

<div class="container"> 
    <input id="myautocomplete" name="myautocomplete" type="text" /> 
    <input id="myvalue" name="myvalue" type="hidden" value="" /> 
    </div> 

這樣,你要麼被迫選擇一個項目,或者你輸入自由格式文本。在後端,如果帶有'myvalue'鍵的請求參數爲空,那麼您應該使用'myautocomplete'鍵來查看請求參數。

+0

另外,在jQuery UI自動完成的選擇處理程序中,每次選擇一個項目時,都可以創建一個具有相同名稱的隱藏字段,因此如果選擇多個國家/地區,請將隱藏字段的名稱屬性設置爲'countries'。如果您單擊某個條目以將其刪除,則會刪除相關的隱藏字段。在服務器端,您最終會檢索必須拆分並轉換爲整數/長整型數組的ID的逗號分隔列表。 – jamiebarrow 2010-07-27 13:47:20

+0

這是一個很好的建議,在沒有任何簡單的情況下,這就是我要去的方式。理想情況下,我更喜歡在jQuery UI小部件上構建更少的東西 - 在我看來,小部件應該支持我想要做的或多或少的開箱即用功能。 – Shabbyrobe 2010-07-27 14:30:14

+0

嗯,我一直負責類似的東西,所以我也在尋找如何做到這一點的建議:)很高興我的建議幫助! 另一件事是,如果有人使用相同的頁面進行創建和編輯 - 編輯時重新加載頁面,則必須重新創建隱藏字段中值的所有跨度等。目前我只是在服務器端做這件事。唯一的問題是,像現在使用的類的東西現在必須保持在前端代碼和後端代碼...我不喜歡它,但它的工作原理。 – jamiebarrow 2010-07-28 08:40:19

1

當我想你有以下字段設置:

<div> 
    <input type="text" name="visible" class="autocomplete-reference" /> 
    <input type="hidden" name="hidden" /> 
</div> 

您需要初始化以下JS(它的工作原理與jQuery 1.5.2):

$(document).ready(function() { 
    $('.autocomplete-reference').each(function() { 
     $(this).keydown(function(e){ 
      /* 
      * this will reset hidden id reference on each visible field manual change 
      * we have to bind it on keydown because we want to recognize event of submiting form by enter after autocomplete set 
      */ 
      if (e.keyCode != 13) { 
       $(this).siblings('input[type=hidden]').each(function() { 
        $(this).val(''); 
       }); 
      } 
     }); 
     $(this).autocomplete({ 
      minLength: 1, 
      /* you can set appending of autocomplete menu into some container to set css contextually 
      appendTo: '#someElem',*/ 
      source: sourceFunction, 
      search:function (event, ui) { 
       //TODO ...spinner init... 
      }, 
      open:function (event, ui) { 
       /* you can grab autocomplete menu widget by this to manipulate some recognizing id, etc.. 
       * $(this).autocomplete('widget') 
       */ 
       //TODO ..stop spinner ... 
       $(this).keydown(function(e){ 
        /* this is important for live reference updates while arrow keys changes */ 
        if (e.keyCode == 37 || e.keyCode == 39) { 
         $($(this).data('autocomplete').menu.active).find('a').trigger('click'); 
        } 
       }); 
      }, 
      focus: function(event, ui) { 
       /* here we'll map our data object onto both fields */ 
       $(this).val(ui.item.label); 
       $(this).siblings('input[type=hidden]').each(function() { 
        $(this).val(ui.item.key); 
       }); 
      }, 
      select: function(event, ui) { 
       /* here we'll map our data object onto both fields */ 
       $(this).val(ui.item.label); 
       $(this).siblings('input[type=hidden]').each(function() { 
        $(this).val(ui.item.key); 
       }); 
      }, 
      close: function(event, ui) { 
       //TODO ..stop spinner ... 
      } 
     }); 
    }); 
}); 

這是非常好的,有一些服務器端驗證,可以將精確的:可見的字段值轉換爲引用,以便快速打字。

0

雖然它的一個老問題,我的方法可以幫助。

.change事件中,您可以使用循環從源列表中搜索帶有值的文本框值。

轉到更多的細節:這裏是在Ajax源列表中,但鍛鍊是類似的。 Search a text In Jquery AutoComplete Ui

這件事就一直困擾了我很多次,最終現在我理解了它:)

0

您可以使用event.preventDefault

通過ui.item.label收集你選擇的值或ui.item.value並獲取所需的值並將其設置爲相同的文本框。

var idNameCombo = ui.item.label; 
      event.preventDefault(); 
      $("#mID").val(idNameCombo.split(",")[0].trim());