Making a php javascript slideshow in wordpress - javascript

I am making my first steps learning to code. I made some courses on Internet and now I'm continue learning from the experience while I build a Wordpress child theme.
The thing is that I'm making an image slideshow. I found this great and simple one in w3schools: http://www.w3schools.com/w3css/tryit.asp?filename=tryw3css_slideshow_self.
It's really fine but there are some problems if I want to use it in Wordpress.
I have a post type template with some fields that I build using the Advanced custom fields app. For the moment I have 10 images fields to make the slideshow.
So it means that this:
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css">
<body>
<h2 class="w3-center">Manual Slideshow</h2>
<div class="w3-content" style="max-width:800px;position:relative">
<img class="mySlides" src="img_fjords.jpg" style="width:100%">
<img class="mySlides" src="img_lights.jpg" style="width:100%">
<img class="mySlides" src="img_mountains.jpg" style="width:100%">
<img class="mySlides" src="img_forest.jpg" style="width:100%">
<a class="w3-btn-floating" style="position:absolute;top:45%;left:0" onclick="plusDivs(-1)">❮</a>
<a class="w3-btn-floating" style="position:absolute;top:45%;right:0" onclick="plusDivs(1)">❯</a>
</div>
<script>
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex-1].style.display = "block";
}
</script>
</body>
</html>
Becomes this in Wordpress:
<?php get_header(); ?>
<script>
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex-1].style.display = "block";
}
</script>
<div class="mySlides"><?php the_field("image"); ?></div>
<div class="mySlides"><?php the_field("image_2"); ?></div>
<div class="mySlides"><?php the_field("image_3"); ?></div>
<div class="mySlides"><?php the_field("image_4"); ?></div>
<div class="mySlides"><?php the_field("image_5"); ?></div>
<div class="mySlides"><?php the_field("image_6"); ?></div>
<div class="mySlides"><?php the_field("image_7"); ?></div>
<div class="mySlides"><?php the_field("image_8"); ?></div>
<div class="mySlides"><?php the_field("image_9"); ?></div>
<div class="mySlides"><?php the_field("image_10"); ?></div>
<a class="home-btn-left" onclick="plusDivs(-1)">❮</a>
<a class="home-btn-right" onclick="plusDivs(1)">❯</a>
</div><!-- .content-area -->
<a class="homelink" href="http://localhost/wordpress/">Sarah Morris</a>
<?php get_footer(); ?>
Now the problem is that I have to upload 10 images in all my posts. If one day I upload only 8 images for example, I will see the 8 images but I will also see two blank spaces because of the other image fields that I'm not using.
After some days trying to find a solution, I found that I have two options to do it:
1) Using the repeater field of the Advanced custom fields plugin.
2) Using this code:
<?php if(get_field("image") != ""): ?>
<div class="mySlides"><?php the_field("image"); ?></div>
<?php endif; ?>
The repeater field is a premium feature. I don't want to pay for a plugin, I prefer to learn how to make by my self so I decided to use the second option.
Now the problem is that the second option doesn't work correctly. It doesn't make what I want: To make an Slideshow without blank spaces when I'm using less than 10 images.
I know that this code is really near from the objective that I want to achieve. Do you have some suggestion?

You can hide empty fields, here's the link
So your php code should probably look something like this:
<?php if( get_field("image") ): ?>
<div class="mySlides"><?php the_field("image"); ?></div>
<?php endif; ?>
Complete Tutorial - default WP Twenty Sixteen theme used
Here's the suggestion of how to make this work - tested and working 100%
Navigate to "Custom Fields"
In the "Field Groups" create a new one and name it "slider" for example
Click "+ Add Field" button and you should setup your field like this
Repeat this for as many images you want to appear in the slider
in the "locations settings" setup the condition where you want your slider to appear, here's the example - this one appears on all pages and posts
Hit "Publish" button and your slider is ready
Page Template code
I suggest you to create a custom page template for this, although it's not necessary
<?php
/**
* Template Name: Example Template
*
*
* #package WordPress
* #subpackage Twenty_Sixteen
* #since Twenty Sixteen 1.0
*/
get_header();
// get ACF values
$image = get_field('image');
$image2 = get_field('image_2');
$image3 = get_field('image_3');
?>
<div id="primary" class="content-area" style="position:relative;">
<main id="main" class="site-main" role="main">
<?php // 1st image
if( !empty($image) ): ?>
<div class="mySlides"><img style="width:100%;" src="<?php echo $image['url']; ?>" alt="<?php echo $image['alt']; ?>" /></div>
<?php endif; ?>
<?php // 2nd image
if( !empty($image2) ): ?>
<div class="mySlides"><img style="width:100%" src="<?php echo $image2['url']; ?>" alt="<?php echo $image2['alt']; ?>" /></div>
<?php endif; ?>
<?php // 3rd image
if( !empty($image3) ): ?>
<div class="mySlides"><img style="width:100%" src="<?php echo $image3['url']; ?>" alt="<?php echo $image3['alt']; ?>" /></div>
<?php endif; ?>
<a class="w3-btn-floating" style="position:absolute;top:45%;left:0" onclick="plusDivs(-1)">❮</a>
<a class="w3-btn-floating" style="position:absolute;top:45%;right:0" onclick="plusDivs(1)">❯</a>
</main><!-- .site-main -->
<script>
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex-1].style.display = "block";
}
</script>
<?php get_sidebar( 'content-bottom' ); ?>
Or Another simpler solution:
using php empty
if( !empty(get_field('image')) ): ?>
<div class="mySlides"><?php the_field("image"); ?></div>
<?php endif; ?>
if( !empty(get_field('image_2')) ): ?>
<div class="mySlides"><?php the_field("image_2"); ?></div>
<?php endif; ?>
if( !empty(get_field('image_3')) ): ?>
<div class="mySlides"><?php the_field("image_3"); ?></div>
<?php endif; ?>
Try like this first - with your existing code

Related

Dynamically sort posts by tags into a Wordpress loop

I got a a custom loop into my Wordpress custom blog page, and Im displaying all my posts into it, like that :
<section class="container blog-article-actu">
<div class="row">
<?php
$the_query = new WP_Query('showposts=-1');
while ($the_query->have_posts()) :
$the_query->the_post();
$catObj = get_the_category();
?>
<article class="blog-article-actu-article" style="background:url('<?php $url = wp_get_attachment_url( get_post_thumbnail_id($post->ID), 'thumbnail' ); ?><?php echo $url ?>');">
<div class="blog-article-actu-article-top">
<h2><?php the_title(); ?></h2>
<div class="details-blog-article-actu">
<div class="blog-article-actu-date">
<span class="day"><?php the_time( 'd' ) ?></span><br>
<span class="month"><?php the_time( 'F' ) ?></span>
</div>
<a href="#" target="_blank"><p>
<?php
if (($catObj[0]->name == 'Actualités et évènements') OR ($catObj[1]->name == 'Actualités et évènements')) {
echo "<img src=\"XXX/actu-icon.png\" alt=\"Actualités et évènements\">";
} elseif (($catObj[0]->name == 'Témoignages') OR ($catObj[1]->name == 'Témoignages')) {
echo "<img src=\"XXX/chat-icon.png\" alt=\"Témoignages\">";
} elseif (($catObj[0]->name == 'Vidéos') OR ($catObj[1]->name == 'Vidéos')) {
echo "<img src=\"XXX/video-icon.png\" alt=\"Vidéos\">";
} else {
echo "";
}
?>
</p></a>
</div>
</div>
<div class="blog-article-actu-article-bottom-wrap">
<span class="blog-article-actu-article-excerpt"><?php the_excerpt();?></span>
<span class="blog-article-actu-article-bottom">En savoir <span>+</span></span>
<div class="social-blog-article-actu">
<i class="fa fa-twitter" aria-hidden="true"></i>
<i class="fa fa-facebook" aria-hidden="true"></i>
</div>
</div>
</article>
<?php // End of the loop.
endwhile;
?>
</div>
</section>
Then I was asked to build something to sort them, by tags, dynamically, with a tag system like this one : https://codepen.io/Chaaampy/pen/gWOrvp
But Im a bit lost about that ... I thought about get the tags for each posts in my loop, and then add them as a CSS class, like that maybe I could show or hide some articles in JS ... Meh, I don't know, has someone got any ideas for me ?
Thanks ! :)
If anyone is interested, found a solution by building something like that : https://codepen.io/Chaaampy/pen/gWOrvp
$(function filter() {
var selectedClass = "";
$(".link").click(function(){
selectedClass = $(this).attr("data-rel");
$(".wrap").fadeTo(100, 0.1);
$(".wrap section").not("."+selectedClass).fadeOut().removeClass('scale_anm');
setTimeout(function() {
$("."+selectedClass).fadeIn().addClass('scale_anm');
$(".wrap").fadeTo(300, 1);
}, 300);
});
});
Note that I get the tags into Wordpress with get_the_tags, and then I add them as a class to the elements I want to show / hide

dynamic slider double content displaying

Im trying to make a W3 slider dynamic the original slider is from this-link
i want to make it in a way that it only displys all the bottom images and only current image at the top see this-link for better understanding.
with my code everythings is displayed double.
This is my code for the slider:
<section id="slider">
<div class="container wow fadeInUp">
<div class="row">
<div class="col-md-12">
<h3 class="section-title">Photo Gallery</h3>
<div class="section-title-divider"></div>
<div class="w3-content" style="max-width:1200px">
<?php
include("admin/db/db.php");
$select_db = "select * from gallery";
$run_events = mysql_query($select_db);
while($row=mysql_fetch_array($run_events)){
$id = $row['id'];
$image= $row['image'];
?>
<img class="mySlides" src="admin/images/gallery/<?php echo $image; ?>" style="width:100%;height:350px;">
<div class="w3-row-padding w3-section">
<div class="w3-col s4">
<img class="demo w3-opacity w3-hover-opacity-off" src="admin/images/gallery/<?php echo $image; ?>" style="width:100%" onclick="currentDiv(<?php echo $id; ?>)">
</div>
<?php }?>
</div>
</div>
<script>
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function currentDiv(n) {
showDivs(slideIndex = n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" w3-opacity-off", "");
}
x[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " w3-opacity-off";
}
</script>
</div>
</div>
</div>
</section>
You need to replace your code with this and see:
<section id="slider">
<div class="container wow fadeInUp">
<div class="row">
<div class="col-md-12">
<h3 class="section-title">Photo Gallery</h3>
<div class="section-title-divider"></div>
<div class="w3-content" style="max-width:1200px">
<?php
include("admin/db/db.php");
$select_db = "select * from gallery";
$run_events = mysql_query($select_db);
while($row=mysql_fetch_array($run_events)){
$id = $row['id'];
$image= $row['image'];
?>
<img class="mySlides" src="admin/images/gallery/<?php echo $image; ?>" style="width:100%;height:350px;">
<div class="w3-row-padding w3-section">
<div class="w3-col s4">
<img class="demo w3-opacity w3-hover-opacity-off" src="admin/images/gallery/<?php echo $image; ?>" style="width:100%" onclick="currentDiv(<?php echo $id; ?>)">
</div>
</div>
<?php }?>
</div>
<script>
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function currentDiv(n) {
showDivs(slideIndex = n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" w3-opacity-off", "");
}
x[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " w3-opacity-off";
}
</script>
</div>
</div>
</div>
</section>

Javascript from PHP (wordpress)

I created a new WordPress theme. When I moved it into an IIS webserver it fails.
Here's my code:
<?php get_header(); ?>
<h2><?php the_title();?></h2>
<div class="infoBox" id="infoTxt">
<?php
if(get_the_title() == 'Home'){
$page = get_page_by_title( get_the_title());
$Pagecontent = apply_filters('the_content', $page->post_content);
$ContentArray = explode(";",$Pagecontent);
echo $ContentArray[count($ContentArray) -1];
<script type="text/javascript">
var info = <?php echo json_encode($ContentArray) ?>;
document.getElementById('infoTxt').innerHTML = info[1];
setInterval(function()
{
var i = Math.round((Math.random()) * info.length);
if (i == info.length) --i;
document.getElementById('infoTxt').innerHTML = info[i];
}, 5 * 1000);
</script>
<?php
}
else{
$page = get_page_by_title( get_the_title());
$content = apply_filters('the_content', $page->post_content);
$InfoboxStr = substr($content, 0, strpos($content, '#:'));
echo $InfoboxStr;
}
?>
</div><!--End InfoTxt-->
<div id="Flagbox">
<ul style="list-style-type:none;">
<li><img class="flagContainer" alt="English" src="<?php bloginfo('stylesheet_directory'); ?>/img/GbFlag.png""/></li>
<li><img class="flagContainer" alt="Deutsch" src="<?php bloginfo('stylesheet_directory'); ?>/img/GmFlag.png""/></li>
<li><img class="flagContainer" alt="French" src="<?php bloginfo('stylesheet_directory'); ?>/img/FrFlag.png""/></li>
</ul>
</div> <!-- end Flag Box-->
<div style="margin-bottom:25%;">
</div>
<?php get_footer(); ?>
It is because of the JavaScript but I have some problem fixing this, I have first of all tried to echo the JavaScript, but I then got a problem with the first line of the script which is: var info = <?php echo json_encode($ContentArray) ?>;
When I ex. tried to
Echo 'var info = ' + echo json_encode($ContentArray) ?> + ";"
I just gets an http 500-error. Do any of you have an idea of what I can try to fix my problem
If you want to use the <Script> tag, you need to close the php tag, in here:
echo $ContentArray[count($ContentArray) -1];
<script type="text/javascript">
So it should look like that:
?>
<script>
[..]
</script>
<?php
The best practice it that you should place the JS either in at the top or bottom of your file or in another file.
The Problem is that you did not close the PHP Tags before entering the <Script> Block... In other words; you were still in PHP Mode when you wrote your Javascript as if you were writing it on a normal HTML Document. Sure you can output Javascript via PHP but then, you may have to build that up.
Here you go with something that might assist:::
<?php get_header(); ?>
<h2><?php the_title();?></h2>
<div class="infoBox" id="infoTxt">
<?php
if(get_the_title() == 'Home'){
$page = get_page_by_title( get_the_title());
$Pagecontent = apply_filters('the_content', $page->post_content);
$ContentArray = explode(";",$Pagecontent);
echo $ContentArray[count($ContentArray) -1];
?>
<script type="text/javascript">
var info = <?php echo json_encode($ContentArray) ?>;
document.getElementById('infoTxt').innerHTML = info[1];
setInterval(function() {
var i = Math.round((Math.random()) * info.length);
if (i == info.length){ --i; }
document.getElementById('infoTxt').innerHTML = info[i];
}, 5 * 1000);
</script>
<?php
}else{
$page = get_page_by_title( get_the_title());
$content = apply_filters('the_content', $page->post_content);
$InfoboxStr = substr($content, 0, strpos($content, '#:'));
echo $InfoboxStr;
}
?>
</div><!--End InfoTxt-->
<div id="Flagbox">
<ul style="list-style-type:none;">
<li><img class="flagContainer" alt="English" src="<?php bloginfo('stylesheet_directory'); ?>/img/GbFlag.png""/></li>
<li><img class="flagContainer" alt="Deutsch" src="<?php bloginfo('stylesheet_directory'); ?>/img/GmFlag.png""/></li>
<li><img class="flagContainer" alt="French" src="<?php bloginfo('stylesheet_directory'); ?>/img/FrFlag.png""/></li>
</ul>
</div> <!-- end Flag Box-->
<div style="margin-bottom:25%;">
</div>
<?php get_footer(); ?>

Open Google Maps InfoWindow on link click outside of map

This is javascript I use to make all markers and set click listener
var infowindow = new google.maps.InfoWindow();
var markernovi, i;
for (i = 0; i < lokacije.length; i++) {
var ll = lokacije[i][2];
var latlng = ll.split(',');
markernovi = new google.maps.Marker({
position: new google.maps.LatLng(parseFloat(latlng[0]), parseFloat(latlng[1])),
map: mapObject,
icon: 'img/pins/' + key + '.png',
});
google.maps.event.addListener(markernovi, 'click', (function (markernovi, i) {
return function () {
infowindow.setContent(lokacije[i][0]);
infowindow.open(mapObject, markernovi);
}
})(markernovi, i));
markers.push(markernovi);
}
}
google.maps.event.addDomListener(window, 'load' , initialize);
function myClick(id){
google.maps.event.trigger(markers[id], 'click');
}
And I have this to list all locations on page :
<?php
foreach($lokacijebuy1 as $sve) {
?>
<div class="col-lg-6 col-md-12 col-sm-6">
<div class="img_wrapper">
<div class="img_container">
<a href="#" onclick="myClick(0);" >
<img src="http://evidentiraj.me/gkcard/slikemjesta/<?php echo $sve['photo']; ?>" width="800" height="533" class="img-responsive" alt="">
<div class="short_info">
<h3><?php echo $sve['ime2']; ?></h3>
<em><?php echo $sve['adresa']; ?></em>
<p>
<?php echo $sve['opis2']; ?>
</p>
</div>
</a>
</div>
</div><!-- End img_wrapper -->
</div><!-- End col-md-6 -->
<?php }
?>
And no matter which one I click only infowindow I open is the first one in array.
You can see page live here : http://evidentiraj.me/gorskikotarcard/locationsbuy.php
And I found that the only thing I need to change to display other marker is number inside myClick
<a href="#" onclick="myClick(1);" >
ANSWER:
only thing I did was to add counter in my <a href tag
Now it looks like this:
<?php
$counter = 0;
foreach($lokacijebuy1 as $sve) {
?>
<div class="col-lg-6 col-md-12 col-sm-6">
<div class="img_wrapper">
<div class="img_container">
<a href="#" onclick="myClick(<?php echo $counter; ?>);" >
<img src="http://evidentiraj.me/gkcard/slikemjesta/<?php echo $sve['photo']; ?>" width="800" height="533" class="img-responsive" alt="">
<div class="short_info">
<h3><?php echo $sve['ime2']; ?></h3>
<em><?php echo $sve['adresa']; ?></em>
<p>
<?php echo $sve['opis2']; ?>
</p>
</div>
</a>
</div>
</div><!-- End img_wrapper -->
</div><!-- End col-md-6 -->
<?php
$counter++;
}
?>
It's because you render the a element with function myClick with input argument set to 0, and you use this argument as an index in the markers array inside your function, which is still the first marker in the array. You need to change the way you render the a element to get results like this:

jQuery not working the same

I am having a problem with my website.
The padding-top of div class="row slide-content" is acting weird.
For some slides it is about 223px and for other slides it uses a different padding.
PHP
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="home-slider">
<ul class="slides">
<?php while ($slide =& $loop->next()): ?>
<li>
<div class="row slide-content">
<div class="large-10 large-centered columns text-center">
<?php if ( ! empty( $slide->button ) ) : ?>
<div class="SLIDERLOGO">
<?php echo $slide->button; ?>
</div><?php endif; ?><?php if ( ! empty( $slide->ititle ) || ! empty( $slide->caption ) ) : ?>
<div class="hero-title">
<div class="large-3 columns nopad border-bottom">
</div>
<div class="large-6 columns text-center">
<?php if ( ! empty( $slide->ititle ) ) : ?>
<h4 class="text-white alt-h">
<?php echo $slide->ititle; ?></h4><?php endif; ?>
</div><?php if ( empty( $slide->ititle ) ) : ?>
<div class="large-6 columns nopad border-bottom">
</div><?php endif; ?>
<div class="large-3 columns nopad border-bottom">
</div>
<h1 class="text-white">
<?php echo $slide->caption; ?></h1>
</div><!--end of hero title-->
<?php endif; ?>
</div>
</div><img alt="<?php echo esc_attr( $slide->alt ); ?>" class=
"slider-bg" src=
"%3C?php%20echo%20esc_attr(%20$slide-%3Eimg%20);%20?%3E">
</li><?php endwhile; ?>
</ul>
</div><!--end of Home slider-->
</body>
</html>
The logo is inserted here
<?php echo $slide->button; ?>
Both logo's are exactly the same dimensions
JS
// Append HTML 's as CSS Background for slides
// also center the content of the slide
jQuery('.home-slider .slides li').each(function () {
var imgSrc = jQuery(this).children('.slider-bg').attr('src');
jQuery(this).css('background', 'url("' + imgSrc + '")');
jQuery(this).children('.slider-bg').remove();
var slideHeight = jQuery(this).height();
var contentHeight = jQuery(this).children('.slide-content').height();
var padTop = (slideHeight / 2) - (contentHeight / 2);
jQuery(this).children('.slide-content').css('padding-top', padTop);
});
It wont happen every time but sometimes the padding between the logo and the top of the page changes. I hope i have explained wel enough :)
Many thanks!
Daan
try running your code on $(window).load(function() { }); instead of at the bottom of the page, chances are if you are working with larger slide images that not all of them are fully loaded before your calculations are applying.
The new code would look like this...
jQuery(window.load(function() {
jQuery('.home-slider .slides li').each(function () {
var imgSrc = jQuery(this).children('.slider-bg').attr('src');
jQuery(this).css('background', 'url("' + imgSrc + '")');
jQuery(this).children('.slider-bg').remove();
var slideHeight = jQuery(this).height();
var contentHeight = jQuery(this).children('.slide-content').height();
var padTop = (slideHeight / 2) - (contentHeight / 2);
jQuery(this).children('.slide-content').css('padding-top', padTop);
});
});

Categories