Function to scroll and open an accordian - javascript

I am struggling to get my Javascript code to work.
I want it so that when someone clicks on the product review summary of my website that it will scroll to the reviews section and open the relevant tab.
I have managed to get the scroll part working but have been unable to get the accordian to open.
Here is a link to the site: https://mgdev.monstershop.co.uk/t-mech-5-in-1-52cc-petrol-garden-cutter-multi-tool
Here is the code i have so far.
<script>
function viewReviews(){
document.getElementById('customer-reviews').scrollIntoView({
behavior: 'smooth'});
document.getElementsByClassName('productAccordian').style.display='block';
}
</script>
<div class="reviews-actions">
<a class="action view" style="cursor: pointer;" onclick="viewReviews()">
This is the code that generates the accordian
<div>
<input id="ac-<?php echo $counter; ?>" name="accordion-1" type="radio" <?php if($counter == 1){echo 'checked';} ?>>
<label for="ac-<?php echo $counter; ?>" class="accordion <?php if($counter == 1){echo 'active';} ?>"><strong><?= /* #noEscape */ $label ?></strong><span class="fa fa-angle-down pull-right" style="color: #6E716E;padding: 10px;"></span></label>
<article class="productAccordian">
<?= /* #noEscape */ $html ?>
</article>
</div>
I notice that when i try to open the accordian by clicking on it normally that seems to work. Just not with my new function.
Any help on this would be appriciated.

getElementsByClassName returns array of elements. Hence, the assignment is not working. You can try getElementById to make it work or document.getElementsByClassName('productAccordian')[0].style.display='block'

Related

Displaying the content dynamically from the dynamic id of the button using jquery

Scenario:
I have a bit tricky case here:
Upon cicking the button inside the first div block (I have named it as DIV Block A for readability), I want to display the channels which is inside the second DIV Block
(I have named it as DIV Block B for readability).
The id of button from DIV Block A is:
id="sub_category_dc_button_<?=$category['category_id'];?>"
Upon clicking this button, the content inside the DIV Block B should be displayed.
Attempt 1:
For this, I have followed this approach:
$(".sub_dc_channels").on("click", function(){
$($(this).attr("data-target")).show();
});
Here is my DIV Block A:
<div class="sub_cat_buttons channel" id="dc_subcategory_button_tab">
<div class="sub_dc_channels" id="sub_dc_button">
<?php foreach ($output as $category) {
<button type="button" data-toggle="collapse"
id="sub_category_dc_button_<?=$category['category_id'];?>"
class="btn btn-primary sub_digitalchannel_button"
data-target="#Category_<?= $category['category_id'];?>">
<?= $category['category_title']?>
</button>
</div>
</div>
Here is my DIV Block B:
<?php foreach ($output as $category) {?>
<div class="channel" id="Category_<?= $category['category_id'];?>">
<div id="subchannel_list_tab">
<?php foreach ($output as $category) {?>
<?php foreach ($category['channels'] as $channels) { ?>
<img src="<?= $channels['channel_logo']; ?>"
alt="<?= $channels['channel_name']; ?>"
title="<?= $channels['channel_name']; ?>"
style="width: 100px; height: 60px;" />
<?php } ?>
<?php } ?>
</div>
</div>
<?php } ?>
Attempt 2:
I have also used this approach with the same DIV Blocks but it fails too.
$('div[id^="Category_"]').click(function() {
$(".channel").hide();
$("#subchannel_list_tab").show();
});
Issue Faced:
When I clicked the button from DIV Block A then it targets the contents inside the DIV Block B but the contents inside the DIV Block B are not shown.
What am I missing here? Or am I following the wrong approach?
Suggestions are highly appreciated.
your click is going to be triggered in the div and not in the button, it is likely that this is the problem.
Here's a dummy example of what I think you're up to.
$('.showDiv').click( function () {
let div = $(this).attr('data-target');
$(`#${div}`).show();
});
#divB {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="divA">
<button class="showDiv" data-target="divB">show div</button>
</div>
<div id="divB">
info divB
</div>
You want to show dynamic data as per id of button click.You missed a target button class in selector.your issue is solved.
$(document).on("click",".sub_dc_channels .sub_digitalchannel_button",function(){
alert();
$($(this).attr("data-target")).show();
});
for reference you can click here.

PHP read more read less - Magento 2

I made an read more read less script for my Magento 2 webshop. This is used on a category page where there are serval subcategorie blocks to choose, each subcategory has a description with.
The problem: if I click read more all the descriptions of the subcategories will expand in stead of only the description of the subcategory I clicked read moreI am starting to learn PHP and Magento 2 but I can't fix this, does someone know the solution?
<div class="product description product-item-description">
<div class="more">
<?php if ($_subCategory->getDescription()) {
$string = strip_tags($_subCategory->getDescription());
if (strlen($string) > 250) {
// truncate string
$stringCut = substr($string, 0, 250);
$string = substr($stringCut, 0, strrpos($stringCut, ' ')).'... Lees meer';
}
echo $string;
?>
</div>
<?php
}else {?>
<?php /* #escapeNotVerified */ echo $_attributeValue;
}
?>
</div>
<div class="less" style="display:none">
<?php echo $_subCategory->getDescription(); ?>
Lees minder
</div>
<script type="text/javascript">
console.log('test');
require(["jquery"],function($){
$('.readmore').on("click",function(){
$('.less').show();
$('.more').hide();
});
$('.readless').on("click",function(){
$('.less').hide();
$('.more').show();
});
});
</script>
</div>
This is because, when you type $('.less').hide(); this is grabbing every element with the attribute class='less'. This is the way I would overcome this:
Start by attaching a unique attribute to each <div class="more"> or <div class="less"> - in this case, we use the class attribute: (and move 'more' or 'less' to an id)
<div id="read-more-block" class="cat-<?php echo $_subCategory->getId(); ?>">
<!-- my "read more" content -->
<a class="link" href="#read-more-block">Read Less</a>
</div>
<div id="read-less-block" class="cat-<?php echo $_subCategory->getId(); ?>">
<!-- my "read less" content -->
<a class="link" href="#read-less-block">Read More</a>
</div>
We now have a read-more-block and a read-less-block for each subcategory. When we click the inside link a jQuery event should fire which will hide itself and display the other.
And then, in your jQuery:
$('#read-more-block .link').on('click', function() {
var $readLessBlock = $('#read-less-block.' + $(this).parent().attr('class'));
$readLessBlock.show(); //Show the read less block
$(this).parent().hide(); //Hide the read more block
});
..and vice versa for read less.

Wordpress: Turn off display of posts until filter button is clicked

(This is an extension of a series of questions I have asked previously as I'm going through the process of learning how to work with Wordpress)
I'm using a small javascript to turn on and off the display of posts on a page, depending on the posts respective category. The script enables a group of filter buttons at the top of the page to switch between displaying posts that belong to a certain category.
Now I would like to change the page's code so that upon loading the page for the first time (i.e. before any of the filter buttons have been clicked) there is no content/posts being displayed at all. Right now when accessing the page, all posts which belong to the parent category of the sub-categories (which the buttons allow to filter) are being displayed.
How do I have to change the site to do so?
An online version of the site can be visited here: http://udkdev.skopec.de/category/studierende/
Here's the site's code along with the javascript of the filter-button at the bottom:
<?php get_header(); ?>
</div>
<br>
<div class="wrapper-offset-fix wrapper-studierende">
<div class="projekte content">
<div class="button-group filters-button-group">
<button class="projekt-btn btn" id="category-stud-sose17">SoSe 2017</button>
<button class="projekt-btn btn" id="category-stud-wise1617">WiSe 2016/17</button>
<button class="projekt-btn btn" id="category-wise-201415">SoSe 2016 </button>
<button class="projekt-btn btn" id="category-sose-14">WiSe 2015/16</button>
<button class="projekt-btn btn" id="category-sose-14">SoSe 2015 </button>
<button class="projekt-btn btn" id="category-sose-14">WiSe 2014/15</button>
</div>
<?php if (have_posts()): ?>
<?php while(have_posts()): the_post(); ?>
<div <?php post_class(); ?>>
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail('full');
} ?>
<?php the_content(); ?>
</a>
<!--<div class="meta">Tags: <?php the_tags( '', ', ', '<br />' ); ?> </div>-->
</div>
<?php endwhile; ?>
<?php else : ?>
<h2>Couldn’t find any articles!</h2>
<?php endif; ?>
</div>
<script>
var $btns = $('.btn').click(function() {
if (this.id == 'all') {
$('.projekte > .post').fadeIn(300);
} else {
var $el = $('.' + this.id).fadeIn(300);
$('.projekte > .post').not($el).fadeOut(300);
}
$btns.removeClass('active');
$(this).addClass('active');
})
</script>
<?php get_footer(); ?>
You can begin this by first hiding all the posts. One way to do this would be add a CSS style
.projekte .post {display:none;}
Looking at your codes, rest should just work out by itself. I would however swap these lines so that the posts are removed before the new ones are added like this:
$('.projekte > .post').not($el).fadeOut(300);
var $el = $('.' + this.id).fadeIn(300);

Refresh to show new/random taxonomy

I have an area on my Wordpress theme where I am showing info about a random taxonomy. Basically, the taxonomy is "playwrights" and I am featuring a random one on the home page. Here is the HTML:
<div id="home-top-right">
<?php
$allpw = get_terms( 'playwrights', 'hide_empty=0' );
$randpw = $allpw[ array_rand( $allpw ) ];
$randpw = get_term($randpw->term_id, 'playwrights');
$pwlink = get_term_link($randpw->term_id, 'playwrights');
?>
<div class="title">
Playwright Spotlight
<li class="fa fa-refresh refresh"></li>
</div>
<div class="content" id="p-spotlight">
<?php if (get_field('image', 'playwrights_'.$randpw->term_id)) { ?>
<div class="thumb">
<?php $imageid = get_field('image', 'playwrights_'.$randpw->term_id); ?>
<a href="<?php echo $pwlink; ?>">
<?php echo wp_get_attachment_image($imageid, 'pwthumb'); ?>
</a>
</div>
<?php } ?>
<div class="text">
<div class="sub-title">
<?php echo $randpw->name; ?>
</div>
<?php echo print_excerpt('', '200'); ?>
</div>
</div>
</div>
I want to be able to click a button (in the code, it is the <i> tag) and reload just that section (not the whole page) with a new random taxonomy term (playwright). I'm not great at JS/jquery and I'm not able to find a tutorial online that gets me where I need to go, especially considering the exchange between post data and the js function.
How should I go about this?
By default, WordPress has an admin-ajax.php file which you can send AJAX calls to. You can create a hook that is linked to your own custom function in which you can do the stuff you want, like getting the random term and send it back to the client.
Then you can pass a value to your AJAX call, called 'action'. When admin-ajax.php is getting a POST request with the action you 'hooked', your custom function is being executed.
Have a look at the links below for a more detailed explanation:
http://premium.wpmudev.org/blog/how-to-use-ajax-with-php-on-your-wp-site-without-a-plugin/
http://codex.wordpress.org/AJAX_in_Plugins

Need help making jQuery loop for basic .fadeIn()/.fadeOut() slider

I'm new to jQuery and am having trouble figuring out the right way to loop a set of code for a basic carousel/banner rotator. I've tried a few versions of "for" statements and .each(), but I can't get it to work on my own so I'm reaching out for help.
Here's my code so far:
$('.next-1').click(function () {
$('.featured-1').fadeOut(500,function(){
$('.featured-2').fadeIn(500,function(){
$('.featured-2').toggleClass("hide");
});
});
});
$('.next-2').click(function () {
$('.featured-2').fadeOut(500,function(){
$('.featured-3').fadeIn(500,function(){
$('.featured-3').toggleClass("hide");
});
});
});
And then a similar code block for going back within the slider:
$('.prev-2').click(function () {
$('.featured-2').fadeOut(500,function(){
$('.featured-1').fadeIn(500,function(){
$('.featured-2').toggleClass("hide");
});
});
});
$('.prev-3').click(function () {
$('.featured-3').fadeOut(500,function(){
$('.featured-2').fadeIn(500,function(){
$('.featured-3').toggleClass("hide");
});
});
});
This code does work right now, I just don't want to have to output so many unnecessary lines of code when I know I could loop it. I'd like to be able to loop until there are no more "featured-n" divs to cycle through (being able to cycle around to the beginning would be great too!)
Here's the PHP/HTML I'm using to generate each "featured-n" div block:
function home_slider_loop() {
$count = 0;
query_posts ('tag=slider');
if (have_posts()) : while (have_posts()) : the_post();
$count++;
?>
<div class="featured-post featured-<?php echo $count; if ($count>1) { echo ' hide';}?>">
<div class="featured-header">
<h1 class="featured-title"><?php the_title(); ?></h1>
<p class="author">Written by Evan Luzi</p>
</div>
<div class="image-wrap">
<?php the_post_thumbnail('full', array('class' => 'slider-image')); ?>
<div class="slider-nav">
<div class="featured-prev prev-<?php echo $count; ?>"></div>
<div class="featured-next next-<?php echo $count; ?>"></div>
</div><!--End Navigation-->
</div><!--End Image <?php echo $count; ?>-->
<div class="featured-footer">
<?php the_excerpt(); ?>
<a class="more-link" href="<?php the_permalink(); ?>" alt="<?php the_title(); ?>" >Read more</a>
</div>
</div><!--End Featured <?php echo $count; ?>-->
<?php
endwhile;
endif;
}
Here's a sample of one of the static HTML outputs (just imagine this iterated several times with the "featured-n" classes incrementing:
<div class="featured-1">
<div class="featured-header">
<h1 class="featured-title">5 Useful Cinematography Apps for iOS You Should Download Today</h1>
<p class="author">Written by Evan Luzi</p>
</div>
<div class="image-wrap">
<img width="1018" height="416" src="http://www.tbabdev.com/wp-content/uploads/2013/07/cinematography-apps-8-hero.jpg" class="slider-image wp-post-image" alt="cinematography-apps-8-hero" />
<div class="slider-nav">
<div class="featured-prev prev-1"></div>
<div class="featured-next next-1"></div>
</div><!--End Navigation-->
</div><!--End Image 1-->
<div class="featured-footer">
<p>The devices we have in our pockets, the ones that can run these apps, these are the new leathermans. They have everything we need. They eliminate the need to carry paper manuals and enable us to do complex timelapse calculations in a fraction of the time as a paper and pen.</p>
<a class="more-link" href="http://www.tbabdev.com/?p=27" alt="5 Useful Cinematography Apps for iOS You Should Download Today" >Read more</a>
</div>
</div><!--End Featured 1-->
You can see the code in action at http://www.tbabdev.com/
Thank you in advance for your help and please be kind to a n00b :)
Use something like this :
$('.nav .prev').click(function(){
activeBlock = $('.featured.active');
prevBlock = activeBlock.prev('.featured');
activeBlock.fadeOut('slow',function(){
prevBlock.fadeIn().addClass('active');
}).removeClass('active');
});
$('.nav .next').click(function(){
activeBlock = $('.featured.active');
nextBlock = activeBlock.next('.featured');
activeBlock.fadeOut('slow',function(){
nextBlock.fadeIn().addClass('active');
}).removeClass('active');
});
Html
<div class="nav">
<div class="prev"> </div>
<div class="next"> </div>
</div>
<div class="featured-post featured <?php if($count>1) echo 'hide' ?>">
<div class="featured-header">
<h1 class="featured-title"><?php the_title(); ?></h1>
<p class="author">Written by Evan Luzi</p>
</div>
<div class="image-wrap">
<?php the_post_thumbnail('full', array('class' => 'slider-image')); ?>
</div>
<!--End Image <?php echo $count; ?>-->
<div class="featured-footer">
<?php the_excerpt(); ?>
<a class="more-link" href="<?php the_permalink(); ?>" alt="<?php the_title(); ?>" >Read more</a>
</div>
</div>
You could do it this way :
$('.featured-next, .featured-prev').click(function () {
//find out if the clicked element is a prev or next element, extract the last part, will be useful later
var direction = $(this).hasClass("featured-next") ? "next" : "prev";
//select the ".featured-n" block which is the super-parent of clicked element
var $fullBlock = $(this).closest('div[class^="featured-"]'); //or add a class here to make your life easier
//fade out full block
$fullBlock.fadeOut(500, function () {
//search for the next element and show it
//note that $fullBlock.next() => $fullBlock["next"]() => $fullBlock[direction]()
$fullBlock[direction]().fadeIn(500, function () {
//toggle the class "hide" of the element next to fullBlock
$(this).toggleClass("hide");
});
});
});
Explanation:
You can join up both prev and next events together.
Then, you have to check if its a next or a prev element. Set that to a variable called direction. We'll be using this to find out if we have to use prev() or next() when we're trying to fadeIn featured-n divs.
Find the parent with the class set to featured-n (in your case its the superparent). It might be better if you give a common class to all these elements so that we can stop using 'div[class^="featured-"]' selector, which is slightly inefficient.
Fade out the superparent.
In the callback, based on the direction variable, we'll have to decide if the carousel is gonna go to prev block or next block, something like this :
if(direction === "prev")
{
$fullBlock.prev().fadeIn(//your code)
}
else
{
$fullBlock.next().fadeIn(//your code)
}
You must also know that, in an object like this :
var data = {"name" : "Blah Blah"}
To get the "Blah Blah" out, we can say
data.name
or we could say :
data["name"]
So based on this, in our situation, instead of
$fullBlock.prev()
Or we could say
$fullBlock["prev"]()
Which is what direction variable contains. So finally, we could do this to select the next/prev element based on what was clicked :
$fullBlockdirection
Show the prev/next element.
Add/remove "hide" class.
Hope this helped!

Categories