Toggle class upon change of data attribute - javascript

I'm working on a shopping cart and my client wants it to have one background when it's empty and another one when it has items. So here's what I got as a mark up:
<a href="#" id="shopping-cart" data-count="0" class="trigger cart">
<span>
</span>
</a>
The changes on the data-count are being handled on server side and updated via php my problem is that I have no idea how to make jquery read the data-count and make the if statement so it reads
if data-count= 0 then add .empty
else data-count > 0 then add .full
Also, I'm not sure if I should use .addClass or .toggleClass from empty to full, I'm sorry, so far all my attempts to write jquery have failed and the handler for all that is on vacation so I would appreciate all the help.
A decision was made to change the plugin being used and now I tried to replicate this on the new one and cant seem to wrap my head around it to achieve it the new code available looks something like this:
<?php global $woocommerce; ?>
<a class="cart-contents" href="<?php echo $woocommerce->cart->get_cart_url(); ?>"
title="<?php _e('View your shopping cart', 'woothemes'); ?>">
<?php echo sprintf(_n('%d item', '%d items', $woocommerce->cart->cart_contents_count, 'woothemes'), $woocommerce->cart->cart_contents_count);?> - <?php echo $woocommerce->cart->get_cart_total(); ?></a>

$('a.cart').data('count')
Gives the value of count.

why don't you do this ? :
$cart = sprintf(_n('%d', cart::$cart_contents_count, 'mini-cart'), cart::$cart_contents_count);
if($cart >= '1')
{
?>
<a href="#" id="shopping-cart" data-count="$cart" class="trigger cart">
<span>
</span>
</a> <?php
}
else
{ ?>
<a href="#" id="shopping-cart" data-count="0" class="trigger cart">
<span>
</span>
</a>
<?php
}
this way you do not need to use jQuery to hide elements that are not needed.

Related

JQuery won't set right value onclick of button

So what I'm trying to achieve is to set the value of a hidden input so that I can send that value to a PHP file where this value will be used to execute a delete query.
The only problem that I'm facing is that it will only select the data-id from the first element, which is not what I want.
Here is the JQuery code, if any other files are required for more info I'll post those aswell.
$('document').ready(function(){
// Makes menu visibility toggable
$('#hamburger_btn').on("click", function() {
$('#sidemenu').toggleClass("show");
})
// Closes menu via separate button
$('#close_btn').on("click", function() {
$('#sidemenu').removeClass("show");
})
// Opens dialogbox
$('.openDialog').on("click", function() {
$('#dialog').addClass("showBox");
$('#overlay').addClass("showOv");
// Sets the input value in dialog
$('#post_id').val($('.openDialog').data("id")); // Here lies the problem
})
// Closes dialogbox
$('#closeDialog').on("click", function() {
$('#dialog').removeClass("showBox");
$('#overlay').removeClass("showOv");
// Sets value to empty and remove attribute value
$('#post_id').val('').removeAttr("value");
})
});
If this question has already been answered elsewhere please let me know aswell, because I couldnt find it.
EDIT:
The HTML
<?php
// Get all posts from DB
$sql = "SELECT * FROM cm_posts";
$stmt = $conn->prepare($sql);
$stmt->execute();
$results = $stmt->get_result();
?>
<section class="s-reset s-posts-overview">
<div id="top"></div>
<div class="posts-overview-content-wrapper">
<h3 class="s-title">Overview</h3>
<div class="post-cards-container">
<?php // Display all posts in a card ?>
<?php while($row = $results->fetch_assoc()):?>
<div class="post-card">
<h4 class="card-title"><?php echo $row["post_title"];?></h4>
<h5 class="card-sub-title"><?php echo $row["post_date"];?></h5>
<div class="card-btn">
<button>View</button>
<button class="btn-small openDialog" id="openDialog" data-id="<?php echo $row["post_id"];?>">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
<?php endwhile ?>
</div>
<div class="scroll-btn">
<a href="#top" class="button">
<i class="fas fa-arrow-up"></i>
</a>
<a href="#bottom" class="button">
<i class="fas fa-arrow-down"></i>
</a>
</div>
</div>
<div id="bottom"></div>
</section>
<div class="overlay" id="overlay"></div>
<div class="dialog" id="dialog">
<div class="dialog-content-wrapper">
<h3>Are you sure you want to delete this item?</h3>
<form action="data/post_db_files/delete-post-db.php" method="post" id="del_post_item">
<input type="hidden" id="post_id" name="post_id">
<input type="submit" value="Delete" id="del_post" class="del_post">
</form>
<button id="closeDialog" class="close-btn">Cancel</button>
</div>
</div>
Picture of the browser with devtools
The image shows where the id is supposed to appear, now if i click the delete button on any of these elements, I always get the value of 1, but if I select "hello 2" which has a post_id of 2 I want that id to appear in the hidden input. I hope this clears somethings up.
You are trying to get the data-id of the clicked item, but you are using $('.openDialog') => This would get all elements wich class is openDialog.
Use this instead:
$('#post_id').val($(this).data("id"));
you can also create on onClick function on this button like this & pass value in that function
<button id="openDialog onClick=openDialogButtonClick("<php echo $row["post_id"];>")>
after this just create function in your Js file or tag
function openDialogButtonClick(id){
//in this id param you will get id then set this id to your hidden field
$("#post_id").val(id);
}

"javascript:void() just renders as "void()"

It use to work in the past and on other current websites but updating this site it no longer works. I had a pop up message with woocommerce notices, just saying the item has been added to cart, and with a close button using the javascript:void method. However it no longer works and when I look at the source code it's just out putting as "void(0)" instead of "javascript:void(0)"
I've tried other way such as just using # instead. Nothing works. Box won't close.
<div id="woocommerce-message">
<div class="close">
<a href="javascript:void(0)" class="closeEmbtn" onclick="closeEm()"
title="Close Notification"><i class="fa fa-times" aria-hidden="true"></i>
</a></div>
<div class="success-cart">
<div class="woocommerce-message">
<?php foreach ( $messages as $message ) : ?>
<?php echo wp_kses_post( $message ); ?>
<?php endforeach; ?>
</div>
</div>
<div class="message-cart-buttons">
<a class="button" href="/cart/">View Cart/Checkout</a>
Continue Shopping
</div>
</div>
<script type="text/javascript">
function closeEm() {
document.getElementById("woocommerce-message").style.display = "none";
}
</script>
I'm wanting just a way to close/hide the the "woocommerce-message" div when they click a close button.
--Edit --
I tried a different approach
<div class="close">
<a class="closeEmbtn" onclick="closeEm()" href="#" title="Close Notification"><i class="fa fa-times" aria-hidden="true"></i></a></div>
<script>
function closeEm() {
var x = document.getElementById("woocommerce-message");
x.style.display = "none";
}
</script>
But it's the "onclick=" isn't showing up in the source code either. Is there something in wordpress that could be blocking it?
I figured out a work around with a new script function
<script>
document.getElementById("close1").onclick = function() {
document.getElementById("woocommerce-message").style.display = "none";
}
</script>
which then doesn't have to rely on javscript:void(0) and onclick in the html.
But I am still curious to know why those elements suddenly disappeared from the output code

Getting variable passed from PHP to JS on Click event, returns all elements variable, not just the one that's clicked

I'm working on a WP code, but my problem in specific to JS. So I post my question here at StackOverflow.
Final goal is, clicking on the post image, showing the HTML markup of large img on Console. Here's my code:
<div class="img lightbox-trigger">
<?php the_post_thumbnail(); ?>
<div class="hover" >
<i class="fa fa-arrows-alt"></i>
</div><!--hover-->
</div><!-- .img .lightbox-trigger -->
<?php $large_thumb = get_the_post_thumbnail($post->ID, 'large') ?>
<script type="text/javascript">
jQuery(document).ready(function($){
$(".lightbox-trigger").click(function(){
var largeThumb = <?php echo json_encode( $large_thumb ); ?>;
console.log( largeThumb );
});
});
</script>
The problem is when I click on one of the post's images, the largeThumb value of all other posts (there are 10 posts) printed on Console!
I don't know how to use $(this) in this specific context to just get the value related to the element being clicked on.
Any help is appreciated.
You could use data-* attributes to store the $large_thumb of every lightbox-trigger in the related div :
<div class="img lightbox-trigger" data-large-thumb='<?php echo get_the_post_thumbnail($post->ID, 'large'); ?>'>
<?php the_post_thumbnail(); ?>
<div class="hover" >
<i class="fa fa-arrows-alt"></i>
</div><!--hover-->
</div><!-- .img .lightbox-trigger -->
Then in the js you could get this info :
jQuery(document).ready(function($){
$(".lightbox-trigger").click(function(){
console.log( $(this).data('large-thumb') );
console.log( $(this).html() );
});
});
Hope this helps.

Identity of the clicked id

i am using php codeigniter. I am sending data in an array to my view. In my view i have a foreach loop in place which iterates through the array and displays the data in my view. Also inside this foreach loop i am displaying some action buttons.
<?php
foreach($studentList as $r)
{
echo '<tr>';
echo $r->id;
echo '</tr>'?>
<a class="lock" data-id="<?= $r->id?>_lock" data-placement="top" data-original-title="Lock Profile" href="javascript:void(0)"><i class="clip-locked"></i></a>
<a class="hidden unlock" data-id="<?= $r->id?>_unlock" data-placement="top" data-original-title="Unlock Profile" href="javascript:void(0)"><i class="clip-unlocked"></i></a>
<?php
} ?>
What i want to do is to display the lock button by default, when someone clicks on this button lock should get hidden and unlock button should get displayed. in my jquery i am doing it like this but clicking on single button accounts for changing the buttons on the whole page.
I know the reason as i am accessing the element using class which all of them have common but i haven't yet figured out how to do that using id which will account for single elements.
$('.unlock').click(function() {
var id = $(this).attr("data-id");
console.log(id);
$('.unlock').addClass("hidden");
$('.lock').removeClass("hidden");
});
This slight modification should help you.
$('.unlock').click(function(){
var id = $(this).attr("data-id").split('_')[0];
console.log(id);
$(this).addClass("hidden");
$('[data-id='+id+'_unlock]').removeClass("hidden");
});
OK, so first off, you're putting the anchors outside of the <tr>'s. Is this intended?
If you have code like this:
<?php
foreach($studentList as $r)
{
echo '<tr>';
echo $r->id;?>
<a class="lock" data-id="<?= $r->id?>_lock" data-placement="top" data-original-title="Lock Profile" href="javascript:void(0)"><i class="clip-locked"></i></a>
<a class="hidden unlock" data-id="<?= $r->id?>_unlock" data-placement="top" data-original-title="Unlock Profile" href="javascript:void(0)"><i class="clip-unlocked"></i></a>
<?php
echo '</tr>';
} ?>
You can simply do:
$('.unlock').click(function(){
var id = $(this).attr("data-id");
console.log(id);
$(this).parent('tr').find('.unlock').addClass("hidden");
$(this).parent('tr').find('.lock').removeClass("hidden");
});
Also have a look here on information on how to fetch siblings, as an alternative way to locate the element you're looking for.
First of all, your html is semantically wrong, tr should contain th or td depending of what you want to do. Even when the browsers doesn't complaint for bad html doesn't mean it is correct. So, this is what a recommend:
Supposing we have this
<table id="myTable">
<tbody>
<?php foreach($studentList as $r) { ?>
<?php echo '<tr><td>'; ?>
<?php echo $r->id; ?>
<a class="lock" data-id="<?= $r->id?>_lock" data-placement="top" data-original-title="Lock Profile" href="javascript:void(0)"><i class="clip-locked"></i></a>
<a class="hidden unlock" data-id="<?= $r->id?>_unlock" data-placement="top" data-original-title="Unlock Profile" href="javascript:void(0)"><i class="clip-unlocked"></i></a>
<?php echo '</td></tr>'; ?>
<?php } ?>
</tbody>
</table>
Bind a single event to both anchors:
$("#myTable tr a").click(function(){
//save the element for future reference and avoid repeat $(this)
var elm = $(this),
id = elm.attr("data-id"),
elmtoShow = elm.hasClass('unlock') ? '.lock' : '.unlock';
console.log(id);
elm.addClass("hidden");
//we can pass a second param to jQuery to query into
//that single element instead the whole document
$(elmtoShow, this.parentNode).removeClass("hidden");
});
Please, note that I added an id to the table to make the query to all anchors, also read the comments in the code. Hope it helps

<li> not recognising php foreach loop (possibly including JS)

First I realise I'm talking about an external framework but please hear me out as I think it may be more of an html php issue (possibly JS). I am trying to incorporate this horizontal timeline into my web page as a school project:
https://codyhouse.co/gem/horizontal-timeline/
I am trying to print out results I got from an array. I am converting the datetime format to the same that is taken in.
Their method is as follows:
<ol>
<li>16 Jan</li>
<li>28 Feb</li>
<li>20 Mar</li>
<li>20 May</li>
............
</ol>
While mine looks like this:
<ol>
<?php foreach ($mile2[ "milestones"] as $key=>$value) { if ($key != 0) { ?>
<li>
<a href="#0" data-date="<?=date('d/m/Y',strtotime($mile2['milestones'][$key]['start_time']['date']));?>">
<?=d ate( 'd M', strtotime($mile2[ 'milestones'][$key][ 'start_time'][ 'date']));?>
</a>
</li>
<?php } else{ ?>
<li>
<a href="#0" data-date="<?=date('d/m/Y',strtotime($mile2['milestones'][$key]['start_time']['date']));?>" class="selected">
<?=d ate( 'd M', strtotime($mile2[ 'milestones'][$key][ 'start_time'][ 'date']));?>
</a>
</li>
<?php }} ?>
</ol>
The outputs are very different, this is a link to the demo https://codyhouse.co/demo/horizontal-timeline/index.html.
And this is how mine currently appears:
The first Problem I see in your code is that date is declared d ate even though im not shure if that is actually the problem. I suggest to var_dump() the contents of your array to rule out the possibility of sending in false data to your frontend.
Additionally you can make shure the javascript ist loaded after the DOM is done loading by using jQuery $(function()) as the javascript might trigger before your html is fully loaded.
Here some optimized code:
<ol>
<?php foreach ($mile2["milestones"] as $key => $value) : ?>
<?php if ($key != 0): ?>
<li>
<a href="#0"
data-date="<?= date('d/m/Y', strtotime($value['start_time']['date'])); ?>"
><?= date('d M', strtotime($value['start_time']['date'])); ?></a>
</li>
<?php else: ?>
<li>
<a href="#0"
data-date="<?= date('d/m/Y', strtotime($value['start_time']['date'])); ?>"
class="selected"
><?= date('d M', strtotime($value['start_time']['date'])); ?></a>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ol>

Categories

Resources