addClass when a number inside a span is greater than 0 - javascript

I want to add class "active" to "fav-contractors" container only when number inside "fav-con-count" span is greater than 0.
This is HTML code
<span class="fav-contractors">
<span class="fav-con-count">7</span>
</span>
and this is jQuery code
function favCounter() {
if ($(".fav-con-count").textContent > 0) {
$(".fav-contractors").addClass("active");
}
};
favCounter();
Which "if" rule should I use? I also tried something like that but it didn't work:
function favCounter() {
var favValue = $(".fav-con-count").textContent;
if (+favValue > 0)) {
$(".fav-contractors").addClass("active");
}
};
favCounter();

Node.textContent is JavaScript, not part of the jQuery library per-se. jQuery uses the .text() method to get the text by using textContent under the hood. Also, read about jQuery's toggleClass() method, you can use a second boolean parameter instead, making the if statement unnecessary.
Since you use classes it's pretty dangerous to just do $(".fav-contractors").addClass("active");, since you could:
have many .fav-contractors Elements in a single page and all will get the active class
$(".fav-con-count").text() > 0 means that only if the first of that class Element has text greater than 0 - which might also be incorrect and lead to a buggy undesired behavior.
Solution
Use .each() to iterate all your elements of a specific class
Use .closest() to traverse to a specific element ancestor (or self)
(As already mentioned) use toggleClass()
$(".fav-con-count").each(function() {
$(this).closest(".fav-contractors").toggleClass("active", $(this).text() > 0);
});
.fav-contractors { padding: 1rem; }
.active { background: gold; }
<span class="fav-contractors">
<span class="fav-con-count">7</span>
</span>
<span class="fav-contractors">
<span class="fav-con-count">0</span>
</span>
<span class="fav-contractors">
<span class="fav-con-count">3</span>
</span>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

You should use .text() instead of textContent
function favCounter() {
if ($(".fav-con-count").text() > 0) {
$(".fav-contractors").addClass("active");
}
};
favCounter();
.active {
background: yellow;
}
<span class="fav-contractors">
<span class="fav-con-count">7</span>
</span>
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
This is an example of the number 0 not adding the active class
function favCounter() {
if ($(".fav-con-count").text() > 0) {
$(".fav-contractors").addClass("active");
}
};
favCounter();
.active {
background: yellow;
}
<span class="fav-contractors">
<span class="fav-con-count">0</span>
</span>
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>

Related

Can I use variables or regex for selectors in CSS?

Hi,
I have this markup:
<div data-users="room2">
<span data-room="room1,room2,room3">john</span>
<span data-room="room1">george</span>
<span data-room="room2">jane</span>
</div>
I want only users that have the same room data as the div parent so I wrote this css:
span { display: none; }
[data-users="room2"] [data-room*="room2"] { display: block; }
fiddle: https://jsfiddle.net/ehpt9f5z/2/
However, since the data in the div parent can change to any room number I need a variable there so the CSS selector will always match the room data from the child with its parent, something like this:
[data-users=$1] [data-room*=$1] { display: block; }
Is it even possible with pure css?
Thank you.
This is not accomplishable with CSS alone, since there is no CSS parent selector.
A JavaScript solution would be to loop through each div which has the data-users attribute, then loop through each child of the div and show the ones whose data-room attribute contains the data-users attribute value.
const divs = document.querySelectorAll('div[data-users]')
divs.forEach(e => [...e.children].forEach(f => {
if(f.dataset.room.split(',').includes(e.dataset.users)){
f.style.display = "block"
}
}))
span { display: none; }
<div data-users="room2">
<span data-room="room1,room2,room3">john</span>
<span data-room="room1">george</span>
<span data-room="room2">jane</span>
</div>

How to loop through elements and their sub elements in order add or remove classes — Javascript/jQuery

I have a list of events – I want to only show the ones that are in the past. To do this I was thinking to loop though these elements, find the containing div with the date, and then compare this to todays current date.
A basic structure of these events is as follows:
<div class="past-event">
<span class="event-title">Event 1</span>
<span class="event-date">05.05.19</span>
</div>
<div class="past-event">
<span class="event-title">Event 2</span>
<span class="event-date">20.04.19</span>
</div>
I've used Moment.js to parse the dates. I've used jQuery for this so far (I usually try not to) but this is hosted on a Wordpress site anyway so jQuery is already available. I'm happy to hear any solution and not just a jQuery related one.
Here is a JSFiddle of a simplified version of my code. The way its laid out, the first two elements should be hidden and the second two should be blue (I have added a "blue" class to make it clearer when the code is not working)
https://jsfiddle.net/ngpvkscf/
There's a couple of issues here:
You're trying to create event_date as a moment object, yet you're passing the value of itself instead of event_date_raw
The resulting dates will be a moment object and a string. For the comparison to work you need to equalise the types. I'd suggest using plain Date objects, so you need to call .toDate() in moment and use new Date() to get the current date time.
You need to use find() to get the .event-date element within the current .past-event. Your current logic is only working with the first one.
With those issues fixed, it works:
$('.past-event').each(function(i, obj) {
var event_date_raw = $(this).find('.event-date').text();
var event_date = moment(event_date_raw, "DD.MM.YY").toDate();
var now = new Date();
if (now < event_date) {
$(this).addClass("hidden");
} else {
$(this).addClass("blue");
}
});
body {
display: flex;
width: 100%;
flex-wrap: ; /* fix this too */
margin: 0;
color: #EEE;
}
.past-event {
width: 50%;
display: flex;
flex-direction: column;
}
.blue {
background-color: blue;
}
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>
<div class="past-event">
<span class="event-title">Event 1</span>
<span class="event-date">05.05.19</span>
</div>
<div class="past-event">
<span class="event-title">Event 2</span>
<span class="event-date">20.04.19</span>
</div>
<div class="past-event">
<span class="event-title">Event 3</span>
<span class="event-date">01.02.19</span>
</div>
<div class="past-event">
<span class="event-title">Event 4</span>
<span class="event-date">05.05.18</span>
</div>
I believe the following is what you want:
https://jsfiddle.net/4dehv2pj/
jQuery('.past-event').each(function(i, obj) {
var event_date_raw = jQuery(this).children('.event-date').text();
var event_date = moment(event_date_raw, "DD/MM/YY");
var now = moment().format("DD/MM/YY");
console.log(event_date_raw);
if (now < event_date) {
jQuery(this).addClass("hidden");
} else {
jQuery(this).addClass("blue");
}
});
Comparing dates with moment.js is a little bit different than just a greater than/less than operator.
I'm using moment(event_date).isAfter(now)
This will get you the correct comparison.
Also by using jQuery('.event-date').text(); you're getting ALL of the elements that match .event-date, so instead I do something like jQuery(this).children('.event-date').text();, which takes the current element and checks the children of the current element for that query selector.
This is what you may need
$('.event-date').each((index, item) => {
var date = moment($(item).text(), 'DD.MM.YY').toDate();
if (date > new Date()) {
console.log(date)
$(item).closest('.past-event').css('display', 'none');
}
});

jquery check the attribute element value [duplicate]

This question already has answers here:
How do I check if an element is hidden in jQuery?
(65 answers)
Closed 6 years ago.
<li style="padding-bottom: 0px; display: none;">
<span> Content </span>
</li>
i want to check display == none
i got the solution with the below script.
if($(this).closest('li').attr('style') =='padding-bottom: 0px; display: none;'){
// script
}
any other simple way to write.
Thanks
The issue you have is that you're mixing jQuery and vanilla JS methods here, with .attr().display. You're also trying to compare the whole style string against (if it worked) one CSS rule.
A better method of achieving this would be to use jQuery's is() method, along with the :visible selector. Try this:
if ($(this).closest('li').is(':visible')) {
// script
}
If you want only to check if the element is hidden you can check if the display is set to none using css() method. Using .attr('style') it will return the whole style on the element.
if($(this).closest('li').css('display') == 'none' ){
}
Working demonstrative example (I've put the inline style just for demonstration, but I don't recommend you to use it):
$('li').each(function(i) {
if ($(this).css('display') == 'none') {
console.log(i); // logs the indexes of the hidden elements
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li style="padding-bottom: 0px; display: none;">
<span> Content </span>
</li>
<li style="padding-bottom: 0px; display: none;">
<span> Content </span>
</li>
<li style="padding-bottom: 0px;">
<span> Content </span>
</li>
You can use :visible or :hidden selectors directly:
if ( $('li:visible').length > 0 ) {
// it is visible
}
You can use :visible or :hidden selectors with is():
if ( $('li').is(':visible') ) {
// it is visible
}
Finally, you can check the specific value of 'display' with css():
if ( $('li').css('display') === 'none' ) {
// it is hidden
}

How to check a hide an element inside element on click using jquery(not duplicate)?

I have a div with an i tag:
<div class="accordion-heading datalist" data-toggle="collapse" data-parent="#accordion2" href="##i.Id">div
<i class="fa fa-chevron-down table-middle" aria-hidden="true">i tag</i>
</div>
On first click of the div the i tag should disappear, on next click of the div the i tag should appear again. How can I do that?
You can use toggle() to achieve that:
$('.accordion-heading').click(function() {
$(this).find('i').toggle();
});
Note that depending on your styling rules, it may be hard and/or impossible to click the div element with the i hidden as it will have no height. To fix that you can set a min-height rule on the div, or put a non-breaking space ( ) in it.
I want to switch between display: none and display: tablecell
In this case you have to manage the display value yourself, like this:
$('.accordion-heading').click(function() {
$(this).find('i').css('display', function(i, d) {
return d == 'none' ? 'tablecell' : 'none';
})
});
use jquery toggle().
check this
jsfiddle
Without jQuery:
var accordion = document.querySelector('.accordion-heading');
accordion.addEventListener('click', toggleTag);
function toggleTag() {
var tagToToggle = accordion.querySelector('i');
if (!tagToToggle.classList.contains('active')) {
tagToToggle.classList.add('active');
} else {
tagToToggle.classList.remove('active');
}
}
CSS:
i {
display: none;
}
i.active {
display:block;
}
You can also use toggleClass() method but u create a css class for jquery function. its most customizeable
.display-none{display:none;} or
.display-none{opacity:0;transition:1s solid ease;}
$('.accordion-heading').on('click',function() {
$(this).find('i').toggleClass('display-none');
});
Click-Here to view example -jsbin

Removing an element added by ::before pseudo selector

I have the following case: (styling is done in SASS and unnecessary stylings are omitted.)
.header {
...
&::before {
...
position: absolute;
height: 0.5rem;
...
}
}
This creates a bar on top of the application's menu bar. In certain cases this bar has to be removed. I have read questions like these, but with no success. What would be the best way to remove this bar added by the ::before selector?
Only CSS can remove pseudo element, so you need to have an other class that display:none; the before. First declare that class in the CSS :
.header {
...
&::before {
...
position: absolute;
height: 0.5rem;
...
}
&.no-before::before{
display:none;
}
}
Then, when you want to remove it :
$('.header').addClass('no-before'); //Remove before
$('.header').removeClass('no-before'); //Re-add before
The usual way is to create a more specific rule that applies to the element(s) in question (or a later rule with the same specificity), and specify display: none to hide the pseudo in that case.
For example: Here, I want to have an X in front of <span class="foo">, but not if they're in .header:
span.foo::before {
content: 'X ';
}
.header span.foo::before {
display: none;
}
<div>
These have the X:
<span class="foo">span.foo 1</span>
<span class="foo">span.foo 2</span>
<span class="foo">span.foo 3</span>
</div>
<div class="header">
These don't:
<span class="foo">span.foo 4</span>
<span class="foo">span.foo 5</span>
<span class="foo">span.foo 6</span>
</div>
If you are manipulating the DOM by using JavaScript, you can add a class name - for instance .remove-bar - to the element having .header in order to remove the pseudo-element (generated content):
.remove-bar {
&::before { content: none; }
}
Also make sure that it is placed after the previous styles, or use a more specific selector if needed.
For remove special element use this method.
<button onclick="myFunction()">Remove</button>
<div id="myList">
<div> Coffee </div>
<div id="child2" > Tea </div>
<div> Milk </div>
</div>
your JavaScript :
<script>
function myFunction() {
const list = document.getElementById("myList");
if (list.hasChildNodes()) {
list.removeChild(list.children[0]);
}
}
</script>
you can combine above function with this code:
const parent = document.getElementById('myList');
const children = parent.children;
let index = -1;
for (let i = 0; i < children.length; i++) {
if (children[i].id === 'child3') {
index = i;
break;
}
}
alert(index); // 👉️ 2

Categories