title: React beautiful DnD drag out of position problem
body: <p>I created a draggable drag and drop table with draggable rows.<br/>
  I'm using <code>react beautiful-dnd</code> for this.<br/>
  When I drag a row, the row gets out of position instead on the position of my cursor.<br/>
  When I drag  a row, the row gets <code>position: fixed</code> and some <code>top</code> and <code>left</code> styling.<br/>
  I suspect thats the issue, but why does it get the wrong numbers, so that its causing to not show on the right position?<br/>
  This <strong>GIF</strong> will show the problem.<br/>
  <a href="https://i.stack.imgur.com/9Qeok.gif" rel="noreferrer"><img src="https://i.stack.imgur.com/9Qeok.gif" alt="enter image description here"></a></p>
  
  <p>This is my full code:</p>
  
  <pre><code>import update from "immutability-helper";
  import * as React from "react";
  import * as ReactDnD from "react-dnd";
  import { WithNamespaces, withNamespaces } from "react-i18next";
  import { toastr } from "react-redux-toastr";
  import * as HttpHelper from "../../httpHelper";
  import { FormState } from "../common/ValidatedForm";
  import Addtagmodal from "../common/AttributeModal";
  import AttributeModal from "./AttributeModal";
  import PreviewModal from "./PreviewModal";
  import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
  /* import locale from "react-json-editor-ajrm/locale/en"; */
  type Props = WithNamespaces &amp; {
    id: number;
    displayName: string;
  };
  
  interface Fields {
    columns: any;
  }
  
  type State = FormState&lt;Fields&gt; &amp; {
    isLoading: boolean,
    canSave: boolean,
    isSaving: boolean,
    possibleTags: any,
    configTagModalActive: boolean,
    previewModalActive: boolean,
    activeTag: any
  };
  const getItemStyle = (draggableStyle: any) =&gt; ({
    ...draggableStyle
  });
  const Card = (props: any) =&gt; {
    const opacitys = props.isDragging ? 0.3 : 1;
  
    function findindex(val: any) {
      return props.tags.some((item: any) =&gt; val === item.name);
    }
    let select;
    let selectStyle = {};
    let tagInputStyle = {};
    if (props.tags.length == 0 || props.tags.length &gt; 3) {
      selectStyle = { border: "0px", outline: "none", width: "100%", height: "20px", backgroundColor: "transparent", zIndex: 0, float: "left", position: "relative" };
      tagInputStyle = {border: "1px solid #ced4da", height: "auto", width: "400px", padding: "8px", minHeight: "38px", background: "white"};
    }
    else {
      selectStyle = { border: "0px", outline: "none", width: "100%", height: "20px", backgroundColor: "transparent", zIndex: 0, float: "left", top: "-20px", position: "relative" };
      tagInputStyle = {border: "1px solid #ced4da", height: "auto", width: "400px", padding: "8px", minHeight: "38px", background: "white", marginTop: "10px"};
    }
    if (props.tags.length &lt; 4) {
      select =
    &lt;select value="" className="autocomplete-select" style={selectStyle} id={props.index} onChange={props.onaddtag}&gt;
      &lt;option value="" disabled &gt;&lt;/option&gt;
      {props.possibleTags.map((i: any) =&gt;
  
        &lt;option value={i.name} disabled={i.uses == 0 || findindex(i.name) == true ? true : false}&gt;{i.name}&lt;/option&gt;
  
      )}
    &lt;/select&gt;;
    }
    else {
      select = undefined;
    }
    return (
          &lt;tr ref={props.provided.innerRef}
          {...props.provided.draggableProps} style={getItemStyle(props.provided.draggableProps.style)} className={(props.indexnr % 2 ? "whiterow" : "grayrow")} key={props.indexnr} data-id={props.indexnr} &gt;
            &lt;td {...props.provided.dragHandleProps} style={{width: "50px", textAlign: "center"}}&gt;&lt;i className="fa fa-bars" style={{lineHeight: "40px", fontSize: "24px"}}&gt;&lt;/i&gt;&lt;/td&gt;
            &lt;td style={{ textAlign: "center", width: "80px" }}&gt;
              &lt;input
                type="checkbox"
                className="flipswitch"
                id={props.index}
                checked={props.export}
                onChange={props.oncheck}
              /&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;input
                type="text"
                name="caption"
                id={props.index}
                className="form-control"
                value={props.caption}
                onChange={props.ontextupdate}
              /&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;input
                type="text"
                name="fieldname"
                id={props.index}
                className="form-control"
                value={props.fieldname}
                onChange={props.ontextupdate}
              /&gt;
            &lt;/td&gt;
            &lt;td style={{width: "400px"}}&gt;
              &lt;div className="tags-input" style={tagInputStyle}&gt;
              {Object.keys(props.tags).map((key, i) =&gt;
                &lt;div key={key} style={{backgroundColor: "#0753ad", height: "20px", borderRadius: "3px", display: "inline-block", padding: "5px", lineHeight: "12px", float: "left", color: "white", marginRight: "5px", fontSize: "10px", width: "90px", position: "relative", zIndex: 20}}&gt;
                  {props.tags[i].name} &lt;i className="fa fa-trash" id={props.index} data-key={i} data-name={props.tags[i].name} onClick={props.ondeletetag} style={{float: "right"}} &gt;&lt;/i&gt;&lt;i className="fa fa-cog" data-id={i} data-parent={props.index} style={{float: "right", marginRight: "5px"}} onClick={props.onConfigButtonClicked}&gt;&lt;/i&gt;
                &lt;/div&gt;
              )}
              {select}
              &lt;/div&gt;
             &lt;/td&gt;
            &lt;td style={{ textAlign: "center", width: "80px" }}&gt;
            &lt;button onClick={() =&gt; props.ondeleterow(props.index)} type="button" style={{padding : "8px 16px" }} className="btn btn-danger btn-rounded"&gt;&lt;i className="fa fa-trash"&gt;&lt;/i&gt;&lt;/button&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
    );
  };
  const reorder = (list: any, startIndex: any, endIndex: any) =&gt; {
    const result = Array.from(list);
    const [removed] = result.splice(startIndex, 1);
    console.log(startIndex, endIndex, removed);
    result.splice(endIndex, 0, removed);
  
    return result;
  };
  interface SetColumnsResponse extends HttpHelper.ResponseData { columns: any; }
  
  class CrmConnectorColumns extends React.Component&lt;Props, State&gt; {
  
    constructor(props: Props) {
      super(props);
      this.moveCard = this.moveCard.bind(this);
      this.oncheck = this.oncheck.bind(this);
      this.ontextupdate = this.ontextupdate.bind(this);
      this.ondeleterow = this.ondeleterow.bind(this);
      this.onaddnewrow = this.onaddnewrow.bind(this);
      this.ondeletetag = this.ondeletetag.bind(this);
      this.onaddtag = this.onaddtag.bind(this);
      this.onConfigButtonClicked = this.onConfigButtonClicked.bind(this);
      this.onPreviewButtonClicked = this.onPreviewButtonClicked.bind(this);
      this.onClosePreview = this.onClosePreview.bind(this);
      this.state = {
        isLoading: true,
        isSaving: false,
        canSave: false,
        errorColor: "danger",
        fields: { columns: {} },
        deleteModalActive: false,
        configTagModalActive: false,
        previewModalActive: false,
        activeTag: {name: "", attributes: [{name: "", value: ""}]},
        possibleTags: [
          {name: "SUBTITLE", status: "new", helptexts: [{language: "nl", helptext: "Dit is de subtitel van een record"}], attributes: [], uses: 1},
          {name: "URL", status: "new", helptexts: [{language: "nl", helptext: "De waarde wordt gezien als html link."}], attributes: [{name: "link", status: "new", helptexts: [{language: "nl", helptext: "De link is deze waarde. Voorbeeld waarde is \"http://www.google.nl?search=[naam]\". op de plaats van \"[naam]\" wordt de waarde van het veld \"naam\" ingevuld."}], uses: undefined}]},
          {name: "TITLE", status: "new", helptexts: [{language: "nl", helptext: "Dit is de hoofdtitel van een record"}], attributes: [], uses: 1},
          {name: "PHONE", status: "new", helptexts: [{language: "nl", helptext: "De waarde wordt gezien telefoonnummer"}], attributes: [], uses: undefined},
          {name: "BUTTON", status: "new", helptexts: [{language: "nl", helptext: "Uiterlijk van een knop"}], attributes: [], uses: undefined},
          {name: "EMAIL", status: "new", helptexts: [{language: "nl", helptext: "De waarde wordt gezien e-mail adres"}], attributes: [], uses: undefined},
          {name: "IMAGE", status: "new", helptexts: [{language: "nl", helptext: "De waarde wordt als afbeelding weergegeven"}], attributes: [], uses: undefined},
          {name: "HTML", status: "new", helptexts: [{language: "nl", helptext: "De waarde wordt gezien als HTML"}], attributes: [{name: "HTML code", status: "new", helptexts: [{language: "nl", helptext: "Vul hier je custom HTML code in. De waarde tussen de [] word vervangen door de data."}], uses: undefined}]}
        ]
      };
      this.onDragEnd = this.onDragEnd.bind(this);
    }
    onDragEnd(result: any) {
      // dropped outside the list
      if (!result.destination) {
        return;
      }
      let newlist = [...this.state.fields.columns];
      newlist = reorder(
        newlist,
        result.source.index,
        result.destination.index
      );
      Object.keys(newlist).forEach((nr) =&gt; {
        newlist[parseInt(nr, 10)].index = parseInt(nr, 10);
        });
      this.setState({ fields: { columns: newlist } });
      console.log(this.state.fields.columns);
      this.setState({ canSave: true });
  
  
  
  
    }
    async componentDidMount() {
      console.log("Start select columns");
  
      const fields = await HttpHelper.getJson&lt;Fields&gt;(`/connectortypes/${this.props.id}/columns`);
      this.setState(prevState =&gt; {
        return update(prevState, {
          fields: { $set: fields },
          isLoading: { $set: false },
        });
      });
      for (let i = 0; i &lt; fields.columns.length; i++) {
        fields.columns[i].index = i;
      }
      this.setState({ fields: { columns: fields.columns } });
      const newlist = [...this.state.possibleTags];
      console.log(newlist);
      for (const column of fields.columns) {
        for (const tags of column.tags) {
          const index = newlist.findIndex(item =&gt; item.name == tags.name);
          if (newlist[index].uses &gt; 0) {
            newlist[index].uses = 0;
          }
        }
      }
      this.setState({ possibleTags: newlist });
      console.log(this.state.possibleTags);
  
    }
    moveCard (index: any, indexnr: any) {
      const cards = this.state.fields.columns;
      const sourceCard = cards.find((card: any) =&gt; card.index === index);
      const sortCards = cards.filter((card: any) =&gt; card.index !== index);
      sortCards.splice(indexnr, 0, sourceCard);
       Object.keys(sortCards).forEach((nr) =&gt; {
      sortCards[nr].index = parseInt(nr, 10);
      });
      this.setState({ fields: { columns: sortCards } });
      console.log(this.state.fields.columns);
      this.setState({ canSave: true });
    }
    oncheck(e: any) {
      const cards = this.state.fields.columns;
      cards[e.target.id].export = e.target.checked;
      this.setState({ fields: { columns: cards } });
      console.log(this.state.fields.columns);
      this.setState({ canSave: true });
    }
    ondeleterow(nr: any) {
      console.log(nr);
      const array = [...this.state.fields.columns]; // make a separate copy of the array
      const arrayCopy = array.filter((row: any) =&gt; row.index !== nr);
      this.setState({ fields: { columns: arrayCopy }});
      console.log(this.state.fields.columns);
      this.setState({ canSave: true });
    }
    ontextupdate(e: any) {
      const cards = this.state.fields.columns;
      cards[e.target.id][e.target.name] = e.target.value;
      this.setState({ fields: { columns: cards } });
      this.setState({ canSave: true });
    }
    onaddnewrow() {
      const columnsCopy = this.state.fields.columns;
      columnsCopy.push({index: this.state.fields.columns.length, export: true, editable: false, fieldname: "", caption: "", tags: [] });
      this.setState({ fields: { columns: columnsCopy } });
      this.setState({ canSave: true });
    }
    onDragStart = (e: any) =&gt; {
      e.dataTransfer.effectAllowed = "move";
      e.dataTransfer.setData("text/html", e.target.parentNode);
      e.dataTransfer.setDragImage(e.target.parentNode, 20, 20);
    }
    ondragOver(e: any) {
      e.preventDefault();
      const columnsCopy = this.state.fields.columns;
      columnsCopy.pop();
      columnsCopy.push({index: e.target.dataset.id, export: true, editable: false, fieldname: "", caption: "", tags: [] });
      this.setState({ fields: { columns: columnsCopy } });
    }
    onaddtag(e: any) {
      function findindex(element: any) {
        return element.name == e.target.value;
      }
      const index = this.state.possibleTags.findIndex(findindex);
      const array = this.state.fields.columns;
  
      for (const column of array) {
  
        if (column.index == e.target.id) {
           const newArray = [ ...array[e.target.id].tags, {name: this.state.possibleTags[index].name, attributes: [] } ];
           array[e.target.id].tags = newArray;
        }
        else {
          const newArray = [...column.tags];
          column.tags = newArray;
        }
        this.setState({ fields: { columns: array } });
      }
      this.setState({ canSave: true });
      const tags = this.state.possibleTags;
      if (tags[index].uses &gt; 0) {
        tags[index].uses = 0;
      }
      this.setState({ possibleTags: tags });
    }
    ondeletetag(e: any) {
      const array = this.state.fields.columns;
      for (const column of array) {
        if (column.index == e.target.id) {
          const newlist = [].concat(array[e.target.id].tags); // Clone array with concat or slice(0)
          newlist.splice(e.target.dataset.key, 1);
          array[e.target.id].tags = newlist;
        }
        else {
          const newArray = [...column.tags];
          column.tags = newArray;
        }
      }
      this.setState({ fields: { columns: array } });
      this.setState({ canSave: true });
      function findindex(element: any) {
        return element.name == e.target.dataset.name;
      }
      const index = this.state.possibleTags.findIndex(findindex);
      const tags = this.state.possibleTags;
      if (tags[index].uses == 0) {
        tags[index].uses = 1;
      }
      this.setState({ possibleTags: tags });
    }
    onUpdateAttribute() {
      this.setState({ configTagModalActive: false });
      this.setState({ canSave: true });
    }
    onPreviewButtonClicked() {
      this.setState({ previewModalActive: true });
    }
    onClosePreview() {
      this.setState({ previewModalActive: false });
    }
    onCancelUpdateAttribute() {
      this.setState({ configTagModalActive: false });
    }
    onConfigButtonClicked(e: any) {
      e.preventDefault();
      this.setState({ activeTag: this.state.fields.columns[e.target.dataset.parent].tags[e.target.dataset.id]});
      this.setState({ configTagModalActive: true, errorMessage: undefined });
      console.log(this.state.activeTag);
    }
    onSubmit = (e: any) =&gt; {
      e.preventDefault();
      console.log("Start saving changes");
      this.setState({ isSaving: true }, () =&gt; {
        if (this.state.fields) {
          HttpHelper.postJson&lt;SetColumnsResponse&gt;(`/connectortypes/${this.props.id}/columns/`, { columns: this.state.fields.columns }).then((responseData) =&gt; {
            if (responseData.responseStatus !== undefined &amp;&amp; responseData.responseStatus !== null &amp;&amp; responseData.responseStatus.message !== null) {
              this.setState({ isSaving: false, errorMessage: responseData.responseStatus.message });
            }
            else {
              this.setState({ canSave: false, isSaving: false, fields: { columns: responseData.columns } }, () =&gt; {
                toastr.success(this.props.displayName, this.props.t("columnsUpdated"));
              });
            }
          });
        }
      });
    }
    public render() {
      const columns = this.state.fields.columns || [] ;
      const { t } = this.props;
      return (
      &lt;form&gt;
        &lt;div className="App"&gt;
          &lt;main&gt;
            &lt;button onClick={this.onSubmit} className="btn btn-primary" type="submit" style={{float: "right"}} disabled={!this.state.canSave || this.state.isSaving}&gt;{this.state.isSaving ? &lt;i className="fa fa-spinner fa-spin"&gt;&lt;/i&gt; : ""} {this.props.t("update")}&lt;/button&gt;&lt;br/&gt;&lt;br/&gt;
            &lt;DragDropContext onDragEnd={this.onDragEnd}&gt;
            &lt;Droppable droppableId="droppable"&gt;
            {(provided: any) =&gt; (
            &lt;table ref={provided.innerRef} className="col-8 table columns" style={{border: "1px solid #dee2e6"}} &gt;
            &lt;thead className="thead-dark" style={{border: "1px solid #1b2847"}}&gt;
            &lt;tr&gt;
            &lt;th colSpan={2}&gt;
              &lt;button onClick={this.onaddnewrow} type="button" style={{padding : "8px 16px" }} className="btn btn-primary btn-rounded"&gt;&lt;i className="fa fa-plus"&gt;&lt;/i&gt; &lt;/button&gt;
            &lt;/th&gt;
             &lt;th&gt;{t("displayname")}&lt;/th&gt;
             &lt;th&gt;Element&lt;/th&gt;
             &lt;th&gt;Tags&lt;/th&gt;
             &lt;th&gt;
               &lt;button onClick={this.onPreviewButtonClicked} type="button" className="btn btn-primary"  style={{float: "right"}} &gt;Preview&lt;/button&gt;
            &lt;/th&gt;
            &lt;/tr&gt;
          &lt;/thead&gt;
          &lt;tbody&gt;
              {Object.keys(columns).map((key, i) =&gt; (
                &lt;Draggable key={i} draggableId={key} index={i}&gt;
                {(provided) =&gt; (
               &lt;Card
               key={columns[i].index}
               indexnr={i}
               oncheck={this.oncheck}
               ontextupdate={this.ontextupdate}
               ondeleterow={this.ondeleterow}
               ondeletetag={this.ondeletetag}
               onaddtag={this.onaddtag}
               possibleTags={this.state.possibleTags}
               onConfigButtonClicked={this.onConfigButtonClicked}
               onPreviewButtonClicked={this.onPreviewButtonClicked}
               onClosePreview={this.onClosePreview}
               provided={provided}
               {...columns[i]}
             /&gt;
             )}
             &lt;/Draggable&gt;
             ))}
              &lt;/tbody&gt;
            &lt;/table&gt;
            )}
           &lt;/Droppable&gt;
        &lt;/DragDropContext&gt;
          &lt;/main&gt;
        &lt;/div&gt;
        &lt;AttributeModal
          startAction={this.onUpdateAttribute.bind(this)}
          isOpen={this.state.configTagModalActive}
          headerText={t("header")}
          activeTag={this.state.activeTag}
          addText={t("close")}
          possibleTags={this.state.possibleTags} &gt;
        &lt;/AttributeModal&gt;
  
        &lt;PreviewModal
          startAction={this.onClosePreview.bind(this)}
          isOpen={this.state.previewModalActive}
          headerText="Preview"
          addText={t("close")}
          columns={this.state.fields.columns} &gt;
        &lt;/PreviewModal&gt;
      &lt;/form&gt;
      );
    }
  }
  
  export default withNamespaces("crmConnectorColumns")(CrmConnectorColumns);
  </code></pre>
  
  <p>Does anyone know why my draggable item gets out of position?<br/>
  The only css I'm using is <code>bootstrap</code> and the ones in my code.<br/></p>