Loading spinner VueJS - javascript

I have to make a loading animation when a client clicks the button search to popup a spinner animation, in order the client can't click multiple times on the search button. However, I don't know how to call this animation. I have made this until now:
table.vue:
<div id="overlay-back"></div>
<div id="overlay">
<div id="dvLoading">
<img id="loading-image" src="../assets/images/spinner.gif" alt="Loading..."/>
</div>
</div>
loadData(filter) {
var self = this;
const url = this.$session.get('apiUrl') + 'loadSystemList'
this.submit('post', url, filter);
}
main.css:
#overlay {
position : absolute;
top : 0;
left : 0;
width : 100%;
height : 100%;
z-index : 995;
display : none;
}
#overlay-back {
position : absolute;
top : 0;
left : 0;
width : 100%;
height : 100%;
background : #000;
opacity : 0.6;
filter : alpha(opacity=60);
z-index : 990;
display : none;
}
#dvLoading {
padding: 20px;
background-color: #fff;
border-radius: 10px;
height: 150px;
width: 250px;
position: fixed;
z-index: 1000;
left: 50%;
top: 50%;
margin: -125px 0 0 -125px;
text-align: center;
display: none;
}
I need to call the animation when the button Search is clicked and invokes the function loadData. I would be happy if you help me guys :) I am kinda lost
Update1:
file.vue:
<template>
<div>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.1/css/all.css" integrity="sha384-O8whS3fhG2OnA5Kas0Y9l3cfpmYjapjI0E4theH4iuMD+pLhbf6JI0jIMfYcK3yZ" crossorigin="anonymous">
<div id="dvLoading">
<i class="fa fa-spinner fa-spin fa-10x"></i>
</div>
<div class="toolbarStrip">
<br><h1 style="text-align: center; padding-bottom: 10px;">System table</h1>
<fieldset class="buttons">
<span class="logInBTN" v-on:click="loadData(filter)" id="loadData">Search</span>
</fieldset>
</div>
</div>
</template>
<script type="text/javascript">
import config from '../main.js'
var loadButton = document.getElementById("loadData");
export default {
data(){
return {
},
methods: {
stopShowingLoading(){
var element = document.getElementById("dvLoading");
element.classList.remove("showloading");
var button = document.getElementById("loadData");
button.classList.remove("showloading");
},
loadData(filter) {
var element = document.getElementById("dvLoading");
element.classList.add("showloading");
var button = document.getElementById("loadData");
button.classList.add("showloading");
var self = this;
const url = this.$session.get('apiUrl') + 'loadSystemList'
this.submit('post', url, filter);
window.setTimeout(function(){stopShowingLoading();},3000);
},
submit(requestType, url, submitData) {
this.$http[requestType](url, submitData)
.then(response => {
this.items = response.data;
})
.catch(error => {
console.log('error:' + error);
});
},
newData: function(){
config.router.push('/systemData')
}
}
}
</script>

first of all, whilst I have done things with vue.js in the past, I've forgotten much of that so there may be a better way within that framework than this, which is a vanilla JS approach really...
You don't seem to have a requirement to stop showing the loading animation. When I've done this sort of thing in the past, I've usually made use of callbacks to know when the loading operation is complete, and at that point 'turn off' the loading animation. I've included a function to hide the loading, but don't know where/if you'd want to call this.
This is untested, so apologies for typos or other minor errors...
css:
/*
Override the display:none on the #dvloading element if it has a class
of 'showloading
*/
#dvLoading.showloading{
display:block
}
JS:
function loadData(filter) {
/*
Add the 'showloading' class to the #dvLoading element.
this should make it appear due to the css change...
*/
var element = document.getElementById("dvLoading");
element.classList.add("showloading");
var self = this;
const url = this.$session.get('apiUrl') + 'loadSystemList'
this.submit('post', url, filter);
}
function stopShowingLoading(){
/*
When loading finishes, reverse the process
*/
var element = document.getElementById("dvLoading");
element.classList.remove("showloading");
}
edit: jsFiddle to show general approach
further edit: To stop showing animation only after data has loaded (I just used a timeout to simulate this in my example) then you need to simply stop it after the data has loaded, which would be something like this:
submit(requestType, url, submitData) {
this.$http[requestType](url, submitData)
.then(response => {
// We've received the data now, so set items and
//also hide the loading animation.
this.items = response.data;
this.stopShowingLoading();
})
...
and then remove the window.setTimeout() call altogether.

Related

Use html <a> tag with same z-index?

I have slider and when i mouseover on slider play button is displaying, but slider images are inside a tag and when play button is not hidden i can't click on images inside a tag. i tried set same z-index for both (slider images and play button) but still not working
i need to click on play button when it shown and go to link placed bottom of this play button
if it is possible please help, and sorry for my bad english.
Main question: how can i click on play button with and redirect to link placed inside a tag?
Here is image how slider looks like onmouseover and image when mouse is out of slider
here is my html code:
<style type="text/css">
#slider-play-button-container{
position: absolute;
z-index: 2;
left: 0;
right: 0;
text-align: center;
cursor: pointer;
}
#slider-play-button{
position: relative;
top: 25vh;
width: 2vw;
opacity: 0;
}
.slide-img{
width: 100%;
height: 55vh;
object-fit: cover;
border-radius: .7vw;
overflow:hidden;
}
</style>
<main class=content>
<span id="slider-play-button-container"><img src="https://i.imgur.com/md7vyI8.png" id="slider-play-button"></span>
<div id="slider">
<a href="Link to go after play button click" target="_Blank">
<h3 class="slider-movie-name">ჯონ ვიკი: III თავი - პარაბელუმი</h3>
<img src="https://i.imgur.com/OP3AITl.jpg" class="slide-img">
</a>
<a href="Another link to go after play button click" target="_Blank">
<h3 class="slider-movie-name">შურისმაძიებლები: დასასრული</h3>
<img src="https://i.imgur.com/3vDzVHa.jpg" class="slide-img">
</a>
</div>
</main>
<script>
function bid(n){return document.getElementById(n)}
function qs(n){return document.querySelector(n)}
function qsa(n){return document.querySelectorAll(n)}
let slider = bid('slider');
let arrowTop = bid('slide_arrow_top');
let arrowBottom = bid('slide_arrow_bottom');
let sliderImage = qsa('.slide-img');
let sliderPlayButtonContainer = bid('slider-play-button-container');
let sliderPlayButton = bid('slider-play-button');
let count = 0;
let imageOffset = 0;
let imgOffset = 0;
var slideInterval;
let sliderImageOffset;
/* autoscroll */
window.addEventListener('load',winLoadForSlide);
function winLoadForSlide(){
/* slider */
slider.addEventListener('wheel',slideMouseScroll);
arrowBottom.addEventListener('click',scrollBottom);
arrowTop.addEventListener('click',scrollTop);
function bottomSlide(){
if (count < 4) {
count++;
}
imageOffset = sliderImage[count].offsetTop;
slider.scrollTo(0,imageOffset);
}
function topSlide(){
if (count > 0) {
count--;
}
imageOffset = sliderImage[count].offsetTop;
slider.scrollTo(0,imageOffset-5);
}
function slideMouseScroll(){
if (event.deltaY < 0){
topSlide();
}else if (event.deltaY > 0){
bottomSlide();
}
}
function scrollBottom(){
bottomSlide();
}
function scrollTop(){
topSlide();
}
slideInterval = setInterval(repeatScroll,100 * 20);
function showSliderPlayButton(){
sliderPlayButton.style.transform = "scale(5)";
sliderPlayButton.style.opacity = "1";
sliderPlayButton.style.transition = "250ms";
}
function hideSliderPlayButton(){
sliderPlayButton.style.transform = "scale(1)";
sliderPlayButton.style.opacity = "0";
sliderPlayButton.style.transition = "250ms";
}
[slider,arrowBottom,arrowTop,sliderPlayButtonContainer,sliderPlayButton].forEach(slideElements => {
slideElements.addEventListener('mouseover',()=>{
clearInterval(slideInterval);
});
slideElements.ondragstart = function(){ return false; }
});
[slider,sliderPlayButtonContainer,sliderPlayButton].forEach(slideElementsWithoutButtons => {
slideElementsWithoutButtons.addEventListener('mouseover',()=>{
showSliderPlayButton();
});
});
slider.addEventListener('mouseleave',()=>{
slideInterval = setInterval(repeatScroll,100 * 20);
hideSliderPlayButton();
});
function repeatScroll(){
if( (slider.scrollHeight - slider.scrollTop - slider.clientHeight) !== 4 ){
if (imgOffset < 4) {
imgOffset++;
}
sliderImageOffset = sliderImage[imgOffset].offsetTop;
slider.scrollTo(0,sliderImageOffset);
}else{
imgOffset = 0;
slider.scrollTo(0,0);
}
}
/* END slider */
}
/* END autoscroll */
</script>
There are a few ways to get around this problem.
One would involve getting rid of the anchor tags altogether, grouping each image inside a single container and assigning a click event listener to each one to ultimately open the link. If you then add another click listener to the arrow button which executes event.preventDefault(); the click event will be passed through to the object below - the <div> including your image.
If you want to keep the anchor tags, things are a little tricky. Luckily there are some helpful JavaScript functions, foremost document.elementsFromPoint(x,y).
If you feed the current mouse coordinates to this function - e.g. by clicking on the arrow button - it will return an array of objects below this point.
This array contains the anchor element in the background, so it's just a matter of picking it out of the array, get the link assigned to it and open it using the window.open() command.
Here's an example:
function bid(n) {
return document.getElementById(n)
}
let sliderPlayButtonContainer = bid('slider-play-button-container');
let sliderPlayButton = bid('slider-play-button');
sliderPlayButtonContainer.addEventListener('click', (event) => {
var list = document.elementsFromPoint(event.clientX, event.clientY)
var anchorElement = list.find(element => element instanceof HTMLImageElement && element.className == 'slide-img').parentElement;
window.open(anchorElement.href, anchorElement.target);
});
function showSliderPlayButton() {
sliderPlayButton.style.transform = "scale(5)";
sliderPlayButton.style.opacity = "1";
sliderPlayButton.style.transition = "250ms";
}
sliderPlayButtonContainer.addEventListener('mouseover', () => {
showSliderPlayButton();
});
#slider-play-button-container {
position: absolute;
z-index: 2;
left: 0;
right: 0;
text-align: center;
cursor: pointer;
}
#slider-play-button {
position: relative;
top: 25vh;
width: 2vw;
opacity: 1;
}
.slide-img {
width: 100%;
height: 55vh;
object-fit: cover;
border-radius: .7vw;
overflow: hidden;
}
<span id="slider-play-button-container"><img src="https://i.imgur.com/md7vyI8.png" id="slider-play-button"></span>
<div id="slider">
<a href="https://www.startpage.com" target="_blank">
<h3 class="slider-movie-name">ჯონ ვიკი: III თავი - პარაბელუმი</h3>
<img src="https://i.imgur.com/OP3AITl.jpg" class="slide-img">
</a>
</div>
parentElement property helped a lot to solve my problem
playButtonATagHref = sliderImage[imgOffset].parentElement.href;
sliderPlayButton.addEventListener('click',()=>{
window.location.href = playButtonATagHref;
});

Creating Drop down page

I am after creating a drop down page like on my examples below:
This is how I would like it to show when the arrow on the side is cliked.
How would I make something like this and is there any examples any where for me to study to help me make this ?
If you can use jquery you can play with hasClass, addClass and removeClass to change the height of the submenu
Working Demo.
$(".btn").click(function() {
if ($(".menu").hasClass("dropped")) {
$(".menu").removeClass("dropped");
} else {
$(".menu").addClass("dropped");
}
});
.menu {
height: 0;
overflow: hidden;
transition: all 0.5s ease 0s;
}
.dropped {
height: inherit;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button class="btn">
Dropdown
</button>
<div class="menu">
<p>Stufss...</p>
<p>Stufss...</p>
<p>Stufss...</p>
<p>Stufss...</p>
<p>Stufss...</p>
<p>Stufss...</p>
</div>
With 3 div elements you can get a result like the one pictured. From the picture it looks like one div is wrapping around two other div elements, a div element that already has some information and a div element that will grow/shrink in size through appending/removing elements when the user presses the dropdown button.
Here is a working example:
var extraInformation = document.getElementById('infoLong');
var dropdown = document.getElementById('dropdown');
// The extra info that will be appended into the infoLong div
var someHeading = document.createElement('h4');
someHeading.innerHTML = 'Detailed Game Information';
someHeading.style.background = '#C58AC5';
var teamOneInfo = document.createElement('p');
teamOneInfo.innerHTML = 'Team 1: Lost';
teamOneInfo.style.background = '#FF516B';
var teamTwoInfo = document.createElement('p');
teamTwoInfo.innerHTML = 'Team 2: Won';
teamTwoInfo.style.background = '#3FBFBF';
// Should add more detailed information when the dropdown button
// is pressed only if the infoLong div is empty
dropdown.addEventListener('click', function(){
if(extraInformation.children.length === 0){
extraInformation.appendChild(someHeading);
extraInformation.appendChild(teamOneInfo);
extraInformation.appendChild(teamTwoInfo);
}else{
while(extraInformation.firstChild){
extraInformation.removeChild(extraInformation.firstChild);
}
}
});
#infoShort {
background: #3FBFBF;
}
p {
margin: 0;
}
h4 {
margin: 0;
}
<div id='gameInfoContainer'>
<div id='infoShort'>
<h3>Game Summary</h3>
<button id='dropdown'>Dropdown</button>
</div>
<div id='infoLong'></div>
</div>

jQuery - prev/next navigation between non-siblings

I have a bunch of elements of the same type that have different parents, but I would like to be able to seamlessly navigate/cycle through all of them as if they were together.
<div>
<a href="#" class="open></a>
</div>
<div>
</div>
<div>
</div>
‹
›
I've managed to get this far: https://jsfiddle.net/pj0ecxge/
Currently it doesn't function as intended, as prev() and next() are only meant to target sibling elements, so the arrows don't work if the previous or next element is in another parent.
A single element will always be open by default, but it won't always be the same element as shown in the example. Also, only one element can be open at the same time.
If it makes a difference, I can add a single class to all children elements, but I can't change the HTML structure i.e put them all inside the same parent.
It would be nice if the navigation is infinite - i.e clicking next while the last element is open will show the first element and vice versa, but this is not required if it's too complex to do.
Thanks in advance and any help will be very appreciated!
You can check whether there are next/previous elements, if not then you can move a layer up/down like
$('.prev').click(function(e) {
e.preventDefault();
var current = $('.open');
var prev = current.prev();
if (!prev.length) {
prev = current.parent().prev('div').children('a:last-child')
}
if (prev.length) {
current.removeClass('open');
prev.addClass('open');
}
});
$('.next').click(function(e) {
e.preventDefault();
var current = $('.open');
var next = current.next();
if (!next.length) {
next = current.parent().next('div').children('a:first-child')
}
if (next.length) {
current.removeClass('open');
next.addClass('open');
}
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
text-align: center;
}
div {
font-size: 0;
}
div a {
width: 150px;
height: 150px;
border: 2px solid black;
}
a {
display: inline-block;
}
.open {
background: red;
}
.prev,
.next {
font-size: 100px;
text-decoration: none;
margin: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
</div>
<div>
</div>
<div>
</div>
‹
›
Find the next set when the current set has reached either end. And the if the set is the last one then go back to the first one (and vice-versa).
$('.prev').click(function(e) {
e.preventDefault();
var current = $('.open');
var prev = current.prev();
if (!prev.length) {
prev = current.parent().prev('div').children('a:last-of-type');
if (!prev.length) {
prev = $('div:last-of-type').children('a:last-of-type');
}
}
current.removeClass('open');
prev.addClass('open');
});
$('.next').click(function(e) {
e.preventDefault();
var current = $('.open');
var next = current.next();
if (!next.length) {
next = current.parent().next('div').children('a:first-of-type');
if (!next.length) {
next = $('div:first-of-type').children('a:first-of-type');
}
}
current.removeClass('open');
next.addClass('open');
});

jQuery, multiple content sliders in single page

I want to make a lot of slides in a one-page scrolling site. A neat way to do this was with a code from Stano. My problem is that this code was only meant to occur once per page. In order to make it fit my needs I made it into this fiddle. I realized that this would accumulate very fast into some rather messy coding if I had 20+ of these:
$(document).ready(function() {
var divs = $('.divs>div');
var now = 0; // currently shown div
divs.hide().first().show(); // hide all divs except first
$(".next").click(function() {
divs.eq(now).hide();
now = (now + 1 < divs.length) ? now + 1 : 0;
divs.eq(now).show(); // show next
});
$(".prev").click(function() {
divs.eq(now).hide();
now = (now > 0) ? now - 1 : divs.length - 1;
divs.eq(now).show(); // show previous
});
});
Is there any way to create a common ID/class for the divs and clickers (previous, next) or a container that ensures that the slider functions by itself without interrupting other sliders?
For example creating a variable with the ID of the container
var test = $('.container').attr('id') )
Implementing the ID in the divs
var divs = $(test).attr( 'id',$(test).attr('id') );
Implementing the ID in the next (and prev), so that when they are being clicked they will only affect the divs with the same ID
$(".next",test).click(function () {...
Maybe have a wrapper with a specific ID where the 3 divs (divs, prev and next) are includes and tell the script that they need to be in the same wrapper in order to affect each other.
<div ID="wrap1">
<div class="prev"></div>
<div class="next"></div>
<div class="divs"></div>
</div>
I do not know how the script will change. Maybe including .child() or .parent()?
I am very new at java scripting and hope that my question is understood properly. Please let me know if there is anything that needs to be clarified.
Check my code, each slider has now a function at document ready, not mixing thing around, and a jquery higher version was used.
$(document).ready(function () {
function FirstSlider(){
var divs = $('.div1>div');
var now = 0; // currently shown div
console.log(divs);
divs.hide().first().show(); // hide all divs except first
$(".nex1").click(function () {
divs.eq(now).hide();
now = (now + 1 < divs.length) ? now + 1 : 0;
divs.eq(now).show(); // show next
});
$(".pre1").click(function () {
divs.eq(now).hide();
now = (now > 0) ? now - 1 : divs.length - 1;
divs.eq(now).show(); // show previous
});
}
function SecondSlider(){
var divs = $('.div2>div');
var now = 0; // currently shown div
divs.hide().first().show(); // hide all divs except first
$(".nex2").click(function () {
divs.eq(now).hide();
now = (now + 1 < divs.length) ? now + 1 : 0;
divs.eq(now).show(); // show next
});
$(".pre2").click(function () {
divs.eq(now).hide();
now = (now > 0) ? now - 1 : divs.length - 1;
divs.eq(now).show(); // show previous
});
}
FirstSlider();
SecondSlider();
});
.body {
margin: 0 0;
}
.prenex {
position: fixed;
top:15vh;
display: block;
background-color: #aaa;
cursor: pointer;
width: auto;
height: auto;
font-size: 10vh;
padding: 2vh 4vh;
text-align: center;
opacity: .5;
-webkit-user-select: none;
/* Chrome/Safari */
-moz-user-select: none;
/* Firefox */
-ms-user-select: none;
/* IE10+ */
}
.prev, .pre1, .pre2 {
left:5vh;
float:left;
}
.next, .nex1, .nex2 {
right: 5vh;
float:right;
}
.pre1, .nex1 {
top:20vh;
}
.pre2, .nex2 {
top:70vh;
}
.divs, .div1, .div2 {
width:70vw;
height:40vh;
margin: 0 auto;
display:block;
background-color:#aaa;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="prenex nex1">></div>
<div class="prenex pre1">
<</div>
<div class="div1">
<div>Hello World,</div>
<div>I</div>
<div>Am</div>
<div>The</div>
<div>Test</div>
</div>
<br>
<hr>
<br>
<div class="prenex nex2">></div>
<div class="prenex pre2">
<</div>
<div class="div2">
<div>Hello World,</div>
<div>why do I</div>
<div>follow</div>
<div>the steps of</div>
<div>my evil twin?</div>
</div>

Onclick switch from one to two images then back to one

Trying to figure out how to switch from one to two images then back to one with an onlick.
So far I have below which works no problem for switching to one image and back to original image. Ultimately I'm trying to get the first onclick event to be two images vertically and then click again back to the first single image.
var play = false;
function toggle() {
var image = document.getElementById('image')
var scan = document.getElementById('scan');
play = !play;
if (play) {
image.src = "pause.png";image.width="182";image.height="182";image.border="0";
scan.play();
}
else {
image.src = "play.png";image.width="182";image.height="182";image.border="0";
scan.pause();
}
}
and in body:
<img onclick="toggle()" id="image" src="play.png" alt="image" width="182" height="182" style="margin:auto; position:absolute; top: 0; right: 0; bottom: 0; left: 0; border: 0;">
This should work fine except, take out the width, height and border from the javascript, they're not changing so why have it there and risk some browsers freaking out on them?
I just put this together real quick to test and it works a treat.. I've commented out scan.play and pause of course but I'm assuming you've checked the console in your browser to see if those are throwing any errors?
I took the <a> out and used style cursor=pointer instead for the click-able element as well.. either way works but this is neater and works from ie6 I think, ie7+ definately.
edit: removed source block didn't achieve goal of question
After discussion in comment there's heaps of ways to do it, and I'd probably use jQuery but since you're not here's one not
<!doctype html>
<html>
<head>
<script type="text/javascript">
var play = true;
function toggle() {
//var scan = document.getElementById('scan');
var playpause = document.getElementById('playpause');
var btnplay = playpause.getElementsByClassName('play');
var btnpause = playpause.getElementsByClassName('pause');
play = !play;
if (play) {
btnplay[0].className = 'btn play active';
btnpause[0].className = 'btn pause';
//scan.play();
}
else {
btnplay[0].className = 'btn play';
btnpause[0].className = 'btn pause active';
//scan.pause();
}
}
</script>
<style>
.btn {
width: 182px;
height: 182px;
cursor: pointer;
position: absolute;
visibility: hidden;
}
.btn.active { visibility: visible; }
.btn.play { background: url('play.png') no-repeat 0 0; }
.btn.pause {
background: url('pause.png') no-repeat 0 0;
padding: 182px 0 0 0;
}
</style>
</head>
<body>
<div id="playpause">
<div class="btn play active" onclick="toggle()">
</div>
<div class="btn pause" onclick="toggle()">
<img src="other.png" alt="other" />
</div>
</body>
</html>

Categories