Simplify my javascript click add/toggle/remove class - javascript

I am working on a section on my website where I need to toggle, add, and remove a class.
I have something that works really good but I was wondering if there is a simple solution to make my code better, organized, and much more readable than how it is now.
I have 4 buttons:
.info-button-left-1
.info-button-left-2
.info-button-right-1
.info-button-right-2
These buttons trigger a class to ad to the following divs:
.product-information-block-left-1
.product-information-block-left-2
.product-information-block-right-1
.product-information-block-right-2
And this is my code:
<?php
// Create id attribute allowing for custom "anchor" value.
$id = 'info-product-block-' . $block['id'];
if( !empty($block['anchor']) ) {
$id = $block['anchor'];
}
// Create class attribute allowing for custom "className" and "align" values.
$className = 'info-product-block';
if( !empty($block['className']) ) {
$className .= ' ' . $block['className'];
}
if( !empty($block['align']) ) {
$className .= ' align' . $block['align'];
}
?>
<section id="<?php echo esc_attr($id); ?>" class="<?php echo esc_attr($className); ?> container-fluid">
<div class="row">
<div class="container">
<div class="row product-heading">
<div class="col">
<h2><?php echo the_field('product_heading'); ?></h2>
<?php echo the_field('product_content'); ?>
</div>
</div>
<div class="row product-information">
<div class="col-left-product">
<div class="left">
<div class="product-name"><?php echo the_field('product_name_left'); ?></div>
<div class="product-year"><?php echo the_field('product_year_left'); ?></div>
<div class="product-button">
<?php
$link = get_field('product_link_left');
if( $link ):
$link_url = $link['url'];
$link_title = $link['title'];
$link_target = $link['target'] ? $link['target'] : '_self';
?>
<a class="buy-button" href="<?php echo esc_url( $link_url ); ?>" target="<?php echo esc_attr( $link_target ); ?>"><?php echo esc_html( $link_title ); ?></a>
<?php endif; ?>
</div>
</div>
<div class="right">
<div class="product-image">
<div class="info-button-left-1"></div>
<div class="info-button-left-2"></div>
<?php
$image = get_field('product_image_left');
if( !empty( $image ) ): ?>
<img src="<?php echo esc_url($image['url']); ?>" alt="<?php echo esc_attr($image['alt']); ?>" />
<?php endif; ?>
</div>
<div class="product-information-block-left-1">
<?php echo the_field('product_content_left'); ?>
</div>
<div class="product-information-block-left-2">
<?php echo the_field('product_content_left'); ?>
</div>
</div>
</div>
<div class="col-right-product">
<div class="right">
<div class="product-image">
<div class="info-button-right-1"></div>
<div class="info-button-right-2"></div>
<?php
$image_right = get_field('product_image_right');
if( !empty( $image_right ) ): ?>
<img src="<?php echo esc_url($image_right['url']); ?>" alt="<?php echo esc_attr($image_right['alt']); ?>" />
<?php endif; ?>
</div>
<div class="product-information-block-right-1">
<?php echo the_field('product_content_left'); ?>
</div>
<div class="product-information-block-right-2">
<?php echo the_field('product_content_left'); ?>
</div>
</div>
<div class="left">
<div class="product-name"><?php echo the_field('product_name_right'); ?></div>
<div class="product-year"><?php echo the_field('product_year_right'); ?></div>
<div class="product-button">
<?php
$link_right = get_field('product_link_right');
if( $link_right ):
$link_right_url = $link_right['url'];
$link_right_title = $link_right['title'];
$link_right_target = $link_right['target'] ? $link_right['target'] : '_self';
?>
<a class="buy-button" href="<?php echo esc_url( $link_right_url ); ?>" target="<?php echo esc_attr( $link_right_target ); ?>"><?php echo esc_html( $link_right_title ); ?></a>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$(".col-left-product .info-button-left-1").click(function() {
$(".product-information-block-left-1").toggleClass("active");
$(".product-information-block-left-2").removeClass("active");
$(".product-information-block-right-1").removeClass("active");
$(".product-information-block-right-2").removeClass("active");
});
$(".col-left-product .info-button-left-2").click(function() {
$(".product-information-block-left-2").toggleClass("active");
$(".product-information-block-left-1").removeClass("active");
$(".product-information-block-right-1").removeClass("active");
$(".product-information-block-right-2").removeClass("active");
});
$(".col-right-product .info-button-right-1").click(function() {
$(".product-information-block-right-1").toggleClass("active");
$(".product-information-block-right-2").removeClass("active");
$(".product-information-block-left-1").removeClass("active");
$(".product-information-block-left-2").removeClass("active");
});
$(".col-right-product .info-button-right-2").click(function() {
$(".product-information-block-right-2").toggleClass("active");
$(".product-information-block-right-1").removeClass("active");
$(".product-information-block-left-1").removeClass("active");
$(".product-information-block-left-2").removeClass("active");
});
</script>
</section>
I am learning more and more every day. but I do think that there is a better way to do this.
Is there anyone who can give me an answer or a path to follow?
Thank you in advance.

To make the JS more generic you can use common class names on the elements. Then you can relate them to each other by using DOM traversal methods, such as closest() and find() to target the required element by matching indexes. Something like this:
let $productInfoBlocks = $('.product-information-block');
$('.info-button').on('click', e => {
let $el = $(e.target);
let $targetInfoBlock = $el.closest('.col').find('.product-information-block').eq($el.index()).toggleClass('active');
$productInfoBlocks.not($targetInfoBlock).removeClass('active');
});
.active { color: #C00; }
<!-- Note: I reduced the HTML to the relevant elements only -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row product-information">
<div class="col col-left-product">
<div class="right">
<div class="product-image">
<div class="info-button">info-button-left-1</div>
<div class="info-button">info-button-left-2</div>
</div>
<div class="product-information-block">product-information-block-left-1</div>
<div class="product-information-block">product-information-block-left-2</div>
</div>
</div>
<div class="col col-right-product">
<div class="right">
<div class="product-image">
<div class="info-button">info-button-right-1</div>
<div class="info-button">info-button-right-2</div>
</div>
<div class="product-information-block">product-information-block-right-1</div>
<div class="product-information-block">product-information-block-right-2</div>
</div>
</div>
</div>

In similar case I used data attribute in combination with a general class name:
The general syntax for buttons:
<div class="info-button" data-place="left" data-targetId="1"></div>
The general code for target divs:
<div class="product-information-block" data-place="right" data-targetId="1">
<?php echo the_field('product_content_left'); ?>
</div>
The general code to handle all occurances:
$(".col-right-product .info-button").click(function() {
var place=$(this).data("place");
var targetId=$(this).data("targetId");
$(".product-information-block").removeClass("active");
$(".product-information-block[data-place='"+ place +"'][data-targetId='"+ targetId +"']").addClass("active");
});

Related

My accordion toggle signs '+', '-' not changing i thin removeClass('current-bod') not working

This is my html code i am using ACF-
When i clicking others panel then it works but when i click same panel (open and close) then toggle sign only show '-' its not convert into '+' sign.
<section class="section-padding" id="currentOpening" style="background-color:#f2f2f2;">
<div class="container">
<div class="row">
<?php
if( have_rows('current_openings') ): ?>
<div class="current-opening">
<h2 class="section-heading">Current Openings</h2>
<div class="accordion-carrier">
<?php
while( have_rows('current_openings') ): the_row();
$profile = get_sub_field('opening_profile');
?>
<div class="openingTab"><a class="openingsToggle" href="javascript:void(0);"><?php the_sub_field('opening_profile'); ?> </a>
<?php
if( have_rows('openings') ): ?>
<div class="inner-carrier">
<?php
while( have_rows('openings') ): the_row();?>
<?php /*<h5><?php the_sub_field('opening_title'); ?></h5> */?>
<div class="inner-carrierrr">
<?php the_sub_field('opening_jd'); ?> Apply Now
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
</div>
<?php endwhile; ?>
</div>
</div>
<?php endif; ?>
</div>
</div>
</section>
and this js code-
<script>
jQuery('.openingsToggle').click(function(e) {
e.preventDefault();
jQuery('div.openingTab > a.openingsToggle.current-bod').removeClass('current-bod');
jQuery(this).addClass('current-bod');
var $this = jQuery(this);
if ($this.next().hasClass('show')) {
$this.next().removeClass('show');
$this.next().slideUp(350);
} else {
$this.parent().parent().find('.openingTab .inner-carrier').removeClass('show');
$this.parent().parent().find('.openingTab .inner-carrier').slideUp(350);
$this.next().toggleClass('show');
$this.next().slideToggle(350);
}
});
</script>

How to add wrapAll jquery or php after tags with the same id

php
<?php foreach ($forlop as $value) : ?>
<?php
$stringTitle = substr($value->getTitle(), 0, 1);
?>
<?php if(is_numeric($stringTitle)){
echo "<h3 id='other'>0-9</h3>";
} else{
echo "<h3 id=".strtolower($stringTitle).">".strtoupper($stringTitle)."</h3>";
}?>
<div class="item"><?php echo $value->getId(); ?></div>
<?php endforeach; ?>
<h3 id="c">C</h3>
<div class="item">1</div>
<div class="item">2</div>
<h3 id="d">D</h3>
<div class="item">3</div>
<div class="item">4</div>
<h3 id="e">E</h3>
<div class="item">5</div>
js
$('[id]').each(function (i) {
$('[id="' + this.id + '"]').slice(1).remove();
});
desired result
<h3 id="c">C</h3>
<div class="items-add">
<div class="item">1</div>
<div class="item">2</div>
</div>
<h3 id="d">D</h3>
<div class="items-add">
<div class="item">3</div>
<div class="item">4</div>
</div>
<h3 id="e">E</h3>
<div class="items-add">
<div class="item">5</div>
</div>
I want products with the same initials to be grouped together, I don't have an effective solution.
I want to add a wrapper tag to the tags that have a class item in the loop using jquery is there any way I can do this . or have any other treatment let me know about your ideas. Thanks.
You can solve it in php like this:
<?php $oldTitle = ""; ?>
<?php foreach ($forlop as $value) : ?>
<?php
$stringTitle = substr($value->getTitle(), 0, 1);
?>
<?php if($oldTitle !== $stringTitle && $oldTitle !== ""){
echo "</div>"; // close items add tag
?>
<?php if(is_numeric($stringTitle)){
echo "<h3 id='other'>0-9</h3>";
} else{
echo "<h3 id=".strtolower($stringTitle).">".strtoupper($stringTitle)."</h3>";
}?>
<?php if($oldTitle !== $stringTitle){
echo "<div class='items-add'>";
$oldTitle = $stringTitle;
?>
<div class="item"><?php echo $value->getId(); ?></div>
<?php endforeach; ?>

Is there a way to get all fetched ids from a PHP while loop?

I want to know if I can get all fetched ids from a PHP while loop to use them in a jQuery for a flip effect?
while ($fetch_locomotion = mysqli_fetch_assoc($result_locomotion))
{
$id = $fetch_locomotion['id'];
echo
'<a href="index.php?price='.$hash.'" style="text-decoration: none;" id="object_a_jquery">
<div id="'.$id.'" style="perspective:1000px;height:100%;width:13%;display:inline-table;">
<div class="front">
<div id="object_list_price_bg" style="background-image:url(images/bg_price_f.png);"></div>
</div>
<div class="back">
<div id="object_list_price_bg_b" style="background-image:url(images/bg_price.png);"></div>
</div>
</div>
</a>';
}
<script>$(<?php echo $id;?>).flip();</script>
You can dump them into an array and use them at a later time.
// do this before entering the loop so it isn't overwritten
$ids = [];
// Do this part inside of the while loop
$ids[] = $fetch_locomotion ['id'];
?>
/* do this part in the html section you wish to execute the javascript code */
<script>
jQuery(function ($) {
<?php foreach ($ids as $id): ?>
<?php echo "$('#". $id . "').flip();\n"; ?>
<?php endforeach; ?>
});
</script>
Edited for your exact code:
$ids = [];
while ($fetch_locomotion = mysqli_fetch_assoc($result_locomotion))
{
$ids[] = $fetch_locomotion['id'];
echo
'<a href="index.php?price='.$hash.'" style="text-decoration: none;" id="object_a_jquery">
<div id="'. $fetch_locomotion ['id'] .'" style="perspective:1000px;height:100%;width:13%;display:inline-table;">
<div class="front">
<div id="object_list_price_bg" style="background-image:url(images/bg_price_f.png);"></div>
</div>
<div class="back">
<div id="object_list_price_bg_b" style="background-image:url(images/bg_price.png);"></div>
</div>
</div>
</a>';
}
<script>
jQuery(function ($) {
<?php foreach ($ids as $id): ?>
<?php echo "$('#". $id . "').flip();\n"; ?>
<?php endforeach; ?>
});
</script>
I would suggest adding a class attribute and querying on it (instead of each ID separately).
Also, using the alternative PHP syntax would be cleaner in this context.
This becomes:
<?php while ($fetch_locomotion = mysqli_fetch_assoc($result_locomotion)): ?>
<a href="index.php?price=<?= $hash ?>" style="text-decoration: none;" id="object_a_jquery_<?= $id ?>">
<div id="<?= $fetch_locomotion['id'] ?>" class="js-flipMe" style="perspective:1000px;height:100%;width:13%;display:inline-table;">
<div class="front">
<div id="object_list_price_bg" style="background-image:url(images/bg_price_f.png);"></div>
</div>
<div class="back">
<div id="object_list_price_bg_b" style="background-image:url(images/bg_price.png);"></div>
</div>
</div>
</a>
<?php endwhile ?>
<script>
jQuery(function ($) {
$('.js-flipMe').flip();
});
</script>
Note that I also changed your <a>'s id attribute to be unique, as it should be.

Window on load function is not firing until i refresh page manually?

I'm showing a loading bar before the content loads successfully. And after load I am displaying the content by jQuery but when i visit the page first time the loader is showing forever and the on load event isn't firing. It fires when i manually refresh the page. What's wrong with my code?
Event call code:
$(window).on('load', function(){
$("#slider-pre-loader").fadeOut("slow");
$("#video-blog-slider").fadeIn();
});
Dynamic HTML:
<div id="slider-pre-loader"></div>
<div id="video-blog-slider" style="display: none">
<div class="blog-category-items blog-page" id="blogIndex">
<div class="container">
<?php
$hpos = 0;
foreach ($categories as $category):
$categoryhref = fakeUrl::genSlugFromText($category['name']);
$listVideos = $category['videos'];
if (in_array($category['name'], $categoryDisplay)) :
?>
<div class="blog-groups">
<div class="group-heading">
<h3>
Test title
</h3>
</div>
<?php if ($category['desc'] != '') :?>
<p class="group-desc"><?php echo $category['desc'];?></p>
<?php endif;?>
<?php
$slideClass = '';
if (!$detect->isMobile() && !$detect->isTablet() ) {
$slideClass = 'blog-slider';
}
?>
<div class="<?php echo $slideClass;?> owl-lg-dot mb-none owl-theme owl-loaded" id="videoList">
<?php
$v = 0;
foreach ($listVideos as $video) :
$v++;
$itemClass = '';
if (($detect->isMobile() || $detect->isTablet()) && $v > 5) {
$itemClass = 'item-disable';
}
$videoSlug = fakeUrl::genSlugFromText($video['title']);
?>
<div class="blog-item <?php echo $itemClass;?>">
<div class="blog-image">
<a href="/blog/<?php echo $videoSlug; ?>" title="<?php echo $video['title'];?>">
</a>
</div>
<div class="caption">
<a class="blog-list-video-title" href="/blog/<?php echo $videoSlug; ?>" title="<?php echo $video['title'];?>">
</a>
</div>
<div class="blog-metas">
<small class="blog-views"><?php echo number_format($video['views']); ?> views</small>
</div>
</div>
<?php
endforeach;
?>
</div>
</div>
<?php
endif;
endforeach;
?>
</div>
</div>
</div>
jQuery placed before event call:
<script src="//code.jquery.com/jquery-1.11.3.min.js" async></script>
Don't place async attribute on your script tags unless you really need your script file to be loaded asynchronously. Right now, your 'jQuery' code is being loaded asynchronously, i.e. jQuery is most probably not loaded when you are trying to attach your event.
The only explanation for it working the second time upon manual refresh is that the browser is 'synchronously' loading the cached resource. Different browsers do this differently, so you can expect inconsistent behaviour there.
Just remove the async attribute, and you should see your event firing every time.
The $(window) selector is for selecting the viewport whereas the $(document) selector is for the entire document (that is, what's inside the <html> tag).
Try using the following:
$(document).on('load', function(){
$("#slider-pre-loader").fadeOut("slow");
$("#video-blog-slider").fadeIn();
});
I hope this working with you, I have created example you will be woking with document.ready it means JQuery see and focus on all elements in your web page, here is fiddle
Simple for test
<div id="slider-pre-loader">no</div>
<div id="video-blog-slider" style="display: none">
hi
</div>
OR your code
<div id="slider-pre-loader">no</div>
<div id="video-blog-slider" style="display: none">
<div class="blog-category-items blog-page" id="blogIndex">
<div class="container">
<?php
$hpos = 0;
foreach ($categories as $category):
$categoryhref = fakeUrl::genSlugFromText($category['name']);
$listVideos = $category['videos'];
if (in_array($category['name'], $categoryDisplay)) :
?>
<div class="blog-groups">
<div class="group-heading">
<h3>
Test title
</h3>
</div>
<?php if ($category['desc'] != '') :?>
<p class="group-desc"><?php echo $category['desc'];?></p>
<?php endif;?>
<?php
$slideClass = '';
if (!$detect->isMobile() && !$detect->isTablet() ) {
$slideClass = 'blog-slider';
}
?>
<div class="<?php echo $slideClass;?> owl-lg-dot mb-none owl-theme owl-loaded" id="videoList">
<?php
$v = 0;
foreach ($listVideos as $video) :
$v++;
$itemClass = '';
if (($detect->isMobile() || $detect->isTablet()) && $v > 5) {
$itemClass = 'item-disable';
}
$videoSlug = fakeUrl::genSlugFromText($video['title']);
?>
<div class="blog-item <?php echo $itemClass;?>">
<div class="blog-image">
<a href="/blog/<?php echo $videoSlug; ?>" title="<?php echo $video['title'];?>">
</a>
</div>
<div class="caption">
<a class="blog-list-video-title" href="/blog/<?php echo $videoSlug; ?>" title="<?php echo $video['title'];?>">
</a>
</div>
<div class="blog-metas">
<small class="blog-views"><?php echo number_format($video['views']); ?> views</small>
</div>
</div>
<?php
endforeach;
?>
</div>
</div>
<?php
endif;
endforeach;
?>
</div>
</div>
</div>
Javascript:
$(document).ready(function() {
$("#slider-pre-loader").fadeOut('slow');
$("#video-blog-slider").fadeIn('slow');
});

javascript for changing image based on php variable

<div style="margin-left:5%;width:5%;float:left;margin-right:10%;">
<img src="./1.png" id="imgstatus"/>
</div>
<div style="width:80%;float:left;">
<h3>Your transaction was <?php echo $message; ?> ! Your transaction reference number for any furthur communication is <?php echo $cust_ref_no; ?> .</h3>
</div>
</div>
I have this html. All I want is javascript which chnages the img src to <img src="./1.png" /> if $message='succes' and <img src="./2.png"/> when $message='failed'.
You could use the ternary operator to minimize code length.
<div style="margin-left:5%;width:5%;float:left;margin-right:10%;">
<img src="<?php echo ($message == 'success' ? 'success.jpg' : 'failed.jpg'); ?>" id="imgstatus"/>
</div>
<div style="width:80%;float:left;">
<h3>Your transaction was <?php echo $message; ?> ! Your transaction reference number for any furthur communication is <?php echo $cust_ref_no; ?> .</h3>
</div>
</div>
<div style="margin-left:5%;width:5%;float:left;margin-right:10%;">
<img src="<?php
if($message == 'success')
{
echo 'success.jpg';
}
else
{
echo 'failed.jpg';
}
?>" id="imgstatus"/>
</div>
<div style="width:80%;float:left;">
<h3>Your transaction was <?php echo $message; ?> ! Your transaction reference number for any furthur communication is <?php echo $cust_ref_no; ?> .</h3>
</div>
</div>

Categories