Friday, February 24, 2017

jQuery sortable keep table's width

Leave a Comment

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\">&nbsp;</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(); 

JSfiddle

Source article

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.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment