Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set the containment on a jQuery UI Dialog?

Is it possible to add containment (confining to the boundary of another element) to jQuery UI's Dialog?

like image 754
PPPHP Avatar asked May 25 '10 10:05

PPPHP


3 Answers

@Mottie's on the right track, but there's a simpler and better solution:

var container = $('.dialog-container'),
    dialog = $('.ui-dialog');
dialog.draggable( "option", "containment", container );

Unlike Mottie's solution, this will not break if the viewport resizes. I've forked the JSFiddle here.

like image 58
Mac Avatar answered Sep 24 '22 12:09

Mac


@Mac's on the right track, but the solution is not complete. You must also set the containment of the dialog's Resizable widget. If you only set the Draggable, you'll get containment when you drag, but when you grab the edges and resize you'll still go out of bounds.

So you'll want to do this, assuming #mydialog is the element you initially created the dialog from, and #boundary is the element you wish to confine it to (by the way, the container parameter can also be a selector):

let ui = $('#mydialog').closest('.ui-dialog');       // get parent frame
ui.draggable('option', 'containment', '#boundary');  // <-- drag, but not resize
ui.resizable('option', 'containment', '#boundary');  // <-- don't forget!!!

Here's an example snippet, toggle the checkboxes to switch the corresponding widget's confinement between 'document' (the default), and '#area'. Then experiment both with dragging the dialog by its title bar, and resizing it by its edges. Note what happens when you only select "Confine drag":

// Create dialog from #win with mostly default options.
$('#win').dialog({
  width: 200,
  height: 150,
  position: { my: 'center', at: 'center', of: '#area' }
});

// When checkbox changed, update confinement settings.
$('#draggable, #resizable').change(function () {
  let d = $('#draggable').prop('checked');
  let r = $('#resizable').prop('checked');
  let ui = $('#win').closest('.ui-dialog');
  ui.draggable('option', 'containment', d ? '#area' : 'document');
  ui.resizable('option', 'containment', r ? '#area' : 'document');
});
#area {
  position: relative;
  left: 2ex;
  top: 2ex;
  width: 400px;
  height: 300px;
  border: 1px solid red;
}

#win {
  font-size: 10pt;
  display: flex;
  flex-direction: column;
}

label {
  display: flex;
  align-items: center;
}
<head>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
  <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
</head>

<body>
  <div>Example</div>
  <div id="area"></div>
  <div id="win" title="test">
    <label><input type="checkbox" id="draggable">Contain drag</label>
    <label><input type="checkbox" id="resizable">Contain resize</label>
  </div>
</body>
like image 37
Jason C Avatar answered Sep 21 '22 12:09

Jason C


You could target the dialog box and apply a containment to it. Try this:

var container = $('.dialog-container'),
    dialog = $('.ui-dialog');
// get container top left corner locations
var cx1 = container.offset().left,
    cy1 = container.offset().top;
// get dialog size
var dw = dialog.outerWidth(),
    dh = dialog.outerHeight();
// get container bottom right location, then subtract the dialog size
var cx2 = container.width() + cx1 - dw,
    cy2 = container.height() + cy1 - dh;
dialog.draggable( "option", "containment", [cx1, cy1, cx2, cy2] );

Edit: I set up a demo for you.
Edit2: Changed to use dialog outerWidth & outerHeight

like image 21
Mottie Avatar answered Sep 23 '22 12:09

Mottie