Couldn't find a simple solution for jquery's sortable to keep width of table during dragging element, forcePlaceholderSize is not actually working this time, if table have some large element - if i start dragging it then the table resized to still-in-table element's max width, so here is what I've done:
jQuery("#sortable1").sortable({ items: "tbody:not([not-sortable])", cursor: "move", zIndex: 9999, start: function (event, ui) { var colW = jQuery(".faq_glyph_owner").width(); self.textWidth = ui.item.innerWidth() - colW * 3; jQuery(".faq_text").width(self.textWidth); jQuery("#sortable1").css("table-layout", "fixed"); ui.item.find("div").parent().width(self.textWidth + colW); }, stop: function (event, ui) { jQuery("#sortable1").css("table-layout", "auto"); } });
So i'm generally just counting size as it supposed to be and apply fixed layout to table, here is sample of this with table. So my question is : Is there any built-in ways to keep table width during sorting, as if dragged element is still inside table? Please note that i do not want to keep table's layout fixed.
P.S. please ignore 'jQuery', we just still have legacy prototype code that interferes with it
4 Answers
Answers 1
This is the code I use for this. I create a helper function that gets the height and width of everything in the row and then explicitly sets it to those heights and widths, plus adds a row back in as a placeholder.
var fixHelper = function (e, ui) { ui.children().each(function () { if ($(this).children().length > 0) { fixHelper(e, $(this)); } if(parseInt($(this).css("margin-left")) != 0) $(this).css("margin-left", $(this).css("margin-left")); if (parseInt($(this).css("margin-right")) != 0) $(this).css("margin-right", $(this).css("margin-right")); $(this).width($(this).realWidth(true)); $(this).height($(this).realHeight(true)); }); ui.height(ui.realHeight()); return ui; }; var unfixHelper = function (ui) { ui.children().each(function () { if ($(this).children().length > 0) { unfixHelper($(this)); } $(this).css("margin-left", ""); $(this).css("margin-right", ""); $(this).css("width", ""); $(this).css("height", ""); }); ui.css("height", ""); }; var sortableOptions = new Object({ items: "tbody:not([not-sortable])", cursor: "move", zIndex: 9999, helper: fixHelper, start: function (e, ui) { ui.placeholder.height(ui.item.height()); ui.placeholder.html("<td colspan=\"10\"> </td>"); }, stop: function (e, ui) { unfixHelper(ui.item); ui.placeholder.html(""); } }); jQuery("#sortable1").sortable(sortableOptions);
Another file (real-dimensions.js):
$.fn.realWidth = function (inner) { var $t = $(this); var rect = this[0].getBoundingClientRect(); var width; if (rect.width) { // `width` is available for IE9+ width = rect.width; } else { // Calculate width for IE8 and below width = rect.right - rect.left; } if (inner) width -= parseInt($t.css("padding-left")) + parseInt($t.css("padding-right")); return width; } $.fn.realHeight = function (inner) { var $t = $(this); var rect = this[0].getBoundingClientRect(); var height; if (rect.height) { // `height` is available for IE9+ height = rect.height; } else { // Calculate height for IE8 and below height = rect.top - rect.bottom; } if (inner) height -= parseInt($t.css("padding-top")) + parseInt($t.css("padding-bottom")); return height; }
Answers 2
There is an option called helper in the sortable widget. Its purpose is to add some behaviour to the dragging display action. The relevant part of the modification is:
jQuery('#sortable1').sortable({ helper: fixedWidth }); function fixedWidth(e, ui) { var max_w = 0; // get the max width from all the children ui.children().each(function() { var w = $(this).width(); if (w > max_w) max_w = w; }); // set the width of the table to be the max $('#sortable1').width(max_w); return ui; }
A full implementation can be found in this JSFiddle. I got inspiration from this blog.
Also, if you mind my opinion, I would build this structure in a simpler way, using <ul>
instead of <table>
. Like this. You only have to style the <ul>
in order to have a fixed width.
Answers 3
var fixHelper = function(e, ui) { ui.children().each(function() { console.log(e); $(this).width($(this).width()); }); return ui; }; $("#sortable1 tbody").sortable({ helper: fixHelper }).disableSelection();
Answers 4
How about this:
$("#sortable1").sortable({ items: "tbody:not([not-sortable])", helper: 'clone', cursor: "move", zIndex: 9999, start: function (event, ui) { $(ui.item[0]).show().css('opacity','0'); }, stop: function (event, ui) { $(ui.item[0]).css('opacity','1'); } });
You are basically cloning the element and instead of hiding it whilst moving, you just apply opacity
of 0 and then applying opacity
of 1 once dropped. I didn't really have time to test it.
0 comments:
Post a Comment