Reputation: 21
Modification from "https://www.w3schools.com/howto/howto_js_slideshow.asp":
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName('mySlides');
var dots = document.getElementsByClassName('dot');
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = 'none';
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(' active', '');
}
slides[slideIndex-1].style.display = 'block';
dots[slideIndex-1].className += ' active';
}
I am calling these functions from php as given below:
for($j=0; $j < 2; $j++) {
for($i=0; $i < 10; $i++) {
echo "<div>
<!-- Next and previous buttons -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>";
}
}
I want to modify above code to below code which is not working for me:
for($j=0; $j < 2; $j++) {
for($i=0; $i < 10; $i++) {
echo "<div>
<!-- Next and previous buttons -->
<a class="prev" onclick="plusSlides_".$i."(-1)">❮</a>
<a class="next" onclick="plusSlides_".$i."(1)">❯</a>
</div>";
}
}
I want 2 separate sliders with 10 images in each and separate controls for both the sliders.
how can i make the above code working? what should i modify?
I tried using the following to call a function:
window["plusSlides".concat("_",$i)](slideIndex);
and the following to define a function:
window["plusSlides".concat("_",$i)] = function(n) {}
and eval function, but these didnot work for me.
Upvotes: 2
Views: 49
Reputation: 2134
Rather than alter your back end code, why don't you just alter your front end code? It's much more simplistic in my opinion, and not to mention the fact that it's possibly easier all round.
Secondly, why don't you make some function to produce a slider rather than use a loop? I'm just thinking, surely that would be the easier option? An example:
Keep in mind, I'm not saying that you should use this specific PHP code, I was simply providing an example of what you could do to make your life easier in the long run. PS I've written this PHP code on the fly, so I have no idea if it works or not, it's more pseudo code than a formal solution.
This is just a simple update containing the data structure(s) that I had in mind for the image array(s). Please keep in mind that I've not tried or tested this code, this is more pseudo code than anything else, this is simply here to aid you towards solving your solution.
<?php
// This is just a POPO - Plain old php object.
// Aka a data/value object.
class Image {
public $src;
public $caption;
public $index;
function __construct ($src, $caption, $index) {
$this->src = $src;
$this->caption = $caption;
$this->index = $index;
}
}
// How you do this is up to you, but this is an EXAMPLE...
$imageArray1 = array(
new Image('../image.png', 'This is an awesome image', '1/10')
);
?>
Then this is the original code that I wrote in this answer...
<?php
function slideshow (images) {
ob_start();
<div class="slideshow-container">
<?php foreach ($images as $image) : ?>
<div class="mySlides fade">
<div class="numbertext"><?php echo $image->index ?></div>
<img src="<?php echo $image->src?>" style="width:100%">
<div class="text"><?php echo $image->caption ?></div>
</div>
<?php endforeach; ?>
<a class="prev">❮</a>
<a class="next">❯</a>
</div>
return ob_get_clean();
}
echo slideshow($imageArray1);
echo slideshow($imageArray2);
?>
Also, as a side note, looking at what you're trying to achieve and what you're currently implementing, your approach is totally off? Surely, it would make more sense to produce many elements with the class name slideshow-container
. Not only does this seem more logical from a mark down perspective, but it also means that your JavaScript can then do more with it. As an example, here's my idea with regards to how you'd code your JavaScript, rather than have many JavaScript functions created server side, just make it more generic and flexible, it's just easier?
With this solution, as you can see, rather than having many JavaScript functions, you just have the two, start
and slideshow
, it's nothing complex, simple & flexible. Plus if you want to add more slideshows at a later date, I think this approach would be easier to manage and maintain.
const slideshow = (el) => {
let slideIndex = 1;
const plusSlides = n => showSlides(slideIndex += n);
const currentSlide = n => showSlides(slideIndex = n);
function showSlides(n) {
const slides = el.querySelectorAll('.mySlides');
if (n > slides.length) slideIndex = 1;
else if (n < 1) slideIndex = slides.length;
for (let i = 0; i < slides.length; i++) slides[i].style.display = 'none';
slides[slideIndex - 1].style.display = 'block';
}
showSlides(slideIndex);
el.querySelectorAll(".prev").forEach(i => {
i.addEventListener('click', x => plusSlides(-1));
});
el.querySelectorAll(".next").forEach(i => {
i.addEventListener('click', x => plusSlides(1));
});
};
const start = () => {
document.querySelectorAll(".slideshow-container").forEach(el => slideshow(el));
};
setTimeout(start, 250); // A super lazy implementation of document ready...
/*
NO CHANGES HAVE BEEN MADE HERE...
*/
* {
box-sizing: border-box
}
body {
font-family: Verdana, sans-serif;
margin: 0
}
.mySlides {
display: none
}
img {
vertical-align: middle;
}
/* Slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -22px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
}
/* Caption text */
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* The dots/bullets/indicators */
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active,
.dot:hover {
background-color: #717171;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: 1.5s;
}
@-webkit-keyframes fade {
from {
opacity: .4
}
to {
opacity: 1
}
}
@keyframes fade {
from {
opacity: .4
}
to {
opacity: 1
}
}
/* On smaller screens, decrease text size */
@media only screen and (max-width: 300px) {
.prev,
.next,
.text {
font-size: 11px
}
}
<!-- First slideshow -->
<div class="slideshow-container">
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img src="https://www.w3schools.com/howto/img_nature_wide.jpg" style="width:100%">
<div class="text">Caption Text</div>
</div>
<div class="mySlides fade">
<div class="numbertext">2 / 3</div>
<img src="https://www.w3schools.com/howto/img_snow_wide.jpg" style="width:100%">
<div class="text">Caption Two</div>
</div>
<div class="mySlides fade">
<div class="numbertext">3 / 3</div>
<img src="https://www.w3schools.com/howto/img_mountains_wide.jpg" style="width:100%">
<div class="text">Caption Three</div>
</div>
<a class="prev">❮</a>
<a class="next">❯</a>
</div>
<br>
<!-- Just to show where the code splits. -->
<hr>
<!-- Second slideshow. -->
<div class="slideshow-container">
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img src="https://www.w3schools.com/howto/img_nature_wide.jpg" style="width:100%">
<div class="text">Caption Text</div>
</div>
<div class="mySlides fade">
<div class="numbertext">2 / 3</div>
<img src="https://www.w3schools.com/howto/img_snow_wide.jpg" style="width:100%">
<div class="text">Caption Two</div>
</div>
<div class="mySlides fade">
<div class="numbertext">3 / 3</div>
<img src="https://www.w3schools.com/howto/img_mountains_wide.jpg" style="width:100%">
<div class="text">Caption Three</div>
</div>
<a class="prev">❮</a>
<a class="next">❯</a>
</div>
<br>
Upvotes: 1