2010-07-21 10 views
11

Tôi đang gặp nhiều rắc rối khi tiện ích tự động hoàn thành của jQuery hoạt động cho tôi. Tôi đang sử dụng một danh sách các cặp khóa/giá trị từ một máy chủ.Tự động hoàn thành giao diện người dùng jQuery với tìm kiếm văn bản/id hỗn hợp

Tôi có các yêu cầu sau:

Nếu người dùng chọn giá trị từ tiện ích, tôi muốn chuyển ID đến máy chủ.

Nếu người dùng không chọn giá trị và nhập văn bản thô hoặc sửa đổi giá trị đã được chọn, tôi muốn xóa trường ID và chỉ gửi văn bản thô tới máy chủ.

Giả sử rằng someAjaxFunction trả về một mảng các đối tượng mà tiện ích tự động hoàn thành mong đợi: {label:label, value:key}.

Ban đầu tôi đặt autocomplete phụ tùng lên như vậy:

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

Thay đổi lựa chọn thậm chí bởi lơ lửng trên một trong những mặt hàng thay đổi văn bản trong hộp văn bản tham chiếu bởi $ (đầu vào) để chìa khóa cơ bản, thay vì nhãn. Điều này là không mong muốn từ quan điểm tương tác của người dùng - thực sự, lý do tại sao tôi điều tra điều này là bởi vì người dùng trang web tôi đang xây dựng luôn bị bối rối bởi văn bản họ nhập dường như biến thành số ngẫu nhiên!

Tôi đã thêm một lĩnh vực ẩn dưới hộp văn bản và thực hiện các lựa chọn() và tập trung() sự kiện để cloak ID như vậy:

$(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 
}); 

này hoạt động tốt khi người dùng gắn bó với các tập lệnh được cung cấp bởi menu thả xuống tự động hoàn tất. ID được che giấu và được gửi chính xác đến máy chủ. Thật không may, nếu người dùng muốn nhập một số văn bản dạng tự do vào hộp và tìm kiếm dựa trên giá trị đó, trường ID không được đặt lại và ID đã chọn trước đó được gửi đến máy chủ. Điều này cũng khá khó hiểu.

Tài liệu Tự động điền giao diện người dùng jQuery liệt kê sự kiện change và nêu rõ thuộc tính item của đối số ui sẽ được đặt thành mục đã chọn. Tôi figured tôi có thể thiết lập lại trường id ẩn trên một phím bấm và tái cư ID nếu autocomplete được thay đổi. Thật không may, ngoài sự kiện nhấn phím chụp toàn bộ các lần nhấn phím mà không cần đặt lại ID, câu lệnh return false trong sự kiện select ở trên cần thiết để quản lý văn bản trong hộp văn bản ngăn sự kiện change không có .item được chỉ định đúng.

Vì vậy, bây giờ tôi đang mắc kẹt - Tôi không thực sự biết những gì khác tôi có thể thử để làm cho các chức năng hỗ trợ widget mà nó có vẻ như nó nên hỗ trợ theo mặc định. Hoặc là quá trình này là phức tạp hơn nó phải là, hoặc tôi đang thiếu một cái gì đó thực sự rõ ràng. Tôi đã chọn qua tất cả các sự kiện có sẵn và tất cả các ví dụ và đưa ra tay trống. Trong thực tế, ngay cả ví dụ "Dữ liệu tùy chỉnh và hiển thị" trên trang giao diện người dùng jQuery cũng gặp vấn đề này.

Tôi có thể thêm một số hacks ở phía máy chủ để trang trải cho điều này, nhưng tôi thực sự muốn có thể làm điều này ở cấp độ khách hàng.

Tôi cũng muốn gắn vào tiện ích tự động hoàn thành giao diện người dùng jQuery hơn là chuyển sang tiện ích con khác.

+0

Xin lỗi, tôi có thể làm rõ điều gì đó không? Ít nhất một trong các vấn đề của bạn là bạn muốn hộp ID được điền * hoặc * ID được liên kết nếu người dùng nhập giá trị có ID tương ứng hoặc bất kỳ điều gì người dùng nhập nếu không có giá trị tương ứng - đúng/sai? – Stephen

+0

Không, tôi chỉ muốn trường ID ẩn bị trống nếu văn bản trong hộp văn bản được đặt thành một thứ không tương ứng với lựa chọn do tự động điền cung cấp. – Shabbyrobe

Trả lời

2

Cách tôi đang thực hiện tự động hoàn tất, là tạo div vùng chứa chứa đầu vào.Khi tôi chọn một phần tử, tôi thêm một liên kết chứa khoảng cách vào vùng chứa và tôi ẩn hộp nhập.

Liên kết và khoảng được tạo kiểu để trông giống như nút, có dấu X và có trình xử lý sự kiện nhấp để xóa mục nhập khỏi DOM, xóa trường bị ẩn và hiển thị lại hộp nhập khi được nhấp . Vì vậy, khi một mục được chọn:

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

Và khi một mục không được chọn:

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

Bằng cách này, bạn đang hoặc buộc phải chọn một mục, hoặc bạn nhập văn bản dưới hình thức miễn phí. Trên backend, nếu tham số request với key 'myvalue' rỗng, thì bạn sẽ xem xét tham số request với khóa 'myautocomplete'.

+0

Ngoài ra, trong trình xử lý chọn của giao diện người dùng jQuery tự động hoàn thành, mỗi khi bạn chọn một mục, bạn có thể tạo trường ẩn có cùng tên, vì vậy nếu bạn chọn nhiều quốc gia, hãy đặt tên thuộc tính của trường ẩn 'quốc gia'. Nếu bạn nhấp vào một mục để xóa nó, nó sẽ loại bỏ trường được liên kết ẩn. Ở phía máy chủ, bạn sẽ lấy ra một danh sách các ID được phân cách bằng dấu phẩy và phải được tách ra và chuyển thành một mảng nguyên/dài. – jamiebarrow

+0

Đây là một gợi ý tuyệt vời và trong trường hợp không có bất cứ điều gì đơn giản, đó là cách tôi sẽ đi. Lý tưởng nhất là, tôi muốn một cái gì đó đòi hỏi phải xây dựng ít hơn rất nhiều trên đầu trang của tiện ích UI jQuery - có vẻ như với tôi rằng các widget nên hỗ trợ những gì tôi muốn làm nhiều hơn hoặc ít hơn trong hộp. – Shabbyrobe

+0

Vâng, tôi đã được giao nhiệm vụ với một cái gì đó tương tự vì vậy tôi cũng đang tìm kiếm các đề xuất về cách làm tốt :) Cười Vui mừng đề nghị của tôi đã giúp! Một điều khác là nếu một người đang sử dụng cùng một trang để tạo và chỉnh sửa - khi tải lại trang trong khi chỉnh sửa, bạn phải tạo lại tất cả các khoảng thời gian vv cho các giá trị trong trường ẩn. Tại thời điểm này tôi chỉ làm điều này ở phía máy chủ. Chỉ có vấn đề là những thứ như các lớp đang được sử dụng bây giờ phải được duy trì trong mã lối vào và mã phụ trợ ... Tôi không thích nó nhưng nó hoạt động. – jamiebarrow

1

Khi tôi đoán bạn đã thiết lập các lĩnh vực sau:

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

Bạn cần init js sau (nó hoạt động với 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 ... 
      } 
     }); 
    }); 
}); 

Nó rất thú vị khi có một số xác thực serverside có thể chuyển đổi chính xác: các giá trị trường nhìn thấy được thành các tham chiếu cho các người nhập nhanh chóng của khóa học.

0

Mặc dù câu hỏi cũ của nó, phương pháp của tôi có thể hữu ích.

Trên .change sự kiện, bạn có thể tìm kiếm giá trị hộp văn bản với giá trị trong từ Danh sách nguồn của bạn bằng vòng lặp.

Goto để biết thêm chi tiết: Đây là trong danh sách nguồn Ajax nhưng tập luyện là tương tự. Search a text In Jquery AutoComplete Ui

điều này đã được gây phiền hà cho tôi nhiều lần và cuối cùng bây giờ tôi figured it out :)

0

Bạn có thể sử dụng event.preventDefault

Thu thập các giá trị được lựa chọn của bạn thông qua ui.item.label hoặc ui.item.value và nhận giá trị cần thiết và đặt nó vào cùng một hộp văn bản.

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