0
votes

I am trying to build a UI by using jQuery UI Drag and Drop feature but stuck in an instance. Basically, what i am doing is making the content boxes draggable and droppable in areas.

I am making the clone of a draggable box and dropping in the area. The problem in this is that when a element in dropped on any area, it should drag and could be dropped again in any respective area.

I have been looking for its solutions but didn't find any help.

Thanks

Following is the code in this i am working on.

/**/
	
	var blockBoxEle = $('.block-box');
	var blockBoxWd = blockBoxEle.width();
	blockBoxEle.css({'width': blockBoxWd});
	var blockBoxLen = blockBoxEle.length;
	for(var x=0; x<blockBoxLen; x++) {
			blockBoxEle.eq(x).addClass('block-count'+(x+1));
	}
	
	blockBoxEle.draggable({
	  revert: "invalid",
	  stack: blockBoxEle,
	  helper: 'clone',
	  stop: function(e, ui) {
		  
	  }
	});
	console.log('blockBoxElements Loaded!!!!!!!');
	
	
	/**/
	var areaBoxEle = $('.area-box');
	var areaBoxLen = areaBoxEle.length;
    for(var y=0; y<areaBoxLen; y++) {
        areaBoxEle.eq(y).prop('id', 'areaBox'+(y+1));
    }
	areaBoxEle.droppable({
	  accept: blockBoxEle,
	  tolerance: "pointer",
	  //greedy: true,
	  drop: function(event, ui) {
		var droppable = $(this);
		var draggable = ui.draggable;
		 if (droppable.find('.ui-draggable').length) return; 
		var dragClass = draggable.attr("class").split(' ')[1];
		
		var drag = areaBoxEle.has(ui.draggable).length ? draggable : draggable.clone().draggable({
		  revert: "invalid",
		  stack: blockBoxEle,
		  helper: 'clone'
		});
		
		droppable.empty();
		droppable.after(drag).hide();
		console.log('Dropped block class:'+dragClass+' on area id:'+this.id);
	  }
	});
	console.log('areaBoxElements Loaded!!!!!!!');
.block-box,
.area-box { margin: 0 0 10px; text-align: center; position: relative; }
.block-box { padding: 10px 5px; border: 2px solid #000; background: red; color: #fff; max-width: 100%; min-width: 100%; z-index: 2; }
.area-box { padding: 30px 5px; border: 2px dashed #333; background: #eee; z-index: 1; }
.block-box h3,
.area-box h3 { margin: 0; font-size: 14px; font-weight: 700; }
#block-fields .block-box { padding-top: 30px; padding-bottom: 30px; }
<link href="https://code.jquery.com/ui/1.12.1/jquery-ui.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<div class="panel panel-default">
	<div class="panel-body">
		<div class="row">
			<div id="block-panel" class="col-xs-3">
				<div class="row">
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 1</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 2</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 3</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 4</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 5</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 6</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 7</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 8</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 9</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 10</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 11</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 12</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 13</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 14</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 15</h3>
						</div>
					</div>
				</div>
			</div>
			<div id="block-fields" class="col-xs-9">
				<div class="row">
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 1</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 2</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 3</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 4</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 5</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 6</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 7</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 8</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 9</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 10</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 11</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 12</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 13</h3>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>
1
I have found that .draggable() is best initialized after the element is appended. Would try re-initializing draggable after the clone is added to the drop area. - Twisty
Hi @Twisty, actually when the box is drag on to area, and after its dragged, its not the its clone will be created, but the same box.. Clone will only be created only first time after that box can be shifted only. - SaurabhLP
So I think what is happening is that you have a new element that is not part of blockBoxEle any longer and thus, droppable will not accept it: accept: blockBoxEle. It is accepted the first time, which is weird. So maybe that is not it, but that's the only thing I can think of. - Twisty

1 Answers

1
votes

Minor change fixes the issue. Setting accept: ".block-box" allows drop to accept any of the draggables.

$(function() {
  function makeFirstDrag($el, $s) {
    $el.draggable({
      revert: "invalid",
      stack: $s,
      helper: 'clone'
    });
  }

  function makeSecondDrag($el, $s) {
    $el.draggable({
      revert: "invalid",
      stack: $s,
      helper: 'clone',
      start: function(e, ui) {
        $(this).css("opacity", ".25");
      },
      stop: function(e, ui) {
        $(this).prev().show();
        $(this).remove();
      }
    });
  }
  var blockBoxEle = $('.block-box');
  var blockBoxWd = blockBoxEle.width();
  blockBoxEle.css({
    'width': blockBoxWd
  });
  var blockBoxLen = blockBoxEle.length;
  for (var x = 0; x < blockBoxLen; x++) {
    blockBoxEle.eq(x).addClass('block-count' + (x + 1));
  }

  makeFirstDrag(blockBoxEle, blockBoxEle);
  console.log('blockBoxElements Loaded!!!!!!!');

  var areaBoxEle = $('.area-box');
  var areaBoxLen = areaBoxEle.length;
  for (var y = 0; y < areaBoxLen; y++) {
    areaBoxEle.eq(y).prop('id', 'areaBox' + (y + 1));
  }
  areaBoxEle.droppable({
    accept: ".block-box",
    tolerance: "pointer",
    drop: function(event, ui) {
      var droppable = $(this);
      var draggable = ui.draggable;
      if (droppable.find('.ui-draggable').length) return;
      var dragClass = draggable.attr("class").split(' ')[1];


      var drag = areaBoxEle.has(ui.draggable).length ? draggable : draggable.clone().draggable({
        revert: "invalid",
        stack: blockBoxEle,
        helper: 'clone'
      });
      drag.css("opacity", "1");
      makeSecondDrag(drag, blockBoxEle);

      //droppable.empty();
      droppable.addClass("hiding").hide().after(drag);
      console.log('Dropped block class:' + dragClass + ' on area id:' + this.id);
    }
  });
  console.log('areaBoxElements Loaded!!!!!!!');
});
.block-box,
.area-box {
  margin: 0 0 10px;
  text-align: center;
  position: relative;
}

.block-box {
  padding: 10px 5px;
  border: 2px solid #000;
  background: red;
  color: #fff;
  max-width: 100%;
  min-width: 100%;
  z-index: 2;
}

.area-box {
  padding: 30px 5px;
  border: 2px dashed #333;
  background: #eee;
  z-index: 1;
}

.block-box h3,
.area-box h3 {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
}

#block-fields .block-box {
  padding-top: 30px;
  padding-bottom: 30px;
}
<link href="https://code.jquery.com/ui/1.12.1/jquery-ui.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<div class="panel panel-default">
  <div class="panel-body">
    <div class="row">
      <div id="block-panel" class="col-xs-3">
        <div class="row">
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 1</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 2</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 3</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 4</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 5</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 6</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 7</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 8</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 9</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 10</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 11</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 12</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 13</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 14</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 15</h3>
            </div>
          </div>
        </div>
      </div>
      <div id="block-fields" class="col-xs-9">
        <div class="row">
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 1</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 2</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 3</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 4</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 5</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 6</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 7</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 8</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 9</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 10</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 11</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 12</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 13</h3>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Updated

Added a number of start and stop callbacks for draggable to help simulate the activity you desired. I also moved these to their own functions to make it easier to manipulate.