1

I have a problem and I want to do that can move 3 div (more later) to move in the X axis min and max have a position relative to the container. Initially works well but when you start moving the separators several times begins the problem, does not respect the minimum or the maximum, I wonder if someone can help me to know what could be the problem (They can check in the browser console where the values ​​are updated according to move the separators are.) https://jsfiddle.net/66un403y/

$( document ).ready(function() {

$(function(){
   var A = parseInt($('#A').width()),
       B = parseInt($('#B').width()),
       C = parseInt($('#C').width()),

       minw       = parseInt((A + B + C) * 10 / 100), //  min 10 percentage
       offset     = $('#container').offset(),
       containw   = $('#container').outerWidth(),
       splitter_1 = $('#container').outerWidth() / 3;
       splitter_2 = (($('#container').outerWidth() / 3) * 2);

       $("#min_width").text(minw + "px");

       splitter = function(event, ui){
            $( '#DragContent' ).unbind( 'draggable' );
            A = parseInt(ui.position.left);
            B = Math.abs(containw - A - C);
            C = containw - A - B;

            splitter_1 = ui.position.left;
            splitter_2 = splitter_2;
            console.log("A:" + A);
            console.log("B:" + B);
            console.log("C:" + C);
            console.log("splitter_1:" + splitter_1);
            console.log("splitter_2:" + splitter_2);
            console.log("offset.left:"+offset.left);
            console.log("ui.position.left:"+ ui.position.left);
            console.log("max:"+ (A + B - minw));
            console.log("min:"+ ( minw ));

            // update the new limits
            //$( '#X' ).unbind( 'draggable' );
            $( '#X' ).draggable({
              containment : [
                 offset.left + minw,
                 offset.top,
                 offset.left + C + B - minw,
                 offset.top + $('#container').height()
            ]});


           //set widths and information...
           $('#A').css({width : A}).children().text("current px: " + A);
           $('#B').css({width : B}).children().text("current px: " + B);
           $('#C').css({width : C}).children().text("current px: " + C);;
       };
       splitter2 = function(event, ui){


          C = containw - (ui.position.left);
            B = Math.abs( ui.position.left - A );//parseInt(ui.position.left) - A - C;
          A = containw - (B + C);

         splitter_1 = splitter_1;
         splitter_2 = ui.position.left;
         console.log("A:" + A);
         console.log("B:" + B);
         console.log("C:" + C);
         console.log("splitter_1:" + splitter_1);
         console.log("splitter_2:" + splitter_2);
         console.log("offset.left:"+offset.left);
         console.log("ui.position.left:"+ ui.position.left);
         console.log("limite:"+ (containw - minw));
         console.log("minimo:"+ ( A + minw ));



         // update the new limits
         //$( '#X' ).unbind( 'draggable' );
         $('#Z').draggable({
          containment : [
             offset.left + A + minw,
             offset.top,
             offset.left + containw - minw,
             offset.top + $('#container').height()
        ]});
         $('#A').css({width : A}).children().text("current px: " + A);
         $('#B').css({width : B}).children().text("current px: " + B );
         $('#C').css({width : C}).children().text("current px: " + C  );

       };

   $('#X').draggable({
      axis : 'x', 
      drag : splitter,
      containment : [
                   offset.left + minw,
                   offset.top,
                   offset.left + C + B - minw,
                   offset.top + $('#container').height()
              ]
   });

   $('#Z').draggable({
       axis : 'x',
       drag : splitter2,
       containment : [
             offset.left + A + minw,
             offset.top,
             offset.left + containw - minw,
             offset.top + $('#container').height()
        ]
   });


   //information...
   $('#width').text(A + B + C);
   $('#A div').text("current px: " + A );
   $('#B div').text("current px: " + B );
   $('#C div').text("current px: " + C );
   console.log();
});

});
Lenin Zapata
  • 1,417
  • 1
  • 11
  • 14

1 Answers1

1

Sorry for not coping with your exact code, but just to show you how I'd create

Resizable sibling containers

jsBin demo

Will handle any number of resizable boxes, and keep them Responsive thanx to the width conversion back to % on resize end:

var minWidth = 50, // Set here the minimal resize width
    $box = $(".box"),
    $cont = $box.parent(),

    startX = 0,
    isDrag = false,

    $that, thatW = 0,
    $next, nextW = 0;

$(".resizeHandler").on('mousedown', function( e ) {

  isDrag = true;
  startX = e.pageX;

  $that = $(this).closest(".box");
  thatW = $that.width();

  $next = $that.next(".box");
  nextW = $next.width();
  
  $box.css({userSelect: isDrag?'none':'auto'});

});

$(document).on('mousemove', function( e ) {

  if(!isDrag) return;
  var x = e.pageX;

  var nextWNew = Math.max(minWidth, nextW + startX - x);
  var thatWNew = Math.max(minWidth, thatW + x - startX);
  if(thatWNew <= 50) return thatWNew = minWidth;
  if(nextWNew <= 50) return nextWNew = minWidth;
  $that.width(thatWNew);
  $next.width(nextWNew);

}).on("mouseup", function() {

  isDrag = false;
  // Convert widths to percent (to keep responsiveness)
  var contW = $cont.width();
  $box.css("width", function(i, w){
    return (parseInt(w,10) / contW * 100) +"%";
  });

});
*{margin:0;box-sizing:border-box;}html,body{height:100%;font:14px/1.4 sans-serif;}

.box {
  width: 33.333%;
  float: left;
  background: #eee;
  position: relative;
}
.box:last-child .resizeHandler {
  display:none;
}
.boxContent{
  padding: 16px;
  height: 200px;
  overflow: hidden;
  overflow-y: auto;
}
.resizeHandler {
  position: absolute;
  z-index:2;
  top: 0;
  height: 100%;
  width: 6px;
  right: -6px;
  background: blue;
  cursor: e-resize;
} .resizeHandler:hover {
  background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="boxes">
  
  <div class="box">
    <div class="boxContent">
      Adipisicing elit. Distinctio numquam accusantium perspiciatis quis ipsam modi optio odio quaerat magni! Repellendus, maxime voluptatum et sunt nobis, quae consequatur minus? Ducimus, voluptate!
    </div>
    <div class="resizeHandler"></div>
  </div>
  
  <div class="box">
    <div class="boxContent">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit.
    </div>
    <div class="resizeHandler"></div>
  </div>
  
  <div class="box">
    <div class="boxContent">
      Sit amet, consectetur adipisicing elit. Asperiores porro, ut aliquam, laudantium esse pariatur nihil provident vero quam excepturi. Incidunt fugit sit nihil, exercitationem sequi obcaecati, error impedit aspernatur!
    </div>
    <div class="resizeHandler"></div>
  </div>
  
</div>

As you can see I moved the handlers inside each box.
On handler drag/move I target / modify the width of the handler's parent box and the width of the next sibling box. That's pretty much it. The code should be pretty self-explanatory, but as always, if you have questions feel free to ask.


Adding .box and .row dynamically:

Here's an example with dynamic BOX and ROW creation: jsBin demo

var minWidth = 50, // Set here the minimal resize width
    $box = $(".box"),
    $cont = $box.parent(),

    startX = 0,
    isDrag = false,

    $that, thatW = 0,
    $next, nextW = 0;




// GRIDDER ////////////////
var $selectedBox = null,
    $selectedRow = null,
    b = 0;

function newBox() {
  return $("<div/>", {
    class: "box",
    css: {width:"100%"},
    html : "<div class='boxContent' contenteditable>BOX "+ (b++) +"</div>"+
    "<div class='resizeHandler'></div>"
  });
}

$(document).on("click", ".box", function(){

  $selectedBox = $(this);
  $selectedRow = $selectedBox.closest(".row");

}).on("click", "#addRow", function() {

  if(!$selectedBox) return alert("Select a box first");
  $("<div/>", {
    class: "row",
    append: newBox(),
    insertAfter: $selectedRow
  });

}).on("click", "#addBox", function() {

  if(!$selectedBox) return alert("Select a box first");
  var $newBox = newBox();
  $selectedBox.after($newBox);

  var $rowBoxes = $selectedRow.find(".box"),
      totBoxes = $rowBoxes.length;

  $rowBoxes.css("width", function(i, w){
    return (100/totBoxes) +"%";
  });

});



// RESIZER ////////////////

$(document).on('mousemove', ".row", function( e ) {

  if(!isDrag) return;
  var x = e.pageX;

  var nextWNew = Math.max(minWidth, nextW + startX - x);
  var thatWNew = Math.max(minWidth, thatW + x - startX);
  if(thatWNew <= 50) return thatWNew = minWidth;
  if(nextWNew <= 50) return nextWNew = minWidth;
  $that.width(thatWNew);
  $next.width(nextWNew);

}).on('mousedown', ".resizeHandler", function( e ) {

  isDrag = true;
  startX = e.pageX;

  $that = $(this).closest(".box");
  thatW = $that.width();

  $next = $that.next(".box");
  nextW = $next.width();

  $box.css({userSelect: isDrag?'none':'auto'});

}).on("mouseup", function() {

  isDrag = false;
  // Convert widths to percent (to keep responsiveness)
  var contW = $cont.width();
  $box.css("width", function(i, w){
    return (parseInt(w,10) / contW * 100) +"%";
  });

})
*{margin:0;box-sizing:border-box;}html,body{height:100%;font:14px/1.4 sans-serif;}

.row{
  clear:both;
  margin:10px 0;
  overflow:auto;
}
.box {
  width: 25%;
  float: left;
  background: #eee;
  position: relative;
}
.box:last-child .resizeHandler {
  display:none;
}
.boxContent{
  padding: 16px;
  height: 200px;
  overflow: hidden;
  overflow-y: auto;
}
.resizeHandler {
  position: absolute;
  z-index:2;
  top: 0;
  height: 100%;
  width: 6px;
  right: -6px;
  background: #448;
  cursor: e-resize;
} .resizeHandler:hover {
  background: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="addRow">ADD ROW AFTER</button>
    <button id="addBox">ADD BOX AFTER</button>

    <div id="page">
      <div class="row">
        <div class="box">
          <div class="boxContent" contenteditable>
            Adipisicing elit. Distinctio numquam accusantium perspiciatis quis ipsam modi optio odio quaerat magni! Repellendus, maxime voluptatum et sunt nobis, quae consequatur minus? Ducimus, voluptate!
          </div>
          <div class="resizeHandler"></div>
        </div>
        <div class="box">
          <div class="boxContent" contenteditable>
            Sit amet, consectetur adipisicing elit. Asperiores porro, ut aliquam, laudantium esse pariatur nihil provident vero quam excepturi. Incidunt fugit sit nihil, exercitationem sequi obcaecati, error impedit aspernatur!
          </div>
          <div class="resizeHandler"></div>
        </div>
        <div class="box">
          <div class="boxContent" contenteditable>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit.
          </div>
          <div class="resizeHandler"></div>
        </div>
        <div class="box">
          <div class="boxContent" contenteditable>
            Ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus non officia illum odit, optio inventore ad vero eos sed voluptas recusandae vel quod natus magnam totam quos, repellat mollitia veniam!
          </div>
          <div class="resizeHandler"></div>
        </div>
      </div>
    </div>
Community
  • 1
  • 1
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
  • How could make this dynamic ?, I worked hard to do it in 3 columns but want something dynamic that is a function wants the boxes add_row_column(3 or 2 or 1 or 4) fit the number of columns. example. http://i.imgur.com/X4eUN60.jpg I can add each row through jquery.append but I want you to help me with a function within that div container have the number of columns per row needs, please – Lenin Zapata Nov 07 '16 at 00:36
  • @iLen yep, for dynamically appending `.box` inside every `.boxes` you should tweak a bit the above code. I'll show you how – Roko C. Buljan Nov 07 '16 at 00:38
  • If please you help me a lot if you add columns 1 function dynamically, I hope your code, thanks – Lenin Zapata Nov 07 '16 at 01:17
  • @iLen something like this? http://jsbin.com/lurawu/11/edit?html,css,js,console,output – Roko C. Buljan Nov 07 '16 at 01:23
  • staying well, you're very good. I would like to work like this in the picture, I think very quick and easy c'mon as it is your code, you could help me it looks like the image? http://i.imgur.com/80ImJG2.png pd: I're helping a lot, I d.o.n.a.te in some mail? – Lenin Zapata Nov 07 '16 at 02:08
  • @iLen Should not be hard to achieve what you want with the provided code. – Roko C. Buljan Nov 07 '16 at 02:10
  • You will do that change much faster than me, please help. One question, which is the variable that has the value of the width of each box? – Lenin Zapata Nov 07 '16 at 02:32