I want to make something that makes much sense, but I think its not actually included in the jQueryUI.
I have a list of items, that are both sortable and selectable.
I can sort them one at a time, and I can select multiple items.
The question is, how can I sort multiple selected items together ?
I got this code atm,
$( "#centermainlist" ).sortable({
scroll: false,
handle: ".dots",
appendTo: 'body',
helper: 'clone',
});
what should I add, to make it sort all selected items ?
Thanks in advance :)
All the best,
Alexander
This functionality is not included in jQueryUI, so there's nothing you can just add to make it work the way you want. You will need to write your own code or search for plugins if you want to sort multiple items like that.
I imagine the reason this isn't in jQuery is due to the high number of situational variables involved. You're probably trying to do something like select three sequential items, then drag to move them all up or down - but this isn't the only possibility. What if the items selected aren't in a row? How do you handle that?
Example:
Item 1
Item 2 - selected
Item 3
Item 4 - selected
Item 5 - selected
Item 6
How do you move these items? Do you enforce the space in between the selected items? If so, do you stop moving items when the user moves Item 2 to the first position (since you have to keep the space)? Or in that case do you collapse them? Then do you remember that there was a hole if they move back down again? Maybe you just collapse them to begin with (easiest to implement, but maybe not the desired functionality)? Or maybe you enforce sequential selection for the move - if the items are all next to each other you can move them, if there are holes you can't?
So there are a lot of things to consider here. This is easy to implement with buttons (select items, click up or down buttons to move - just loop through and apply the move to each selected item) but much more difficult with drag reordering.
Related
I'm pretty new here and also with coding, I need help figuring out how to group items on a slider I have working on my website, so the thing is I want to classify them and group them, I wanna show 3 together then 2 others and then 4 each group with a title on top different for each one.
I can't do it cause it shows 4 slides every time I click on the arrows for the transitions, I can't find how to customize the number of slides to show on each transition.
Does anyone have any idea how to solve it or at least what would you recommend in this situation?
I'm trying to modify this over "miSlider jQuery Plugin".
http://www.mislider.com/
In a plugin there is a option called slidesOnStage which handle how many slide you want show at one time. You can use slidesOnStage like this.
var slider = $('.YourDivClass').miSlider({
// Number of slides visible at one time.
// Options: false or positive integer.
// false = Fit as many as possible.
slidesOnStage: 1, // If you use only 1 option remove `,` from last
});
For more option read documentation.
I am working with the vis.js timeline (http://visjs.org/docs/timeline/).
I want to achieve that it is not possible to have gaps between the elements.
If someone is removing an element between other elements the and adding a new element to the gap the new element should auto-fit into the gap.
If someone is updating the time (size) of an element by resizing, it should also auto fit to the next element.
I need an validation that all elements in all groups are filled between a given date range.
These are my editable options:
editable: {
add: true, // add new items by double tapping
updateTime: true, // drag items horizontally
updateGroup: false, // drag items from one group to another
remove: true, // delete an item by tapping the delete button top right
overrideItems: false // allow these options to override item.editable
},
It is not allowed to move the elements between the groups.
My first guess is to use the onMove function but I couldn't figure out how to find the previous and next element do adjust the start and end.
Maybe someone else had the same problem and found a solution.
I had a similar scenario in which dragging an element would rearrenge all the others and dragging an element to another group would make it snap just after the last element.
There is no easy option to set to do this. Basically you have to listen to these events and keep track of where are your elements in order to update it.
For example, in your first case what you have to do is:
Listen for onAdd() event
Search through the elements of that group where this new element will be created by looking at the start and end times.
Update this new item to have the start equals to the end of the previous element and have the end equals to the start of the next element.
Here's a simple JS Fiddle to get you started: http://jsfiddle.net/rj35mbvd/
In this fiddle, everytime you try to add an item, it is added between the two elements already present in the timeline.
Here is the good answer guys :
Use in options of stack: false + stackSubgroups: true and simply use the same subgroup by default, the elements will be displayed inline ;)
Check the <script> at the end of this html page http://visjs.org/examples/timeline/groups/subgroups.html
I will share an advanced roadmap I am working on ;)
Best
I'm working on a drawing application where the user can create and delete shapes and select them with the mouse to drag them. Should selected shapes be referenced in a "selection" array or should they each have an isSelected property? Is there any advantage to one method over the other? Here's what I noticed so far (I will update it with whatever people find). My main concerns are programming simplicity and performance. This question is language independent for the most part, but the app is in javascript and rendering is done on an html5 canvas.
Checking for selection state
While we know instantaneously if an item is selected through the boolean property, the array-based solution requires looping through the array to search for the item's reference. This verification is quite common considering the cursor should change to a "dragging" icon when the mouse hovers a selected shape or a "pointing hand" icon when it hovers over a non-selected item.
Deselecting items
Selecting and deselecting specific items is instantaneous with the boolean property. With the array-selection, however, we must first loop through the selection to see if the item is there before adding or removing it from the selection. This makes "toggle selection" and "add to selection" options much slower. However, the most common action in such a drawing program is to clear the selection before selecting specific elements. With the array method, clearing the selection is as simple as replacing the array, while the boolean method requires setting the isSelected property to false on all items.
Deleting items
It is worth mentioning that an item must be removed from the selection array before it gets deleted. This detail doesn't show up in the isSelected approach.
Calling on all selected items
Actions which apply to all selected items require minimal code with an array as we only have to loop through the selection and call the method on each element. If the selection is small compared to the total amount of items, having to loop only through the selection can be a considerable time gain. With a boolean property, the time required to call an action on all selected items depends on the total amount of items instead of the selection's size.
Drawing time
Selected items commonly have colored borders that can be seen through other elements. It means that selection borders must be drawn in front of all other elements. Given the number of items "n" and the number of selected items ("s")...
The array solution takes from O(n) to 2*O(n) to render.
The boolean solution takes about 2*O(n) to render.
While you might think that this justifies opting for the array method on its own, keep in mind that redrawing is only done after actions are triggered, not 60 times a second. Checking the pointed shape to know if it is selected or not is more common then drawing. The only features that might noticeably slow down are dragging, stretching and making rectangle selections. Since the application is used to represent real life items, people usually enter the size they want on their keyboard instead of actually dragging items.
Encapsulation
The encapsulation is stronger with a boolean property, as items know whether they are selected or not without having to look at an application-scope variable. That difference can mean a lot in strict-scope environments, but it isn't that big of a deal in javascript. I suppose one could think that it isn't the shapes' role to select themselves.
I have implemented the boolean isSelected property and as the application grew, I built more and more functions which applied to all elements. In each function, I had to put a for loop which would make sure to only alter selected items. I'll write some kind of pseudo-code to keep this solution language agnostic again.
for each item {
if item is selected
do stuff
}
Having the same loop everywhere annoyed me, it felt wrong. When you copy-paste code parts between functions, it's never a good sign. So I made a getSelection() function which returned an array of the selected elements. That seemed to solve the problem I had before by extracting the horrible loop.
function getSelection() {
selection = new empty array
for each item in selection {
if item is selected
add item to selection array
}
return selection
}
function doStuffOnSelection() {
selection = getSelection()
for each item in selection {
do stuff
}
}
But this only revealed something much worse. Manipulating arrays (constantly pushing items into an array, creating an array, etc) is much slower than just looking through them. This change slowed down the application so much that in Firefox, I couldn't even have 100 items at once while I used to be able to have 2000 without a frame drop. Such a slowdown all because I now create an array. That's because the getSelection function needs to be called on every frame of the program to draw a blue border on all selected elements!
When I posted this question, I wasn't sure if it was premature optimization, now I know it wasn't.
The major downsides of keeping track of selected items with an array
- You need to look at all selected elements to determine if a specific element is selected and to change that state.
- To remove selected elements from the array of all elements, you need array researching, which is especially slow when either array is big.
The major downside of keeping track of selected items with a per-item boolean
- You need to look at all elements to know which elements are selected and to change that state.
So I've settled on a much better way to deal with all the negative sides: do both. I'll keep an array of selected items in the background, which gets updated when things are selected and deselected. This gets rid of all the bad sides of array-only selection, as I no longer need to search through any array to know if a specific element is selected (I can look at its boolean). And all functions which apply to selected items but do not select and deselect items (such as move, resize, draw) can just loop through the selection array. The best of both worlds!
I'm coming here because I'm having trouble doing something with jQuery UI's sortable/draggable/droppable.
I'm trying to do something like iTunes playlist (when you change the order of tracklist or move a track to another playlist)
The idea is that I have a list of tracks (in a ) and I want this list to be sortable, and that's the easy part. Indeed I also have a second list (of playlist) and I want tracks to be draggable to those "playlist" items to do something.
Here's an exemple : http://jsfiddle.net/MSGhf/1/
(the sortable is working exactly as I want it, the black line is just a <div class="plholder"></div>)
But when you start dragging a track, sortable works fine. But when you move the track out of the draggable, the new order stays, and so dragging tracks on playlist potentialy change the track list order too, which is a problem.
So I don't know how to block the sortable when a track leaves it.
If you have any idea :)
Thanks !
Ah, ok, I see what's happening. Here's what you want to do (working example, here: http://jsfiddle.net/mori57/L3CF8/1/)
$(".droppable").droppable({
tolerance: "pointer",
drop:function(){
// You need to tell your sortable to cancel
// the last drag/drop interaction
$("ul").sortable("cancel");
alert("Do something on drop ...");
}
});
I have the following setup:
A sortable list where one of the <li> has a table with lists in each cell.
All of the lists are sortable with each other.
Draggable items that can be added to any of the sortables
Issue: When adding a draggable item ('drag 1', 'drag 2', 'drag 3') to one of the lists in the horizontal lists (table of lists) it duplicates the draggable when dropped. Sometimes it will create both copies in the same list or one in the item list and one in the column list.
Here is a demo: http://jsfiddle.net/MQTgA/
Question: How do I prevent the second item being created when dropping the draggable?
UPDATE: With changing the class names of the horizontal lists to something else ('hlist') and omitting the new class name from the 'connectToSortable' option ('ul.hlist'), it no longer drops two copies and still allows the item to be dropped in any list. This doesn't seem right. Also when trying to drop an item into the horizontal list instead of the main list it seems very touchy as well (won't make for a good user experience). Thoughts?
Updated demo: http://jsfiddle.net/MQTgA/3/
It's doing that because your top level unordered list ( the one with Items 1 - X) has the same class as the tables unordered list. If you change the top level , to a different class name it should stop double dropping the draggable. I hope I'm understanding your problem correctly, here is my change. New code
EDIT: Actually that won't help either because then you wont be able to drop into your upper lists. I think the issue is that as you are dragging and dropping jquery doesn't know which ul you actually want to drop into. You could try making all the elements a little bigger so the user would not have to finesse the draggable into the right spot.
With some more experimenting I have found the best way is to have the horizontal lists not part of the main list. This way there are no double items being created when an item is dropped onto them and no touchiness when moving items around.
Here's a demo of what I'm going with looks like:
http://jsfiddle.net/MQTgA/5/