Drag and drop to reorder HTML lists - javascript

I have an app for which I would like to be able to drag and drop to reorder and arrange colours into groups. jQuery's sortable for grids seems rather unresponsive and a little buggy. microjs recommends kbjr's DragDrop, but that library has no concept of lists, only movable objects. Sproutcore has a nice implementation, but I can't find a demo of it working for a grid.
My UI looks like this:
and I'd like users to be able to drag colours around within the groups as well as drag them between groups.

Try this: HTML5 Sortable. It is a jQuery plugin to create sortable lists and grids using native HTML5 drag and drop API.

Just a friendly update, since this question came up in the search. HTML5Sortable is no longer maintained. The recommended library is Sortable.
Size: 12kb minified.
Code:
var sortable = Sortable.create($('#items'));
Hope this help the next wanderer.

I found out that this (Nastable) is a little bit more usefull for it has nesting capabilities.
Update
Actually ended up using this plugin with more options.
Hope it helps.
Cheers!

I stumbled into this problem recently as well and implemented a fairly nice approach using proximity sorting - which is not how Sortable does it, curiously enough. Article can be found here. The basic premise is this:
const orderables = Array.from(parent.children).map((element, i) => {
return {i, element, centroid: computeCentroid(element)};
});
and then in the drag event handler:
const byDistance = orderables.map((orderable) => {
return {distance: distanceBetweenCursorAndPoint(evt, orderable.centroid), ...orderable};
}).sort((a, b) => a.distance - b.distance);
The first element in byDistance is the one you are reordering relative to, and there is some more code to determine direction.

Related

Angular Auto-scrolling with drag and drop

I'm new to Angular in the last few weeks. For a work project, I want the window to scroll up or down when I drag a DOM element to the top or bottom of the window.
I'm following an example for integrating dragula and dom-autoscroller into my application, since dragula doesn't have autos-crolling built in. I'm following this example from an angular application which uses touch and another on codepen which uses dragula and auto-scroller together.
From the examples, I created this logic:
const drake = this.dragulaService.find('MyDragGroup').drake;
this.scroll = autoScroll(
window,
{
margin: 30,
maxSpeed: 25,
scrollWhenOutside: true,
autoScroll() {
return this.down && drake.dragging;
}
});
Originally, I put this logic in a parent component, but the drake came back undefined. When I put it right on one of the components that handles the drag and drop, I get the following TypeError in the console:
...followed by an ERROR CONTEXT, which applies to the template associated to the component.
<div class="drag-things" dragula="MyDragGroup" [(dragulaModel)]="currentGroup.MyDragThings">
<div *ngFor='let item of currentGroup.MyDragThings'>
<app-drag-thing [currentDragThing]='item'></app-drag-thing>
</div>
</div>
I checked with the documentation and I don't think I'm doing anything unusual. The primary difference between the way I'm doing things and the way the examples and the documentation give is I'm using the directive to create the drake (using [(dragulaModel)], where they choose to create the drake within the component.
Could this be causing the problem? Why would it be causing the problem? How do I get my auto-scrolling to work? Is there just a better way to accomplish this in general?
So the answer is... Don't use Dragula if you need auto-scrolling. Instead use Angular Material's CDK drag and drop. It has auto-scrolling built in. Check it out:
https://material.angular.io/cdk/drag-drop/overview

Z-Index control objects in FabricJS using jQuery UI sortable

Hi I want to have Layers sort control like on photoshop using FabricJS
I have this solution but it's not working well when you have more than 3 objects on canvas:
$("#containerLayers").sortable({
change: function(event, ui){
$( "#containerLayers li" ).each(function(index,list){
if(objectArray[$(list).attr('id')]){
canvas.moveTo(objectArray[$(list).attr('id')],index);
}
});
canvas.renderAll();
}
});
Here is other parts of code:
https://jsfiddle.net/peLcju2h/16/
does anyone have a better solution than this?
Best solution for Layer ordering using FabricJS is this one:
$("#containerLayers").sortable({
update: function(event, ui){
var items = $(this).children();
items.each(function(i,item){
canvas.sendToBack(objectArray[item.id]);
});
canvas.renderAll();
}
});
Instead of using canvas.moveTo() just use canvas.sendToBack() and it will work perfect
Here is link and you can see that ordering is working good
https://jsfiddle.net/peLcju2h/24/
First of all, you have some important refactorings to make in your code, mainly because of the fact that a lot of its snipets are duplicated.
I did it already, and the final working code is here: https://jsfiddle.net/peLcju2h/18/
Let's see some considerations:
All the Canvas object creations had the same code, so wrap it into a function;
You were adding objs to your array through push() function, which is not wrong, but it messed up with your UI sortable handling. That's because every time you change li's position, only the canvas and HTML are updated, but not the array itself.
You could use a reordering function for this, but it wouldn't fit the goal here once element positions don't have a predefined order or changing logic.
Instead, I decided to go with an auxiliary array, which is gonna be populated every time the items are sorted.
Push the items via [] operator into the array, using the object id as the key;
In the end, notice that I put a promise to guarantee the new objectArray will be rendered only after the canvas work has been done.
Note: JSFiddle only works with HTTPS external links, so make sure you
import them correctly in future attempts, even if you're doing this
via CSS #import.

What does ui.draggable.draggable means?

I am new to javascript and have stated to learn javascript. I came across a piece of code .I would like to know the use and meaning of
ui.draggable.dragabble in the code shown below
drop:function(e,ui){
var drag = ui.draggable;
$(this).droppable('option', 'accept', drag);
drag.css({'top':$(this).css('top'),'left':$(this).css('left')});
drag.draggable('option', 'revert', function(){return false});
var drop_index=$(this).attr("id").split('_')[1];
I would also like to know the sites to learn about drag and drop in javascript,in a better way.
Any help is appreciated in advance.
"ui.draggable" refers to the object containing all the elements that are currently being dragged on the page.
The function
drop: function(e, ui) {
}
is executed when a draggable object is dropped on a droppable element. You can refer to the jquery-ui API documentation here: http://api.jqueryui.com/category/interactions/ for drag and drop functionalities. It is to the point and apt. Also do check their demos. Start with the demos for better grasp of it.
For drag and Drop:
HTML5 already has attributes 'draggable="true"' that you can add to your elements. You can then attach events like handleDrag, handleDrop etc so you get the required functionality. Check it here: https://www.html5rocks.com/en/tutorials/dnd/basics/
jQueryUI has interactive widgets that can be added to your page elements. It is pretty simple to grasp. Refer to the above link mentioned for exploring. You can use touch-punch library http://touchpunch.furf.com/ to make jqueryUI work on mobile devices as well.
You can write your own pure javascript drag and drop function. I found one here: https://github.com/lukasolson/drag-n-drop-js .
I know only these 3 ways for drag-and-drop. There might be others as well.

Rearrange divs randomly using Javascript or Jquery

I've got a 3x3 grid layout using divs which upon clicking a button I need the divs to rearrange randomly. The following link illustrates an idea of what I need to create.
I don't need help with the HTML layout nor CSS design of the assignment per-se, but rather how to create the onclick function using native Javascript or jQuery in order for the "shuffle" and "sort" buttons to work. If possible, preferably Jquery, as I am more comfortable with its syntax.
I thank all in advance for help and support. Any useful links for me to do my own research is highly appreciated.
I am not looking for others to per say do my work for me, although solutions are highly appreciated, but perhaps guide me in a pseudo-code sort of way.
There are a number of different algorithms that you can use to "shuffle" a list of items. However, one of my favorite methods is the following because it is very concise.
General Shuffle Algorithm:
Find a list of items to rearrange.
Remove a random element from the items to rearrange
Insert the element into a new list
Repeat steps 1-3 until there are no more items left in the original list
Code Example
Here is a function that should do the trick:
$container = $("#container");
$divList = $("div");
$("#shuffle").on("click", function(){
//copy and remove all divs
$divCopy = $divList.clone(true);
$("div").remove();
while($divCopy.length > 0){
//chose random index of div array
var randomIndex = Math.floor(Math.random() * $divList.length);
$container.append($divCopy.splice(randomIndex, 1));
}
});
There is a full working version at https://jsfiddle.net/oruq1qou/
If you are interested in looking for other methods of solving this problem, I would recommend doing some reading on the different types of shuffle algorithms around.

Jquery, User Interaction: Hover links to highlight project combinations

JS Fiddle (code)
This is more of a task I have set myself to learn Arrays but now I was wondering if any of you can think of a better cleaner way of doing this task. I simply want a list of projects which highlight when the user hovers over some links..
What I want to do
I have a list of projects, on each project I could have worked on the SEO, Develpment or Design. On the page there is also a list of links say: Design, Development and SEO. When hovering over a link I want some of the projects to highlight..(combinations). So some projects I might of done more then one task on will highlight for more then one link.....
How I currently tried to do this
I thought that I could make a 2d array with a list of on offs for the projects. Depending on what link you hovered over pulls out the correct array, if you see the JSfiddle link, that is as far as I could go.
An Example of something very similar
ID Design
Thank You for anyhelp or advice
I hope I explained that clearly, I know I could rip the code off for the example link, but I rather learn from doing then just cut and paste.. - see what others think and use jquery.
You can use 3 different styles for each project , let say : ".design", ".seo", ".development"
$("#link1").hover(
function ()
{
$(".design").each(function()
{
$(this).toggleClass("highlight");
});
},
function ()
{
$(".design").each(function()
{
$(this).toggleClass("highlight");
});
}
);
Explanation:
When mouse is hovered over link1 a class .highlight is toggled (added when mouseover,removed when mouseout) on elements that use .design class. You can do similar way to others 2 classes.

Categories

Resources