Reputation: 376
I'm trying to adapt this code to my li lists.
[
I sketched something that shows the exact logic.
Clicked element goes first!
Second element clicked goes first but the preview cliched goes last.
This is the code:
$('ul li').each(function() {
var $this = $(this).data({
position: $(this).index()
}),
$table = $this.closest('ul'),
$input = $this.find('input');
$input.bind('click', function(e) {
var $first = $table.find('li:first'),
position;
if ($(this).is(':checked')) {
position = $first.data('position');
$table.find('li input').not($(this)).removeAttr('checked');
if (position != 0) $first.insertAfter($table.find('li').eq(position));
$this.prependTo($table);
} else if ($this.data('position') != 0) {
position = $this.data('position');
$this.insertAfter($table.find('li').eq(position));
}
});
});
I have the code below that works with tables but I'd like to implement this on a ul li. Is there a way to make the checkbox input becoming a li or a anchor tag?
Upvotes: 3
Views: 1652
Reputation: 6606
Based on your example I assume you don't have control on the html source and you want to change the table to a list dynamically.
Here is an example (commented) based on your code and original example html.
Pretty straight forward:
//Unique table selector that is targeted to be parsed and replaced:
var $targetTable = $("table");
//This is the target new list that will store the list items:
var $sudoul = $("<ul></ul>");
//Toggle through all the rows and create a list item:
$targetTable.find('tr').each(function () {
$sudoul.append($("<li style='border:1px solid black; cursor:pointer'>" + $(this).text() + "</li>")
//This binds a click event to the new LI stored in $sudoul
.bind("click", function(){
//if we click the first element avoid and don't to anything:
if ($(this).is(':first-child')) return;
var $container = $(this).closest("ul");
var $this = $(this); // The clicked item to move UP.
var $first = $container.find("li").eq(0); // The first list item to be replaced.
//First move the item to the head of the list:
$container.prepend($this.data("alreadyclicked", true));
//Check if the first element was already moved the append it to the end of the list
if ($first.data("alreadyclicked")) $container.append($first);
})
.data({alreadyclicked: false }) // this flag is set to true when the element is clicked
);
});
//Replace the table with the newly created list:
$targetTable.replaceWith($sudoul);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td><input type="checkbox" /></td>
<td>1</td>
</tr>
<tr>
<td><input type="checkbox" /></td>
<td>3</td>
</tr>
<tr>
<td><input type="checkbox" /></td>
<td>A</td>
</tr>
<tr>
<td><input type="checkbox" /></td>
<td>B</td>
</tr>
<tr>
<td><input type="checkbox" /></td>
<td>C</td>
</tr>
</tbody>
</table>
Upvotes: 1
Reputation: 6966
If you don't want to use checkbox but use simple tags, see this example:
See in JSFiddler: http://jsfiddle.net/nfywg06b/5/
I have not renamed the variables so that it is easy to understand the important adjustments.
Use the goToLast
variable to define the behavior: Send to last position or change position (legacy behavior)
jQuery:
var goToLast = true;
$('.item').each(function() {
var $this = $(this).data({
position: $(this).index()
}),
$table = $this.closest('.container'),
$input = $this;
$input.bind('click', function(e) {
$input.toggleClass('selected');
var $first = $table.find('.item:first'),
position;
if ($(this).hasClass('selected')) {
position = !goToLast ? $first.data('position') : $table.children().length - 1;
$table.find('.item').not($(this)).removeClass('selected');
if (position != 0) $first.insertAfter($table.find('.item').eq(position));
$this.prependTo($table);
} else if ($this.data('position') != 0) {
position = $this.data('position');
$this.insertAfter($table.find('.item').eq(position));
}
});
});
HTML:
<div class="container">
<a href="#" class="item">1</a>
<a href="#" class="item">3</a>
<a href="#" class="item">A</a>
<a href="#" class="item">B</a>
<a href="#" class="item">C</a>
</div>
CSS:
a.item {
display: block;
background-color: silver;
border: 1px solid gray;
padding: 10px;
margin: 10px;
}
a.item.selected {
background-color: green;
}
Upvotes: 1
Reputation: 6966
Making some adjustments in your JSFiddle code is working like this:
See the example here: http://jsfiddle.net/z0bga89t/
See de HTML code above:
<ul>
<li>
<input type="checkbox" />
1
</li>
<li>
<input type="checkbox" />
3
</li>
<li>
<input type="checkbox" />
A
</li>
<li>
<input type="checkbox" />
B
</li>
<li>
<input type="checkbox" />
C
</li>
</ul>
And jQuery:
$('li').each(function () {
var $this = $(this).data({position: $(this).index()}),
$table = $this.closest('ul'),
$input = $this.find('input');
$input.bind('click', function (e) {
var $first = $table.find('li:first'),
position;
if ($(this).is(':checked')) {
position = $first.data('position');
$table.find('li input').not($(this)).removeAttr('checked');
if (position != 0) $first.insertAfter($table.find('li').eq(position));
$this.prependTo($table);
} else if ($this.data('position') != 0) {
position = $this.data('position');
$this.insertAfter($table.find('li').eq(position));
}
});
});
Note that just changing the corresponding tags:
Upvotes: 1