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.
Related
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
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.
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.
I have an app built using jQuery (and using various jQuery-UI tools).
For some reason, i have to port it to smartphones/tablet computer, and decided to use jQuery Mobile for that (in order to minimize the number of changes).
In my vanilla app, I created some elements of the page on the fly, depending of user interactions.
For example a slider could be created like that (p is an object with a bunch of params):
function createSlider(p){
return $("<div/>",{
"id":p.id,
"class":p.divClass,
}).slider({
"orientation": p.align,
"min":p.constraint.min,
"max":p.constraint.max,
"step":p.step,
"value":p.curVal,
"animate":"normal"
/*and some event handling here, but it doesn't matter*/
});
}
And it will produce a nice looking slider. Now it looks like:
function createSlider(p){
return $("<range/>",{
"id":p.id,
"class":p.divClass,
"min":p.constraint.min,
"max":p.constraint.max,
"step":p.step,
"value":p.curVal,
});
}
But as it's created on the fly, all the stuff done by jQuery Mobile on the page load isn't done on it.
Is there a way to force that initialization without writing the slider in the html?
Thanks.
EDIT: I found in the doc that it could be achieved using container.trigger("create");
However this does not work yet.
EDIT2: Ok create was the solution.
According to the documentation (see edit in the question), using trigger("create") on the containing element works.
And to make that work, you also need to remember that range is an input type and not a tag...
Working solution:
function createSlider(){
return $("<input/>",{
"type":"range",
"id":"sl",
"min":0,
"max":15,
"step":1,
"value":1,
});
}
function appendSlider(){
$("#yourdiv").append(createSlider()).trigger("create");
}
As a sidenote, the documentation for jQuery mobile lacks a search option.
Try calling .page() on the container the content is being added to. Alternatively, adding .page() to the content you're returning may also work.
I am using jQuery UI's resizable for nested divs, like so:
<div id="resizable1">
<div id="resizable2">
</div>
</div>
I'm running into a problem where disabling resizable 1 also disables resizable 2. So, if I call the following...
$("#resizable1").resizable("disable");
...then I can no longer resize resizable2 either.
Has anyone else encountered this, and know of a way around this behaviour?
Thanks,
Travis
I was having trouble using nested resizables as well.. after setting up the second (nested) I lost the ability to resize the top level one.
To work around this I initialize, and destroy the nested one upon hover over/out:
$(".the-nested-elements").each(function() {
$(this).hover(function() {
$(this).resizable();
},function() {
$(this).resizable("destroy");
});
});
It's not the most elegant solution, but it works.
A little late, as I'm sure you've moved on, but I ran into the same issue. This is related to a known issue: http://bugs.jqueryui.com/ticket/5973
According to rdworth, you can do a workaround for this:
$("#resizable1").resizable("disable")
.removeClass("ui-state-disabled ui-resizable-disabled")
.children(".ui-resizable-handle").hide();
You can check out the original post at: http://forum.jquery.com/topic/trouble-with-nested-resizables, or check out the fiddle at: http://jsfiddle.net/rdworth/vaD8v/