Auto ImageSlider Not Working with SetInterval() - JavaScript/JQuery - javascript

Problem: Want to create a simple javascript/jquery auto image slider, but something doesn't seem to work.
// jquery //
$(document).ready(function() {
$("#imgSlider_img1").show();
$("#imgSlider_img2").hide();
$("#imgSlider_img3").hide();
$("#imgSlider_img4").hide();
})
// slider //
var current_image_number = 1;
function slider() {
if (current_image_number == 1) {
$("#imgSlider_img1").hide();
$("#imgSlider_img2").show('fast');
$("#imgSlider_img3").hide();
$("#imgSlider_img4").hide();
current_image_number = 2;
}
if (current_image_number == 2) {
$("#imgSlider_img1").hide();
$("#imgSlider_img2").hide();
$("#imgSlider_img3").show('fast');
$("#imgSlider_img4").hide();
current_image_number = 3;
}
if (current_image_number == 3) {
$("#imgSlider_img1").hide();
$("#imgSlider_img2").hide();
$("#imgSlider_img3").hide();
$("#imgSlider_img4").show('fast');
current_image_number = 4;
}
if (current_image_number == 4) {
$("#imgSlider_img1").show('fast');
$("#imgSlider_img2").hide();
$("#imgSlider_img3").hide();
$("#imgSlider_img4").hide();
current_image_number = 1;
}
}
window.setInterval(slider, 4000);
.imgSlider {
height: 500px;
margin-left: 10%;
margin-right: 10%;
margin-top: 10px;
box-shadow: 5px 5px 5px #333;
}
.imgSlider img {
width: 100%;
height: 100%;
}
<div class="imgSlider">
<img id="imgSlider_img1" src="images/index/imgSlider_img1.png">
<img id="imgSlider_img2" src="images/index/imgSlider_img2.jpg">
<img id="imgSlider_img3" src="images/index/imgSlider_img3.jpg">
<img id="imgSlider_img4" src="images/index/imgSlider_img4.jpg">
</div>
Logic: I want to make a simple auto slider using the current html scheme. I want to be able to either increment inside the 'imgSlider' div or change images through ID's (like the current one). But the problem is that after each interval, all the images get displayed.
Any help is appreciated!

With 4 if's, all the if's are executed. So, let us say at the entry point the value of index is 1. It will be true for first if and it will set the index to 2. Now, second if condition also becomes true and it will set index to 3. And so on till it resets the value back to 1.
Hence, in place of 4 if's you need to use if else
// jquery //
$(document).ready(function(){
$("#imgSlider_img1").show();
$("#imgSlider_img2").hide();
$("#imgSlider_img3").hide();
$("#imgSlider_img4").hide();
})
// slider //
var current_image_number = 1;
function slider() {
if (current_image_number == 1) {
$("#imgSlider_img1").hide();
$("#imgSlider_img2").show('fast');
$("#imgSlider_img3").hide();
$("#imgSlider_img4").hide();
current_image_number = 2;
} else if (current_image_number == 2) {
$("#imgSlider_img1").hide();
$("#imgSlider_img2").hide();
$("#imgSlider_img3").show('fast');
$("#imgSlider_img4").hide();
current_image_number = 3;
} else if (current_image_number == 3) {
$("#imgSlider_img1").hide();
$("#imgSlider_img2").hide();
$("#imgSlider_img3").hide();
$("#imgSlider_img4").show('fast');
current_image_number = 4;
} else if (current_image_number == 4) {
$("#imgSlider_img1").show('fast');
$("#imgSlider_img2").hide();
$("#imgSlider_img3").hide();
$("#imgSlider_img4").hide();
current_image_number = 1;
}
}
window.setInterval(slider, 4000);
.imgSlider {
height: 500px;
margin-left: 10%;
margin-right: 10%;
margin-top: 10px;
box-shadow: 5px 5px 5px #333;
}
.imgSlider img {
width: 100%;
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="imgSlider">
<img id="imgSlider_img1" alt="imgSlider_img1" src="images/index/imgSlider_img1.png">
<img id="imgSlider_img2" alt="imgSlider_img2" src="images/index/imgSlider_img2.jpg">
<img id="imgSlider_img3" alt="imgSlider_img3" src="images/index/imgSlider_img3.jpg">
<img id="imgSlider_img4" alt="imgSlider_img4" src="images/index/imgSlider_img4.jpg">
</div>
You can further simplify your code to following
// jquery //
$(document).ready(function(){
$(".imgSlider > img").hide(); // hide all images
$("#imgSlider_img1").show(); // show 1st image
});
var current_image_number = 1;
function slider() {
$(".imgSlider > img").hide(); // hide all images
current_image_number = ++current_image_number > 4 ? 1 : current_image_number; // calculate the next image
$("#imgSlider_img" + current_image_number).show('fast'); // show the image
}
window.setInterval(slider, 4000);
.imgSlider {
height: 500px;
margin-left: 10%;
margin-right: 10%;
margin-top: 10px;
box-shadow: 5px 5px 5px #333;
}
.imgSlider img {
width: 100%;
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="imgSlider">
<img id="imgSlider_img1" alt="imgSlider_img1" src="images/index/imgSlider_img1.png">
<img id="imgSlider_img2" alt="imgSlider_img2" src="images/index/imgSlider_img2.jpg">
<img id="imgSlider_img3" alt="imgSlider_img3" src="images/index/imgSlider_img3.jpg">
<img id="imgSlider_img4" alt="imgSlider_img4" src="images/index/imgSlider_img4.jpg">
</div>

I've simplified your JS logic a bit to make it more clear what's going on. The simplified JS will also allow you to add or remove images from your HTML without having to touch your JS:
// all images
var images = document.querySelectorAll('.imgSlider img');
// currently active number
var active = 1;
// slider
function activate() {
for (var i=0; i<images.length; i++) {
images[i].style.display = 'none';
}
// display the active image;
document.querySelector('#imgSlider_img' + active).style.display = 'block';
// increment the active image number
active++;
if (active > images.length) active = 1;
}
window.setInterval(activate, 3000);
activate();
.imgSlider {
height: 500px;
margin-left: 10%;
margin-right: 10%;
margin-top: 10px;
box-shadow: 5px 5px 5px #333;
position: relative;
}
.imgSlider img {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
<div class="imgSlider">
<img id="imgSlider_img1" src="https://placeimg.com/640/480/1.jpg">
<img id="imgSlider_img2" src="https://placeimg.com/640/480/2.jpg">
<img id="imgSlider_img3" src="https://placeimg.com/640/480/3.jpg">
<img id="imgSlider_img4" src="https://placeimg.com/640/480/4.jpg">
</div>
To make this work, you needed to increment the integer that stores the currently active image. You want to do that inside the function that changes the images.
When you increment that active image number, you also should check if the incremented number is greater than the max number of images. If so, you should set the active image number to 1.
That's all there is to it!

If many images occurs means if condition which is stated above deals with problem. So i have suggested to use below type of JavaScript image slider.
var _imgPath = {
"imageDetails": [{
"Id": "F0001",
"Name": "figure1.jpg",
"Src": 'https://homepages.cae.wisc.edu/~ece533/images/airplane.png'
},
{
"Id": "F0002",
"Name": "figure2.jpg",
"Src": 'https://homepages.cae.wisc.edu/~ece533/images/arctichare.png'
},
{
"Id": "F0003",
"Name": "figure3.jpg",
"Src": 'https://homepages.cae.wisc.edu/~ece533/images/baboon.png'
},
{
"Id": "F0004",
"Name": "figure4.jpg",
"Src": 'https://homepages.cae.wisc.edu/~ece533/images/barbara.png'
},
{
"Id": "F0005",
"Name": "figure5.jpg",
"Src": 'https://homepages.cae.wisc.edu/~ece533/images/boat.png'
},
{
"Id": "F0006",
"Name": "figure6.jpg",
"Src": 'https://homepages.cae.wisc.edu/~ece533/images/cat.png'
},
{
"Id": "F0007",
"Name": "figure7.jpg",
"Src": 'https://homepages.cae.wisc.edu/~ece533/images/fruits.png'
},
{
"Id": "F0008",
"Name": "figure8.jpg",
"Src": 'https://homepages.cae.wisc.edu/~ece533/images/frymire.png'
},
{
"Id": "F0009",
"Name": "figure9.jpg",
"Src": 'https://homepages.cae.wisc.edu/~ece533/images/girl.png'
},
{
"Id": "F00010",
"Name": "figure10.jpg",
"Src": 'https://homepages.cae.wisc.edu/~ece533/images/monarch.png'
}
]
}
var currentImage, LastImage;
function initLoader(arg_imgPath) {
if (arg_imgPath.imageDetails.length > 0) {
sliderImgTag.src = arg_imgPath.imageDetails[0]['Src'];
sliderImgTag.setAttribute('cid', arg_imgPath.imageDetails[0]['Id']);
sliderImgTag.setAttribute('alt', arg_imgPath.imageDetails[0]['name']);
currentImage = 0;
document.querySelector('.Prod_Arrow.left').style.visibility = "hidden"
}
document.querySelector('.Prod_Arrow.right').addEventListener('click', function () {
btnArrowShift((currentImage + 1), true);
})
document.querySelector('.Prod_Arrow.left').addEventListener('click', function () {
btnArrowShift((currentImage - 1), false);
})
}
initLoader(_imgPath);
document.querySelector('.Prod_Arrow.right').addEventListener('click', function () {
btnArrowShift((currentImage + 1), true);
})
document.querySelector('.Prod_Arrow.left').addEventListener('click', function () {
btnArrowShift((currentImage - 1), false);
})
function btnArrowShift(value, types) {
if (types) {
if (value != _imgPath.imageDetails.length) {
document.querySelector('.Prod_Arrow.left').style.visibility = "visible"
sliderImgTag.src = _imgPath.imageDetails[value]['Src'];
sliderImgTag.setAttribute('cid', _imgPath.imageDetails[value]['Id']);
sliderImgTag.setAttribute('alt', _imgPath.imageDetails[value]['name']);
currentImage = value;
if (value === (_imgPath.imageDetails.length - 1)) {
document.querySelector('.Prod_Arrow.right').style.visibility = "hidden";
}
}
} else {
if (value != _imgPath.imageDetails.length) {
document.querySelector('.Prod_Arrow.right').style.visibility = "visible"
sliderImgTag.src = _imgPath.imageDetails[value]['Src'];
sliderImgTag.setAttribute('cid', _imgPath.imageDetails[value]['Id']);
sliderImgTag.setAttribute('alt', _imgPath.imageDetails[value]['name']);
currentImage = value;
if (value === 0) {
document.querySelector('.Prod_Arrow.left').style.visibility = "hidden";
}
}
}
}
setInterval(function () {
if (currentImage != _imgPath.imageDetails.length) {
if (currentImage === (_imgPath.imageDetails.length - 1)) {
currentImage = 0;
document.querySelector('.Prod_Arrow.right').style.visibility = "visible";
document.querySelector('.Prod_Arrow.left').style.visibility = "hidden";
} else if(currentImage === (0)) {
currentImage = currentImage + 1;
document.querySelector('.Prod_Arrow.left').style.visibility = "visible";
} else if(currentImage !== (0)){
currentImage = currentImage + 1;
document.querySelector('.Prod_Arrow.left').style.visibility = "visible";
}
sliderImgTag.src = _imgPath.imageDetails[currentImage]['Src'];
sliderImgTag.setAttribute('cid', _imgPath.imageDetails[currentImage]['Id']);
sliderImgTag.setAttribute('alt', _imgPath.imageDetails[currentImage]['name']);
}
}, 5000)
#import url("https://fonts.googleapis.com/css?family=Nunito:400,600,700");
/* font-family: 'Nunito', sans-serif; */
:after,
:before,
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
*::selection {
background: transparent;
}
.Prod-dialog * {
font-family: "Nunito", sans-serif;
}
.Prodclear {
clear: both;
}
.Prod-pull-right {
float: right !important;
}
.Prod-pulk-left {
float: left !important;
}
.Prod-col-4 {
width: 45%;
float: left;
padding: 0px 15px;
}
.Prod-col-8 {
width: 55%;
float: left;
padding: 0px 15px 0px 30px;
}
/* dialog start */
.Prod-dialog.active {
visibility: visible;
position: fixed;
background: rgb(33, 32, 32);
left: 0px;
right: 0px;
bottom: 0px;
top: 0px;
transition: all 0.5s;
padding: 30px;
z-index: 99999;
}
.Prod-container {
max-width: 1440px;
background: #fff;
margin: auto;
/* box-shadow: 0px 0px 15px #ffffff; */
padding: 0px;
margin-top: 50px;
max-height: calc(100vh - 90px);
overflow-y: auto;
background: linear-gradient(to right, white 44%, #f9fafb 44%);
}
.Prod-Gallery-footer .Prod-col-8 {
padding-right: 0px;
}
/* width */
.Prod-container::-webkit-scrollbar,
.Prod_slider::-webkit-scrollbar {
width: 10px;
height: 10px;
}
/* Track */
.Prod-container::-webkit-scrollbar-track,
.Prod_slider::-webkit-scrollbar-track {
background: #f1f1f1;
}
/* Handle */
.Prod-container::-webkit-scrollbar-thumb,
.Prod_slider::-webkit-scrollbar-thumb {
background: #888;
border-radius: 4px;
}
/* Handle on hover */
.Prod-container::-webkit-scrollbar-thumb:hover {
background: #555;
}
.Prod-scroll-hidden {
overflow: hidden;
}
#Prod-dialog-close {
position: absolute;
right: 40px;
top: 15px;
width: 40px;
height: 40px;
opacity: 1;
background: #fff;
border-radius: 50%;
}
#Prod-dialog-close:hover {
opacity: 1;
}
#Prod-dialog-close:before,
#Prod-dialog-close:after {
position: absolute;
left: 19px;
content: " ";
height: 24px;
width: 2px;
background-color: #212020;
z-index: 4;
/* z-index: 888; */
top: 9px;
}
#Prod-dialog-close:before {
transform: rotate(45deg);
}
#Prod-dialog-close:after {
transform: rotate(-45deg);
}
/* dialog end */
/* header start */
.Prod-header h2 {
color: #252525;
font-size: 26px;
font-weight: 700;
line-height: 33px;
text-align: left;
position: relative;
margin: 0px 0px 25px 0px;
padding: 0px 0px 15px 0px;
}
.Prod-header h2:before {
position: absolute;
content: "";
width: 65px;
height: 3px;
background: #fa7000;
bottom: 0px;
}
/* header end*/
/* footer start */
.Prod-footer {
padding: 15px;
background: #fff;
}
.Prod-footer p {
color: #6a7070;
font-size: 16px;
font-weight: 500;
line-height: 24px;
text-align: center;
margin: 0px;
}
.Prod-footer p a {
color: #6a7070;
text-decoration: none;
}
/* footer end */
/* form start*/
.Prod-invoice-sec {
max-width: 994px;
margin: auto;
/* background: #f1f1f1;
background: linear-gradient(to right, white 40%, #f9fafb 40%); */
margin-bottom: 0px;
padding-bottom: 0px;
padding: 30px;
border-bottom: 1px solid #979797;
}
.Prod-col-6 {
width: 50%;
padding: 0px 15px;
float: left;
}
.Prod-row {
margin: 0px -15px;
}
.Prod-form-row {
margin-bottom: 15px;
}
.Prod-form-row label {
color: #9b9b9b;
font-size: 16px;
font-weight: 600;
line-height: 19px;
}
.Prod-form-row p {
color: #252525;
font-size: 16px;
font-weight: 600;
line-height: 22px;
margin: 0px;
}
/* form end*/
/* Gallery Start */
.Prod-Gallery {
margin: 15px 0px;
}
.Prod-Gallery-Header {
position: relative;
border-bottom: 1px solid #979797;
padding-bottom: 8px;
}
.Prod-Gallery-Header h2 {
color: #6a7070;
font-size: 16px;
font-weight: 900;
line-height: 19px;
margin: 0px;
padding: 10px 0px;
display: inline-block;
}
.Prod-tabs {
margin: 0px;
padding: 0px;
position: absolute;
right: 0px;
top: 5px;
}
.Prod-tabs li {
margin: 0px;
padding: 0px;
display: inline-block;
font-size: 16px;
line-height: 32px;
padding: 0px 8px 0px 8px;
position: relative;
cursor: pointer;
border-radius: 6px;
}
ul.Prod-tabs img {
width: 18px;
vertical-align: middle;
cursor: pointer;
}
li#Prod-tab1.active,
li#Prod-tab2.active {
background: #ddd;
}
.Prod-Gallery-body {
padding: 15px 0px 15px 0px;
}
/* Gallery Start */
/* Tab Start */
.Prod-tab-link.current {
background: #d8d8d8;
color: #5b5b5b;
}
.Prod-tab-link.current {
display: inline-block;
}
.Prod-tab-content {
display: none;
}
.Prod-tab-content.current {
display: block;
}
li#ProdSelectedTab.current {
background: transparent;
}
/* Tab End*/
/* selected */
.Prod-grid-group li {
position: relative;
}
.Prod-grid-group li.selected {
position: relative;
}
.Prod-grid-group li.selected:after {
content: "";
display: block;
position: absolute;
background: rgba(250, 112, 0, 0.6);
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
}
.Prod-grid-group li.selected:before {
content: "";
display: block;
width: 18px;
height: 30px;
border: solid #fff;
border-width: 0 3px 3px 0;
transform: rotate(45deg);
position: absolute;
top: 35px;
left: 50px;
z-index: 1;
}
.Prod-grid-group {
margin: 0px;
padding: 0px;
margin-left: -15px;
}
.Prod-grid-group li {
margin: 0px;
padding: 0px;
width: 110px;
height: 110px;
list-style-type: none;
display: inline-block;
overflow: hidden;
margin-left: 16px;
margin-bottom: 16px;
border-radius: 5px;
}
.Prod-grid-group li img {
max-width: 100%;
}
table.Prod-table {
border-collapse: collapse;
width: 100%;
}
table.Prod-table tfoot tr td {
border-top: 1px solid #979797;
border-bottom: 1px solid #979797;
padding: 18px 0px;
font-size: 18px;
}
table.Prod-table td,
table.Prod-table th {
text-align: left;
}
table.Prod-table tr th,
table.Prod-table tr td {
padding: 5px 40px 10px 0px;
}
.Prod-table thead th {
font-weight: 700;
color: #6a7070;
font-size: 16px;
}
.Prod-table tbody td {
font-size: 16px;
font-weight: 600;
line-height: 22px;
text-align: left;
color: #252525;
}
.Prod-table tfoot td {
font-weight: 700;
color: #252525;
font-size: 16px;
}
.Prod-payment-action {
padding: 50px 0px 0px 0px;
text-align: right;
}
.Prod-payment-action button {
border: 2px solid #fa7000;
opacity: 0.8;
border-radius: 5px;
display: inline-block;
padding: 8px 15px;
background: transparent;
text-transform: uppercase;
color: #fa7000;
font-weight: 700;
margin-left: 15px;
}
.Prod-payment-action button:hover {
color: #fff;
background-color: #fa7000;
box-shadow: 0 2px 6px 4px rgba(250, 112, 0, 0.25);
}
/* slider start */
.Prod_slider {
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
margin-bottom: 35px;
}
.lSSlideOuter .lSPager.lSGallery img {
width: 100%;
}
/* slider End */
.Prod_slider ul li {
white-space: nowrap;
margin-bottom: 0px;
}
.Prodt-mark {
position: relative;
width: 20px;
height: 20px;
border: 1px solid #bfc3c3;
float: left;
margin-right: 10px;
top: 5px;
border-radius: 4px;
}
.Prodt-mark::before {
content: "";
display: block;
width: 6px;
height: 14px;
border: solid transparent;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
position: absolute;
top: 0px;
left: 6px;
z-index: 1;
}
.Prod-tab-link.current .Prodt-mark {
background: #bfc3c3;
}
.Prod-tab-link.current .Prodt-mark::before {
content: "";
display: block;
width: 6px;
height: 14px;
border: solid #fff;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
position: absolute;
top: 0px;
left: 6px;
z-index: 1;
}
.Prod-Caption {
margin: 8px 0px 0px 0px;
font-size: 14px;
}
.newImgViewer {
width: 150px;
height: 800px;
}
.Prod_slider {
position: relative;
}
.Prod_Arrow {
width: 50px;
height: 50px;
background: #bfc3c3;
border-radius: 50%;
position: absolute;
cursor: pointer;
}
.Prod_Arrow.left {
left: 0px;
top: 45%;
}
.Prod_Arrow.left::before {
position: absolute;
content: "";
top: 20px;
left: 20px;
border: solid #fff;
border-width: 0 3px 3px 0;
display: inline-block;
padding: 3px;
transform: rotate(135deg);
-webkit-transform: rotate(135deg);
}
.Prod_Arrow.right {
right: 0px;
top: 45%;
}
.Prod_Arrow.right::before {
position: absolute;
content: "";
top: 20px;
left: 20px;
border: solid #fff;
border-width: 0 3px 3px 0;
display: inline-block;
padding: 3px;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.Prod-slider-view {
text-align: center;
position: relative;
height: 450px;
}
.Prod-slider-view img {
height: 400px;
border-radius: 6px;
vertical-align: middle;
margin-top: 25px;
}
.Prod_Selected {
width: 50px;
height: 50px;
position: absolute;
top: 30px;
right: 200px;
border-radius: 4px;
}
.Prod_Selected[isselected="true"]::before {
content: "";
display: block;
width: 8px;
height: 16px;
border: solid #fff;
border-width: 0 3px 3px 0;
transform: rotate(45deg);
position: absolute;
top: 15px;
left: 20px;
z-index: 1;
}
.Prod_Selected::after {
content: "";
display: block;
position: absolute;
background: #bfc3c3;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
border-radius: 6px;
}
.allitems li {
display: none;
}
.allitems li.selected {
display: inline-block;
}
#Prod-grid-slider li.isactive {
border: 4px solid #fa7000;
}
#Prod-grid-slider li {
border: 4px solid transparent;
}
#ProdSelectedTab.current span.ProdAllImages {
display: none;
}
span.ProdAllImages {
display: none;
}
.Prod-tab-link.current span.ProdSelectedImg {
display: inline-block;
}
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<link rel="stylesheet" type="text/css" media="screen" href="src/index.css" />
</head>
<body>
<div class="Prod-dialog">
<div class="Prod-container">
<div class="Prod-invoice-sec">
<div class="Prod-header">
<h2>Slider</h2>
</div>
<div class="Prod-container-body">
<div class="Prod-Gallery">
<div class="Prod-Gallery-body">
<!--Wrapper to contain interchanging content-->
<div class="Prod-tabs-wrapper">
<div id="ProdSliderContent" class="Prod-tab-content current">
<div class="Prod-slider-view">
<img id="sliderImgTag">
<div class="Prod_Arrow left"></div>
<div class="Prod_Arrow right"></div>
</div>
<div class="Prod_slider">
<ul class="Prod-grid-group" id="Prod-grid-slider"> </ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="Prod-footer">
<p>Prasanna Brabourame</p>
<p>Open Source Enthusiasts</p>
<p>Place:
<a> Puducherry,Pondicherry,INDIA</a>
</p>
<p>Email:
prasanna18101994#gmail.com
</p>
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>

Related

How to target and display error message with data-error in JavaScript

I'de like to validate a form with data propriety data-error and data-error-visible. I want to display the error message only with JS and don't use anymore HTML codes to do it.
The current code I use is below and I left only the first input :
/******
*
FORM VALIDATION
*
******/
// DOM
const formData = document.querySelectorAll(".formData");
const form = document.getElementById("form");
const firstName = document.getElementById("firstName");
const lastName = document.getElementById("lastName");
const email = document.getElementById("email");
const birthdate = document.getElementById("birthdate");
const quantity = document.getElementById("quantity");
const tournament = document.getElementsByName("location");
const checkbox = document.getElementsByName("checkbox");
// form preventDefault + checkInputs function
form.addEventListener('submit', e => {
e.preventDefault();
});
/***********
*
DATA-ATTRIBUTE
*
************/
// set error message to "true"
const displayErrorMsg = (element, message) => {
const formData = element
formData.setAttribute("data-error", message)
formData.setAttribute("data-error-visible", true)
}
// Function for remove one error msg
const removeErrorMsg = (element) => {
const formData = element
formData.removeAttribute('data-error')
formData.removeAttribute('data-error-visible')
}
/***********
*
* VALIDATION FUNCTION
*
************/
function validate(formData) {
let isFormValid = true;
// Regex
const nameRegex = /[a-zA-Z]+/i;
// First name
if (firstName.value.match(nameRegex) || firstName.value.length < 2) {
isFormValid = false;
displayErrorMsg(firstName);
} else {
removeErrorMsg(firstName);
}
}
:root {
--font-default: "DM Sans", Arial, Helvetica, sans-serif;
--font-slab: var(--font-default);
--modal-duration: 0.8s;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/* Landing Page */
body {
margin: 0;
display: flex;
flex-direction: column;
font-family: var(--font-default);
font-size: 18px;
max-width: 1300px;
margin: 0 auto;
}
p {
margin-bottom: 0;
padding: 0.5vw;
}
img {
padding-right: 1rem;
}
.topnav {
overflow: hidden;
margin: 3.5%;
}
.header-logo {
float: left;
}
.main-navbar {
float: right;
}
.topnav a {
float: left;
display: block;
color: #000000;
text-align: center;
padding: 12px 12px;
margin: 5px;
text-decoration: none;
font-size: 20px;
font-family: Roboto, sans-serif;
}
.topnav a:hover {
background-color: #ff0000;
color: #ffffff;
border-radius: 15px;
}
.topnav a.active {
background-color: #ff0000;
color: #ffffff;
border-radius: 15px;
}
.topnav .icon {
display: none;
}
#media screen and (max-width: 768px) {
.topnav a {display: none;}
.topnav a.icon {
float: right;
display: block;
}
}
#media screen and (max-width: 768px) {
.topnav.responsive {position: relative;}
.topnav.responsive .icon {
position: absolute;
right: 0;
top: 0;
}
.topnav.responsive a {
float: none;
display: block;
text-align: left;
}
}
#media screen and (max-width: 540px) {
.topnav a {display: none;}
.topnav a.icon {
float: right;
display: block;
margin-top: -15px;
}
}
main {
font-size: 130%;
font-weight: bolder;
color: black;
padding-top: 0.5vw;
padding-left: 2vw;
padding-right: 2vw;
margin: 1px 20px 15px;
border-radius: 2rem;
text-align: justify;
}
.modal-btn {
font-size: 145%;
background: #fe142f;
display: flex;
margin: auto;
padding: 2em;
color: #fff;
padding: 0.75rem 2.5rem;
border-radius: 1rem;
cursor: pointer;
}
.modal-btn:hover {
background: #3876ac;
}
.footer {
margin: 20px;
padding: 10px;
font-family: var(--font-slab);
}
/* Modal form */
.button {
background: #fe142f;
margin-top: 0.5em;
padding: 1em;
color: #fff;
border-radius: 15px;
cursor: pointer;
font-size: 16px;
}
.button:hover {
background: #3876ac;
}
.smFont {
font-size: 16px;
}
.bground {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
height: 100%;
width: 100%;
overflow: auto;
background-color: rgba(26, 39, 156, 0.4);
}
.content {
margin: 5% auto;
width: 100%;
max-width: 500px;
animation-name: modalopen;
animation-duration: var(--modal-duration);
background: #232323;
border-radius: 10px;
overflow: hidden;
position: relative;
color: #fff;
padding-top: 10px;
}
.modal-body {
padding: 15px 8%;
margin: 15px auto;
}
label {
font-family: var(--font-default);
font-size: 17px;
font-weight: normal;
display: inline-block;
margin-bottom: 11px;
}
input {
padding: 8px;
border: 0.8px solid #ccc;
outline: none;
}
.text-control {
margin: 0;
padding: 8px;
width: 100%;
border-radius: 8px;
font-size: 20px;
height: 48px;
}
.formData[data-error]::after {
content: attr(data-error);
font-size: 0.4em;
color: #e54858;
display: block;
margin-top: 7px;
margin-bottom: 7px;
text-align: right;
line-height: 0.3;
opacity: 0;
transition: 0.3s;
}
.formData[data-error-visible="true"]::after {
opacity: 1;
}
.formData[data-error-visible="true"] .text-control {
border: 2px solid #e54858;
}
/*
input[data-error]::after {
content: attr(data-error);
font-size: 0.4em;
color: red;
} */
.checkbox-label,
.checkbox2-label {
position: relative;
margin-left: 36px;
font-size: 12px;
font-weight: normal;
}
.checkbox-label .checkbox-icon,
.checkbox2-label .checkbox-icon {
display: block;
width: 20px;
height: 20px;
border: 2px solid #279e7a;
border-radius: 50%;
text-indent: 29px;
white-space: nowrap;
position: absolute;
left: -30px;
top: -1px;
transition: 0.3s;
}
.checkbox-label .checkbox-icon::after,
.checkbox2-label .checkbox-icon::after {
content: "";
width: 13px;
height: 13px;
background-color: #279e7a;
border-radius: 50%;
text-indent: 29px;
white-space: nowrap;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
transition: 0.3s;
opacity: 0;
}
.checkbox-input {
display: none;
}
.checkbox-input:checked + .checkbox-label .checkbox-icon::after,
.checkbox-input:checked + .checkbox2-label .checkbox-icon::after {
opacity: 1;
}
.checkbox-input:checked + .checkbox2-label .checkbox-icon {
background: #279e7a;
}
.checkbox2-label .checkbox-icon {
border-radius: 4px;
border: 0;
background: #c4c4c4;
}
.checkbox2-label .checkbox-icon::after {
width: 7px;
height: 4px;
border-radius: 2px;
background: transparent;
border: 2px solid transparent;
border-bottom-color: #fff;
border-left-color: #fff;
transform: rotate(-55deg);
left: 21%;
top: 19%;
}
.close {
position: absolute;
right: 15px;
top: 15px;
width: 32px;
height: 32px;
opacity: 1;
cursor: pointer;
transform: scale(0.7);
}
.close:before,
.close:after {
position: absolute;
left: 15px;
content: " ";
height: 33px;
width: 3px;
background-color: #fff;
}
.close:before {
transform: rotate(45deg);
}
.close:after {
transform: rotate(-45deg);
}
.btn-submit,
.btn-signup {
background: #fe142f;
display: block;
margin: 0 auto;
border-radius: 7px;
font-size: 1rem;
padding: 12px 82px;
color: #fff;
cursor: pointer;
border: 0;
}
/* custom select styles */
.custom-select {
position: relative;
font-family: Arial;
font-size: 1.1rem;
font-weight: normal;
}
.custom-select select {
display: none;
}
.select-selected {
background-color: #fff;
}
/* Style the arrow inside the select element: */
.select-selected:after {
position: absolute;
content: "";
top: 10px;
right: 13px;
width: 11px;
height: 11px;
border: 3px solid transparent;
border-bottom-color: #f00;
border-left-color: #f00;
transform: rotate(-48deg);
border-radius: 5px 0 5px 0;
}
/* Point the arrow upwards when the select box is open (active): */
.select-selected.select-arrow-active:after {
transform: rotate(135deg);
top: 13px;
}
.select-items div,
.select-selected {
color: #000;
padding: 11px 16px;
border: 1px solid transparent;
border-color: transparent transparent rgba(0, 0, 0, 0.1) transparent;
cursor: pointer;
border-radius: 8px;
height: 48px;
}
/* Style items (options): */
.select-items {
position: absolute;
background-color: #fff;
top: 89%;
left: 0;
right: 0;
z-index: 99;
}
/* Hide the items when the select box is closed: */
.select-hide {
display: none;
}
.select-items div:hover,
.same-as-selected {
background-color: rgba(0, 0, 0, 0.1);
}
/* custom select end */
.text-label {
font-weight: normal;
font-size: 16px;
}
.hero-section {
min-height: 93vh;
border-radius: 10px;
display: grid;
grid-template-columns: repeat(12, 1fr);
overflow: hidden;
box-shadow: 0 2px 7px 2px rgba(0, 0, 0, 0.2);
margin-bottom: 10px;
}
.hero-content {
padding: 51px 67px;
grid-column: span 4;
background: #232323;
color: #fff;
position: relative;
text-align: left;
min-width: 424px;
}
.hero-content::after {
content: "";
width: 100%;
height: 100%;
background: #232323;
position: absolute;
right: -80px;
top: 0;
}
.hero-content > * {
position: relative;
z-index: 1;
}
.hero-headline {
font-size: 6rem;
font-weight: normal;
white-space: nowrap;
}
.hero-text {
width: 146%;
font-weight: normal;
margin-top: 57px;
padding: 0;
}
.btn-signup {
outline: none;
text-transform: capitalize;
font-size: 1.3rem;
padding: 15px 23px;
margin: 0;
margin-top: 59px;
}
.hero-img {
grid-column: span 8;
}
.hero-img img {
width: 100%;
height: 100%;
display: block;
padding: 0;
}
.copyrights {
color: #fe142f;
padding: 0;
font-size: 1rem;
margin: 60px 0 30px;
font-weight: bolder;
}
.hero-section > .btn-signup {
display: none;
}
footer {
padding-left: 2vw;
padding-right: 2vw;
margin: 0 20px;
}
#media screen and (max-width: 800px) {
.hero-section {
display: block;
box-shadow: unset;
}
.hero-content {
background: #fff;
color: #000;
padding: 20px;
}
.hero-content::after {
content: unset;
}
.hero-content .btn-signup {
display: none;
}
.hero-headline {
font-size: 4.5rem;
white-space: normal;
}
.hero-text {
width: unset;
font-size: 1.5rem;
}
.hero-img img {
border-radius: 10px;
margin-top: 40px;
}
.hero-section > .btn-signup {
display: block;
margin: 32px auto 10px;
padding: 12px 35px;
}
.copyrights {
margin-top: 50px;
text-align: center;
}
}
#keyframes modalopen {
from {
opacity: 0;
transform: translateY(-150px);
}
to {
opacity: 1;
}
}
<form
id="form"
name="reserve"
action="index.html"
method="get"
>
<div class="formData">
<label for="firstName">Prénom</label><br>
<input
class="text-control"
type="text"
id="firstName"
name="first"
minlength="2"
required
/><br>
</div>
<input
class="btn-submit"
type="submit"
class="button"
value="C'est parti"
/>
</form>

Onclick Function in Dropdown Menu not working

I'm a newbie and practicing dropdown menu using the following Youtube video https://www.youtube.com/watch?v=uFIl4BvYne0. Everything is working except the onclick function.
Can anyone point out where I'm going wrong?
function show(anything) {
document.querySelector('.textBox').value =
anything;
}
let dropdown = document.querySelector('.dropdown');
dropdown.onclick = function() {
dropdown.classList.toggle('active');
}
#import url('https://fonts.googleapis.com/css?family=Poppins:100,200,300,400,500,600,700,800,900');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body {
display: flex;
justify-content: center;
min-height: 100vh;
background: #fafafa;
}
.dropdown {
position: relative;
margin-top: 100px;
width: 300px;
height: 50px;
}
.dropdown::before {
content: "";
position: absolute;
right: 20px;
top: 15px;
z-index: 10000;
width: 8px;
height: 8px;
border: 2px solid #333;
border-top: 2px solid #fff;
border-right: 2px solid #fff;
transform: rotate(-45deg);
transition: 0.5s;
pointer-events: none;
}
.dropdown.active::before {
top: 22px;
transform: rotate(-225deg);
}
.dropdown input {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100;
cursor: pointer;
background: #fff;
border: none;
outline: none;
box-shadow: 0px 5px 20px rgba(0, 0, 0, 0.05);
padding: 12px 20px;
border-radius: 10px;
}
.dropdown .option {
position: absolute;
top: 70px;
width: 100%;
background: #fff;
box-shadow: 0px 30px 30px rgba(0, 0, 0, 0.05);
border-radius: 10px;
overflow: hidden;
/*display: none*/
;
}
.dropdown.active .option {
display: block;
}
.dropdown .option div {
padding: 10px 20px;
cursor: pointer;
}
.dropdown .option div:hover {
background: #62baea;
color: #fff;
}
<body>
<h2>Converter</h2>
<label>Litres</label>
<div class="dropdown">
<input type="text" class="textBox" placeholder="HTML" readonly>
<div class="option">
<div onlcick="show('HTML')">HTML</div>
<div onclick="show('HTML')">HTML</div>
<div onclick="show('HTML')">HTML</div>
<div onclick="show('HTML')">HTML</div>
</div>
</div>
</body>
I have tried some fixes but couldn't find out the problem.
Note: I'm pretty new in this field.
You need to add addEventListener in order to append an action:
function show(anything) {
document.querySelector('.textBox').value =
anything;
}
let dropdown = document.querySelector('.dropdown');
dropdown.addEventListener('click', function(event) { // add click function
dropdown.classList.toggle('active'); // i don't know what class you want to change so i changed the background to a class to demonstrate the click
});
#import url('https://fonts.googleapis.com/css?family=Poppins:100,200,300,400,500,600,700,800,900');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body {
display: flex;
justify-content: center;
min-height: 100vh;
background: #fafafa;
}
.dropdown {
position: relative;
margin-top: 100px;
width: 300px;
height: 50px;
}
.dropdown::before {
content: "";
position: absolute;
right: 20px;
top: 15px;
z-index: 10000;
width: 8px;
height: 8px;
border: 2px solid #333;
border-top: 2px solid #fff;
border-right: 2px solid #fff;
transform: rotate(-45deg);
transition: 0.5s;
pointer-events: none;
}
.dropdown.active::before {
top: 22px;
transform: rotate(-225deg);
}
.dropdown input {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100;
cursor: pointer;
background: #fff;
border: none;
outline: none;
box-shadow: 0px 5px 20px rgba(0, 0, 0, 0.05);
padding: 12px 20px;
border-radius: 10px;
}
.dropdown .option {
position: absolute;
top: 70px;
width: 100%;
background: #fff;
box-shadow: 0px 30px 30px rgba(0, 0, 0, 0.05);
border-radius: 10px;
overflow: hidden;
/*display: none*/
;
}
.dropdown.active .option {
display: block;
background-color: grey;
}
.dropdown .option div {
padding: 10px 20px;
cursor: pointer;
}
.dropdown .option div:hover {
background: #62baea;
color: #fff;
}
<body>
<h2>Converter</h2>
<label>Litres</label>
<div class="dropdown">
<input type="text" class="textBox" placeholder="HTML" readonly>
<div class="option">
<div onlcick="show('HTML')">HTML</div>
<div onclick="show('HTML')">HTML</div>
<div onclick="show('HTML')">HTML</div>
<div onclick="show('HTML')">HTML</div>
</div>
</div>
</body>

Aligning a chat bubble content to the right

I have a bootstrap card that is adding chat bubbles to a list group. I want to align the content to the right so the bubble isn't just in the middle. I tried using align=right and wrapping that div tag in:
$("#messages").append($("<div align=right><div class=bubble-r><li></div></div><br />").text(msg));
but that didn't work. What am I missing?
$("#messages").append(
$("<div class=bubble-r><li></div><br />").text(msg)
);
} else {
$("#messages").append(
$("<div class=bubble><li></div> <br />").text(msg)
);
}
});
}
render() {
return (
<ul id="messages">
<div />
</ul>
);
}
CSS
.chat {
color: white;
}
.chat .dropdown-toggle:after {
content: none;
}
.userbutton {
size: 2px;
}
.card {
color: black;
}
.card-text {
overflow: auto;
height: 10rem;
}
.onlinebar {
position: "absolute";
color: red;
bottom: 0;
left: 0;
}
#chatbtn {
color: black;
width: 200px;
margin-left: 5px;
margin-top: 0px;
}
.chatcollapse {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
#chatHeader {
margin: 0px;
padding: 0px;
}
#chatcard {
width: 2rem;
}
.card-deck .card {
max-width: calc(25% + 80px);
}
.card-body {
padding: 0px;
margin: 0px;
}
.bubble-r {
align-items: flex-end;
position: relative;
background: #0072c6;
max-width: 100px;
padding: 5px;
font-family: arial;
margin: 0 auto;
font-size: 14px;
color: white;
border-radius: 6px;
}
.bubble-r:after,
.bubble-r:before {
left: 100%; /*change this from right to left*/
top: 42%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.bubble-r:after {
border-color: rgba(200, 200, 204, 0);
border-left-color: #0072c6; /*change this from right to left */
border-width: 8px;
margin-top: -3px;
}
.bubble-r:before {
border-color: rgba(200, 204, 0, 0);
border-left-color: #0072c6; /*change this from right to left*/
border-width: 8px;
margin-top: -3px;
}
.bubble {
position: relative;
background: #cad5d7;
max-width: 100px;
padding: 5px;
font-family: arial;
margin: 0 auto;
font-size: 14px;
border-radius: 6px;
}
.bubble:after,
.bubble:before {
right: 100%;
top: 42%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.bubble:after {
border-color: rgba(255, 255, 204, 0);
border-right-color: #cad5d7;
border-width: 8px;
margin-top: -3px;
}
.bubble:before {
border-color: rgba(255, 204, 0, 0);
border-right-color: #cad5d7;
border-width: 8px;
margin-top: -3px;
}

How do I close custom popover when click outside?

I'm developing a Cordova app. For that I'm using Vue.js and jQuery for bindings and script and I'm developing UI on my own. I could do page transitions and animations for most of the UI like, Radio buttons and check boxes etc. But I could not be able to develop a custom popover. I have tried following code.
Vue.directive('popover', {
bind: function(el, bindings, vnode) {
$(el).click(function() {
var pageEl = $(this).closest('.ui-page');
pageEl.find('.drawer').toggleClass('active');
$(el).closest('.ui-page').click(function(e) {
// $('.drawer', this).removeClass('active');
});
});
}
})
var pageInstace = new Vue({
el: '#popover-page',
data: {
options: [1, 2, 3, 4, 5]
}
})
html,
body {
position: relative;
width: 100%;
height: 100%;
}
body {
font-family: 'Open Sans';
font-size: 16px;
margin: 0;
overflow: hidden;
}
* {
box-sizing: border-box;
}
*, *:active, *:hover, *:focus {
outline: 0;
}
button {
padding: 0;
}
img {
max-width: 100%;
}
.ui-page,
.header,
.scroll-content {
position: absolute;
width: 100%;
top: 0;
left: 0;
overflow: hidden;
}
.ui-page {
height: 100%;
background-color: #fff;
}
.page-content {
position: relative;
height: 100%;
overflow-y: auto;
z-index: 1;
}
.header {
height: 54px;
box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), 0 3px 3px -2px rgba(0, 0, 0, 0.12), 0 1px 8px 0 rgba(0, 0, 0, 0.2);
background-color: #607D8B;
color: #fff;
display: flex;
align-items: center;
padding-left: 16px;
padding-right: 16px;
z-index: 1;
}
.scroll-content {
bottom: 0;
overflow: auto;
}
.scroll-content.has-header {
top: 54px;
}
.header button {
color: #fff;
height: 100%;
}
.header .header-title {
margin: 0 22px;
font-size: 18px;
font-weight: 600;
width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.header .buttons {
position: relative;
display: flex;
}
.header .buttons button {
padding: 4px 8px;
}
.header .buttons button:last-child {
padding: 4px 0 4px 8px;
}
.btn {
position: relative;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
border: none;
padding: 8px 16px;
font-size: 16px;
border-radius: 4px;
font-family: unset;
overflow: hidden;
}
.btn-clear {
background-color: transparent;
border: none;
}
.item {
position: relative;
display: flex;
overflow: hidden;
border-bottom: 1px solid #bdbdbd;
}
.drawer {
position: absolute;
background-color: #fff;
z-index: 4;
top: 60px;
right: 4px;
border-radius: 2px;
box-shadow: 0px 2px 8px 2px rgba(0, 0, 0, 0.4);
transform: scale(0, 0);
transform-origin: top right;
transition: transform ease 0.3s;
min-width: 180px;
}
.drawer.active {
transform: scale(1, 1);
}
.drawer .drawer-content {
position: relative;
padding: 4px 0;
}
.drawer .drawer-content:after {
content: '';
position: absolute;
border: 8px solid transparent;
border-bottom-color: #fff;
top: -14px;
right: 22px;
}
.drawer .item {
padding: 12px 16px;
font-size: 14px;
}
.drawer .item:last-child {
border-bottom: none;
}
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div class="ui-page" id="popover-page">
<div class="page-content">
<div class="header">
<div class="header-title">
Page Title
</div>
<button class="btn-clear" v-popover>Popover</button>
</div>
<div class="drawer">
<div class="drawer-content">
<div class="item" v-for="option in options">{{ option }}</div>
</div>
</div>
<div class="scroll-content has-header">
<div class="page-content">
<p>Some Content</p>
</div>
</div>
</div>
</div>
This works fine for toggling popover on button click. I tried so much. But I could not hide the popover when click on outside of the popover.
How can I hide popover when clicking out side of it?
Please try this. I have added jQuery
$('body').click(function(e) {
if (!$(e.target).closest('.drawer').length){
$(".drawer").removeClass("active");
}
});
$('body').click(function(e) {
if (!$(e.target).closest('.drawer').length){
$(".drawer").removeClass("active");
}
});
Vue.directive('popover', {
bind: function(el, bindings, vnode) {
$(el).click(function(e) {
e.stopPropagation();
var pageEl = $(this).closest('.ui-page');
pageEl.find('.drawer').toggleClass('active');
$(el).closest('.ui-page').click(function(e) {
// $('.drawer', this).removeClass('active');
});
});
}
})
var pageInstace = new Vue({
el: '#popover-page',
data: {
options: [1, 2, 3, 4, 5]
}
})
html,
body {
position: relative;
width: 100%;
height: 100%;
}
body {
font-family: 'Open Sans';
font-size: 16px;
margin: 0;
overflow: hidden;
}
* {
box-sizing: border-box;
}
*, *:active, *:hover, *:focus {
outline: 0;
}
button {
padding: 0;
}
img {
max-width: 100%;
}
.ui-page,
.header,
.scroll-content {
position: absolute;
width: 100%;
top: 0;
left: 0;
overflow: hidden;
}
.ui-page {
height: 100%;
background-color: #fff;
}
.page-content {
position: relative;
height: 100%;
overflow-y: auto;
z-index: 1;
}
.header {
height: 54px;
box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), 0 3px 3px -2px rgba(0, 0, 0, 0.12), 0 1px 8px 0 rgba(0, 0, 0, 0.2);
background-color: #607D8B;
color: #fff;
display: flex;
align-items: center;
padding-left: 16px;
padding-right: 16px;
z-index: 1;
}
.scroll-content {
bottom: 0;
overflow: auto;
}
.scroll-content.has-header {
top: 54px;
}
.header button {
color: #fff;
height: 100%;
}
.header .header-title {
margin: 0 22px;
font-size: 18px;
font-weight: 600;
width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.header .buttons {
position: relative;
display: flex;
}
.header .buttons button {
padding: 4px 8px;
}
.header .buttons button:last-child {
padding: 4px 0 4px 8px;
}
.btn {
position: relative;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
border: none;
padding: 8px 16px;
font-size: 16px;
border-radius: 4px;
font-family: unset;
overflow: hidden;
}
.btn-clear {
background-color: transparent;
border: none;
}
.item {
position: relative;
display: flex;
overflow: hidden;
border-bottom: 1px solid #bdbdbd;
}
.drawer {
position: absolute;
background-color: #fff;
z-index: 4;
top: 60px;
right: 4px;
border-radius: 2px;
box-shadow: 0px 2px 8px 2px rgba(0, 0, 0, 0.4);
transform: scale(0, 0);
transform-origin: top right;
transition: transform ease 0.3s;
min-width: 180px;
}
.drawer.active {
transform: scale(1, 1);
}
.drawer .drawer-content {
position: relative;
padding: 4px 0;
}
.drawer .drawer-content:after {
content: '';
position: absolute;
border: 8px solid transparent;
border-bottom-color: #fff;
top: -14px;
right: 22px;
}
.drawer .item {
padding: 12px 16px;
font-size: 14px;
}
.drawer .item:last-child {
border-bottom: none;
}
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div class="ui-page" id="popover-page">
<div class="page-content">
<div class="header">
<div class="header-title">
Page Title
</div>
<button class="btn-clear" v-popover>Popover</button>
</div>
<div class="drawer">
<div class="drawer-content">
<div class="item" v-for="option in options">{{ option }}</div>
</div>
</div>
<div class="scroll-content has-header">
<div class="page-content">
<p>Some Content</p>
</div>
</div>
</div>
</div>
Vue.directive('popover', {
bind: function(el, bindings, vnode) {
$(el).click(function() {
$(el).closest('.ui-page').find('.drawer').toggleClass('active');
});
$('body').on('click', $(el).closest('.ui-page'), function(e) {
var $drawer = $(el).closest('.ui-page').find('.drawer');
var $target = $(e.target);
if ($target.closest($(el)).length <= 0
&& $drawer.hasClass('active')
&& $target.closest('.drawer').length <= 0) {
$drawer.removeClass('active');
}
});
}
})
var pageInstace = new Vue({
el: '#popover-page',
data: {
options: [1, 2, 3, 4, 5]
}
})
html,
body {
position: relative;
width: 100%;
height: 100%;
}
body {
font-family: 'Open Sans';
font-size: 16px;
margin: 0;
overflow: hidden;
}
* {
box-sizing: border-box;
}
*, *:active, *:hover, *:focus {
outline: 0;
}
button {
padding: 0;
}
img {
max-width: 100%;
}
.ui-page,
.header,
.scroll-content {
position: absolute;
width: 100%;
top: 0;
left: 0;
overflow: hidden;
}
.ui-page {
height: 100%;
background-color: #fff;
}
.page-content {
position: relative;
height: 100%;
overflow-y: auto;
z-index: 1;
}
.header {
height: 54px;
box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), 0 3px 3px -2px rgba(0, 0, 0, 0.12), 0 1px 8px 0 rgba(0, 0, 0, 0.2);
background-color: #607D8B;
color: #fff;
display: flex;
align-items: center;
padding-left: 16px;
padding-right: 16px;
z-index: 1;
}
.scroll-content {
bottom: 0;
overflow: auto;
}
.scroll-content.has-header {
top: 54px;
}
.header button {
color: #fff;
height: 100%;
}
.header .header-title {
margin: 0 22px;
font-size: 18px;
font-weight: 600;
width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.header .buttons {
position: relative;
display: flex;
}
.header .buttons button {
padding: 4px 8px;
}
.header .buttons button:last-child {
padding: 4px 0 4px 8px;
}
.btn {
position: relative;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
border: none;
padding: 8px 16px;
font-size: 16px;
border-radius: 4px;
font-family: unset;
overflow: hidden;
}
.btn-clear {
background-color: transparent;
border: none;
}
.item {
position: relative;
display: flex;
overflow: hidden;
border-bottom: 1px solid #bdbdbd;
}
.drawer {
position: absolute;
background-color: #fff;
z-index: 4;
top: 60px;
right: 4px;
border-radius: 2px;
box-shadow: 0px 2px 8px 2px rgba(0, 0, 0, 0.4);
transform: scale(0, 0);
transform-origin: top right;
transition: transform ease 0.3s;
min-width: 180px;
}
.drawer.active {
transform: scale(1, 1);
}
.drawer .drawer-content {
position: relative;
padding: 4px 0;
}
.drawer .drawer-content:after {
content: '';
position: absolute;
border: 8px solid transparent;
border-bottom-color: #fff;
top: -14px;
right: 22px;
}
.drawer .item {
padding: 12px 16px;
font-size: 14px;
}
.drawer .item:last-child {
border-bottom: none;
}
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div class="ui-page" id="popover-page">
<div class="page-content">
<div class="header">
<div class="header-title">
Page Title
</div>
<button class="btn-clear" v-popover>Popover</button>
</div>
<div class="drawer">
<div class="drawer-content">
<div class="item" v-for="option in options">{{ option }}</div>
</div>
</div>
<div class="scroll-content has-header">
<div class="page-content">
<p>Some Content</p>
</div>
</div>
</div>
</div>

How to move scrollbar in a jquery-jscrollpane to textarea cursor position

I try to implement in jsfiddle. When textarea expand scrollbar not move to textarea cursor.
JavaScript:
function addJScrollPaneTo($container) {
// use jScrollPane jquery plugin
$container.jScrollPane({
verticalGutter: 1,
stickToBottom: true,
enableKeyboardNavigation : false,
autoReinitialise: true
});
}
function appendTextareaTo($container) {
var $textarea = $("<textarea />");
// set textarea attribute
$textarea.css({'border': 'medium none'});
$textarea.width($container.width());
// use TextAreaExpander jquery plugin
$textarea.TextAreaExpander($container.height()-1);
$container.append($textarea);
}
// for padding with elem
function appendContainer(elem) {
var $container = $("<div />");
// set container attribute
$container.width($(elem).width());
$container.height($(elem).height());
$(elem).append($container);
appendTextareaTo($container);
addJScrollPaneTo($container);
}
function setCSS(elem) {
$(elem).css({
'border': 'thin solid #CCCCCC',
'padding': '1px'
});
}
setCSS("#test");
appendContainer("#test");
HTML:
<div id="test" style="width: 235px; height: 50px;"></div>
CSS:
.jspContainer
{
overflow: hidden;
position: relative;
}
.jspPane
{
position: absolute;
}
.jspVerticalBar
{
position: absolute;
top: 0;
right: 0;
width: 16px;
height: 100%;
background: red;
}
.jspHorizontalBar
{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 16px;
background: red;
}
.jspVerticalBar *,
.jspHorizontalBar *
{
margin: 0;
padding: 0;
}
.jspCap
{
display: none;
}
.jspHorizontalBar .jspCap
{
float: left;
}
.jspTrack
{
background: #dde;
position: relative;
}
.jspDrag
{
background: #bbd;
position: relative;
top: 0;
left: 0;
cursor: pointer;
}
.jspHorizontalBar .jspTrack,
.jspHorizontalBar .jspDrag
{
float: left;
height: 100%;
}
.jspArrow
{
background: #50506d;
text-indent: -20000px;
display: block;
cursor: pointer;
}
.jspArrow.jspDisabled
{
cursor: default;
background: #80808d;
}
.jspVerticalBar .jspArrow
{
height: 16px;
}
.jspHorizontalBar .jspArrow
{
width: 16px;
float: left;
height: 100%;
}
.jspVerticalBar .jspArrow:focus
{
outline: none;
}
.jspCorner
{
background: #eeeef4;
float: left;
height: 100%;
}
/* Yuk! CSS Hack for IE6 3 pixel bug :( */
* html .jspCorner
{
margin: 0 -3px 0 0;
}
.jspVerticalBar {
background: none;
border-radius: 5px 5px 5px 5px;
right: 0px;
width: 5px;
}
.jspScrollable .jspHorizontalBar {
background: none;
bottom: 0px;
height: 10px;
border-radius: 5px 5px 5px 5px;
}
.jspScrollable .jspTrack {
background: none repeat scroll 0 0 #D1D3D5;
border-radius: 5px 5px 5px 5px;
}
.jspScrollable .jspDrag {
background: none repeat scroll 0 0 #5E6063;
border-radius: 5px 5px 5px 5px;
}

Categories

Resources