Created
February 1, 2013 13:09
-
-
Save jpic/4691211 to your computer and use it in GitHub Desktop.
KISS jQuery plugin for table column reorganisation via drag'n'drop. Requires jquery-ui with draggable and droppable support of course.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% block extra_head %} | |
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}fusion/table.css" /> | |
{% endblock %} | |
{% block extra_body %} | |
{% block jquery_ui %} | |
<script src="{{ STATIC_URL }}fusion/jquery-ui.js" type="text/javascript"></script> | |
{% endblock %} | |
<script type="text/javascript" src="{{ STATIC_URL }}fusion/table.js"></script> | |
<script type="text/javascript"> | |
$('.bloc-content table') | |
.on('columnMoved', function(e) { | |
var table = $(this).yourlabsTable(); | |
if (table.xhr) table.xhr.abort(); | |
data = { | |
columns: [], | |
}; | |
table.table.find('[data-widget-pk]').each(function() { | |
if ($(this).parents('table.helper').length) return; | |
data.columns.push({widget_pk: $(this).data('widget-pk')}) | |
}); | |
table.xhr = $.ajax('{% url 'fusion_list_update' object.pk %}', { | |
'data': {data: JSON.stringify(data)}, | |
'type': 'POST', | |
}) | |
}) | |
.yourlabsTable(); | |
}); | |
</script> | |
{% endblock %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.dragging { | |
display: none; | |
} | |
.resize-handle { | |
float: right; | |
} | |
.droppable-target { | |
background-color: green; | |
} | |
.helper { | |
width: 80px; | |
} | |
.placeholder { | |
width: 0px; | |
} | |
.placeholder.active { | |
width: 2px; | |
background-color: #90EE90; | |
border-color: #90EE90; | |
} | |
.placeholder.usable.active { | |
background-color: green; | |
border-color: green; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if (window.yourlabs == undefined) window.yourlabs = {}; | |
// Resizing is temporarely disabled because the browser ignores it. | |
yourlabs.Table = function(table) { | |
// <table> element. | |
this.table = table; | |
// Index of the column being drag. | |
this.dragIndex = null; | |
// Index of the column being hovered or drop on. | |
this.dropIndex = null; | |
// Resize column handle which will be appended to th. | |
// this.resizeHandleHtml = '<span class="handle resize-handle"></span>'; | |
// Selector string for resizeHandleHtml. | |
// this.resizeHandleSelector = '.resize-handle'; | |
// Drag column handle which will be prepended to th. | |
this.dragHandleHtml = '<span class="handle drag-handle"></span>'; | |
// Selector string for dragHandleHtml. | |
this.dragHandleSelector = '.drag-handle'; | |
// CSS class for the column being drag. Will be set on all td, ths. | |
this.dragColumnClass = 'dragging'; | |
// Selector string for the column being drag. | |
this.dragColumnSelector = '.' + this.dragColumnClass; | |
// HTML used to create the semi transparent drag helper. It will be filled | |
// with copies of the contents of the column being drag. | |
this.helperTableHtml = '<table class="helper">'; | |
// Cell HTML used to create placeholder columns. | |
this.placeholderHtml = '<td class="placeholder"></td>'; | |
// Selector string for placeholderHtml | |
this.placeholderSelector = '.placeholder'; | |
// CSS class that should be added to placeholder when they become active. | |
this.placeholderActiveClass = 'active'; | |
// Selector string for active placeholders | |
this.placeholderActiveSelector = [ | |
this.placeholderSelector, | |
'.', | |
this.placeholderActiveClass | |
].join('') | |
} | |
yourlabs.Table.prototype.initialize = function() { | |
this.table.find('th') | |
.prepend(this.dragHandleHtml) | |
.draggable({ | |
cursor: 'move', | |
helper: $.proxy(this.dragHelper, this), | |
start: $.proxy(this.dragStart, this), | |
stop: $.proxy(this.dragStop, this), | |
handle: this.dragHandleSelector, | |
tolerance: 'pointer', | |
opacity: 0.65, | |
axis: 'x', | |
}); | |
this.createPlaceholders(); | |
this.table.find('th, td') | |
.droppable({ | |
greedy: true, | |
tolerance: 'pointer', | |
over: $.proxy(this.dropOver, this), | |
drop: $.proxy(this.dragStop, this), | |
}); | |
// this.table.find('th') | |
// .append(this.resizeHandleHtml) | |
// $(this.resizeHandleSelector) | |
// .on('mousedown', $.proxy(this.resizeStart, this)) | |
// $(document) | |
// .on('mousemove', $.proxy(this.resize, this)) | |
// .on('mouseup', $.proxy(this.resizeStop, this)) | |
// this.createPlaceholders(); | |
} | |
// yourlabs.Table.prototype.resizeStart = function(e) { | |
// this.resizing = $(e.currentTarget).parents('th, td'); | |
// this.initialX = e.pageX; | |
// this.initialWidth = this.resizing.width(); | |
// } | |
// yourlabs.Table.prototype.resize = function(e) { | |
// if(this.resizing !== false) { | |
// $(this.resizing).width(this.initialWidth+(e.pageX-this.initialX)); | |
// } | |
// } | |
// yourlabs.Table.prototype.resizeStop = function(e) { | |
// if(this.resizing !== false) { | |
// this.resizing = false; | |
// } | |
// } | |
// Remove all placeholder cells. | |
yourlabs.Table.prototype.removePlaceholders = function() { | |
this.table.find(this.placeholderSelector).remove() | |
} | |
// Create a placeholder column after each actual column. | |
yourlabs.Table.prototype.createPlaceholders = function() { | |
this.table.find('th, td').before(this.placeholderHtml); | |
this.table.find('tr').append(this.placeholderHtml) | |
} | |
yourlabs.Table.prototype.dragHelper = function(e) { | |
this.dragIndex = $(e.currentTarget).index() + 1; | |
var rows = []; | |
this.getColumn(this.dragIndex).each(function() { | |
rows.push('<tr>') | |
rows.push($('<tr>').html($(this).clone()).html()); | |
rows.push('</tr>') | |
}) | |
return $(this.helperTableHtml).html(rows.join('')); | |
} | |
// On drag start, note the dragged column index and set dragColumnClass. | |
yourlabs.Table.prototype.dragStart = function(e, ui) { | |
this.dragIndex = $(e.currentTarget).index() + 1; | |
this.getColumn(this.dragIndex).addClass(this.dragColumnClass); | |
} | |
// On drag stop, get the drop column index, move the cells, trigger columnMoved | |
// and clean up. | |
yourlabs.Table.prototype.dragStop = function(e, ui) { | |
if (this.dragIndex == null) { | |
// dragStop was already called. | |
return; | |
} | |
this.dropIndex = this.table.find( | |
this.placeholderActiveSelector + ':first').index(); | |
this.table.find(this.placeholderActiveSelector) | |
.removeClass(this.placeholderActiveClass) | |
this.table.find(this.dragColumnSelector) | |
.removeClass(this.dragColumnClass); | |
var dragColumn = this.getColumn(this.dragIndex); | |
var dropColumn = this.getColumn(this.dropIndex); | |
for (var i=0; i<dragColumn.length; i++) { | |
$(dragColumn.get(i)).insertAfter(dropColumn.get(i)) | |
} | |
this.dragIndex = null; | |
this.dropIndex = null; | |
this.removePlaceholders(); | |
// Trigger columnMoved while the table is clean from fake columns. | |
this.table.trigger('columnMoved'); | |
this.createPlaceholders(); | |
} | |
// Return all cells of a particular column. | |
yourlabs.Table.prototype.getColumn = function(index) { | |
return this.table.find( | |
'td:nth-child(' + index + '), th:nth-child(' + index + ')'); | |
} | |
// On drop over, update active placeholder. | |
yourlabs.Table.prototype.dropOver = function(e, ui) { | |
this.dropIndex = $(e.target).index() + 1; | |
this.activePlaceholder = this.dropIndex + 1; | |
this.table.find(this.placeholderSelector) | |
.removeClass(this.placeholderActiveClass) | |
this.getColumn(this.activePlaceholder) | |
.addClass(this.placeholderActiveClass) | |
} | |
$.fn.yourlabsTable = function(overrides) { | |
if (this.length < 1) return; | |
var overrides = overrides ? overrides : {}; | |
if (this.data('yourlabsTable') == undefined) { | |
var table = new yourlabs.Table(this); | |
table = $.extend(table, overrides); | |
this.data('yourlabsTable', table); | |
table.initialize(); | |
} | |
return this.data('yourlabsTable'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment