'How to make reactstrap modal draggable?

how to make reactstrap modal draggable? I have tried by using react-draggable plugin but it is not working properly. It is work only inner section of whole modal. My code is given below.

if i use < Draggable > component into inner section of < Modal > tag then it is worked and move header text as well as body text. it should be worked for whole modal if anybody there please help me.

import React, { Component } from "react";
import { Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
import Draggable from "react-draggable";

class DraggableModal extends Component {
 render() {
    return (
      <div>
      <Draggable>
        <Modal
          isOpen={this.state.showModal}
          toggle={() => {
            this.setState({ showModal: false });
            this.props.modalClose();
          }}
        >
          <ModalHeader
            className="modal-header bg-primary modal-title text-white"
            toggle={() => {
              this.setState({ showModal: false });
              this.props.modalClose();
            }}
          >
            Test Header
          </ModalHeader>
          {this.state.loading ? <Spinner /> : ""}
          <ModalBody
            style={{
              height: modalSettings.modalBodyHeight + "px"
            }}
          >
            <div
              className="form-group row"             
            >
              <div className="formRow col-sm-12">{this.renderData()}</div>
            </div>
          </ModalBody>
        </Modal>
        </Draggable>
      </div>
    );
  }

}



Solution 1:[1]

Found some issue's in your given link.

You have wrapped Modal, ModalHeader & ModalBody with Draggable separately.

Wrapping ModalHeader & ModalBody with Draggable is of no use and will only create weired behaviour. You need to remove it.

You probably obly need to wrap your Modal with Draggable.


Your Modal is not getting dragged because of the transform property,

.modal-dialog {
    position: absolute;
    top: 50%;
    left: 50%;
    -webkit-transform: translate(-50%, -50%) !important;
    transform: translate(-50%, -50%) !important;
    min-width: 500px !important;
}

Here you have applied !important.

The Draggable internally work with transform property only. When you wrap any element with Draggable, it will apply this CSS,

touch-action: none;
transform: translate(0px, 0px);

And on the basis of drag / cursor position it will update the transform property. As you have alreay applied !important on transform property, this update will have no effect and in result your Modal will not get dragged.

So, by removing CSS of modal-dialog your code will work.


Another suggestion is you have written custom CSS for your Modal.

You need to add bootstrap in your project (reactstrap takes CSS from bootstrap only), which will provide CSS for Modal so that you don't need to write custom CSS.

npm i bootstrap --save

And you can add bootstrap.min.css in index.js file like,

import 'bootstrap/dist/css/bootstrap.min.css';

Demo

Note: If you want your Modal at center of screen, for that you can add custom CSS.

Solution 2:[2]

The simplest solution ever

You just need to wrap your Modal code with Draggable

Steps of the solution:

  1. Install react-draggable package using NPM
npm i react-draggable
  1. import react-draggable to your component:
import Draggable from 'react-draggable';
  1. Wrap you reacstrap modal with this Draggable:
<Draggable>
  <Modal
    isOpen={this.props.isModalOpen}
    toggle={this.props.toggleModal}
    className="gray-header-modal md"
  >
    <ModalHeader>
      <label className="modal-header-title text-dark">Modal Title</label>
      <img
        src="/images/close.png"
        alt="close"
        width="20px"
        className="closeIcon"
        onClick={this.props.toggleModal}
      />
    </ModalHeader>
    <ModalBody>
      <Row>
        <Col>
          // Modal body
        </Col>
      </Row>
    </ModalBody>
  </Modal>
</Draggable>

Solution 3:[3]

My solution is better and very simple, because you can draggable the modal only with the header and so also text marking inside the modal is possible.

The handle class name specifies a selector to be used as the handle that initiates drag.

import { Modal, ModalHeader, ModalBody } from "reactstrap";
import Draggable from "react-draggable";

...

<Draggable handle=".handle">
  <Modal size="lg" toggle={function noRefCheck(){}}>
    <ModalHeader toggle={function noRefCheck(){}} className="handle">
      Modal Title
    </ModalHeader>
    <ModalBody>
      Modal Body
    </ModalBody>
  </Modal>
</Draggable>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Ibrahim AlRayyan
Solution 3