jQuery drag and drop simulation does not work for the last draggable
I am trying to simulate the drag and drop simulation using jquery-simulate-ext plugin of jquery-ui.
Before I give the details of the scenario , let me show you the js fiddle here .
I have 3 columns of divs
. In 1st column, I have 3 draggables with country names, in 2nd column 3 droppables of blank divs
and in 3rd column 3 normal div
s with city names . So after all the draggables from 1st column are dropped on 2nd cloumn , 2nd and 3rd column rows will make a sense of country-city relationship.
But the problem is after the simulation is done, 1st and 2nd draggables are dropped on expected droppables but 3rd draggable just sticks to the mouse instead of dropping on the droppable. To find the behaviour, after the js fiddle page mentioned above loads, just move your mouse cursor on the result section and you will see that a draggable is also moving along with the mouse. You have to click somewhere to make the draggable sit on the droppable or draggable section (depends on which area you are clicking ). This happens only in Firefox whereas in chrome, the draggable just moves along with the cursor only inside the appropriate droppable section and then sits inside that automatically.
What I want is: as with other draggables, the 3rd draggable should not move along with the moving of the mouse and should sit on the desired droppable automatically .
Explanation of code :
Every draggable div
with class draggable_div
has an attribute data-index
(value 1,2,3 etc). Same scenario is true with the droppable divs
(with class droppable_blank
) . Now at the start of the JS code, I have the line :
answers_found='[1,2,3]';
These basically are the data-index
values from the draggables. The order of the values just shows the order of the data-index
values of the draggables when they sit on the droppables. In the mentioned case, the first value is 1, so it will be the first (not 2nd or 3rd) draggable that will sit on the 1st droppable. Similarly 2nd and 3rd draggable will sit on the 2nd and 3rd droppables consecutively.
The code executes the following for
loop
for(var i =0; i<answers_found.length; i++){
to get each of the values from the answers_found
array. This value is the draggable data-index
attribute value. Then the call_trigger_drop
function is given 2 params :
call_trigger_drop(parseInt(answer_found_indiv),droppable_index);
1st one is the draggable index and the 2nd one is the corresponding droppable index i.e. the draggable will sit on the droppable. The actual simulation takes place with the following lines then :
draggable.simulate("drag", {
dx: dx,
dy: dy
});
TL;DR:
Draggables from the 1st column are simulated to drop on the droppables on the 2nd column while the 3rd column is of just normal div
s. After the drag and drop simulation, 3rd draggable does not sit on the 3rd droppable in Firefox and moves along with the cursor until a click takes place. How to make it sit on the droppable automatically like other draggables ?
EDIT:
If you want to get the result as a normal web page instead of the js-fiddle, you can find that here.
console = {};
console.log = function(){};
window.console = console;
drag_stop_counter = 0;
answers_found = '[3,2,1]';
answer_all_zero = 0; //REMOVABLE
if (answers_found != "".trim()) {
answers_found = $.parseJSON(answers_found);
answer_all_zero = 1;
for (var i = 0; i < answers_found.length; i++) {
if (parseInt(answers_found[i]) != 0) {
answer_all_zero = 0;
break;
}
} //end of for loop
}
total_answers_found = answers_found.length;
total_actual_answers_found = 0;
for (var i = 0; i < answers_found.length; i++) {
if (parseInt(answers_found[i])) {
++total_actual_answers_found;
}
} //end of for loop
answers = [];
answers_made_for_insert = [];
question_id = 2901;
//Following function is triggered
//when the dNd component is starting the drop
//event
function trigger_drop(draggable_elem_index, droppable_elem_index) {
if (draggable_elem_index && droppable_elem_index) {
if (window.console) {
console.log("from within trigger_drop : draggable_elem_index = " + draggable_elem_index + " droppable_elem_index= " + droppable_elem_index);
}
// var draggable = $(".draggable_container_indiv .draggable_div").eq(draggable_elem_index-1).draggable(),
var draggable = $(".draggable_container_indiv").eq(draggable_elem_index - 1).find(".draggable_div").draggable(),
droppable = $("#droppable_slots .droppable_blank").eq(droppable_elem_index - 1).droppable(),
droppableOffset = droppable.offset(),
draggableOffset = draggable.offset(),
dx = droppableOffset.left - draggableOffset.left,
dy = droppableOffset.top - draggableOffset.top;
draggable.simulate("drag", {
dx: dx,
dy: dy
});
} // end of if(draggable_elem_index && droppable_elem_index){
} // end of function trigger_drop(
//answers stored in array for insertion in DB
function make_answers_for_insert(answer_given) {
answers_made_for_insert.push(answer_given);
} //end of function answers_for_insert
//finds answers from array
function find_answers() {
answers = [];
$('input[name="' + question_id + '[]"]').each(function() {
$elem = $(this);
var value_found = $elem.val().trim();
if (value_found == "".trim()) {
value_found = "0";
}
// if(value_found!="".trim()){
answers.push(value_found);
// }
});
//alert("answers made "+answers);
if (window.console) {
console.log("answers from find_answers = ");
console.log(answers);
}
} //end of function find_answers
function call_trigger_drop(answer_found_indiv, droppable_index) {
trigger_drop(answer_found_indiv, droppable_index);
}
function insert_answer() {
if (window.console) {
console.log(" can_submit in insert_answer = " + can_submit);
}
if (can_submit) {
can_submit = 0
$("#draggable .draggable_div").draggable('disable');
//ui.draggable.draggable({disabled: true});
$('#droppable_slots li').find('.ui-draggable').draggable({
disabled: true
});
answers = [];
$('input[name="' + question_id + '[]"]').each(function() {
$elem = $(this);
var value_found = $elem.val().trim();
if (value_found == "".trim()) {
value_found = "0";
}
// if(value_found!="".trim()){
answers.push(value_found);
// }
});
answers = JSON.stringify(answers);
if (window.console) {
console.log("answers from insert_answers = ");
console.log(answers);
}
//ajax call for insertion
} // end of if(can_submit){
} // end of function insert_anwers
$(document).ready(function() {
answer_status = 0;
review_table_status = 0;
$('input[name="' + question_id + '[]"]').each(function() {
var dnd_value_found = $(this).val().trim();
if (window.console) {
console.log(" dnd_value_found = " + dnd_value_found);
}
if (dnd_value_found != "".trim()) {
answer_status = 1;
review_table_status = 1;
return false;
}
}); // end of each
var draggable_counter = 0;
$(".draggable_container_indiv").each(function() {
// $draggable_elem=$(this);
$draggable_elem = $(".draggable_div").eq(draggable_counter);
var $droppable_elem = $(".droppable_content_indiv").eq(draggable_counter);
var $draggable_container_indiv_elem = $(".draggable_container_indiv").eq(draggable_counter);
var $droppable_blank_elem = $(".droppable_blank").eq(draggable_counter);
var droppable_height = $droppable_elem.css('height');
var draggable_height = $draggable_elem.css('height');
var droppable_width = $droppable_elem.css('width');
var draggable_width = $draggable_elem.css('width');
var height_more = 0;
if (parseInt(draggable_height) > parseInt(droppable_height)) {
height_more = draggable_height;
} else {
height_more = droppable_height;
}
var width_more = 0;
if (parseInt(draggable_width) > parseInt(droppable_width)) {
width_more = draggable_width;
} else {
width_more = droppable_width;
}
if (window.console) {
console.log(" draggable_height " + draggable_height + " droppable_height = " + droppable_height + " height_more = " + height_more);
}
$draggable_elem.css({
'height': height_more
});
$droppable_elem.css({
'height': height_more
});
$droppable_blank_elem.css({
'height': height_more
});
$draggable_container_indiv_elem.css({
'height': height_more
});
//$('.draggable_container_indiv').css({'height':22});// hhhhhhhh
$draggable_elem.css({
'width': width_more
});
$droppable_elem.css({
'width': width_more
});
$droppable_blank_elem.css({
'width': width_more
});
$draggable_container_indiv_elem.css({
'width': width_more
});
$droppable_elem.find(".ui-draggable").css({
'width': width_more
});
++draggable_counter;
});
$("#draggable .draggable_div").draggable({
scroll: false,
revert: true,
// helper: 'clone',
//appendTo: 'body',
start: function() {
if (window.console) {
console.log(" draggable started ....... ");
}
$(this).css({
display: 'none'
});
},
stop: function() {
$(this).css({
display: 'block'
});
var draggableIndex = $(this).data('index');
++drag_stop_counter;
if (window.console) {
console.log(" draggable stopped = " + drag_stop_counter);
console.log("draggable index in stop = " + draggableIndex);
}
var droppableIndex = $('#droppable_slots li').find('.ui-draggable[data-index=' + draggableIndex + ']').closest('.slot').data('index');
var index_found = $.inArray(draggableIndex + "", answers);
if (window.console) {
console.log("inside stop draggableIndex = " + draggableIndex + " after dropped ..... index_found = " + index_found);
}
},
revert: function(dropped) {
var dropped = dropped && dropped.hasClass('slot'); //fix duplicated IDs
if (!dropped) {
$(this).appendTo($(this).data('originalParent'))
}
return !dropped;
},
revertDuration: 0, //removed glitched effect
helper: function() {
return $(this).clone().appendTo('body').show();
},
containment: '.sel_screen_left'
}).each(function() {
$(this).data('originalParent', $(this).parent())
});
$("#droppable_slots li").droppable({
// tolerance:'pointer',
tolerance: 'intersect',
drop: function(event, ui) {
$(this).trigger('dropthis', [event, ui]); //REMOVABLE
$(this).trigger("dropthis", [{}, {
draggable: ui.draggable
}]); //REMOVABLE
var $this = $(this);
if ($this.find('.ui-draggable').length) return; //don't overwrite occupied spot
//$this.empty();
$this.append(ui.draggable);
var width = $this.width();
var height = $this.height();
var cntrLeft = (width / 2) - (ui.draggable.width() / 2);
var cntrTop = (height / 2) - (ui.draggable.height() / 2);
ui.draggable.css({
left: cntrLeft + "px",
top: cntrTop + "px"
});
var draggableIndex = parseInt(ui.draggable.data("index"));
var droppableIndex = parseInt($(this).data("index"));
if (window.console) {
console.log(" draggableIndex = " + draggableIndex + " droppableIndex = " + droppableIndex + " question_id = " + question_id);
}
if (window.console) {
console.log("droppable question_id = " + question_id);
console.log(" droppable drop has draggableIndex answer = " + draggableIndex);
}
if (window.console) {
console.log(" inside drop .......................... ");
}
var index_found = $.inArray(draggableIndex + "", answers);
if (window.console) {
console.log(" draggableIndex = " + draggableIndex + " after dropped ..... index_found = " + index_found);
}
if (index_found != -1) {
answers[index_found] = '';
$('input[name="' + question_id + '[]"]').eq(index_found).val('');
}
$(".droppable_blank[data-index=" + droppableIndex + "]").trigger('click');
if (window.console) {
console.log(" droppable_blank clicked droppableIndex = " + droppableIndex);
}
},
out: function(event, ui) {
},
over: function(event, ui) {
}
});
if (window.console) {
console.log("DnD ANSWERS found = ");
console.log(answers_found);
}
answer_found_indiv = 0;
droppable_index = 0;
for (var i = 0; i < answers_found.length; i++) {
//return false;
if (window.console) {
console.log(" iterating all answers: DnDDnDDnDDnDDnD dragndrop draggable index = " + answers_found[i] + " droppable index = " + (i + 1));
}
var droppable_index = i + 1;
var answer_found_indiv = parseInt(answers_found[i]);
if (answer_found_indiv == 0) {
if (window.console) {
console.log(" answer_found_indiv 000000000000000000");
}
} else if (answer_found_indiv) {
if (window.console) {
console.log("Trigger Drop = " + answer_found_indiv, " droppable_index = " + droppable_index);
}
call_trigger_drop(parseInt(answer_found_indiv), droppable_index);
}
} // end of for loop
});
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
.draggable_container_indiv{
border: 1px solid green;
}
#draggable .draggable_div {
margin-left: -60px;
padding: 10px;
}
.droppable_blank{
/*line-height: 40px;*/
vertical-align: middle;
}
#draggable li, #draggable .draggable_div, #droppable_slots li, .draggable_div{
list-style: none;
}
.dragndrop-questions ul.option-left li{
padding-top: 0;
}
.match-questions ul.option-left li, .dragndrop-questions ul.option-left li{
font-size: 14px;
color: #656f7d;
position: relative;
padding-left: 60px;
min-height: 40px;
}
.draggable_container_indiv{
margin-bottom: -10px !important;
}
<link href="https://epractice.lcbsdhaka.com/mytest/css/bootstrap.min.css" rel="stylesheet">
<link href="https://epractice.lcbsdhaka.com/mytest/js/jquery-ui-1.12.1.custom/jquery-ui.css"></link>
<script src="https://epractice.lcbsdhaka.com/mytest/js/jquery-1.12.4.js"></script>
<script src="https://epractice.lcbsdhaka.com/mytest/js/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
<script src="https://epractice.lcbsdhaka.com/mytest/js/bootstrap.min.js"></script>
<script src="https://epractice.lcbsdhaka.com/mytest/js/jquery.simulate.js"></script>
<script src="https://epractice.lcbsdhaka.com/mytest/js/jquery-simulate-ext/src/jquery.simulate.ext.js"></script>
<script src="https://epractice.lcbsdhaka.com/mytest/js/jquery-simulate-ext/src/jquery.simulate.drag-n-drop.js"></script>
<script src="https://epractice.lcbsdhaka.com/mytest/js/bootstrap.min.js"></script>
<script src="https://epractice.lcbsdhaka.com/mytest/js/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
<div class="dragndrop-questions row">
<div>
<div style="width:30%; float: left; ">
<ul class="option option-left" id="draggable">
<li class="draggable_container_indiv noselect">
<div class="draggable_div" data-index="1">
USA
</div>
</li>
<li class="draggable_container_indiv noselect">
<div class="draggable_div" data-index="2">
JAPAN
</div>
</li>
<li class="draggable_container_indiv noselect">
<div class="draggable_div" data-index="3">
CHINA
</div>
</li>
</ul>
</div>
<div style="width:65%; float: right; margin-right: 10px;">
<ul class="option option-right" id="droppable_slots">
<div class="row ">
<div style="width:45%; float: left; margin-left:10px; border: 1px solid red;">
<li class="slot droppable_blank noselect" data-index="1">
</li>
</div>
<div style="width:48%; float: right; border: 1px solid yellow;">
<li class="droppable_content_indiv noselect">
<p>
NewYork
</p>
</li>
</div>
</div>
<!--end of class row -->
<div class="row ">
<div style="width:45%; float: left; margin-left:10px; border: 1px solid red;">
<li class="slot droppable_blank noselect" data-index="2">
</li>
</div>
<div style="width:48%; float: right; border: 1px solid yellow;">
<li class="droppable_content_indiv noselect">
<p>
Tokyo
</p>
</li>
</div>
</div>
<!--end of class row -->
<div class="row ">
<div style="width:45%; float: left; margin-left:10px; border: 1px solid red;">
<li class="slot droppable_blank noselect" data-index="3">
</li>
</div>
<div style="width:48%; float: right; border: 1px solid yellow;">
<li class="droppable_content_indiv noselect">
<p>
Beijing
</p>
</li>
</div>
</div>
<!--end of class row -->
</ul>
</div>
<div class="" style="clear: both;"></div>
</div>
</div>
<!-- end of class dragndrop-questions-->
it is because it simulating drag
event only without drop
, use drag-n-drop
instead.
draggable.simulate("drag-n-drop", {dx: dx, dy: dy});