I have two ordered lists next to each other.
When I take a node out of one list I want to insert it alphabetically into the other list. The catch is that I want to take just the one element out and place it back in the other list without refreshing the entire list.
The strange thing is that when I insert into the list on the right, it works fine, but when I insert back into the list on the left, the order never comes out right.
I have also tried reading everything into an array and sorting it there just in case the children() method isn't returning things in the order they are displayed, but I still get the same results.
Here is my jQuery:
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", funct开发者_StackOverflow中文版ion(){
$(to_list + " li:nth-child(" + rightful_index + ")").before($(node));
$(node).fadeIn("fast");
});
}
}
Here is what my html looks like:
<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"> + </span>
<div class="ingredient">Enriched Pasta</div>
<span class="minus_sign"> - </span>
</span>
</li>
</ol>
I have created a jsFiddle with working code to solve this problem. I am including the code here as well just in case jsFiddle goes belly up in the distant future:
<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>
and the 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");
});
});
I stripped your HTML down for the sake of brevity, so you will want to modify my code to match yours. Also, if you are going to use user defined attributes (which are not valid HTML and not officially supported by any browser...though it also won't hurt anything....probably), I recommend prefixing them with "data-" to conform with the HTML5 Custom Data Attribute specification. So "ingredient_id" would become "data-ingredient_id". While this is not yet supported on any current browser as HTML5 has not been finalized, it is safer and more robust than just defining your own attributes. And once HTML5 is finalized, your attributes will be fully supported.
Edit - As John pointed out in the comments, this will not work if you need to support UTF-8 characters. In this case you need to use String.prototype.localeCompare() (make sure you check that the browser supports it as per the documentation). So that code would look something like this:
$(".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.
I would get the .text() of each element firs, then put it on an array, sort the array, then move each element where indexes of the SORTED matches the UNSORTED.
and I am too lazy to write the code for that and test it right now :) but just a thought of my way of approaching it.
精彩评论