Multiple jQueryUI sortable objects on same row
Multiple jQueryUI sortable objects on same row
After an exhaustive search process, I'm hoping someone on StackOverflow can point me in the right direction.
Scenario:
I am currently using jQueryUI sortable to create lists of people and their attendance in days per week. I have a few divs of connected sortable <ui >
's and this works really well.
<ui >
In my example, I am listing employees in different groups. They are represented by <li>
's in the sortable blocks. They need to be:
<li>
So far this is not an issue with CSS just marking the <li>
's as 100%, 60%, and 40% widths respectively and all appears properly.
<li>
Problem:
The issue is that these blocks need to be able to allow a 40% + 60% (or vice-versa) part-time position to sit in a single row to indicate a full-time slot is taken.
The users of the app need to have the UI indicate how many empty slots they need to fill, so it has to be dummy proof (ie not using text). Visual cues are best.
Goal is to be able to turn this:
| Jane |
| John |
| Joe |
Into this:
| Jane |
| John | | Joe |
I'm not married to use jQueryUI and/or sortable, though I am using jQuery pretty heavily on the site.
If anyone has had a similar issue or have any ideas, it would be extremely helpful. I'm not asking for code, just ideas or if you are familiar with other libraries that may help.
Thanks in advance.
EDIT - fiddle: https://jsfiddle.net/xpvt214o/783063/
1 Answer
1
You will want to add some more structure to your HTML so that when you move the items, you're really just moving the container.
For example: https://jsfiddle.net/Twisty/0hkn2Lbu/
HTML
<h4 style="display:inline">Monday</h4>
<ul id="class_1" class="list-unstyled connectedSortable ui-sortable">
<li class="panel ui-sortable-handle" id="emp_1801">
<div class="emp-time">
<span class="time-block dpw_5"> </span>
<span class="name-label">Allan</span>
</div>
</li>
<li class="panel ui-sortable-handle" id="emp_1822">
<div class="emp-time">
<span class="time-block dpw_5"> </span>
<span class="name-label">Becca</span>
</div>
</li>
</ul>
<hr>
<h4 style="display:inline">Tuesday</h4>
<ul id="class_2" class="list-unstyled connectedSortable ui-sortable">
<li class="panel ui-sortable-handle" id="emp_1811">
<div class="emp-time">
<span class="time-block dpw_3"> </span>
<span class="name-label">Charlie</span>
</div>
</li>
<li class="panel ui-sortable-handle" id="emp_1823">
<div class="emp-time">
<span class="time-block dpw_2"> </span>
<span class="name-label">Diane</span>
</div>
</li>
</ul>
This also means adding more CSS to style it as you want it. I will layer the label on top of the block.
CSS
.emp-time
position: relative;
width: 100%;
.name-label
position: absolute;
top: 0;
left: 0;
font-weight: bold;
padding-left: 5px;
.time-block
display: block;
position: absolute;
top: 0;
left: 0;
border-radius: 3px;
.dpw_5
width: 100%;
background-color: #fff;
.dpw_3
width: 60%;
background-color: #ccc;
.dpw_2
width: 40%;
background-color: #999;
This makes it a bit simpler to address on a larger amount of items. No changes were made to your JavaScript, except to wrap it.
JavaScript
$(function()
var panelList = $("#class_1, #class_2, #class_3, #class_4, #class_5, #class_6, #class_7, #class_8, #class_12");
panelList.sortable(
connectWith: ".connectedSortable",
forcePlaceholderSize: true,
placeholder: "panel sortable-placeholder",
stop: function(event, ui)
var class_obj = ;
var class_id = 0;
panelList.each(function(class_index, class_element)
class_id = $(class_element).attr("id").slice(6);
class_obj[class_id] = ;
$("#class_" + class_id + " li").each(function(child_index, child_element)
class_obj[class_id].push($(child_element).attr("id").slice(6));
)
);
$.post('enrollment_ajax.php',
action: "saveData",
location_id: "'.$location_id.'",
month: "'.$month_time.'",
data: JSON.stringify(class_obj)
);
);
);
Hope that helps with that.
Now to allow them to be inline, you may consider this:
https://jqueryui.com/sortable/#display-grid
But I suspect that will not work for you as you intend. It sounds like you need more of a Drag and Drop scenario. If the smallest amount of hours a employee can work is 2 hours out of a 10 hour shift, this would be 20%, 4 hours: 40%, 6 hours: 60%, and 10 hours: 100%.
This will define that each day can contain 5 blocks of time. So a container would then be able to contain 0 up to 5 blocks of time. Since we're dragging in parts of a time, they would each have a value and a visual queue.
Example:
+ -- -- -- -- -- +
| A (5) |
+ -- -- -- -- -- +
| B (3) | C (2)|
+ -- -- -- -- -- +
Each container is a Drop area, but it will check each drop and only allow up to a value of 5. You can do this with Sortable too, where each day is a sortable List and it checks on update to ensure we have not over filled it. It's just a bit harder to do.
I will update the case with a better example.
Update 1
https://jsfiddle.net/Twisty/0hkn2Lbu/14/
Here you can see the lists sorting inline.
Thanks for your response. However, in your fiddle, i'm still not able to put Charlie and Diane on the same line/row. Which is the desired function. Am i missing something?
– airyt
Sep 12 '18 at 18:21
Lol not sure if i read your entire response before i commented. yes your summary is accurate in that the draggable objects vary in size and the target drop area would check to make sure it doesn't go over in size. is that a jQUI draggable or sortable? the sortable grid example doesn't have variable sized objects. Thanks again!!
– airyt
Sep 12 '18 at 18:59
@airyt it's sort of neither, it will require some scripting on your part to perform conditional checks. E.G: if 2/5 shifts are filled, only allow a drop if the drop item has 3 or less shifts in it.
– Twisty
Sep 12 '18 at 20:05
right, we're on the same page. I'm down with implementing the logic, but still don't have a method to perform the drag & drop / sortable UI so that user can put multiple elements on the same row in the first place. That's the key - the spec is such that the UI allows the users to visually perform this.
– airyt
Sep 12 '18 at 20:11
@airyt based on your code, it looks like you might have more than 1 shift to fill, for example, you could have 4 employees, 1 working 40% of a shift, and another 60% of a shift, and one working 50% of another shift, etc?
– Twisty
Sep 12 '18 at 21:14
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
What have you done so far? (Share the code!)
– Carlos Abraham
Sep 12 '18 at 15:55