Edit text and href attribute of same element depending on different condition - javascript

I wrote the code below to satisfy different conditions but it seems very repetitive. Is there a way I can edit the #nav-link element's text and href attribute dynamically without having to write out $('#nav-link').text('___').attr("href", "/___"); 3 times to make the code simpler and more readable?
if(window.location.href.indexOf('colors') > -1) {
$('#nav-link').text('Colors').attr("href", "/colors");
} else if (window.location.href.indexOf('cars') > -1) {
$('#nav-link').text('Cars').attr("href", "/cars");
} else if (window.location.href.indexOf('people') > -1) {
$('#nav-link').text('People').attr("href", "/people");
}

How about this
["colors", "cars", "people"]
.forEach(x => window.location.href.indexOf(x) > -1 &&
$('#nav-link').text(x).attr("href", "/" + x))

Related

JavaScript toggle class on current element

Just want to understand a principle of JavaScript, I'm a bit new to this.
I'm adding some styling to some element which are slides which I'm scrolling through.
The "current" div have a transform: none applied, the two others get styled depending on where I am on the slider.
I'm using this code which is working fine.
el.style.transform = i === e.current ? 'none' : i > e.current ? 'translateX(100%)' : 'translateX(-100%)'
My question is how do I add / toggle a class to the current el, and remove it back when it's not the current anymore.
I've tried some couple options using the same principle but can't find the right way to achieve it.
el.classList = i === e.current.toggle('classname') : i > ? e.current.toggle('classname')
el.classList.toggle() = i === e.current ? 'active' : i > e.current ? 'prev' : 'next'
Can somebody give me a heads up on how to achieve what i want to do? I've tried to go through some others post on Stack Overflow and to look on element.classList docs everywhere i could find it, but I'm stuck at this point and JS knowledge is not my strong point.
Thanks!
toggle takes the class name e.g. el.classList.toggle('classname'). You don't pass a variable to a function like this el.classList.toggle() = 'classname'. But you might be better off calling add or remove depending on if the item is the current one since you also need to ensure the other classes aren't still there.
el.classList[i === e.current ? 'add' : 'remove']('active');
However since you also want prev and next probably best not to try and be too clever with ternaries and make it readable:
if (i > e.current) {
el.classList.remove('current', 'prev');
el.classList.add('next');
} else if (i < e.current) {
el.classList.remove('current', 'next');
el.classList.add('prev');
} else {
el.classList.remove('prev', 'next');
el.classList.add('current');
}
If you aren't worried about overwriting other classes you could simplify this using className as it overwrites any existing classes:
if (i > e.current) {
el.className = 'next';
} else if (i < e.current) {
el.className = 'prev';
} else {
el.className = 'current';
}

JS issue with dropdown menu and state selection

Here's the fiddle: https://jsfiddle.net/6aevjxkx/38/
In the dropdown menu, if you select Nebraska, you'll see a school location from Washington state, which shouldn't appear.
The issue I believe is that the script is searching the ENTIRE td section for any matching state initial. In the case of the school from Washington, it has "NE" in the address, causing it to appear when you choose Nebraska from the dropdown.
With that said, how can the script be updated so it can only search for a matching state within the div that has a class "state"? Or if there's another solution, my ears are wide open.
Thanks ahead!
Code of the script
$('select#stateCollege').change( function(e) {
var letter = $(this).val();
if (letter === 'ALL') {
$ ('table.event tr').css('display','inline-block');
} else {
$('table.event tr').each( function(rowIdx,tr) {
$(this).hide().find('td').each( function(idx, td) {
if( idx === 0 || idx === 1) {
var check = $(this).text();
if (check && check.indexOf(letter) > 0) {
$(this).parent().css('display','inline-block');
}
}
});
});
}
});
Something like the following works:
$('table.event tr').each(function(rowIdx, tr) {
var row = $(this).hide();
var state = row.find('.state').text().trim();
if (state === letter)
row.css('display', 'inline-block');
});
Updated demo: https://jsfiddle.net/6aevjxkx/42/
That is, hide the current row, then find the .text() of its .state element, .trim() that, then rather than .indexOf() just use === to compare to the value in the rather confusingly named letter variable.
Note that there was no point to using .each() on your td elements given that there is only one td in each row.

Wanting to toggle class, when value is greater than 0?

I'm trying to use "toggleClass" when the numeric value inside of the span.points is greater than "0". So it'll null, and then, if the value changes to 1, it'll add a class. Not sure how to accomplish this? Learning jQuery at snails pace... any help would be helpful. Thank you guys!
HTML
<div class="box">
<span class="points">4</span>
</div>
Failed JS Attempt
var points = $('.box > .points').length;
if(points > 0) {
$('.box').toggleClass('orange');
} else {
return false;
}
You should be using .text() or .html() and parse that to a number.
var points = parseFloat($('.box > .points').text());
if(points > 0) {
$('.box').toggleClass('orange');
} else {
return false;
}
Fiddle
Don't forget to either put that in a function or in an $(document).ready({ ... }) statement.

In jquery, how can I detect if a paragraph contains one link and only one link, nothing else

I want to apply a class 'solo' to a link in a paragraph where that link is the ONLY element in the paragraph.
So this would get the 'solo' class:
<p><a>I am alone</a></p>
But this would not:
<p><a>I am not alone</a> because there is more text!</p>
You could do:
$('p').filter(function() {
var $childNodes = $(this).contents();
return $childNodes
.not($childNodes.filter('a').first())
.not(function() {
return this.nodeType === 3 && $.trim(this.nodeValue) === '';
}).length === 0;
});
This gets all child nodes (including text nodes) and removes the first a element it finds and all text nodes only containing whitespaces from that set. If the resulting set is empty, the link was the only child (alone).
Reference: filter, not, contents, Node.nodeType, trim
Update: Maybe this could be done easier, but I wanted it to work also for the case your HTML contains line breaks, which would result in text nodes containing only whitespaces:
<p>
<a>I am alone</a>
</p>
<p>
<a>I am not alone</a> because there is more text!
</p>
DEMO
Try this
$('p').filter(function(){
var $childrens = $(this).children();
return ($childrens.length == 1
&& $childrens.is('a')
&& $(this).text() == $childrens.text());
}).addClass('solo');
Demo
There is 1 more way to do this:
if($("p").find('a').length === 1){
//perform operation
}
Not very performant, but this is the most concise and nice (and working) solution I came out with!
$('p').filter( function() {
return !$('<p>'+$.trim($(this).html())+'</p>').contents().not('a:first').length;
}).addClass('solo');
http://jsfiddle.net/DYxgu/

Check between a tag for empty with jQuery

I want check between a tag if empty was between it append a text, How is it?
Example: if empty was between tag <span></span> append phrase There is not between .exist.
This will put the text in the span element.
$("span:empty").text("There is not!")
To check if empty and put the text in different element use:
if ($("span:empty").length != 0) {
$('.empty').text("There is not!")
}
example 1
if ($('span:empty').length != 0) {
$('.exist').show().html($('<b/>').text('There is not').wrap($('<p/>')));
}
example 2
Assuming you have only one span tag
if ($("span").html() == ""){
$(".exist").append('There is not');
}

Categories