2010-05-22 37 views
14

Tôi có hai danh sách có thứ tự bên cạnh nhau.Sử dụng jQuery để chèn động vào danh sách theo thứ tự abc

Khi tôi lấy một nút ra khỏi một danh sách, tôi muốn chèn nó vào bảng chữ cái trong danh sách khác. Việc nắm bắt là tôi muốn chỉ lấy một phần tử ra và đặt nó trở lại trong danh sách khác mà không làm mới toàn bộ danh sách.

Điều kỳ lạ là khi tôi chèn vào danh sách bên phải, nó hoạt động tốt, nhưng khi tôi chèn lại vào danh sách bên trái, thứ tự không bao giờ xuất hiện đúng.

Tôi cũng đã thử đọc mọi thứ vào một mảng và sắp xếp nó ở đó trong trường hợp phương thức children() không trả về thứ tự chúng được hiển thị, nhưng tôi vẫn nhận được kết quả tương tự.

Đây là jQuery tôi:

function moveNode(node, to_list, order_by){ 

    rightful_index = 1; 
    $(to_list) 
     .children() 
     .each(function(){ 
      var ordering_field = (order_by == "A") ? "ingredient_display" : "local_counter"; 

      var compA = $(node).attr(ordering_field).toUpperCase(); 
      var compB = $(this).attr(ordering_field).toUpperCase(); 
      var C = ((compA > compB) ? 1 : 0); 
      if(C == 1){ 
       rightful_index++; 
      } 
     }); 

    if(rightful_index > $(to_list).children().length){ 
     $(node).fadeOut("fast", function(){ 
      $(to_list).append($(node)); 
      $(node).fadeIn("fast"); 
     }); 
    }else{ 
     $(node).fadeOut("fast", function(){ 
      $(to_list + " li:nth-child(" + rightful_index + ")").before($(node)); 
      $(node).fadeIn("fast"); 
     }); 
    } 

} 

Đây là những gì html của tôi trông giống như:

<ol> 
<li ingredient_display="Enriched Pasta" ingredient_id="101635" local_counter="1"> 
    <span class="rank">1</span> 
    <span class="rounded-corners"> 
      <span class="plus_sign">&nbsp;&nbsp;+&nbsp;&nbsp;</span> 
      <div class="ingredient">Enriched Pasta</div> 
      <span class="minus_sign">&nbsp;&nbsp;-&nbsp;&nbsp;</span> 
    </span> 
</li> 
</ol> 
+0

Bạn đã thử sử dụng trình gỡ rối để duyệt qua mã của bạn và đảm bảo rằng hàm gọi lại (...) của bạn hoạt động chính xác? Các công cụ phát triển Firebug hoặc IE8 hoạt động tốt cho việc này. Bạn có thể đặt điểm ngắt trong phần gọi lại của bạn. – RMorrisey

+1

tôi đã kiểm tra w3c. tôi không thể tìm thấy bất kỳ đề cập đến các thuộc tính 'component_display',' ingredient_id' hoặc 'local_counter'. sang một bên, đây là một số html khủng khiếp. tôi hy vọng điều này sẽ không được đưa vào sản xuất ở đâu đó: \ – Jason

+0

Tôi đã từng bước sử dụng firebug và vì lý do nào đó họ không quay lại đúng thứ tự cho một trong các danh sách có thứ tự.Có lẽ tôi nên đi bằng getElementById. @ jason, đây không phải dành cho sản xuất. Đó là những thuộc tính do người dùng định nghĩa. Bạn đề nghị sửa lỗi này như thế nào? – Dex

Trả lời

26

Tôi đã tạo một jsFiddle with working code để giải quyết vấn đề này. Tôi bao gồm cả mã ở đây cũng chỉ trong trường hợp jsFiddle đi bụng lên trong tương lai xa xôi:

<ol class="ingredientList"> 
    <li class="ingredient">Apples</li> 
    <li class="ingredient">Carrots</li> 
    <li class="ingredient">Clams</li> 
    <li class="ingredient">Oysters</li> 
    <li class="ingredient">Wheat</li> 
</ol> 
<ol class="ingredientList"> 
    <li class="ingredient">Barley</li> 
    <li class="ingredient">Eggs</li> 
    <li class="ingredient">Millet</li> 
    <li class="ingredient">Oranges</li> 
    <li class="ingredient">Olives</li> 
</ol>​ 

và jQuery:

$(".ingredient").click(function(){ 
    var element = $(this); 
    var added = false; 
    var targetList = $(this).parent().siblings(".ingredientList")[0]; 
    $(this).fadeOut("fast", function() { 
     $(".ingredient", targetList).each(function(){ 
      if ($(this).text() > $(element).text()) { 
       $(element).insertBefore($(this)).fadeIn("fast"); 
       added = true; 
       return false; 
      } 
     }); 
     if(!added) $(element).appendTo($(targetList)).fadeIn("fast"); 
    }); 
});​ 

Tôi lột HTML của bạn xuống vì lợi ích của ngắn gọn, vì vậy bạn sẽ muốn sửa đổi mã của tôi để phù hợp với mã của bạn. Ngoài ra, nếu bạn định sử dụng thuộc tính do người dùng xác định (không phải là HTML hợp lệ và không được hỗ trợ chính thức bởi bất kỳ trình duyệt nào ... mặc dù nó cũng sẽ không làm hại bất cứ điều gì .... có thể), tôi khuyên bạn nên thêm tiền tố cho họ "để phù hợp với đặc điểm kỹ thuật HTML5 Custom Data Attribute. Vì vậy, "ingredients_id" sẽ trở thành "data-ingredient_id". Mặc dù điều này chưa được hỗ trợ trên bất kỳ trình duyệt hiện tại nào vì HTML5 chưa được hoàn thành, nó an toàn hơn và mạnh mẽ hơn là chỉ định nghĩa các thuộc tính của riêng bạn. Và khi HTML5 được hoàn thành, các thuộc tính của bạn sẽ được hỗ trợ đầy đủ.

Chỉnh sửa - Như John đã nêu trong các nhận xét, điều này sẽ không hoạt động nếu bạn cần hỗ trợ các ký tự UTF-8. Trong trường hợp này, bạn cần sử dụng String.prototype.localeCompare() (đảm bảo rằng bạn kiểm tra xem trình duyệt có hỗ trợ nó theo tài liệu hay không). Vì vậy, mã sẽ trông giống như sau:

$(".ingredient").click(function(){ 
    var element = $(this); 
    var added = false; 
    var targetList = $(this).parent().siblings(".ingredientList")[0]; 
    $(this).fadeOut("fast", function() { 
     $(".ingredient", targetList).each(function(){ 
      if ($(this).text().localeCompare($(element).text()) > 0) { 
       $(element).insertBefore($(this)).fadeIn("fast"); 
       added = true; 
       return false; 
      } 
     }); 
     if(!added) $(element).appendTo($(targetList)).fadeIn("fast"); 
    }); 
}); 

Here is an updated Fiddle implementing localeCompare.

+0

Tôi đã thử phương pháp của bạn và nó hoạt động khi bạn chỉ sử dụng .text(). Tuy nhiên, tôi cũng hoạt động khi bạn sử dụng .text(). Cả hai chúng tôi đều bị phá vỡ khi tôi sử dụng .attr(). Tôi đã ngừng sử dụng các thuộc tính do người dùng định nghĩa và chỉ cố gắng chơi xung quanh với thuộc tính 'id' và tôi vẫn nhận được cùng một hành vi lạ. Một debug cho tôi biết rằng .children() là, trên thực tế, đang lặp lại theo đúng thứ tự. Điều này thật bực mình. – Dex

+0

Tôi cần phải sắp xếp các cách khác theo thứ tự bảng chữ cái. Tôi cũng cần có khả năng sắp xếp theo trường 'local-counter' trong HTML gốc của mình. – Dex

+0

Tôi vừa cập nhật jsFiddle theo thứ tự .attr() và có vẻ như nó hoạt động. http://jsfiddle.net/VQu3S/9/ –

-3

tôi sẽ nhận được .text() của mỗi linh sam yếu tố, sau đó đặt nó trên một mảng , sắp xếp mảng, sau đó di chuyển từng phần tử trong đó các chỉ mục của SORTED khớp với UNSORTED.

và tôi quá lười biếng để viết mã cho điều đó và kiểm tra ngay bây giờ :) nhưng chỉ là một ý nghĩ về cách tiếp cận của tôi.

Các vấn đề liên quan