Jasper
Jasper

Reputation: 161

jQuery UI multiple resizable divs not bigger than parent div

I have a parent div. The parent div contains five other divs (next to each other). What I'm trying to do, is making these divs resizable with jQuery UI.

The problem (which makes it difficult for me), is that the resizable width of all five divs can't be bigger than the width of the parent div. For example:

When div 1 is resized from 100px to 200px width, following happened:

I added an example of code and an image below. I used an example I found on StackOverflow and I adjusted it. Why is this example not working correctly? Why are the divs moving to the next line and not stopping at the end of the screen?

Thanks for the help.

Resizable divs

<style>
body, html {
    margin: 0;
    padding: 0;
}
#app {
    width: 100%;
    height: 100%;
}
#resultColumns {
    width: calc(100% - 20px);
    height: calc(100% - 20px);
    padding: 10px;
}
.columnContainer {
    min-width: 100px;
    height: 100%;
    background-color: #eeeeee;
    float: left;
    border-top: 1px solid #333333;
    border-bottom: 1px solid #333333;
    border-left: 1px solid #333333;
}
.lastColumnContainer {
    border-right: 1px solid #333333;
}
.columnHeader {
    font-size: 16px;
    font-weight: bold;
    text-align: center;
}
.columnContent {
    font-size: 14px;
    text-align: left;
}
</style>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
</head>
<link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<html>
    <body>
        <div id="app">
            <div id="resultColumns">
                <!-- First Column -->
                <div class="columnContainer">
                    <div class="columnHeader">Title 1</div>
                    <div class="columnContent">Content 1</div>
                </div>
                <!-- Second Column -->
                <div class="columnContainer">
                    <div class="columnHeader">Title 2</div>
                    <div class="columnContent">Content 2</div>
                </div>
                <!-- Third Column -->
                <div class="columnContainer">
                    <div class="columnHeader">Title 3</div>
                    <div class="columnContent">Content 3</div>
                </div>
                <!-- Fourth Column -->
                <div class="columnContainer">
                    <div class="columnHeader">Title 4</div>
                    <div class="columnContent">Content 4</div>
                </div>
                <!-- Fifth Column -->
                <div class="columnContainer lastColumnContainer">
                    <div class="columnHeader">Title 5</div>
                    <div class="columnContent">Content 5</div>
                </div>
            </div>
        </div>
    </body>
</html>

<script>
    makeResizable();
    function makeResizable() {
        $('#resultColumns .columnContainer:eq(0)').resizable({
            maxWidth: getMaxWidth($('#resultColumns .columnContainer:eq(0)')),
            stop: updateMaxWidth,
            handles: 'e'
        });
        $('#resultColumns .columnContainer:eq(1)').resizable({
            maxWidth: getMaxWidth($('#resultColumns .columnContainer:eq(1)')),
            stop: updateMaxWidth,
            handles: 'e'
        });
        $('#resultColumns .columnContainer:eq(2)').resizable({
            maxWidth: getMaxWidth($('#resultColumns .columnContainer:eq(2)')),
            stop: updateMaxWidth,
            handles: 'e'
        });
        $('#resultColumns .columnContainer:eq(3)').resizable({
            maxWidth: getMaxWidth($('#resultColumns .columnContainer:eq(3)')),
            stop: updateMaxWidth,
            handles: 'e'
        });
        $('#resultColumns .columnContainer:eq(4)').resizable({
            maxWidth: getMaxWidth($('#resultColumns .columnContainer:eq(4)')),
            stop: updateMaxWidth,
            handles: 'e'
        });
    }
    function getMaxWidth(e) {
        return $('#resultColumns').width() - e.siblings().outerWidth() - 10; // 10px for the borders (2px each) - 5 divs in total
    }
    function updateMaxWidth(e, ui) {
        ui.element.siblings().resizable('option', 'maxWidth', getMaxWidth(ui.element.siblings()));
    }
</script>

Upvotes: 0

Views: 512

Answers (1)

Twisty
Twisty

Reputation: 30899

The issue here is that you must calculate the slices for each resizable, including borders. Initially, you're looking at the first element and calculating the maxWidth on the other sibling elements. for your example, that's the other 4 elements.

If you grab one of the other elements, lets say the 3rd one, the other remaining next siblings need to be updated so their maxWidth is the portion remaining.

$(function() {
  function getPad(o, d) {
    return parseInt(o.css("padding-" + d));
  }

  function getMaxWidth(o) {
    var mw = parseInt(o.parent().innerWidth()) - (getPad(o.parent(), "left") + getPad(o.parent(), "right"));
    var sbw = 2; // First & Last Border
    o.siblings(".columnContainer").each(function(i, el) {
      sbw += parseInt($(el).width()) + 1; // Inner Border
    });
    return mw - sbw;
  }

  function makeResizable() {
    $('#resultColumns .columnContainer').resizable({
      handles: 'e',
      maxWidth: getMaxWidth($("#resultColumns .first")),
      resize: function(e, ui) {
        console.log($(this).width(), getMaxWidth($(this)));
      },
      stop: function(e, ui) {
        $(this).siblings().each(function(i, el) {
          $(el).resizable("option", "maxWidth", getMaxWidth($(el)));
        });
      }
    });
  }

  makeResizable();
});
html,
body {
  margin: 0;
  padding: 0;
}

#app {
  width: 100%;
  height: 100%;
}

#resultColumns {
  width: calc(100% - 20px);
  height: calc(100% - 20px);
  padding: 10px;
}

.columnContainer {
  min-width: 100px;
  height: 100%;
  background-color: #eeeeee;
  float: left;
  border-top: 1px solid #333333;
  border-bottom: 1px solid #333333;
  border-left: 1px solid #333333;
}

.last {
  border-right: 1px solid #333333;
}

.columnHeader {
  font-size: 16px;
  font-weight: bold;
  text-align: center;
}

.columnContent {
  font-size: 14px;
  text-align: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />

<div id="app">
  <div id="resultColumns">
    <!-- First Column -->
    <div class="columnContainer first">
      <div class="columnHeader">Title 1</div>
      <div class="columnContent">Content 1</div>
    </div>
    <!-- Second Column -->
    <div class="columnContainer">
      <div class="columnHeader">Title 2</div>
      <div class="columnContent">Content 2</div>
    </div>
    <!-- Third Column -->
    <div class="columnContainer">
      <div class="columnHeader">Title 3</div>
      <div class="columnContent">Content 3</div>
    </div>
    <!-- Fourth Column -->
    <div class="columnContainer">
      <div class="columnHeader">Title 4</div>
      <div class="columnContent">Content 4</div>
    </div>
    <!-- Fifth Column -->
    <div class="columnContainer last">
      <div class="columnHeader">Title 5</div>
      <div class="columnContent">Content 5</div>
    </div>
  </div>
</div>

Upvotes: 1

Related Questions