Search code examples
javascripthtmljqueryjquery-uijquery-ui-resizable

How to restrict resize minimum height and convert to plain javascript


Javascript report designer band contains absolute positioned fields which can changed in designer.

html:

<div class='designer-panel-body' style='height:100px'>
  <div class='designer-label' style='top:10px'>
    Field1
  </div>
  <div class='designer-label' style='top:60px; left:20px'>
    Field2
  </div>
</div>

CSS:

.designer-panel-body {
  border: solid 1px;
}

.designer-label {
  position: absolute
}

Javascript:

$(".designer-panel-body").resizable({
  start: function(event, ui) {
    $(this).resizable("option", "minHeight", 80)
    },
      handles: "s"
});

Fiddle: https://jsfiddle.net/xk98f2rq/

Band height can also changed by mouse. How to set minimal height so that band height cannot made shorter than last field top position ?

Code in sample uses hard-code value 80 for this. If fields are changed in runtime, for example Field2 is deleted, this value is smaller, so that panel can resized to top of Field1.

How to calculate minHeight is start method? Is it reasonable/how to refactor this code so that it uses plain javascript, without jquery and jquery ui?


Solution

  • By using position: absolute the parent div does not adapt its height to the height of the children. A solution is to compute the height of the children (this includes outerHeight plus offset) in a function get_height() and apply the computed height to the container.

    When removing .designer-label items (by clicking on them) the minHeight of the resizable element is adapted.

    function get_height() {
      var minHeight = 0;
      var h;
      $('.designer-panel-body').find('.designer-label').each(function() {
        h = $(this).outerHeight(true) + $(this).offset().top;
        if (h > minHeight) {
          minHeight = h;
        }
      });
      return minHeight;
    }
    
    $(".designer-panel-body").height(get_height());
    
    $(".designer-panel-body").resizable({
      minHeight: get_height(),
      handles: "s"
    });
    
    $('.designer-label').on('click', function() {
      $(this).remove();
      $(".designer-panel-body").resizable("option", "minHeight", get_height());
    });
    .designer-panel-body {
      border: solid 1px;
      position: relative;
    }
    
    .designer-label {
      position: absolute;
      border: 1px solid blue;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
    <script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.9/jquery-ui.js"></script>
    <link href="https://ajax.microsoft.com/ajax/jquery.ui/1.8.7/themes/black-tie/jquery-ui.css" rel="stylesheet" />
    <div class='designer-panel-body'>
    
      <div class='designer-label' style='top:10px'>
        Field1
      </div>
      <div class='designer-label' style='top:60px; left:20px'>
        Field2
      </div>
    
    </div>