Creating dynamic DIV breaks JQuery-UI Droppable - jquery-ui

I have a draggable element and a div with two static drop zones:
<img id="dragimage" src="_images/image.png" >
<div class="lines">
<div class="dropzone" style="height:100px;width:100px;border:1px solid black">this is a dropzone</div>
<div class="dropzone" style="height:100px;width:100px;border:1px solid black">this is a dropzone</div>
</div>
<script>
$(function () {
$("#dragimage").draggable();
$(".dropzone").droppable({
drop: function(event,ui){
alert('dropped');
}
});
</script>
I have a button that dynamically adds additional drop zones. I add the "ui-droppable" class to the dynamic drop zones since calling .droppable() adds that class automatically to any static droppable elements.
function AddLine()
{
var linecount = $("#linecount").val();
var linediv = $(".lines").html();
linecount++;
$("#linecount").val(linecount);
linediv += '<div class="dropzone ui-droppable " style="height:75px;width:100%;border:1px solid black">New Drop Zone ' + linecount + '</div>';
$(".lines").html(linediv);
}
When I drop the draggable element into one of the static drop zones prior to adding any dynamic drop zones, I get the alert every time with no difficulties.
When I add one or more dynamic drop zones, the drop event never fires again, even for the original static drop zones.
Any suggestions?

I figured it out with the help of This
The AddLine method above is now this:
function AddLine()
{
var linecount = $("#linecount").val();
var linediv = $(".lines").html();
linecount++;
$("#linecount").val(linecount);
var newline = $('<div class="dropzone ui-droppable" class="ui-droppable" style="height:75px;width:100%;border:1px solid black">New Drop Zone ' + linecount + '</div>').appendTo(".lines");
newline.droppable( {
drop: function(event,ui)
{
alert('dropped'+linecount);
}
});
}

Related

JQuery Sortable with dynamic DIV

I have a page that implements jQuery draggable, droppable, and sortable. It contains rows of div's, an "Add Line" button, and an image icon that can be dragged onto any div row that causes a modal window to display allowing an image to be placed onto the row. Everything works great...except:
I use jQuery sortable to allow the rows to be re-arranged. As dragging occurs (constrained to the y-axis), the div that the dragged div is being dragged over, and placed after if it is dropped, is colored gray. This works great, except when there are images in a DIV, causing the dragged DIV to have a much greater height than an empty div. It doesn't seem to track properly, as demomnstrated by how the rows turn to and from gray.
Here is some JQuery code:
$(".dropzone").droppable({
over: function(event,ui)
{
var ElementOver = $(event.target);
var DraggedElement = $(ui.draggable);
var IDofDraggedElement = DraggedElement.attr("id");
ElementOver.css("background-color","lightgray");
},
out: function(event,ui)
{
var ElementOver = $(event.target);
ElementOver.css("background-color","");
},
drop: function(event,ui)
{
DropObject(event,ui); //This handles Ajax activity
var ElementOver = $(event.target);
ElementOver.css("background-color","");
}
});
$("#lines").sortable({
handle: '.iconmove',
axis: 'y',
tolerance: 'pointer',
helper: 'clone'
});
and here is a sample of my HTML:
<div id="linecontainer" class="w3-card-4 w3-padding">
<div id="lines">
<cfoutput query="qFormLines" group="formlineid">
<div class="w3-row w3-padding" style="width:80%" id="line#formlineid#">
<div class="w3-col w3-center l1 m1 s1">
<img id="moveicon#formlineid#" class="iconmove" src="_images/updown24.png" title="Move Line" >
</div>
<div class="dropzone w3-padding w3-col w3-border l11 m11 s11" id="zone#formlineid#" >
<cfoutput>
<cfif imagefile NEQ "">
<img id="formitem#formitemid#" class="w3-border" src="_images/#imagefile#" >
</cfif>
</cfoutput>
</div>
</div>
</cfoutput>
</div>
</div>
Here is a fiddle I created, although it doesn't quite work the same as my local source code:
Fiddle
Although not ideal, just change the JQuery Droppable method's option - Tolerance from its default 'intersect' to 'touch'. It will allow you to see the effect whenever the draggable overlaps the droppable by any amount of touching:
$(".dropzone").droppable({
// Change the tolerance to 'touch'
tolerance: "touch",
over: function(event, ui) {
var ElementOver = $(event.target);
var DraggedElement = $(ui.draggable);
var IDofDraggedElement = DraggedElement.attr("id");
console.log(IDofDraggedElement);
//if (IDofDraggedElement.indexOf("imageicon") == 0) //MOVING A LINE
ElementOver.css("background-color", "lightgray");
},
out: function(event, ui) {
var ElementOver = $(event.target);
ElementOver.css("background-color", "");
},
drop: function(event, ui) {
var ElementOver = $(event.target);
ElementOver.css("background-color", "");
}
});
$("#lines").sortable({
handle: '.iconmove',
axis: 'y',
tolerance: 'pointer',
helper: 'clone'
});
The droppable's tolerance has four options:
"fit − Draggable covers the droppable element in full.
intersect − Draggable overlaps the droppable element at least 50% in both directions.
pointer − Mouse pointer overlaps the droppable element.
touch − Draggable overlaps the droppable any amount of touching."
Quote from https://www.tutorialspoint.com/jqueryui/jqueryui_droppable.htm

Jquery data-role collapsible events aren't being captured in Jquery Mobile

Could anybody please let me know why the following code isn't working when i am using with Jquery mobile JS
http://jsfiddle.net/znz17ctm/7/
This is my code
<div role="main" class="ui-content oms-content" id="dd">
<div class="myactivelabelsWrap" id="result"></div>
</div>
var response = {
"Restaurants": [{
"RestrntArea": "Haii",
"cust_loc_id": "374"
}, {
"RestrntArea": "rerrrwe",
"cust_loc_id": "373"
}]
}
showLabels();
function showLabels() {
//$("#result").html("");
var favoriteresultag = '';
for (var i = 0; i < response.Restaurants.length; i++) {
var name = response.Restaurants[i].RestrntArea;
if (name) {
favoriteresultag +=
'<div data-role="collapsible" data-inset="false" class="my-collaspible"><h3>' +
name +
' <a class="icon-pencil-1 labelEditIcon "></a></h3></div>';
}
}
$("#result").append(favoriteresultag).trigger("create");
}
$(document).ready(function() {
$('.my-collaspible').bind('expand', function() {
alert('Expanded');
});
$('.my-collaspible').bind('collapse', function() {
alert('Collapsed');
});
});
Why the collapse and expand even'ts are being captured ??
Instead of document ready i tried with al the page events of mobile . But no luck .
From your fiddle I can't tell which version of jQM you are using. You have checked version 1.3 but then added the 1.4 css. Assumin version 1.4, I have updated your fiddle:
FIDDLE
Basically, you need to use event delegation to attach the events because the collapsibles do not exist at the time of the bind. Also the event names are actually collapsibleexpand and collapsiblecollapse.
So use on() instead of bind() by handling the event on the parent div and delegating it to all items with class my-collapsible that exist now or added dynamically:
$("#result").on('collapsibleexpand', '.my-collaspible', function () {
alert('Expanded');
});
$("#result").on('collapsiblecollapse', '.my-collaspible', function () {
alert('Collapsed');
});

Drag&Drop in jQuery on Table Cells

I have a table and need to drag/drop cells containing data into blank cells. I'm able to drag and drop fine, but once a cell is dragged away, I need its "old" position to now become a droppable cell. Since the cell is dragged, I need something else to reference. I ended up wrapping each of the td elements in a div element, but all references return "undefined" on the inner cellDiv id (or return the outer tableDiv id). On the fiddle, I notice that the blue background is not appearing so I don't think the 'cellDiv' is doing much.
Next I am going to try swapping the td and cellDiv elements, but I decided to post the question first, as I've searched everywhere and cannot seem to find this specific problem addressed. Thanks for your help.
here is the problem in a jsfiddle: http://jsfiddle.net/tgsz34hx/3/
And the code:
<div id='tableDiv'>
<table>
<tr id='row1'>
<div class='cellDiv' id='r1c1'>
<td class='drop' id='col1'>Drop Here</td></div>
<div class='cellDiv' id='r1c2'>
<td class='nodrop' id='col2'>Drag Me</td></div>
</tr>
</table>
</div>
$(document).ready(function () {
var fromDiv;
$('.nodrop').draggable({
cursor: "move",
appendTo: "body",
revert: "invalid",
start: function (event, ui) {
var thisDiv = $(this).attr('id');
fromDiv = $(this).closest('.cellDiv').attr('id');
alert("thisDiv=" + thisDiv + ", fromDiv=" + fromDiv);
}
});
$('.drop').droppable({
accept: ".nodrop",
tolerance: "pointer",
snap: ".drop",
drop: function (event, ui) {
var parenttd = $(ui.draggable).closest('td').attr('id');
var parentdiv = $(ui.draggable).closest('.cellDiv').attr('id');
// alert("parenttd=" + parenttd + ", parentdiv=" + parentdiv);
$(this).removeClass('drop');
$(this).addClass('nodrop');
$(this).droppable('option', 'disabled', true);
}
});
});
#tableDiv {
background-color: grey;
}
#tableDiv td {
background-color: red;
}
#tableDiv div {
background-color: blue;
}

auto-scroll grid in jqm

I have a simple webapp consisting of a main page that contains a grid with 3 columns.
<div data-role="content">
<div class="ui-grid-b" id="main">
</div>
</div>
At runtime this grid is expanded with new rows by clicking a button.
$(document).on('pageinit', '#page-home', function() {
$('button').on('click', function() {
var table = $('#main');
var blocka = $('<div class="ui-block-a">One</div>');
var blockb = $('<div class="ui-block-b">Two</div>');
var blockc = $('<div class="ui-block-c">Three</div>');
blocka.appendTo(table);
blockb.appendTo(table);
blockc.appendTo(table);
});
});
Now I have the problem that if there are more rows added (let's say 10) then the last rows run out of screen.
Is there a simple way to automatically scroll to the last row everytime a new one is created?
I know that I can get the element by calling table.find('.ui-block-a:last') but I don't know how to scroll to the found element.
Thanks in advance!
As suggested in this answer: How to go to a specific element on page?
Add the following after blockc.appendTo(table) in your click handler:
$('html, body').animate({
scrollTop: blocka.offset().top + 'px'
}, 'fast');
Here is fiddle demo: http://jsfiddle.net/ezanker/5ap48/

Snap a div to the middle of a screen using scrollview

probably nobody is there on a friday of a long weekend to answer this...
Working with jquery mobile beta and jquery mobile Scrollview
plugin.
There are 5 divs which are renedred by the scrtollview plugin and they are successfully drawn in a carousel manner with 5 divs side by side...
<div class="scrollme" data-scroll="x">
<div class="indDiv"> one
</div>
<div class="indDiv"> two
</div>
<div class="indDiv"> three
</div>
<div class="indDiv"> four
</div>
<div class="indDiv"> five
</div>
</div>
$('div.indDiv').bind('tap', function(e){
var clickedDiv = $(this);
// snap clickedDiv to the middle of the page
});
I have this requirement that when I tap on a div inside this carousel, i would want to move the corousel programattically so that the tapped div is snaped to the middle of the screen. I do not see a way to do with the scrollview plugin methods... I am flexible to switch to another plugin too...
anybody??
Thanks
Mostly, this involves appending something to the end of the document body due to position:relative/absolute issues.
I've written a simple plugin that allows centering and shading... It might not be production quality, but I've been happy with it for a while.
(function($) {
$.fn.center = function() {
this.css("position", "absolute");
this.css("top", (($(window).height() * .4) - this.height()) / 2
+ $(window).scrollTop() + "px");
this.css("left", ($(window).width() - this.width()) / 2
+ $(window).scrollLeft() + "px");
return this;
}
var shade = 0;
$.fn.unshade = function() {
$('.shade:last').remove();
var $children = $('.shade-front:last').children();
$children.each(function(k, v) {
if ($.data(v, 'shade-replace-previous').size() != 0) {
$.data(v, 'shade-replace-previous').append(v);
} else {
$.data(v, 'shade-replace-parent').prepend(v);
}
});
$('.shade-front:last').remove();
return $children;
}
$.fn.shade = function(css) {
var $shade = $('<div class="shade"/>');
$shade.css( {
position : "absolute",
width : '100%',
height : '100%',
top : 0,
left : 0,
background : "#000",
opacity : .7
})
$shade.click(function() {
$(this).unshade();
})
$('body').append($shade);
// Record our element's last position
this.each(function(k, v) {
var $this = $(v);
var prev = $this.prev();
var par = $this.parent();
$.data(v, 'shade-replace-previous', prev);
$.data(v, 'shade-replace-parent', par);
});
// Add them to the shadefront
var $shade_front = $('<div class="shade-front"/>');
$shade_front.css("background", "#FFF");
$shade_front.css("margin", "auto");
$shade_front.css("text-align", "center");
if (css) {
$shade_front.css(css);
}
$shade_front.append(this);
$shade_front.center();
$('body').append($shade_front);
return $shade_front;
}
})(jQuery);
I am using this plugin and then binding the swiperight/left to the next/prev buttons.
https://github.com/Wilto/Dynamic-Carousel

Resources