Unexpected width in shopify draggable element - javascript

I made a simple draggable list, using the shopify draggable plugin
<ul id="myList">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
ul {
width: 50%;
border: 1px solid black;
list-style: none;
margin: 0;
padding: 0;
}
li {
margin: 5px;
background: salmon;
width: calc(100% - 10px);
cursor: move;
}
For some reason, when dragging, the dragged item's width gets much greater than the original item's. I suspect it's because I set the width in percentages and that it gets taken out of the parent container, so the percentage reference changes. I made a jsfiddle demo:
https://jsfiddle.net/x3jmkysq/1/
I would like it to work more like this example:
https://shopify.github.io/draggable/examples/simple-list.html
but I don't know how exactly they achieved it.

Anyway, I found the solution here:
https://github.com/Shopify/draggable/issues/147
Basically there is a property to calculate the dimensions of the dragged element from the original one called constrainDimensions.

Related

How to make a scrollable dropdown menu in bootstrap 5? [duplicate]

This question already has answers here:
Scrollable Menu with Bootstrap - Menu expanding its container when it should not
(6 answers)
Closed 1 year ago.
I've seen some great code examples for dropdown menus you can scroll through but sadly most don't work with bootstrap 5. Is there any modern way to do this?
Do you mean a fixed height for the menu?
HTML:
<div class="container">
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Click on Me
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
</div>
CSS:
.dropdown-menu {
max-height: 100px;
overflow-y: scroll;
}
You can try below css for scrollable dropdown. Here You can set max-height: 100vh which limits it to 100% of the viewport's height. So, It will show in any viewport nicely.
Don't forget to minus header height from calc(100vh - 150px). 150px is the height of the header on my site example. You can replace as per your site. which is above the height of the dropdown.
.dropdown-menu {
overflow: hidden;
overflow-y: auto;
max-height: calc(100vh - 150px);
}

Equal Width Tab Items Generated Dynamically

I am creating tabs that needs to be equal in width, it will come dynamically (2-8 tabs). There is no fixed width, tab bar has fluid width. I had tried to achieve it through css, but didn't worked.
demo:http://codepen.io/anon/pen/JdbMwR
<div class="main">
<ul class="list-inline sub-cat-tabs">
<li>
<div>
<span>2014-2015 2014-2015</span>
</div>
</li>
<li>
<div>
<span>2015-2015</span>
</div>
</li>
</ul>
</div>
You could do it with CSS fixed table layout, browser support: IE8+
http://jsfiddle.net/gashvbp6/
.tabs {
list-style: none;
padding: 0;
margin: 0;
display: table;
border-collapse: collapse;
table-layout: fixed;
width: 100%;
}
.tabs li {
display: table-cell;
text-align: center;
vertical-align: middle;
border: 1px solid red;
}
<ul class="tabs">
<li>item - long one</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>

javascript expand/collapse button

I'm trying to create a toggle content button that loads with the content already hidden.
This is the code I'm using but I'm not sure how to make the content appear as hidden (making the toggle button function more used for expanding content)
$(function() {
var b = $("#button");
var w = $("#wrapper");
var l = $("#list");
w.height(l.outerHeight(true));
b.click(function() {
if(w.hasClass('open')) {
w.removeClass('open');
w.height(0);
} else {
w.addClass('open');
w.height(l.outerHeight(true));
}
});
});
#wrapper {
background: #ccc;
overflow: hidden;
transition: height 200ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Toggle Expand/Collapse</button>
<div id="wrapper" class="open">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
Option 1: Simplified Code
You can actually simplify a fair amount by relying on CSS to define the show/hide style, and transitioning on max-height, you then simply toggle the addition of e.g. an open class to allow the height of the content to expand.
This also maintains strict separation of concerns, keeping functionality withiin Javascript and styling within CSS.
$(function() {
var b = $("#button");
var w = $("#wrapper");
var l = $("#list");
b.click(function() {
w.toggleClass('open'); /* <-- toggle the application of the open class on click */
});
});
#wrapper {
background: #ccc;
overflow: hidden;
transition: max-height 300ms;
max-height: 0; /* <---hide by default */
}
#wrapper.open {
max-height: 100px; /* <---when open, allow content to expand to take up as much height as it needs, up to e.g. 100px */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Toggle Expand/Collapse</button>
<div id="wrapper">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
Option 2: Revised Code
Alternatively, if you wish to use your existing code, you need to change it so the default state is hidden. Do this by setting the height to zero in your CSS, removing the open class from your HTML and removing the initial height setting from your Javascript:
$(function() {
var b = $("#button");
var w = $("#wrapper");
var l = $("#list");
// w.height(l.outerHeight(true)); REMOVE THIS
b.click(function() {
if (w.hasClass('open')) {
w.removeClass('open');
w.height(0);
} else {
w.addClass('open');
w.height(l.outerHeight(true));
}
});
});
#wrapper {
background: #ccc;
overflow: hidden;
transition: height 200ms;
height: 0; /* <-- set this */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Toggle Expand/Collapse</button>
<!-- <div id="wrapper" class="open"> REMOVE THIS -->
<div id="wrapper">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
you can use jquery .toggle() method
<button id="button">Toggle Expand/Collapse</button>
<div id="wrapper" class="open">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
$('#button').click(function(){
$('#wrapper').toggle();
});
DEMO
updated
you can add the following .css
#wrapper {
background: #ccc;
display:none
}
DEMO
jQuert toggle method will help you, if you want it hidden for the first time apply style like this -> style="display:none" If you want it visible then don't add this style
Basically what toggle function does is, if your component visible then hides it and if it is hidden then shows it...
$('#button').click(function(){
$('#wrapper').toggle();
})
below code will explain you better
http://jsfiddle.net/31zfvm2u/
using CSS
You can accomplish this with just CSS:
div#wrapper {
transition: max-height 1000ms;
overflow: hidden;
}
#toggle:not(:checked) ~ div#wrapper {
max-height: 0;
}
#toggle:checked ~ div#wrapper {
max-height: 200px;
}
#toggle:checked ~ label:after {
content: "hide"
}
#toggle:not(checked) ~ label:after {
content: "show"
}
<input type="checkbox" id="toggle">
<label for="toggle"></label>
<div id="wrapper" class="open">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
using JavaScript
You're pretty much there. Just use $.hide and $.show instead of $.height.
A more succinct method would be $.toggle, however, which does the same as the below code.
$(function() {
var b = $("#button");
var w = $("#wrapper");
var l = $("#list");
w.height(l.outerHeight(true));
b.click(function() {
if(w.hasClass("open")) {
w.hide();
} else {
w.show()
}
w.toggleClass("open");
});
});
#wrapper {
background: #ccc;
overflow: hidden;
transition: height 200ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Toggle Expand/Collapse</button>
<div id="wrapper" class="open">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
<button id="button" onclick=sample();>Toggle Expand/Collapse</button>
<div id="wrapper" class="open">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
function sample()
{
$(#wrapper).toogle();
}

How to have a floating menu in the middle of the screen

Is this possible without the help of javascript?
Typically we have menu bars at the top of the page - we place them as a child of body and then absolutely position them e.g. top: 10px; right: 10px;.
What if we want to achieve the same goal but as a context menu further down the page?
I have started a fiddle to give an idea - here there's no positioning, we just have the default of overflow: visible.
I can't absolutely position it because I don't know the x,y due to the dynamic nature of the content that precedes it.
The only way I can think of is go down the traditional route of the top nav bar, and with javascript find the x,y of it's container and position it there. However I would need to manage that if the content that precedes it changes then it's position needs to change also.
Does anyone know of a "stick-to" jquery method. Or even better achieve it with pure css?
Thanks
here's my crude fiddle - click "one" http://jsfiddle.net/hHR23/1/
I think you want this but I'm not certain from your description:
http://jsfiddle.net/samih/hHR23/2/
Notice this:
.section {
height: 58px;
background-color: yellow;
position: relative;
}
And this:
.menu {
position: absolute;
}
Now your menu will follow with the "dynamic" page because the absolute position is relative to the "position: relative" container.
Another approach - Fiddle.
HTML
<div class='header'>Header</div>
<div class='floatingmenu'>
<ul class="menu">
<li>One
<ul class="sub-menu">
<li>one a</li>
<li>one b</li>
<li>one c</li>
<li>one d</li>
<li>one e</li>
<li>one f</li>
<li>one g</li>
</ul>
</li>
<li>Two</li>
<li>Three</li>
</ul>
</div>
CSS
.header {
height: 40px;
background-color: blue;
}
.floatingmenu {
width: 30%;
height: 30%;
background-color: green;
color: white;
border: 10px solid white;
border-radius: 10px;
margin: 20px auto;
}
.footer {
height: 200px;
background-color: yellow;
}

hover-menu in right side of fixed div

I have a div with a fixed position (a top panel) which shall also contain a settings menu at the far right (currently via floating).
When hovering over the settings-image, I want to display a menu below the image.
I want the menu to be aligned to the right side just like the image.
<div id="panel" style="position:fixed">
<panel-entry 1>
<panel-entry 2>
<panel-entry n>
<div id="settings" style="float:right/snapped to the right side>
<img src=settings>
<ul>
<li>setting 1</li>
<li>setting 2</li>
<li>setting n</li>
</ul>
</div>
</div>
Any idea using jQuery very much appreciated, feel free to rearrange any html.
No jQuery necessary, just give your #panel a width:
#panel {
position: fixed;
width: 100%;
}
#settings {
float: right;
}
See DEMO.
Aside from your example not being HTML, I would anyhow correct the conceptual approach. There is no jQuery required for such a task, which can be done entirely in CSS.
You want your #panel to first of all contain a <ul> which will contain <li>s, which will be your <panel-entry>, those should be set as inline-block.
The #settings should be one of those, perhaps with a special class or id (we'll keep settings for now). You can position: absolute this to right: 0, or have it float. Don't use an image element for this, but rather use a background-image.
Inside this element, you will have a submenu: i.e. another <ul> with display: none, a position:absolute, right: 0 and top: X, so that X doesn't overlap with your #panel.
Next, you want to make the element visible on :hover of li#settings.
Here's a working demo
Basic HTML
<div id="panel">
<ul>
<li>Panel entry 1</li>
<li>Panel entry 2</li>
<li>Panel entry n</li>
<li id="settings">
<ul>
<li>setting 1</li>
<li>setting 2</li>
<li>setting n</li>
</ul>
</li>
</ul>
</div>
Basic CSS
#panel {
position: fixed;
top: 0;
width: 100%;
}
#panel > ul > li {
display: inline-block;
}
#panel > ul > li > ul {
display: none;
position: absolute;
top: {X};
right: 0;
}
li#settings {
background: url({youricon}) no-repeat top center;
position: absolute;
right: 0;
min-width: {youricon-x};
min-height: {youricon-y};
}
li#settings:hover > ul{
display: block;
}

Categories