hiding portion of div jquery sortable widget - javascript

I have some markup similar to below, and I am trying to hide the "some_row" TR's.
<div id="sortable">
<table>
<tr><td>Some Title 1</td></tr>
<tr class="some_row"><td><textarea ...></td><tr>
</table>
<table>
<tr><td>Some Title 2</td></tr>
<tr class="some_row"><td><textarea ...></td><tr>
</table>
</div>
Here is what I have tried:
$(function () {
$("#sortable")
.sortable({
helper: function (e, o) {
o.find("#some_row").hide();
return o;
},
start: function () {
$(".some_row").hide();
},
stop: function () {
$(".some_row").show();
}
})
.disableSelection();
});
Initially i started with just start and stop events, then I added helper because the, what i am guessing is a cloned selected row, had a hidden some_row div but the same height.
Anyways, the above works as far as style perfectly, however it appears the widget is still taking into account the original heights of the surrounding divs.
Is there anything I can do to salvage this idea?

You need to call the hide on .somerow before the helper is returned.
The helper is a clone of the original div and what you see being dragged. So when you hide the rows the clone has already been created.
The refresh that runs after start is done to reload the sortable objects to adjust for the new height.
Fiddle Example
$(function () {
$("#sortable")
.sortable({
cursor: 'move',
cursorAt: { left: 0, top: 10 },
helper: function (e, o) {
$(".some_row").hide();
o.find("#some_row").hide();
return o;
},
start: function () {
$( "#sortable" ).sortable( "refresh" );
},
stop: function () {
$(".some_row").show();
}
})
.disableSelection();
});
Also you can define the cursor position when dragging (relative to the helper) and the cursor type that displays when hovering using the cursor and cursorAt options of the jqueryui sortable api

Related

How do I light up an entire single row by hovering on a span in one of the columns?

If I hover over the span with class "fromThisSpan", how do I change the background-color of the div that contains classes row and highlightThisRow?
There are a bunch of rows in the ul, and each row has a few columns.
The span is in the last column. The span also has a hover in the css (I didn't include it here).
So far, at one point I did get the desired results, but only for the first row.
I was using id's instead of classes for the div and span.
I've added a couple of my failed attempts of my jquery below.
This is a composite outline of the structure I'm using to show where I'm going with this only.
It's not a working code. The problem I'm having is with the jquery.
[ html/razor ]
<ul>
#foreach(ItemType item in ItemCollection)
<li>
<div class="row highlightThisRow">
<div class="col-md-4">
... item.contents1
</div>
<div class="col-md-4">
... item.contents2
</div>
<div class="col-md-4">
... item.contents3
<span class="fromThisSpan">Delete</span>
</div>
</div>
</li>
</ul>
Here I was trying to attach the hover event using the .on()
[ jquery ]
$(".fromThisSpan").on("hover", $(".fromThisSpan").hover(
(new function () {
$(".highlightThisRow").css("background-color", "#fce2e2");
}),
(new function () {
$(".highlightThisRow").css("background-color", "#ffffff");
})
));
This is an SO post I found and decided to give it a try, but didn't work for me.
The source: Adding hover CSS attributes via jQuery/Javascript
[ jquery ]
$(".fromThisSpan").mouseenter(function () {
$(".highlightThisRow").css("background-color", "#fce2e2");
}).mouseleave(function () {
$(".highlightThisRow").css("background-color", "#ffffff");
});
[ UPDATE ] Solved
This was the solution that worked in my case.
$(".fromThisSpan").hover(function () {
$(this).closest(".highlightThisRow").css("background-color", "#fce2e2");
}, function () {
$(this).closest(".highlightThisRow").css("background-color", "#ffffff");
});
Use closest to get the relative highlightThisRow of the element selected
$(function(){
$(".fromThisSpan").mouseenter(function () {
$(this).closest(".highlightThisRow").css("background-color", "#fce2e2");
}).mouseleave(function () {
$(this).closest(".highlightThisRow").css("background-color", "#ffffff");
});
});
or:
$(function(){
$("body").on('hover','.fromThisSpan',function () {
$(this).closest(".highlightThisRow").css("background-color", "#fce2e2");
},function () {
$(this).closest(".highlightThisRow").css("background-color", "#ffffff");
});
});
demo:https://jsfiddle.net/7bgqfdkj/
try (this).parent
$("#fromThisSpan").on("hover", $("#fromThisSpan").hover(
(new function () {
$(this).parent("#highlightThisRow").css("background-color", "#fce2e2");
}),
(new function () {
$(this).parent("#highlightThisRow").css("background-color", "#ffffff");
})
));

JQuery - Cannot seem to bind event to dynamic DOM elements

Using JQuery UI Draggable, I am cloning elements as they leave an unordered list. As these are new to the DOM, i'm trying to use the JQuery On() method to bind an event which will show a hidden link. The anchor with the class cancel has display: none; in the css.
HTML
<ul class="current-campaign">
<li class="draggable">One <a class="pull-right cancel" href="#">
<i style="color:red">Icon</i>
</a>
</li>
</ul>
<ul class="new-campaign sortable"></ul>
JQuery
$(".sortable").sortable();
$(".draggable").draggable({
connectToSortable: ".sortable",
helper: "clone",
});
$(".current-campaign").on("mouseout", ".cancel", function () {
$(".cancel").show();
});
Really having trouble figuring out why the link doesn't show up when it leaves the unordered list. Here's a JS fiddle to see it in action.
http://jsfiddle.net/og937wy7/
FINAL EDIT WITH ANSWER
Armed with the knowledge of how to use the on() function, I fixed up my code so it's working as I intended.
$(document).on("mouseover", ".new-campaign", function (e) {
console.error($(this));
$(".new-campaign").find('.cancel').show();
});
http://jsfiddle.net/og937wy7/4/
You are attaching an event to .cancel, which is not at all in the view:
$(".current-campaign").on("mouseout", ".cancel", function () {
$(".cancel").show();
});
How can you mouseout, when .cancel doesn't have an area? Replace it with .draggable:
$(".current-campaign").on("mouseout", ".draggable", function () {
$(".cancel").show();
});
I guess you are looking for the cancel to be shown once you hover and when you come away, it should hide. So change your code to:
$(".current-campaign, .new-campaign").on("mouseout", ".draggable", function () {
$(".cancel").hide();
}).on("mouseover", ".draggable", function () {
$(".cancel").show();
});
I would also tell this is not a right way, because, it affects all the .cancel. So you might need to use $(this).find():
$(".current-campaign, .new-campaign").on("mouseout", ".draggable", function () {
$(this).find(".cancel").hide();
}).on("mouseover", ".draggable", function () {
$(this).find(".cancel").show();
});
Fiddle: http://jsfiddle.net/dpojx7so/
But, everything can be done using CSS itself!!!
You just need to add this CSS, instead of the whole JS:
.sortable:hover .cancel {
display: inline;
}
Fiddle: http://jsfiddle.net/mx58stx3/

jquery UI draggable: ui.children is not a function

i have a draggable list, a sortable-droppable list and a couple of li's inside the first.
now i want to pull them over, in the stop-funtion i have a function that adds a class to the first child (it's a span representing the clip-number like
<li>
<span>1.</span>
<span>Title</span>
<span>1min23sec</span>
</li>
). the reason for this is, i want to represent the original clip number in the playlist(sortable).
but i get a console error saying
TypeError: ui.children is not a function
ui.children("li")[0].addClass(".slot_clip_info");
i am not 100% sure, but i think this exact code HAS already worked in the past time, i might have changed somthing without knowing, but i am not aware of that.
draggable:
$(function() {
$(".pl_clipEntry").draggable({
appendTo: "body",
revert: "invalid",
connectToSortable: "#tracks",
distance: 20,
helper: function(){
return $(this).clone().width($(this).width()); // hack for the drag-clone to keep the correct width
},
stop: function(ui) {
ui.children("li")[0].addClass(".slot_clip_info");
},
zIndex: 100
});
});
sortable:
$(function() {
var removeItem;
$("#tracks").sortable({
items: "li:not(.placeholder)",
connectWith: "li",
placeholder: "sort_placeholder",
helper: "clone",
distance: 20,
sort: function () {
$(this).removeClass("ui-state-default");
updatePlaylist();
},
over: function (event,ui) {
updatePlaylist();
removeItem = false;
console.log(event);
console.log(ui);
var originalClass = ui.helper.context.childNodes[0].className;
console.log(originalClass);
var small_clip = originalClass.match(/(\d+)/g)[1];
ui.item.context.children[0].innerHTML = small_clip;
ui.item.context.children[0].classList.add("slot_clip_info");
},
out: function () {
updatePlaylist();
removeItem = true;
},
beforeStop: function(event,ui) {
if (removeItem) {
ui.item.remove();
}
},
stop: function(event,ui) {
console.log("checking placeholder");
var list = $(this);
var count = list.children(':not(.placeholder)').length;
list.children('.placeholder').css("display", count > 0 ? "none" : "block");
savePlaylist();
}
});
as soon as i pull and element IN or reorder them, i get the said error.
also, on refresh, the list seems to multiply itself.. but i guess that's another issue...
Full fiddle (pretty messy, functionality in top dropdown button "PL TOGGLE"
UPDATE: another thing i noticed: the first drag works without problems, then shows the error on release, subsequent drags will (mostly.. sometimes they do...) not work
you need to make ui a jquery object, and then wrap the first element in another jquery object to do what you want.
so change:
ui.children("li")[0].addClass(".slot_clip_info");
to
$($(ui).children("li")[0]).addClass(".slot_clip_info");
In jQuery UI's draggable module, the stop function has 2 parameters : event and ui.
ui is a javascript object (and not a jQuery one, there's a difference.)
This object has 3 attributes :
helper which is a jQuery object
position which is a javascript object
offset which is a javascript object
Depending on your HTML code (we don't have), you could replace
ui.children("li")[0].addClass(".slot_clip_info");
by
ui.helper.children("li")[0].addClass(".slot_clip_info");

Sortable, droppable nested list issue [duplicate]

I'm working on a project where I'm dragging elements from a 3rd party jQuery control to a jQuery sortable, using a combination of droppable and sortable.
This works perfectly fine, except the item being added is always added to the bottom of the sortable list, and you must then move it to the correct location as a separate step.
Is it possible to have the item added to the location where you dropped it in the list?
You can see this behavior in the jQuery shopping card droppable demo from here. Here is a jsfiddle of the same code. As you add items from the products to your cart at the bottom, it always adds at the bottom, even if you drop it near the top.
Here's the jQuery code:
$(function () {
$("#catalog").accordion();
$("#catalog li").draggable({
appendTo: "body",
helper: "clone"
});
$("#cart ol").droppable({
activeClass: "ui-state-default",
hoverClass: "ui-state-hover",
accept: ":not(.ui-sortable-helper)",
drop: function (event, ui) {
$(this).find(".placeholder").remove();
$("<li></li>").text(ui.draggable.text()).appendTo(this);
}
}).sortable({
items: "li:not(.placeholder)",
sort: function () {
$(this).removeClass("ui-state-default");
}
});
});
use droppable's drop event's callback to compare the current top offset position of the draggable helper with the top offset of every element already present or previously added in the droppable
drop: function (event, ui) {
if($(this).find(".placeholder").length>0) //add first element when cart is empty
{
$(this).find(".placeholder").remove();
$("<li></li>").text(ui.draggable.text()).appendTo(this);
}
else
{
var i=0; //used as flag to find out if element added or not
$(this).children('li').each(function()
{
if($(this).offset().top>=ui.offset.top) //compare
{
$("<li></li>").text(ui.draggable.text()).insertBefore($(this));
i=1;
return false; //break loop
}
})
if(i!=1) //if element dropped at the end of cart
{
$("<li></li>").text(ui.draggable.text()).appendTo(this);
}
}
}
DEMO WITH CODE
FULL SCREEN DEMO
What about doing this? Using both the connectToSortable AND connectWith options works, I think. There might be a more clever way to hide/show the placeholder, but this definitely works.
$(function () {
$("#catalog").accordion();
$("#catalog li").draggable({
appendTo: "body",
helper: "clone",
connectToSortable: "#cart ol"
});
$("#cart ol").sortable({
items: "li:not(.placeholder)",
connectWith: "li",
sort: function () {
$(this).removeClass("ui-state-default");
},
over: function () {
//hides the placeholder when the item is over the sortable
$(".placeholder").hide();
},
out: function () {
if ($(this).children(":not(.placeholder)").length == 0) {
//shows the placeholder again if there are no items in the list
$(".placeholder").show();
}
}
});
});
Work Demo in Fiddle

How do I control the style of the clone of a draggable div when moved to a sortable container?

What I'm trying to do is combine two projects:
One is an example of draggable and sortable list-items
The other is jEditable, which I'm using to make the list-items editable
Now I was able to append the edit class to the existing list items in the first link without any trouble. When I go to create a new draggable item (a clone) and move it to the sortable list, I want it to take on the css class of the older items. I have tried adding code to the draggable's stop event and the sortable's receive event with no luck. It's the original's style that changes, not the clone's.
receive: function(event, ui) {
alert("dropped item ID: " + ui.item.attr('id'));
$("#draggable").attr('class', 'edit');
}
stop: function() {
if ( !$( "#draggable" ).hasClass( "ui-state-hover" ) ) {
$( "#draggable" ).removeClass( "ui-state-highlight" );
$( "#draggable" ).addClass( "ui-state-default" );
$( "#draggable" ).addClass( "edit" );
}
}
How can I achieve this?
JSFiddle is here
You can actually utilize the ui in your sortable event stop. Here short definition of them:
ui.
helper: The jQuery object representing the helper being sorted
item: The jQuery object representing the current dragged element
offset: The current absolute position of the helper represented as { top, left }
position: The current position of the helper represented as { top, left }
originalPosition: The original position of the element represented as { top, left }
sender: The sortable that the item comes from if moving from one sortable to another
So you need to use stop event and change the ui.item style like this:
$(ui.item).attr('class', 'ui-state-default edit');
And you have to re-initiate the editable like this:
$(document).ready(function() {
initEditable();
});
function initEditable(){
$('.edit').editable('http://www.example.com/save.php', {
indicator : 'Saving...',
tooltip : 'Click to edit...'
});
$('.edit_area').editable('http://www.example.com/save.php', {
type : 'textarea',
cancel : 'Cancel',
submit : 'OK',
indicator : '<img src="img/indicator.gif">',
tooltip : 'Click to edit...'
});
}
$(function() {
$( "#sortable" ).sortable({
revert: true,
update: function() {
var orders = [];
$.each($(this).children(), function(i, item) {
orders.push($(item).data("x"));
});
$("#info").text("Order: " + orders.join(","));
},
stop: function(event, ui) {
$(ui.item).attr('class', 'ui-state-default edit');
initEditable();
}
});
});
See modified code here: http://jsfiddle.net/xvsMh/1/
Your events are correct, but as you realized, #draggable is the original item, not the cloned one. One way to get your cloned item would be to search for an item with identical classes in the sortable list. So instead of using:
$("#draggable").attr('class', 'edit');
you use:
$('#sortable .ui-draggable')
.removeClass('ui-state-highlight ui-draggable')
.addClass('ui-state-default edit');
Demo at JSFiddle

Categories

Resources