0

I have created a drag-drop task, where an individual is trying to unscramble a sentence. 4 of 5 words make a sentence and the individual takes the last word and drags it to the end where it is outlined in red to signify it was the uneeded word. I want to do 10 of these sentences and would like to put multiple on a page rather than 1 per page.

However, with how I currently have it coded, the individual can drag and drop words across rows, meaning that they can take a word from one sentence and switch it for another in a different sentence. Is there a way for me to limit drag-drop options to one specific row (sentence)? Thanks in advance.

document.addEventListener('DOMContentLoaded', (event) => {

  var dragSrcEl = null;

  function handleDragStart(e) {
    this.style.opacity = '0.4';

    dragSrcEl = this;

    e.dataTransfer.effectAllowed = 'move';
    e.dataTransfer.setData('text/html', this.innerHTML);
  }

  function handleDragOver(e) {
    if (e.preventDefault) {
      e.preventDefault();
    }

    e.dataTransfer.dropEffect = 'move';

    return false;
  }

  function handleDragEnter(e) {
    this.classList.add('over');
  }

  function handleDragLeave(e) {
    this.classList.remove('over');
  }

  function handleDrop(e) {
    if (e.stopPropagation) {
      e.stopPropagation(); // stops the browser from redirecting.
    }

    if (dragSrcEl != this) {
      dragSrcEl.innerHTML = this.innerHTML;
      this.innerHTML = e.dataTransfer.getData('text/html');
    }

    return false;
  }

  function handleDragEnd(e) {
    this.style.opacity = '1';

    items.forEach(function(item) {
      item.classList.remove('over');
    });
  }


  let items = document.querySelectorAll('.container .box');
  items.forEach(function(item) {
    item.addEventListener('dragstart', handleDragStart, false);
    item.addEventListener('dragenter', handleDragEnter, false);
    item.addEventListener('dragover', handleDragOver, false);
    item.addEventListener('dragleave', handleDragLeave, false);
    item.addEventListener('drop', handleDrop, false);
    item.addEventListener('dragend', handleDragEnd, false);
  });
});
body {
  font-family: "Benton Sans", "Helvetica Neue", helvetica, arial, sans-serif;
  margin: 2em;
}

.container {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
}

.box:nth-child(1) {
  border: 3px solid #666;
  background-color: #ddd;
  border-radius: .5em;
  padding: 10px;
  cursor: move;
}

.box:nth-child(2) {
  border: 3px solid #666;
  background-color: #ddd;
  border-radius: .5em;
  padding: 10px;
  cursor: move;
}

.box:nth-child(3) {
  border: 3px solid #666;
  background-color: #ddd;
  border-radius: .5em;
  padding: 10px;
  cursor: move;
}

.box:nth-child(4) {
  border: 3px solid #666;
  background-color: #ddd;
  border-radius: .5em;
  padding: 10px;
  cursor: move;
}

.box:nth-child(5) {
  border: 3px solid #f00;
  background-color: #ddd;
  border-radius: .5em;
  padding: 10px;
  cursor: move;
}

.box.over {
  border: 3px dotted #666;
}

[draggable] {
  user-select: none;
}
1.
<div class="container">
  <div draggable="true" class="box">fall</div>
  <div draggable="true" class="box">was</div>
  <div draggable="true" class="box">worried</div>
  <div draggable="true" class="box">she</div>
  <div draggable="true" class="box">always</div>
</div>
<br> 2.
<div class="container">
  <div draggable="true" class="box">fall</div>
  <div draggable="true" class="box">was</div>
  <div draggable="true" class="box">worried</div>
  <div draggable="true" class="box">she</div>
  <div draggable="true" class="box">always</div>
</div>
cloned
  • 6,346
  • 4
  • 26
  • 38
zotzotzot
  • 1
  • 1
  • Why not hold a reference to the `container` on drag start and then check this when dropping. If the drop zone isn't inside the referenced container, return false and don't allow the drop. – Ryan Wilson Aug 30 '22 at 13:01
  • How would I do this? Sorry I put together this code from other sources to fit my needs so I'm quite new to CSS/JS. – zotzotzot Aug 31 '22 at 03:34

0 Answers0