Search code examples
javascriptjquery-uijquery-ui-resizable

jQuery UI - prevent resizing of dialog outside the parent div


PROBLEM: When doing resize on dialog, I want to prevent it from going outside parent div dialog-container. For some reason containment is not working as I expected. What else can I try?

enter image description here

HTML:

<div id="top"></div>
<div id="dialog-container">
  <div id="dialog">My dialog</div>
</div>

JS:

$(document).ready(function() {
    jQuery("#dialog").dialog({
                            autoOpen:true,
                            modal: false,
                            resizable: true,
                            draggable: true,
                            closeOnEscape: true,
                            title: "Title",
        open: function(){
            jQuery('.ui-widget-overlay').bind('click',function(){
                jQuery('#dialog').dialog('close');
            })
        }
    }).parent().draggable({
        containment: '#dialog-container'
    }).resizable({
        containment: '#dialog-container'
    });
});

JSFIDDLE: https://jsfiddle.net/4zfmbktr/


Solution

  • First, I would STRONGLY advise moving to a newer jQuery UI Library. I found a lot of strange issues with the jQuery UI 1.8.18 selected in your Fiddle.

    One of the things I found was that it was ignoring options applied to the resizable. If you read this article, it talks about how to set this option. Jump top the answer by Jason C. So that is where I started:

    JavaScript

    $(function() {
      $("#dialog").dialog({
        autoOpen: true,
        modal: false,
        resizable: false,
        draggable: true,
        closeOnEscape: true,
        title: "Title",
        open: function() {
          $('.ui-widget-overlay').bind('click', function() {
            $('#dialog').dialog('close');
          })
        }
      });
      var ui = $("#dialog").closest(".ui-dialog");
      ui.draggable("option", "containment", '#dialog-container');
      ui.resizable("option", "containment", '#dialog-container');
    });
    

    This did not work. Draggable containment worked, but resize containment failed HARD. I blame 1.8.18. I might test this again with the modern 1.12.1 just to see.

    This does not mean you cannot use 1.8.18, if you can't change your library, here is a work around. There are caveats here.

    Working example: https://jsfiddle.net/Twisty/2vaf3dr5/39/

    JavaScript

    $(function() {
      $("#dialog").dialog({
        autoOpen: true,
        modal: false,
        resizable: false,
        draggable: true,
        closeOnEscape: true,
        title: "Title",
        open: function() {
          $('.ui-widget-overlay').bind('click', function() {
            $('#dialog').dialog('close');
          })
        }
      });
      var ui = $("#dialog").closest(".ui-dialog");
      ui.draggable("option", "containment", '#dialog-container');
      ui.resizable({
        handles: "n, e, s, w, se",
        minHeight: 150,
        minWidth: 150,
        resize: function(e, ui) {
          var contPos = $("#dialog-container").position();
          contPos.bottom = contPos.top + $("#dialog-container").height();
          contPos.right = contPos.left + $("#dialog-container").width();
          contPos.height = $("#dialog-container").height();
          contPos.width = $("#dialog-container").width();
          if (ui.position.top <= contPos.top) {
            ui.position.top = contPos.top + 1;
          }
          if (ui.position.left <= contPos.left) {
            ui.position.left = contPos.left + 1;
          }
          if (ui.size.height >= contPos.height) {
            ui.size.height = contPos.height - 7;
          }
          if (ui.size.width >= contPos.width) {
            ui.size.width = contPos.width - 7;
          }
        }
      });
    });
    

    I stripped away the pre-configured resizable option in dialog and wrote out the options directly. Again, containment didn't work here, so I had to make my own custom resize logic. In the end, this does what you'd expect.

    One of the oddities or caveats, is that it's reading mouse movement and will continue to do so even when the mouse has exceeded the boundaries. So the Top and Left stop... but the width and height continue to grow. I do not know why and you know where I will point the finger.

    I did try switching your libraries and the resize is... a bit better. Still odd with height but not with width. See here: https://jsfiddle.net/Twisty/2vaf3dr5/44/

    That should get you going, I hope it helps.