I have a problem that I can't seem to figure out. I'm trying to have a droppable element conditionally fire a different function based on the class of the item dropped. For the life of me I can't figure out how to do this. Here's the link: http://jsfiddle.net/643PC/22/
The pageContainer accepts Rows. Rows accept Spans. Spans should accept Actions and Fields and fire a different function based on which item is dropped. Any ideas?
Finished function with David's help:
function generalDrop(event, ui) {
var appendTarget = $(this);
if (ui.draggable.hasClass('field-item')) {
fieldDrop(event, ui, appendTarget);
}
else {
actionDrop(event, ui, appendTarget);
}
}
function actionDrop(event, ui, appendTarget) {
$(document.createElement('a'))
.addClass('btn btn-primary')
.attr('href', '#')
.text('Button')
.appendTo(appendTarget)
}
Change your generalDrop function to this:
function generalDrop(event, ui) {
if (ui.draggable.hasClass('field-item')) {
fieldDrop(event, ui);
}
else {
actionDrop(event, ui);
}
}
Related
I have a sortable div containers, that each contain a button to delete itself. This button calls a function which removes the div container from the DOM. Everything looks fine, until I begin to drag and re-order the sortable items. Now the deleted element does not show in the GUI (which is expected), however doing a check of the sortable array, seems to suggest it's still there.
How can I get it so that this array is properly updated during the removal? or during the sorting. Any help would be appreciated.
Below is my javascript.
$(function() {
// Make Cron Jobs Sortable
$("#controlContainer").sortable({
items: "> div:not(#controlHeader), serialize",
create: function(event, ui) {
cronJobOrder = $(this).sortable("toArray",{attribute: "id"});
},
update: function(event, ui) {
cronJobOrder = $(this).sortable("toArray",{attribute: "id"});
}
});
});
Then my function
// the variable being passed in is the "Delete" button reference, that way it can find the div container it's in.
function deleteCronJob(cronJob) {
var confirmation = window.confirm("Are You Sure?");
if (confirmation) {
$(cronJob).parents(".cronJobElement:eq(0)").fadeOut("medium", function() {
// Remove Item from cronJobOrder array
cronJobOrder.splice(cronJobOrder.indexOf($(this).attr("id")),1);
// Remove CronJob from View
$(this).attr("id").remove();
});
} else {
return null;
}
}
I set up for you a simple fiddle. Alerting the sortable elements as array (and the updates after the remove button is clicked). Build your stuff around it.
http://jsfiddle.net/K3Kxg/
function sortableArrayAlert() {
sortableArray = $('li').toArray();
alert(sortableArray);
}
$(function(){
sortableArrayAlert();
$('ul').sortable();
$('a').click(function(e){
e.preventDefault();
$(this).parent().remove().then(sortableArrayAlert());
});
});
I have a Wijmo Grid which allows row selection, whenever a user click on any column.
And I added a column to display a tooltip with additional info of the specific record.
The problem is when this column is clicked, Wijmo automatically selects the current row.
I've read the documentation, there is no event before selecting a row or clicking on a row. The selectionChanged event is not useful in this case, because it is fired after selecting a row.
I cannot add a tr click event handler and make e.preventDefault, because in this case the tooltip would not appear.
How could I prevent row selection, depending on the column clicked?
There is no native way to do this. What you could do is, handle the currentCellChanging event and set the 'selectionMode' option to none based on the clicked cell.
var isLoaded = false;
$("#gridview2").wijgrid({
loading: function (e, args) {
isLoaded = false;
},
loaded: function (e, args) {
isLoaded = true;
},
currentCellChanging: function (e, args) {
if (isLoaded) {
if (args.cellIndex == 5) {
$(this).wijgrid({ selectionMode: 'none' });
}
else {
$(this).wijgrid({ selectionMode: 'singleRow' });
}
}
}
});
use selectionMode="none" work fine
which not select anything by default
I'm trying to have a jQuery UI event fire only if it meets the criteria of being clicked while the shift key is in the keydown state ( to mimic being held), and if not disable the event.
This example uses jQuery UI's .draggable to drag a container div only if the user clicks and holds shift.
http://jsfiddle.net/zEfyC/
Non working code, not sure if this is the best way to do this or what's wrong.
$(document).click(function(e) {
$('.container').keydown(function() {
if (e.shiftKey) {
$('.container').draggable();
} else {
$('.container').draggable({
disabled: true
});
}
});
});
I see lots of errors with that code. Firstly, you only add the key listener after there's been a click on the document. Second you are adding keydown to the container div, rather than the whole document. Then, you also need to listen to keyup, since releasing the shift key should disable draggability, then you also need to pass disabled: false to the case where shift is down. And your handler is missing the e parameter. Try this:
$(function(e) {
var handler = function(e) {
if (e.shiftKey) {
$('.container').draggable({
disabled: false
});
} else {
$('.container').draggable({
disabled: true
});
}
};
$(document).keydown(handler);
$(document).keyup(handler);
});
I have two sortable lists linked together.
I have an event listener on the first list calling function "A" on "sortupdate" to do some functionality when I am sorting items within the list or when receiving items from the other list.
I also have an event listener on the second list calling function "B" on "sortreceive" to do some functionality when it has received an item from another list.
My problem is that whenever I move something from list 1 to list 2, function "A" is called as well, causing errors in my code. I would like to add an 'if' clause to the beginning of function "A" saying to run this code only if the first list is the target, but I can't for the life of me figure out how to reference the target.
Or maybe there is a better way to check if an item was dragged out of this list?
/* adding current code */
$("#divMainMenu").bind("sortupdate", function(event, ui)
{ dropRootCategory(event,ui);})//when the main menu receives a menu item
$("ul.divSubMenu ").bind("sortreceive", function(event, ui)
{ dropSubMenu(event, ui);})//when the main submenu receives a menu item
function dropRootCategory(event, ui)
{/*item dropped on root category*/
//do some different stuff
}
function dropSubCategory(event, ui)
{//item dropped on a sub submenu
//do some stuff
}
I have tried checking the target:
if (event.target.id == 'divMainMenu') { //
which doesn't work because the target id stays 'divMainMenu' no matter where I am dropping to.
Next I tried checking for sender:
if (ui.sender == 'null'){//
However, this only populated with any information after it passed through the sortupdate phase and went to the sortreceive, so again it triggered the code to run.
/*******Updated with answer
Per Keith's idea below, I answered this with the following code:
On initiation of the menu, I added a variable holding the length of the original length of the main menu
var numMenuItems = $('#divMainMenu').children().length;
Then for my if statement:
if ($('#divMainMenu').children().length >= numMenuItems){
//do some stuff
}
Thanks again Keith! I was going nuts on this one :)
You can trying using ui.sender according to the sortable documentation:
"ui.sender - the sortable where the item comes from (only exists if you move from one connected list to another)"
This looks like what you are looking for.
Ok, I really did find another answer to this.
By adding a flag to the start event when defining the sortable, AS WELL AS a function call to the stop event :
$('ul.divSortable').sortable({
items: "li:not(.liEdit)", //cancel: ".liEdit",
connectWith: '.divSortable',
start: function(event, ui) { setOriginalSub(ui); },
stop: function(event, ui) { isBeingSorted = false; sortSorter(event, ui); }
});
and a function which grabs the id before sorting takes place:
function setOriginalSub(ui)
{
originalSub = $(ui.item[0]).parent().attr('id');
}
I can now compare the original ID with the current ID.
function sortSorter(event, ui){
var parentID = $(ui.item[0]).parent().attr('id');
}
Brilliant, and I wouldn't have thought of it without Keith's help!
I've been looking for the same thing and have found the solution that worked for me here ( all credit to phpduck, I have only found this )
http://phpduck.com/jquery-ui-sortable-drag-items-between-two-lists/
$(function () {
var oldList, newList, item;
$(".categories-sortable").sortable({
connectWith: $('.categories-sortable'),
start: function (event, ui) {
item = ui.item;
newList = oldList = ui.item.parent();
},
stop: function (event, ui) {
console.log("Moved " + item.text() + " from " + oldList.attr('id') + " to " + newList.attr('id'));
},
change: function (event, ui) {
console.log(ui.sender);
if (ui.sender) {
newList = ui.placeholder.parent();
}
},
})
.disableSelection();
});
also, there's a fiddle: http://jsfiddle.net/ajberri/hEJF3/
example: i have an un-ordered list containing a bunch of form inputs.
after making the ul .sortable(), I call .disableSelection() on the sortable (ul) to prevent text-selection when dragging an li item.
..all fine but I need to re/enable text-selection on the form inputs.. or the form is basically un-editable ..
i found a partial solution # http://forum.jquery.com/topic/jquery-ui-sortable-disableselection-firefox-issue-with-inputs
enableSelection, disableSelection seem still to be un-documented: http://wiki.jqueryui.com/Core
any thoughts?
solved . bit of hack but works! .. any comments how i can do this better?
apply .sortable() and then enable text-selection on input fields :
$("#list").sortable({
stop: function () {
// enable text select on inputs
$("#list").find("input")
.bind('mousedown.ui-disableSelection selectstart.ui-disableSelection', function(e) {
e.stopImmediatePropagation();
});
}
}).disableSelection();
// enable text select on inputs
$("#list").find("input")
.bind('mousedown.ui-disableSelection selectstart.ui-disableSelection', function(e) {
e.stopImmediatePropagation();
});
A little improvement from post of Zack - jQuery Plugin
$.fn.extend({
preventDisableSelection: function(){
return this.each(function(i) {
$(this).bind('mousedown.ui-disableSelection selectstart.ui-disableSelection', function(e) {
e.stopImmediatePropagation();
});
});
}
});
And full solution is:
$("#list").sortable({
stop: function () {
// enable text select on inputs
$("#list").find("input").preventDisableSelection();
}
}).disableSelection();
// enable text select on inputs
$("#list").find("input").preventDisableSelection();
jQuery UI 1.9
$("#list").sortable();
$("#list selector").bind('click.sortable mousedown.sortable',function(e){
e.stopImmediatePropagation();
});
selector = input, table, li....
I had the same problem. Solution is quite simple:
$("#list").sortable().disableSelection();
$("#list").find("input").enableSelect();
The following will disable selection for the entire document, but input and select elements will still be functional...
function disableSelection(o) {
var $o = $(o);
if ($o.find('input,select').length) {
$o.children(':not(input,select)').each(function(x,e) {disableSelection(e);});
} else {
$o.disableSelection();
}
}
disableSelection(document);
But note that .disableSelection has been deprecated by jquery-ui and will someday go away.
EASY! just do:
$( "#sortable_container_id input").click(function() { $(this).focus(); });
and replace "sortable_container_id" with the id of the element that is the container of all "sortable" elements.
Quite old, but here is another way:
$('#my-sortable-component').sortable({
// ...
// Add all non draggable parts by class name or id, like search input texts and google maps for example
cancel: '#my-input-text, div.map',
//...
}).disableSelection();