I have a list something similar to this in React
<div id="list">
<Item data-id="1">
<Item data-id="2">
<Item data-id="3">
<Item data-id="4">
<Item data-id="5">
</div>
I am using sortablejs npm library for sorting.
Now, I want to exclude the last 2 elements from sorting,
Below is the function I use for sorting
import Sortable from 'sortablejs';
let list = document.getElementById('list');
Sortable.create(list, {
ghostClass: 'ghost',
store : {
set: (sortable) => {
// logic to store new order in DB
sortable.destroy();
}
}
});
Expected Result:
Last 2 items should become non-draggable
also, first 3 items should not be able to go below them
How can I achieve that?
Solution for a similar problem is at:
How to exclude an element from being dragged in sortable list?
I want equivalent of below mentioned code in React:
$(function() {
$('.sortable').sortable();
$('.sortable').disableSelection();
$('.sortable').sortable({ cancel: '.note' });
});
$('.sortable').sortable({
items : ':not(.note)'
});
maybe you can use the "filter" config option?
var sortable = new Sortable(el, {
// variables
group: "name", // or { name: "...", pull: [true, false, 'clone', array], put: [true, false, array] }
sort: true, // sorting inside list
delay: 0, // time in milliseconds to define when the sorting should start
delayOnTouchOnly: false, // only delay if user is using touch
touchStartThreshold: 0, // px, how many pixels the point should move before cancelling a delayed drag event
disabled: false, // Disables the sortable if set to true.
store: null, // #see Store
animation: 150, // ms, animation speed moving items when sorting, `0` — without animation
easing: "cubic-bezier(1, 0, 0, 1)", // Easing for animation. Defaults to null. See https://easings.net/ for examples.
handle: ".my-handle", // Drag handle selector within list items
filter: ".ignore-elements", // Selectors that do not lead to dragging (String or Function)
preventOnFilter: true, // Call `event.preventDefault()` when triggered `filter`
draggable: ".item", // Specifies which items inside the element should be draggable
dataIdAttr: "data-id",
ghostClass: "sortable-ghost", // Class name for the drop placeholder
chosenClass: "sortable-chosen", // Class name for the chosen item
dragClass: "sortable-drag", // Class name for the dragging item
swapThreshold: 1, // Threshold of the swap zone
invertSwap: false, // Will always use inverted swap zone if set to true
invertedSwapThreshold: 1, // Threshold of the inverted swap zone (will be set to swapThreshold value by default)
direction: "horizontal", // Direction of Sortable (will be detected automatically if not given)
forceFallback: false, // ignore the HTML5 DnD behaviour and force the fallback to kick in
fallbackClass: "sortable-fallback", // Class name for the cloned DOM Element when using forceFallback
fallbackOnBody: false, // Appends the cloned DOM Element into the Document's Body
fallbackTolerance: 0, // Specify in pixels how far the mouse should move before it's considered as a drag.
dragoverBubble: false,
removeCloneOnHide: true, // Remove the clone element when it is not showing, rather than just hiding it
emptyInsertThreshold: 5, // px, distance mouse must be from empty sortable to insert drag element into it
Related
I am currently working on a viewer using OpenSeadragon, and the Picturae selection plugin for adding a cropping tool.
Selection is working fine, but when I rotate the image, rotation of selection is acting weird : it rotate around the bottom left corner, instead of the center of selection.
I made a video of the case : normal behavior of selection rotation when image is straight, and weird behavior when image is rotated.
The desired effect is to rotate around the center of selection...
I use the following code to initialize selection :
var selection = viewer.selection({
element: null, // html element to use for overlay
showSelectionControl: true, // show button to toggle selection mode
toggleButton: null, // dom element to use as toggle button
showConfirmDenyButtons: true,
styleConfirmDenyButtons: true,
returnPixelCoordinates: true,
keyboardShortcut: 'c', // key to toggle selection mode
rect: null, // initial selection as an OpenSeadragon.SelectionRect object
startRotated: false, // alternative method for drawing the selection; useful for rotated crops
startRotatedHeight: 0.1, // only used if startRotated=true; value is relative to image height
restrictToImage: true, // true = do not allow any part of the selection to be outside the image
onSelection: function(rect) { viewer_crop_download(rect); },
cancel : function(){ viewer_crop_disable(); },
prefixUrl: PREFIX_URL,
navImages:
{
selection: {
REST: 'selection_rest.png',
GROUP: 'selection_grouphover.png',
HOVER: 'selection_hover.png',
DOWN: 'selection_pressed.png'
},
selectionConfirm: {
REST: 'selection_confirm_rest.png',
GROUP: 'selection_confirm_grouphover.png',
HOVER: 'selection_confirm_hover.png',
DOWN: 'selection_confirm_pressed.png'
},
selectionCancel: {
REST: 'selection_cancel_rest.png',
GROUP: 'selection_cancel_grouphover.png',
HOVER: 'selection_cancel_hover.png',
DOWN: 'selection_cancel_pressed.png'
},
}
});
OpenSeadragon : https://openseadragon.github.io
Picturae selection plugin : https://picturae.github.io/openseadragonselection/
Thanks !
I have a requirement to create a dragable free-scrolling carousel, which I can do with the likes of http://flickity.metafizzy.co/ or http://idangero.us/swiper/. However neither of these allow me to specify an initial movement. Is it possible to simulate a click-drag on these carousels to 'give them a spin'?
Something like:
$('.home-map-wrapper').trigger('mousedown').trigger('mousemove', { clientX: 0, clientY: 0 }).trigger('mousemove', { clientX: 10, clientY: 0 });
Update 1
I've created a fiddle with Flickety to demonstrate. How do I give this an initial movement?
https://jsfiddle.net/sprintstar/b34w9uec/
Update 2
I want it to move initially like you've grabbed it and given it a gentle spin. But I don't want it to auto advance, like with 'autoPlay'. Unfortunately Flickerty offers no such configuration.
You do not have to use events to launch your carousel using flickity,
You can simply:
Retrieve your Flickity instance
Specify a velocity for your carousel
Specify that you are in freeScrolling mode (and not scrolling toward a specific position)
Launch animation
Code
function initFlickety() {
var flickityElement = $('.home-map-wrapper').flickity({
freeScroll: true,
wrapAround: true,
prevNextButtons: false,
pageDots: false,
freeScrollFriction: 0.00
});
var flickity = flickityElement.data("flickity"); // [1]
flickity.velocity = -1; // [2]
flickity.isFreeScrolling = true; // [3]
flickity.startAnimation(); // [4]
}
Fiddle
https://jsfiddle.net/b34w9uec/6/
If I understood correctly you want to have an initial movement on load.
I have tried setting autoPlay to a specific value on plugin initialization like this:
$('.home-map-wrapper').flickity({
autoPlay: 1000,
freeScroll: true,
wrapAround: true,
prevNextButtons: false,
pageDots: false,
freeScrollFriction: 0.00
});
Check this Fiddle
I have a fancytree populated with some json. I also have a droppable div. I want to be able to drag nodes within the tree (ie to move stuff about within the contained hierarchy) and I want to be able to drag stuff from the tree into my external droppable div.
How can I do this?
Here's what I have:
My html:
<div id="tree"></div>
<div id="droppable">
stuff
</div>
dnd initialisation options:
{
autoExpandMS: 400,
focusOnClick: true,
preventVoidMoves: true, // Prevent dropping nodes 'before self', etc.
preventRecursiveMoves: true, // Prevent dropping nodes on own descendants
dragStart: function(node, data) {return true;},
dragEnter: function(node, data) {return true;},
dragDrop: function(node, data) {data.otherNode.moveTo(node, data.hitMode);},
draggable: {
containment: 'document',
scroll : false,
scrollSpeed: 7,
scrollSensitivity: 10,
}
},
droppable initialisation
$('#droppable').droppable({
onDrop : function(e,source){
alert('dropped: '+source.textContent);
window.dropped = source;
window.event = e;
},
});
Extensions:
I'm making use of ["dnd","edit","contextMenu"] extensions. I'm mentioning this in case there is some conflict I am not aware of... I did however disable the edit and contextMenu to no avail.
Behavior:
The contextMenu and edit extensions work fine.
I can drag and drop items within the tree to reorder nodes.
I cannot drag stuff out of the tree
with scroll: true the tree just gets some scrollbars that scroll to infinity as I drag over the edge
with scroll: false the tree scrollbars behave the same but no actual scrolling occurs
containment seems to have no effect
Included resources:
jquery.js jquery-ui-1.11.0.js
jquery.fancytree-all.css
jquery.contextMenu.css
jquery.contextMenu-1.6.5.js
jquery.fancytree.contextMenu.js
fancytree.min.css
To prevent scrolling inside the tree container:
$("#tree").fancytree({
...
dnd: {
...
draggable: {
scroll: false
},
and custom CSS
ul.fancytree-container {
position: inherit;
}
To make containment work:
$("#tree").fancytree({
dnd: {
...
draggable: {
revert: "invalid"
scroll: false,
appendTo: "body", // Helper parent (defaults to tree.$container)
helper: function(event) {
var $helper,
sourceNode = $.ui.fancytree.getNode(event.target),
$nodeTag = $(sourceNode.span);
$helper = $("<div class='fancytree-drag-helper'><span class='fancytree-drag-helper-img' /></div>")
.append($nodeTag.find("span.fancytree-title").clone());
// Attach node reference to helper object
$helper.data("ftSourceNode", sourceNode);
// we return an unconnected element, so `draggable` will add this
// to the parent specified as `appendTo` option
return $helper;
},
},
}
[...]
});
There is an example that can be found under the tests directory of the fancytree source that does the exact same thing. Take a look at it here: http://wwwendt.de/tech/fancytree/test/test-ext-dnd.html
Hope this helps.
I have faced the same issue with dragging elements out of the tree and ended up with some quick css hack for fancytree-container element:
ul.fancytree-container {
overflow: visible;
}
The problem is that FancyTree uses its own draggable helper which is attached to the tree element. See _onDragEvent in jquery.fancytree.dnd.js (line 389).
I got round this by hacking the code to append the helper to the body i.e.
$("body").append($helper);
...instead of...
$("ul.fancytree-container", node.tree.$div).append($helper);
For my application, after an element is dragged and snapped to the droppable zone I need to continue to allows for that dragged item to be moved vertically only. I have already gone ahead and done this, but I also need for that item to only be dragged and snapped to pixel increments. How can this be done?
For example, I have a timeline and I need the elements to snap to 15 minute increments. I need to know if this is possible with the draggable function or do I need to come up with some slider hybrid? I'd rather not use some hybrid approach if possible.
Code Snippet:
$(".activity_link").draggable({
"snap": ".trek_slider",
"snapMode": "inner",
// "snapTolerance" : 30,
"revert": function (event, ui) {
// on older version of jQuery use "draggable"
// $(this).data("draggable")
// on 2.x versions of jQuery use "ui-draggable"
// $(this).data("ui-draggable")
$(this).data("uiDraggable").originalPosition = {
top: 0,
left: 0
};
$(this).draggable("option", "axis", false);
// return boolean
return !event;
// that evaluate like this:
// return event !== false ? false : true;
}
});
$(".trek_slider").droppable({
"tolerance": "touch",
"over": function (event,
ui) {
var left_position = parseInt($(ui.draggable).css("left"));
$(ui.draggable).find(".activity_caret").show();
$(ui.draggable).draggable("option", "axis", "y");
}
});
Try this
$( ".your_div" ).draggable({ grid: [ 1,1 ] });
In above example it will be draggedx by only one pixel in each direction
Please Note: Do not forget to add your other options.
I have a page with multiple instances of anythingSlider on it and I'm using PHP to dynamically load pages that swap out the content in them.
Reference: http://ceedcreative.com/CEED_2.0/
I would like to edit the anythingSlider to disable the previous / next buttons if the UL it's displaying only has one LI within it.
In other words, no buttons, just a clean div that's the same heigh and width (no scrolling) if there's only one image.
Try this
$('.anythingSlider:not("#topSlider")').each(function(i, slider) {
// If any slider has less than 2 let members
if ( $("ul li", slider).length < 2 ) {
// don't apply the slider functionality
return;
}
$(slider).anythingSlider({
easing: "easeInOutExpo",
autoPlay: false,
delay: 3000,
startStopped: false,
animationTime: 600,
hashTags: false,
buildNextPrevButtons: true,
buildNavigation: false
});
});
If, for some reason, that doesn't work, this snippet will inspect the list length of every anythingSlider and hide the arrow buttons for any list that is only 1 in length (after excluding the front and back clones).
$(".anythingSlider").each(function(i, slider) {
if ( $("ul li", slider).not(".cloned").length == 1 ) {
$(".arrow", slider).hide();
}
});