Vuetify v-slide-group horizontal mouse scroll - vue.js

I want to get rid of arrows on my v-slide-group and be able to scroll it by using the mousewheel on desktop, currently is only scrollable on mobile viewport.
Is this possible?
my template:
<v-layout justify-center>
<div style="width: 600px; background-color: red">
<v-slide-group center-active active-class="success">
<v-slide-item v-slot:default="{ active, toggle }"
v-for="(item, idx) in 25"
:key="idx"
>
<v-card
#click="toggle"
class="mx-2 rounded-lg"
width="250"
height="175"
:ripple="{ class: 'rounded-lg' }"
:color="active ? undefined : 'grey lighten-1'"
/>
</v-slide-item>
</v-slide-group>
</div>
</v-layout>
css
.v-slide-group__next {
display: none;
}
.v-slide-group__prev {
display: none;
}
And a codepen:
https://codepen.io/willcolmenares/pen/qBNWRKY

I figure it out but I'm not sure if its the best way (breaks the center-active animation which I really like).
.v-slide-group__wrapper {
overflow-x: auto; /* Enables the horizontal scrollbar */
/* Next lines hides scrollbar in different browsers for styling purposes */
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.v-slide-group__wrapper::-webkit-scrollbar {
display: none; /* Chrome opera and Safary */
width: 0px;
background: transparent;
}

Related

Vue transition-group - how to prevent "jumping"?

I have two divs that i transition between using transition-group, which works as it should - however, the content below the divs transitioning, is "jumping" depending on the height of the divs.
What I want it that jumping being prevented, and instead it animates somehow, so I get a nice smooth transition when switching between elements without it "pushing" down to content with a "jump"..
Hope it makes sense :)
I've setup an example on codesandbox here: https://codesandbox.io/s/reverent-stallman-8ixhp?file=/src/components/HelloWorld.vue
The template looks like:
<div class="hello">
<button #click="groupShowOne">Show first {{ gShowFirst }}</button>
<button #click="groupShowTwo">Show second {{ gShowSecond }}</button>
<transition-group name="fade-group" tag="div" mode="out-in" appear>
<div
class="group-element"
v-if="gShowFirst"
style="background-color: yellow"
>
<h3>This is a headline</h3>
<p>This is a text</p>
</div>
<div
class="group-element"
v-if="gShowSecond"
style="background-color: red"
>
<h3>
This is a headline <br />This is a headline <br />This is a headline
This is a headline This is a headline This is a headline
</h3>
<p>
This is a text This is a text This is a text This is a text This is a
text v This is a text v <br />This is a text This is a text This is a
text This is a text This is a text v This is a text v <br />This is a
text This is a text This is a text This is a text This is a text v
This is a text v
</p>
</div>
</transition-group>
<div style="background-color: blue; min-height: 500px; color: #FFF">
Prevent this div from jumping<br />
</div>
</div>
The animation looks:
<style scoped>
.group-element {
width: 100%;
min-height: 100px;
max-height: 20000px;
transition: all 0.5s;
}
.fade-group-enter,
.fade-group-leave-to {
opacity: 1;
}
.fade-group-leave-active {
opacity: 0;
position: absolute;
}
</style>
Try this
Setting the transition property in the passive div:
.ele {
background-color: blue;
min-height: 500px;
color: #fff;
-moz-transition: all 0.5s;
-ms-transition: all 0.5s;
-o-transition: all 0.5s;
-webkit-transition: all 0.5s;
transition: all 0.5s;
}
Let it do some animation
eleStyle() {
return {
transform: this.gShowSecond ? "translate3d(0, 100px, 0)" : "none",
};
},
The div:
<div class="ele" :style="eleStyle">Prevent this div from jumping<br /></div>
What you can try:
Vue has a *-move class for group transitions. However, the transition-group has to be applied to all the elements including the one that has the v-move class, to work.
Here's the article link if you need it for more details: https://vuejs.org/guide/built-ins/transition-group.html#move-transitions
(*-move basically animates items from their original position to their new position, making it smooth, rather than jumpy)
You could still work with what you have and dynamically bind a separate CSS transition for the blue box when showSecond or showFirst equate to a certain value.

Why does my v-if not fire when using modals with Vue?

I'm using v-if to control the display of pages in my Vue app. the 'page' data property keeps track of the current page and is updated by button clicks. This works beautifully until I introduce modals, as now when I open a modal and navigate back a couple of pages (using my app's navigation buttons) the page fails to display despite the property being updated correctly.
Here's a simplified example - navigate to page B then C then display Modal 2. Cancel Modal 2, then navigate to Page B and nothing displays (despite the header indicating that the page property is B).
https://jsfiddle.net/fLmq0dxn/1/
I've tried this approach with both bootstrap modals and native js modals but the same problem occurs. No errors reported in the console. I thought it might be wrongly nested divs but I've checked these and put it through a validator.
I realise that my navigation methods are primitive and that the modals probably should be components, but I'm a newbie to Vue, and as far as I understand it my approach 'should' work. Can anyone explain why it doesn't please?
HTML:
<div id="app">
<p>(app.page = {{page}})</p>
<br/>
<div class="page" id="A" v-if="page=='A'">
Page A
<br/>
<button v-on:click="pager('B')">To B</button>
</div>
<div class="page" id="B" v-if="page=='B'">
Page B
<br/>
<button v-on:click="pager('C')">To C</button>
<button v-on:click="modalOpen('mod1')">Modal</button>
</div>
<!-- ************ Modal 1 ************************************ -->
<div id="mod1" class="mod">
<div class="mod-content">
<span class="mod-close" v-on:click="modalClose">×</span>
<h1>Modal 1</h1>
<button v-on:click="modalClose" class="btn btn-secondary">Cancel</button>
</div>
</div>
<div class="page" id="C" v-if="page=='C'">
Page C
<br/>
<button v-on:click="pager('B')">To B</button>
<button v-on:click="modalOpen('mod2')">Modal</button>
</div>
<!-- ************ Modal 2 ************************************ -->
<div id="mod2" class="mod">
<div class="mod-content">
<span class="mod-close" v-on:click="modalClose">×</span>
<h1>Modal 2</h1>
<button v-on:click="modalClose" class="btn btn-secondary">Cancel</button>
</div>
</div>
</div>
CSS:
/* The Modal (background) */
.mod {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content/Box */
.mod-content {
background-color: #fefefe;
margin: 20% auto;
padding: 20px;
border: 1px solid #888;
border-radius:8px;
width: 90%;
max-width:800px;
}
/* The Close Button */
.mod-close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.mod-close:hover,
.mod-close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
Javascript:
new Vue({
el: "#app",
data: {
page: "A"
},
methods: {
pager: function(target){
this.page=target;
},
modalOpen: function(modID) {
$('#'+ modID).css('display','block');
},
modalClose: function(){
$('.mod').css('display','none');
}
}
})
Combining Vue with jQuery is risky unfortunately.
In your specific case, it seems like when you try closing your modal, jQuery looks for all elements with "mod" class, but when hiding them, the selection is tampered by Vue and you end up with incorrect elements being hidden (in your case, the content of your page B). Vue is not designed to have another library fiddling with the DOM.
You can "easily" achieve your goal using Vue only. Since you manage your modal by changing their style, you can do something similar with Vue class and/or style binding.
E.g. you could have a class that overrides your display: none, and you conditionally apply that class based on a data, very similarly as you do for your pages. And you could even probably manage your modal with v-if, exactly like you did with your pages.
Example with conditional class: https://jsfiddle.net/jfx8mbya/
Example with modal managed by v-if:
new Vue({
el: "#app",
data: {
page: "A",
modal: null
},
methods: {
pager: function(target) {
this.page = target;
},
modalOpen: function(modID) {
this.modal = modID;
},
modalClose: function() {
this.modal = null;
}
}
})
/* The Modal (background) */
.mod {
/*display: none;*/
/* Hidden by default */
position: fixed;
/* Stay in place */
z-index: 1;
/* Sit on top */
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: rgb(0, 0, 0);
/* Fallback color */
background-color: rgba(0, 0, 0, 0.4);
/* Black w/ opacity */
}
/* Modal Content/Box */
.mod-content {
background-color: #fefefe;
margin: 20% auto;
padding: 20px;
border: 1px solid #888;
border-radius: 8px;
width: 90%;
max-width: 800px;
}
/* The Close Button */
.mod-close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.mod-close:hover,
.mod-close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<p>(app.page = {{page}})</p>
<br/>
<div class="page" id="A" v-if="page=='A'">
Page A
<br/>
<button v-on:click="pager('B')">To B</button>
</div>
<div class="page" id="B" v-if="page=='B'">
Page B
<br/>
<button v-on:click="pager('C')">To C</button>
<button v-on:click="modalOpen('mod1')">Modal</button>
</div>
<!-- ************ Modal 1 ************************************ -->
<div id="mod1" class="mod" v-if="modal === 'mod1'">
<div class="mod-content">
<span class="mod-close" v-on:click="modalClose">×</span>
<h1>Modal 1</h1>
<button v-on:click="modalClose" class="btn btn-secondary">Cancel</button>
</div>
</div>
<div class="page" id="C" v-if="page=='C'">
Page C
<br/>
<button v-on:click="pager('B')">To B</button>
<button v-on:click="modalOpen('mod2')">Modal</button>
</div>
<!-- ************ Modal 2 ************************************ -->
<div id="mod2" class="mod" v-if="modal === 'mod2'">
<div class="mod-content">
<span class="mod-close" v-on:click="modalClose">×</span>
<h1>Modal 2</h1>
<button v-on:click="modalClose" class="btn btn-secondary">Cancel</button>
</div>
</div>
</div>

Can I use Bulma dropdown in Bulma tabs?

I'm using Nuxt.js and Bulma. I'm making navigation using Bulma tabs(https://bulma.io/documentation/components/tabs/).
I wanna insert Bulma dropdown(https://bulma.io/documentation/components/dropdown/#hoverable-or-toggable). But it doesn't work in middle of Tabs.
I know who wanna use Bulma dropdown needs to use javascript, so I use it. But it doesn't work.
How can i fix it?
To get a dropdown working inside Bulma's tabs, you need to adjust the overflow CSS in the tabs div. I'm not sure why I had to set overflow-x and overflow-y to get this working properly, but I did.
When the dropdown is active:
overflow-x : visible;
overflow-y : visible;
When the dropdown is not active, reset to their defaults:
overflow-y : hidden;
overflow-x : auto;
Yes you can with a little amount of fiddling
There are mainly 2 problems :-
Problem 1
As bulma tabs container is flexbox, and the list of tabs are child of this flexbox, the dropdown will not be visible as it overflows out of flexbox container.
If you add overflow-y:visible to tabs container div, scrolling will happen which is not the behaviour we need
Solution
To fix this, the contents to be shown on tab selection should also come inside the tabs container as second child, so that dropdown button/link in list of
tabs has the space to show the dropdown when clicked/hovered.
#tab-container {
flex-direction: column;
height: 500px;
width: 100%
}
#content-child {
flex-grow: 1;
width: 100%
}
#list-child {
flex-grow: 0; //should be set to 0 as it will take up vertical space (it is set to 1 in bulma)
width: 100%;
}
Problem 2
When dropdown is used within bulma tabs, the anchor tags in dropdown gets styled by those specified for anchor tags in tabs.This is one of the main issue.
The dropdown shown thus will be styled very differently.
Solution
Bulma dropdown also allows us to insert div inside.
We can make use of this to overcome problem 1.
Just add this css for divs inside dropdown so as to make it behave like links.
div.dropdown-item.is-active {
background-color: rgba(55, 122, 195, 0.95);
color: #fff;
}
div.dropdown-item {
padding-right: 3rem;
text-align: left;
white-space: nowrap;
width: 100%;
cursor: pointer;
text-decoration: none;
}
div.dropdown-item:hover {
background-color: whitesmoke;
color: #0a0a0a;
}
Complete solution can be seen below and you can change as required for your use case.
div.dropdown-item.is-active {
background-color: rgba(55, 122, 195, 0.95);
color: #fff;
}
div.dropdown-item {
padding-right: 3rem;
text-align: left;
white-space: nowrap;
width: 100%;
cursor: pointer;
text-decoration: none;
}
div.dropdown-item:hover {
background-color: whitesmoke;
color: #0a0a0a;
}
#content-child {
flex-grow: 1;
width: 100%
}
#tab-container {
flex-direction: column;
height: 500px;
width: 100%
}
#list-child {
flex-grow: 0;
width: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/bulma#0.8.1/css/bulma.min.css" rel="stylesheet" />
<div class="tabs is-boxed" id="tab-container">
<ul id="list-child">
<li><a>Pictures</a></li>
<li><a>Music</a></li>
<li><a>Videos</a></li>
<li><a>Documents</a></li>
<li class="dropdown is-active">
<div class="dropdown-trigger">
<a class="has-text-right custom-padding" aria-haspopup="true" aria-controls="dropdown-menu">
Drop Down
</a>
</div>
<div class="dropdown-menu" id="dropdown-menu" role="menu">
<div class="dropdown-content">
<div class="dropdown-item">Dropdown item</div>
<div class=" dropdown-item">Other dropdown item</div>
<div class=" dropdown-item is-active">Active dropdown item</div>
<div class=" dropdown-item">Other dropdown item</div>
<hr class="dropdown-divider" />
<div class=" dropdown-item">With a divider</div>
</div>
</div>
</li>
</ul>
<div id="content-child">
content
</div>
</div>

Bootstrap tooltip opens and closes repeatedly

I have a bootstrap tooltip which I have custom styled. There seems to be an issue with it. Whenever we hover over it, it opens and then immediately closes.
HTML -
<div class="container" style="padding-top:300px">
<div class="row">
<div class="col-md-12">
<span>A bunch of random text</span><span class="info-circle" data-html="true" title="" data-original-title="Tooltip Text">i</span>
</div>
</div>
<div class="row">
<div class="col-md-12">
<span>A bunch of random text</span><span class="info-circle" data-html="true" title="" data-original-title="Tooltip Text">i</span>
</div>
</div>
Here's an inline link to jsFiddle
UPDATED
I made a few changes. Try this: https://jsfiddle.net/2h7jbt9n/6/
HTML
<div class="container" style="padding-top:30px">
<div class="row">
<div class="col-md-12">
<span>A bunch of random text</span><span class="info-circle" title="YoHo Ho Ho" data-placement="top" data-toggle="tooltip">i</span>
</div>
</div>
<div class="row">
<div class="col-md-12">
<span>A bunch of random text</span><span class="info-circle" title="YoHo Ho Ho" data-placement="top" data-toggle="tooltip">i</span>
</div>
</div>
JS
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip({
container: '.info-circle'
});
});
The issue was with padding for the info-circle. I wrapped it in a container. It doesn't flicker now.
Hope it helps.
You are no longer using the tooltip-arrow as the visual arrow you are using the :before and :after after as the visual arrow. The problem is that you have made the arrow bigger and made your own triangles. When you make your css arrow you are using borders. You have set your top border colors to white and blue to make it seem like the arrow has a border as well. In doing this you have forgotten that your arrow still has a bottom transparent border and this transparent border is covering up the element that you are hovering over to deploy the tooltip. So set your :before and :after psuedo elements for your .tooltip-arrow to have a bottom border of none. Like so:
.tooltip.top .tooltip-arrow:after {
content: " ";
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
left: -17px;
top: -5px;
border-width: 12px;
border-top-color: #003f6e;
border-bottom:none;
}
.tooltip.top .tooltip-arrow:before {
content: " ";
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
left: -15px;
top: -5px;
border-width: 10px 10px 0;
border-top-color: #fff;
border-bottom:none;
z-index: 1;
}

JQuery-Mobile content area 100% height between head and foot

A lot of topics on this... but not getting the point how to do it.
I have my JQM Header and Footer. I want the content area to fill the 100% height in between head and foot.
Thats my code, how is it possible?
<body>
<div data-role="page" id="entryPage" data-theme="d">
<div data-role="header" id="header" data-position="fixed" data-theme="d">
<h1>Page Title</h1>
</div><!-- /header -->
<div data-role="content" id="content" data-theme="d">
<div id="columnwrapper">
<div id="leftcolumn">
<div class="innertube">
Point 1
</div>
<div class="innertube">
Point 1
</div>
</div>
</div>
<div id="rightcolumn">
<div class="innertube">
<div id="switch1">
test
</div>
</div>
<div class="innertube">
test2
</div>
</div>
<div id="contentcolumn">
<div class="innertube">Content</div>
<div class="innertube">Content</div>
</div>
</div><!-- /content -->
<div data-role="footer" id="footer" data-position="fixed" data-theme="d">
<div id="switch2">
Expand main menu
</div>
</div><!-- /footer -->
</div><!-- /page -->
</body>
CSS:
#columnwrapper{
float: left;
width: 100%;
margin-left: -75%; /*Set left margin to -(contentcolumnWidth)*/
background-color: #C8FC98;
}
#leftcolumn{
margin: 0 40px 0 75%; /*Set margin to 0 (rightcolumnWidth) 0 (contentcolumnWidth)*/
background: #C8FC98;
}
#rightcolumn{
float: left;
width: 40px; /*Width of right column*/
margin-left: -40px; /*Set left margin to -(RightColumnWidth)*/
background: yellowgreen;
}
#contentcolumn{
float: left;
width: 75%; /*Width of content column*/
background-color: blue;
}
.innertube{
margin: 0px; /*Margins for inner DIV inside each column (to provide padding)*/
margin-top: 0;
}
Actually the inner area only fills the height depending on the content... means 2 divs 2 rows, but not 100%..
Thanks
The CSS position: fixed doesn't work correctly in mobile browsers. My experience is with Android and iOS browsers and none of them impliment position: fixed properly (the exception is the iOS 5 browser but it's still in beta).
Rather than fixing an element to the screen and not moving it when the user scrolls in mobile browsers it tends to be treated like position: absolute and it moves when the page scrolls.
Also using the CSS overflow property won't allow scrolling on most mobile devices (iOS supports it but the user has to know to use two fingers while scrolling in a scrollable-div).
You can however use CSS but be aware you will need to use position: absolute or you can use JavaScript to set the heights on the elements.
Here is a jQuery Mobile solution using JavaScript to set the heights of the pseudo-page elements:
$(document).delegate('#page_name', 'pageshow', function () {
var the_height = ($(window).height() - $(this).find('[data-role="header"]').height() - $(this).find('[data-role="footer"]').height());
$(this).height($(window).height()).find('[data-role="content"]').height(the_height);
});
To get a flawless finish you need to take into consideration the behavior of the target device's address bar because if you want a fullscreen webpage then you have to add the height of the address bar to the height of the page.
Thanks, Jasper! That helped me a lot.
I had to mess around a lot to get this to work with multiple headers/footers, and to account for the url bar in ios. I thought I would share my solution for any one else having this issue.
This is working for me so far in ios simulator, but I would be eager to hear how it works on other devices.
/* detect device */
var ua = navigator.userAgent,
iphone = ~ua.indexOf('iPhone') || ~ua.indexOf('iPod'),
ipad = ~ua.indexOf('iPad'),
ios = iphone || ipad,
android = ~ua.indexOf('Android');
$(document).delegate('#the_page', 'pageshow', function () {
var $page = $(this),
$target = $(this).find('.fullHeight'),
t_padding = parseInt($target.css('padding-top'))
+ parseInt($target.css('padding-bottom')),
w_height = (ios)? screen.height-65: $(window).height(); // "-65" is to compensate for url bar. Any better ideas?
headFootHeight = 0;
// Get total height for all headers and footers on page
$page.find('[data-role="footer"], [data-role="header"]').each(function() {
var myTotalHeight = $(this).height()
+ parseInt( $(this).css('padding-top') )
+ parseInt( $(this).css('padding-bottom') );
headFootHeight += myTotalHeight;
});
var the_height = (w_height - headFootHeight);
$page
.height(w_height)
.find('.fullHeight')
.height(the_height - t_padding);
});
This script is setting a 100% height on '.fullHeight', instead of [data-role=content] to give more flexibility, but you can just add the fullHeight class to your [data-role=content] element.
One issue I'm still having is compensating for the url bar in ios, and finding a window height that works across devices. Any ideas on that?
the CSS:
footer {
display: block;
position: fixed;
left: 0;
bottom: 0;
right: 0;
height: 50px;
background-color: #333;
overflow: hidden;
z-index:1000;
-webkit-transform: translateZ(0);
opacity:.9;
}
header{
display:block;
position: fixed;
left:0;
right:0;
top:0;
height:50px;
overflow: hidden;
}
section{
display:block;
position:fixed;
left:0;
top:50px;
bottom:50px;
right:0;
overflow-y: auto;
}
nav{
display:block;
height:100%;
-webkit-backface-visibility: hidden;
}
.body{
overflow-y: hidden;
}
.bar {
border: 1px solid #2A2A2A;
background: #111111;
color: #ffffff;
font-weight: bold;
text-shadow: 0 -1px 1px #000000;
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#111)); /* Saf4+, Chrome */
background-image: -webkit-linear-gradient(top, #3c3c3c, #111); /* Chrome 10+, Saf5.1+ */
background-image: -moz-linear-gradient(top, #3c3c3c, #111); /* FF3.6 */
background-image: -ms-linear-gradient(top, #3c3c3c, #111); /* IE10 */
background-image: -o-linear-gradient(top, #3c3c3c, #111); /* Opera 11.10+ */
background-image: linear-gradient(top, #3c3c3c, #111);
}
the only html needed:
<header class="bar" id="AllHead"></header>
<div data-role="content" class="content" id="home"><section><nav></nav></section></div><!-- /content -->
<footer class="bar" id="allFoot"></footer>
</div><!-- /page -->
you can then set whatever items you want inside the footer and the bottom nav bar
this will always look right, no matter what happens, also this wont flash on and off everytime you touch something. hope it helps