45

I would like to be able to move around (on the greyed-out background, by dragging and dropping) the modal form that is provided by Bootstrap 2. Can anyone tell me what the best practice for achieving this is?

LukeP
  • 10,422
  • 6
  • 29
  • 48
AndraD
  • 2,830
  • 6
  • 38
  • 48

5 Answers5

91

The bootstrap doesn't come with any dragging and dropping functionality by default, but you can add a little jQuery UI spice into the mix to get the effect you're looking for. For example, using the draggable interaction from the framework you can target your modal ID to allow it to be dragged around within the modal backdrop.

Try this:

JS

$("#myModal").draggable({
    handle: ".modal-header"
});

Demo, edit here.

Update: bootstrap3 demo

Andres I Perez
  • 75,075
  • 21
  • 157
  • 138
9

Whatever draggable option you go for, you might want to turn off the *-transition properties for .modal.fade in bootstrap’s CSS file, or at least write some JS that temporarily disables them during dragging. Otherwise, the modal doesn’t drag exactly as you would expect.

user535673
  • 908
  • 1
  • 9
  • 13
  • 2
    this issue discussed and solved at http://stackoverflow.com/questions/15881245/draggable-js-bootstrap-modal-performance-issues – bbodenmiller Jun 17 '13 at 18:34
3

You can use a little script likes this.

simplified from Draggable without jQuery UI

    (function ($) {
        $.fn.drags = function (opt) {

            opt = $.extend({
                handle: "",
                cursor: "move"
            }, opt);

            var $selected = this;
            var $elements = (opt.handle === "") ? this : this.find(opt.handle);

            $elements.css('cursor', opt.cursor).on("mousedown", function (e) {
                var pos_y = $selected.offset().top - e.pageY,
                  pos_x = $selected.offset().left - e.pageX;
                $(document).on("mousemove", function (e) {
                    $selected.offset({
                        top: e.pageY + pos_y,
                        left: e.pageX + pos_x
                    });
                }).on("mouseup", function () {
                    $(this).off("mousemove"); // Unbind events from document                
                });
                e.preventDefault(); // disable selection
            });

            return this;

        };
    })(jQuery);

example : $("#someDlg").modal().drags({handle:".modal-header"});

  • 1
    Your code is outdated. Tried your code and it worked, but dragging is buggy. Fixed it by getting the code from the link above. Please update your code, based from the one from the link. – Leonardo Montenegro Aug 05 '15 at 20:16
1

Building on previous answers utilizing jQuery UI, this, included once, will apply to all your modals and keep the modal on screen, so users don't accidentally move the header off screen so they can no longer access the handle. Also sets the cursor to 'move' for better discoverability.

$(document).on('shown.bs.modal', function(evt) {
    let $modal = $(evt.target);
    $modal.find('.modal-content').draggable({
        handle: ".modal-header",
        containment: $modal
    });
    $modal.find('.modal-header').css('cursor', 'move')
});

evt.target is the .modal which is the translucent overlay behind the actual .modal-content.

Felix Böhme
  • 508
  • 5
  • 12
0

jquery UI is large and can conflict with bootstrap.

An alternative is DragDrop.js: http://kbjr.github.io/DragDrop/index.html

DragDrop.bind($('#myModal')[0], {
  anchor: $('#myModal .modal-header')
});

You still have to deal with transitions, as @user535673 suggests. I just remove the fade class from my dialog.

Bryan Larsen
  • 9,468
  • 8
  • 56
  • 46