I'm trying to create a drag & drop interface for icons. Basically, I have three div containers, each one with an ordered list inside. The first list holds the icons (as <li><img /></li>), and the two remaining ones are empty and should receive icons being dragged, dropped, and sorted inside of them. Each empty list is associated to a row where the icons will be displayed in the front end.
I have also created a function to allow item selection on Ctrl/Cmd + Left Mouse Click, so that users can drop multiple icons at a time.
Everything works as expected, except for one single issue: the custom Ctrl/Cmd + Click option stops working on draggable elements that have already been dropped.
After realizing, I did some testing and narrowed it down as much as possible: it seems that the culprit is the ConnectToSortable parameter in the 'Draggable' function. If the parameter is commented out, the Ctrl+Click function works as expected. The problem is that I need to use this parameter in order to store all the icons associated to each empty list (row) so I can retrieve them later.
Here is my HTML code:
<div id="container">
<div id="row1" class="row">
<ol class="drop-container">
<li class='draggable'><span class="squares blue-squares"> </span></li>
<li class='draggable'><span class="squares blue-squares"> </span></li>
<li class='draggable'><span class="squares blue-squares"> </span></li>
</ol>
</div>
<div id="row2" class="row">
<ol class="drop-container">
<li class='draggable'><span class="squares red-squares"> </span></li>
<li class='draggable'><span class="squares red-squares"> </span></li>
<li class='draggable'><span class="squares red-squares"> </span></li>
</ol>
</div>
<div id="row3" class="row">
<ol class="drop-container">
<li class='draggable'><span class="squares green-squares"> </span></li>
<li class='draggable'><span class="squares green-squares"> </span></li>
<li class='draggable'><span class="squares green-squares"> </span></li>
</ol>
</div>
And Here is my JS code:
$(function() {
// Custom function for Ctrl-Cmd Left Mouse Click
$(".draggable, .ui-draggable").click(function(e) {
if (e.ctrlKey || e.metaKey === true) {
if (!$(this).hasClass("selected")) {
$(this).addClass("selected");
} else {
$(this).removeClass("selected");
}
}
});
// Draggable
$('.draggable').draggable({
connectToSortable: ".drop-container",
delay: 200,
drag: function(event, ui) {
$(".selected").removeClass("selected");
},
helper: "original",
revert: "invalid",
revertDuration: 300
});
// Droppable
$('.drop-container').droppable({
tolerance: "touch"
});
// Sortable
$('.drop-container').sortable({
appendTo: ".drop-container",
connectWith: ".drop-container",
items: ".draggable",
revert: true
});
// Disable selection of items
$("div, ol, ul, li, span").disableSelection();
});
I made a JSfiddle to test this, and I was able to reproduce the error. I am using spans instead of actual images for the purposes of this test.
Am I doing something wrong or is this a jQuery UI bug? Any ideas or workarounds are most welcome and appreciated!
You should do
$('.drop-container').sortable("refresh");
once the items are dropped in. See: http://jqueryui.com/demos/sortable/#method-refresh
Related
I've just started working with jQuery UI, and while at first it looked like a wonderful tool, I've found that it lacks exactly what I need: a menu button widget.
What I want is the functionality of the jQuery UI Menu Widget, but with some additional bits, primarily a button/clickable area that will show/hide the menu. This alone is simple enough, but what is driving me mad is adding the expected keyboard functionality to this. When a button expands a menu, one expects that clicking outside that menu or pressing ESCAPE will close that menu, and while this works for the widget's submenus, it isn't built into the main widget.
I've been reading about the Widget Factory and extending/modifying widgets, but I'm completely lost as to how to accomplish this specific problem, and I can't seem to find any answers to this that aren't many years old. I've even tried overriding the "collapse" function in the menu instance, but the problem is that I don't quite understand the flow of the code. I basically added an 'else' statement that calls the 'click' event on the button when the conditions for closing a submenu aren't met. This just creates all sorts of weird bugs and I know I don't really have any idea what I'm doing.
A code example of how this is done would be greatly appreciated, but this is a common enough website behavior that I imagine someone has already put this together. I'm just not finding anything up to date.
Thank you in advance!
If you do not find a Widget that is needed, you can combine various elements and use them together.
$(function() {
$(".widget button").button();
$(".widget button").click(function(event) {
event.preventDefault();
if ($("#menu").is(":visible")) {
$("#menu").hide();
} else {
$("#menu").show().menu("focus", null, $("#menu .ui-menu-item:first"));
}
});
$("#menu").menu({
select: function(e, ui) {
console.log(ui.item.text().trim());
}
}).hide();
});
.ui-menu {
width: 150px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="widget">
<h1>Widget Buttons</h1>
<button>A button element</button>
<ul id="menu">
<li class="ui-state-disabled">
<div>Toys (n/a)</div>
</li>
<li>
<div>Books</div>
</li>
<li>
<div>Clothing</div>
</li>
<li>
<div>Electronics</div>
<ul>
<li class="ui-state-disabled">
<div>Home Entertainment</div>
</li>
<li>
<div>Car Hifi</div>
</li>
<li>
<div>Utilities</div>
</li>
</ul>
</li>
<li>
<div>Movies</div>
</li>
<li>
<div>Music</div>
<ul>
<li>
<div>Rock</div>
<ul>
<li>
<div>Alternative</div>
</li>
<li>
<div>Classic</div>
</li>
</ul>
</li>
<li>
<div>Jazz</div>
<ul>
<li>
<div>Freejazz</div>
</li>
<li>
<div>Big Band</div>
</li>
<li>
<div>Modern</div>
</li>
</ul>
</li>
<li>
<div>Pop</div>
</li>
</ul>
</li>
<li class="ui-state-disabled">
<div>Specials (n/a)</div>
</li>
</ul>
</div>
Base Examples:
https://jqueryui.com/menu/
https://jqueryui.com/button/
You can also make use of the Widget Factory to create your own.
I must apologize for not being able to reproduce this in jsFiddle in the first place (because of code placed in the 2 files).
I got 3 tabs which work fine, in the third I load another file which contains 2 tabs. These tabs are displayed as approximately 400px high gradients wiith content of these tabs shown below them. Which is not what I wanted, as you can imagine :) It´s like the grey header, which contains the tabs was stretched to a whole div...
Here´s the picture:
http://2i.cz/2i/t/954d3e14c7.jpg
As you can see, the tabs itself are big as hell and table is displayed below.
And here´s my code:
1st file:
$(function() {
$( "#tabs" ).tabs();
});
$("#detail").load('./safe/kalkulace_grafy_all.php?k_polozka=<? echo $co; ?>&cu=<? echo $ids; ?>');
<div id="tabs">
<ul>
<li>Info</li>
<li>Info2</li>
<li>Info3</li>
</ul>
<div id="tabs-1" class="detail_ceny_tab" style="height: 446px;"></div>
<div id="tabs-2" class="detail_ceny_tab" style="height: 446px;"></div>
<div id="tabs-3" class="detail_ceny_tab" style="height: 446px;">
<div id="detail"></div>
</div>
</div>
2nd file:
$(function() {
$( "#subTabs" ).tabs();
});
$("#subTab1").load('./safe/kalkulace_kalkVzorec.php?k_polozka=<? echo $k_polozka; ?>&cu='+cu);
<div id="subTabs" style="margin-left:500px">
<ul>
<li>Kalkulační vzorec</li>
<li>Seznam potřeb</li>
</ul>
<div id="subTab1"> </div>
<div id="subTab2"> </div>
</div>
you want to reduce the grey tab panel area?
I think its late but hope it may help some one else if they have something similar in mind.
The following code may be helpful, you can reduce the width of the tab panels.
$( "#subTabs" ).find( ".ui-tabs-nav").css('width', '50%');
$( "#subTabs" ).find( ".ui-tabs-panel").each( function( index, element ){
$( this ).css('width', '50%');
});
I have the following structure.
<ul id="browser" class="filetree">
<li><span class="folder">Folder 1</span>
<ul>
<li><span class="file">Item 1.1</span></li>
</ul>
</li>
<li><span class="folder">Folder 2</span>
<ul>
<li><span class="folder">Subfolder 2.1</span>
<ul id="folder21">
<li><span class="file">File 2.1.1</span></li>
<li><span class="file">File 2.1.2</span></li>
</ul>
</li>
<li><span class="file">File 2.2</span></li>
</ul>
</li>
<li class="closed"><span class="folder">Folder 3 (closed at start)</span>
<ul>
<li><span class="file">File 3.1</span></li>
</ul>
</li>
<li><span class="file">File 4</span></li>
</ul>
In js
I have the following function.
$("#browser li").click(function(){
});
When I clicked on li File 2.1.1.
The function calls 3 times
first time for li File 2.1.1 , second time for li Subfolder 2.1 and third time for li Folder 2.
Can anyone give me the solution to call the function exactly once?
Your Help is greatly Appriciated.
Thanks.
That is because you have many li elements under #broswer.
Try this instead:
$("#browser>li").click(function(){
//only direct children of #browser
//your code
});
Or you can use event.stopPropagation():
$("#browser li").click(function(event){
event.stopPropagation();
//your code
});
Change your function to
$("#browser li").click(function(event){
event.stopPropagation();
//do your other stuff
});
That way, the click on the lower-level li won't "bubble up" to the higher level li.
This is due to the fact events "bubble" up your dom so you if you click
File 2.1.1, it will also be heard by File 2.1 and File 2 to fix this change event to
$("#browser li").click(function(e){
//Your code here
e.stopPropagation();
});
Rather than use the click event on the li object add another element (in example span) and handle click in that. This way can still bubble for higher events just doesn't bubble through nested li.
//Run the following to see the no li bubble result
$(".nobubble").on('click',function(){
$("#result").append($(this).attr("data-id") +"<br />")
});
//uncomment the following to see the li bubble result
/*$(".bubble").on('click',function(){
$("#result").append($(this).attr("data-id") +"<br />")
});*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="bubble" data-id="li-a"><span class="nobubble" data-id="span-a">a</span>
<ul>
<li class="bubble" data-id="li-b"><span class="nobubble" data-id="span-b">b</span>
</li>
</ul>
</li>
</ul>
<div id="result">
</div>
jquery ui accordion contains lot of panels and every panel contains lot of single line menu items.
jqueryui accordion shows only single item in every panel. How to force accordion to show more items ?
$( "#accordion" ).accordion({
fillSpace: true,
autoHeight: false,
navigation: true,
collapsible: true
});
<h3>
mmmmmmm</h3>
<div>
<ul>
<li><a target='DoklstlG' href='xxxxxx'>
jjjjjj</a></li>
<li><a target='DoklstlO' href='yyyyy'>Ostuarve</a></li>
<li><a target='UnpaidG' href='zzzzzzz'>hjkhkjjsumine</a></li>
<li> </li>
...
</ul>
</div>
<h3>
kkkkk</h3>
<ul>
<li><a target='DoklstlVL' href='nnnnnnnn'>Väljastus</a></li>
<li><a target='DoklstlSL' href='mmmmmmmmmm'>Sissetulek</a></li>
...
as the other answer said, The documentation specifically instructs user to NOT do this
"NOTE: If you want multiple sections open at once, don't use an accordion."
yet, there is a way. i use it like this, and i find it very simple and useful:
create multiple one-item accordion panels one after another with collapsible set to true to emulate a multi-panel accordion.
here is the markup:
<div class="accordion">
<h3>First header</h3>
<div>First content</div>
</div>
<div class="accordion">
<h3>Second header</h3>
<div>Second content</div>
</div>
<div class="accordion">
<h3>Third header</h3>
<div>Third content</div>
</div>
here is the script:
$(".accordion").accordion({collapsible: true});
The documentation specifically instructs user to NOT do this:
NOTE: If you want multiple sections open at once, don't use an accordion.
Source: jQuery UI Documentation
UPDATE
Try changing fillSpace: false and autoHeight : true, see what that does.
Guys i have the following UL elements. The nested UL(nestsort) items are sortable in the IE browser Version 7 , but the drag movement seems wired ,while it works smooth in firefox.Please click on this link http://jsfiddle.net/Ds7ds/1/ from IE , the code is in jsfiddle.
<ul id="sortable">
<li>
<p> item 1</p>
<ul id="nestsort">
<li>
Sub item 1
</li>
<li>
Sub item 2
</li>
<li>
Sub item 3
</li>
</ul>
</li>
<li>
<p> item 2</p>
</li>
</ul>
$("#sortable").sortable();
$("#nestsort").sortable();
This should work for you :
$( "#sortable" ).sortable({
cancel: "#nestsort"
});
$("#nestsort").sortable();
Wish you luck.