Multiple blinking text in table - javascript

This javascript I've found on the internet. With this in my table I can only get the first textbox blinking, the next time I want another textbox blinking it doesn't work. I'm a beginner, thanks for your support.
I've tried a second variable in the javascript, I've also copied the javascript with a different id. Still no luck...
In head I've placed:
<script language="javascript">
function blinktext() {
var f = document.getElementById('announcement');
setInterval(function() {
f.style.visibility = (f.style.visibility == 'hidden' ? '' : 'hidden');
}, 500);
}
</script>
In html I used:
<div id="announcement" class="rTableCell">
<span style="color: #99cc00;">groen</span></div>
I expect to have multiple boxes in my table to blink
My table is here: https://zappi.info/faq-howto/hub/42-led-referentie-tabel

Use querySelectorAll and classList.toggle
Also note we have added a CSS class to do our hiding of the element.
The toggle call will add if it is not present and remove is it is.
function blinktext() {
document.querySelectorAll('.announcement').forEach(e =>{
setInterval(() => {
console.log(e);
e.classList.toggle('hide');
}, 500);
});
}
// We use an event listener to only run our code once the HTML is
// loaded and ready to be read.
document.addEventListener('DOMContentLoaded', () => {
blinktext();
});
.hide {
visibility: hidden;
}
<div class="announcement rTableCell">
<span style="color: #99cc00;">groen</span></div>
<div class="announcement rTableCell">
<span style="color: #99cc00;">groen</span></div>
<div class="rTableCell">
<span style="color: #99cc00;">groen</span></div>
<div class="announcement rTableCell">
<span style="color: #99cc00;">groen</span></div>
<div class="rTableCell">
<span style="color: #99cc00;">groen</span></div>
<div class="announcement rTableCell">
<span style="color: #99cc00;">groen</span></div>
<div class="announcement rTableCell">
<span style="color: #99cc00;">groen</span></div>

I strongly suggest not to use setInterval() for this simple job and just stick to CSS animation like this:
The elements that need to blink should include this line in their style...
animation:Blink 2000ms linear 0s infinite none;
And then add this to your CSS section independently...
#keyframes Blink{from{background:white;} to{background:black;}}

for multiple its easiest to go with the class descriptor
<div id="announcement" class="rTableCell blinking">
<span style="color: #99cc00;">groen</span></div>
function blink(target){
return function(){
target.style.visibility = (target.style.visibility == 'hidden' ? '' : 'hidden');
}
}
let blinkers=document.getElementsByClassName('blinking');
for(let blinker of blinkers){
setInterval(blink(blinker), 500);
}
like this should work (you need the return function structure to have the correct reference in the method)

Related

Trying to Append search list to my search input

I am new to HTML ,JavaScript and jQuery. I am currently doing a search box, when I start to type text on the search input the search list must appear and able to click the search list name and append it to search input, and close the search list and left with search input and current text that I clicked on the search list.
var $block = $('.no-results');
$(".personsMenu").hide();
$(".my-textbox").keyup(function() {
var textbox = document.getElementById("textboxEmp");
var val = $(this).val();
var isMatch = false;
var nameAp = document.getElementsByClassName("name12");
$(".personsMenu").show();
if (textbox.value == 0) {
$(".personsMenu").hide();
}
$(".personsMenu div").each(function() {
var content = $(this).html();
if ((content.toLowerCase().indexOf(val) == -1) && (content.toUpperCase().indexOf(val) == -1)) {
$(this).hide();
} else {
isMatch = true;
$(this).show();
}
});
$block.toggle(!isMatch);
});
function mySelect() {
$(".name12").appendTo($(".my-textbox"));
$(".personsMenu").hide();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="cover">
<div name="selected">
<i class="mdi-account-search mdi"></i><input class="my-textbox" id="textboxEmp" autofocus="autofocus" placeholder="search staff member" />
</div>
<div class="personsMenu">
<ul class="infor">
<div class="nm1" name="selected">
<li class="name12" onclick="mySelect()">Malubane Nyikiwe</li>
<li>nyikiwe.malubane#m-t.co.za</li>
</div>
<div class="no-results">no employee found by that name</div>
<div class="nm1" name="selected">
<li class="name12" onclick="mySelect()">Chamano Sydney</li>
<li>sydney.chamano#m-t.co.za</li>
</div>
<div class="nm1" name="selected">
<li class="name12" onclick="mySelect()">Diphofa Tumelo</li>
<li>tumelo.diphofa#m-t.co.za</li>
</div>
</ul>
</div>
</div>
There's several issues in your code which all need to be addressed:
You're using invalid HTML. ul elements can only contain li, not div. I'd suggest restructuring the HTML to use div containers to hold the information for each item in your list.
Use CSS to hide content which should not be visible when the page loads. This avoids the FOUC which can happen as JS only runs after the DOM is ready.
If you've included jQuery in the page, you may as well use it consistently to make your code more succinct.
Use the input method, not keyup, for listening to user input. input will also fire when the user copies content in to the field using the mouse for example, keyup won't.
Use unobtrusive event handlers, eg. jQuery's on() method, not inline onclick attributes. The latter is outdates and bad practice at it doesn't allow for good separation of concerns.
When searching text, equalise the cases of the search and target strings, don't search for both upper and lower versions.
Use text() to search for the content, not html().
To set the value of an input element use val(), not append(). The latter is for adding HTML/text content to an element, not setting its value property.
With all that said, the working code will look something like this:
var $noResults = $('.no-results');
var $names = $(".name12");
var $personsMenu = $('.personsMenu');
var $searchBox = $(".my-textbox").on('input', function() {
var value = $(this).val().trim().toUpperCase();
if (!value) {
$personsMenu.hide();
return;
}
var matches = $personsMenu.show().find('div').each(function() {
var content = $(this).text().toUpperCase();
$(this).toggle(content.indexOf(value) !== -1);
});
$noResults.toggle(matches.filter(':visible').length == 0);
});
$('.item').on('click', function() {
$searchBox.val($(this).find('.name12').text());
$personsMenu.hide();
});
.personsMenu,
.no-results {
display: none;
}
.item {
padding: 10px;
cursor: pointer;
}
.item:hover {
background-color: #CCC;
}
.item p {
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="cover">
<div name="selected">
<i class="mdi-account-search mdi"></i>
<input class="my-textbox" id="textboxEmp" autofocus="autofocus" placeholder="search staff member" />
</div>
<div class="personsMenu">
<div class="no-results">no employee found by that name</div>
<div class="item">
<p class="name12">Malubane Nyikiwe</p>
<p class="email">nyikiwe.malubane#m-t.co.za</p>
</div>
<div class="item">
<p class="name12">Chamano Sydney</p>
<p class="email">sydney.chamano#m-t.co.za</p>
</div>
<div class="item">
<p class="name12">Diphofa Tumelo</p>
<p class="email">tumelo.diphofa#m-t.co.za</p>
</div>
</div>
</div>

Elegant way of avoiding writing so many (click hide show)

im looking for the elegant way to avoid writing so much code to perform onclick, show clicked, hide others.
here's the code im using:
html:
<p align="center" style="font-size: 22px;">
<span class="badge badge-secondary" id="yesterday">Yesterday</span>
<span class="badge badge-dark" id="today">Today</span>
<span class="badge badge-secondary" id="tomorrow">Tomorrow</span>
</p>
jquery:
$('#yesterday').click(function(e) {
e.preventDefault();
$(this).addClass('badge-dark').removeClass('badge-secondary');
$('#today,#tomorrow').addClass('badge-secondary').removeClass('badge-dark');
$('.yesterday').slideDown('slow');
$('.today,.tomorrow').slideUp('1000');
});
$('#today').click(function(e) {
e.preventDefault();
$(this).addClass('badge-dark').removeClass('badge-secondary');
$('#yesterday,#tomorrow').addClass('badge-secondary').removeClass('badge-dark');
$('.today').slideDown('slow');
$('.yesterday,.tomorrow').slideUp('1000');
});
$('#tomorrow').click(function(e) {
e.preventDefault();
$(this).addClass('badge-dark').removeClass('badge-secondary');
$('#yesterday,#today').addClass('badge-secondary').removeClass('badge-dark');
$('.tomorrow').slideDown('slow');
$('.yesterday,.today').slideUp('1000');
});
To do this:
Use a class on those three elements (say, show-hide)
Use a class on the .yesterday, .today, and .tomorrow elements as well (say, slide-target).
Use a single click handler on the class
Within the handler, this is the element you want to show, and its siblings (see siblings) are the ones you want to hide
Within the handler, $('.slide-target') is all the targets, then you can use .filter('.' + this.id) to only target the one for this element, and .not('.' + this.id) to target the others
So roughly speaking:
<p align="center" style="font-size: 22px;">
<span class="show-hide badge badge-secondary">Yesterday</span>
<span class="show-hide badge badge-dark">Today</span>
<span class="show-hide badge badge-secondary">Tomorrow</span>
</p>
and
$('.show-hide').click(function(e) {
e.preventDefault();
// Just to avoid doing it repeatedly
var $this = $(this);
// Add this class
$this.addClass('badge-dark').removeClass('badge-secondary');
// Remove it from siblings
$this.siblings().addClass('badge-secondary').removeClass('badge-dark');
// Find the target elements
$('.slide-target')
.filter('.' + this.id).slideDown('1000').end() // Slide down related
.not('.' + this.id).slideUp('1000') // Slide up others
// Slide down the relevant element(s)
});
A simple extraction of common logic to separate function:
function updateClasses(element, selector) {
element.addClass('badge-dark').removeClass('badge-secondary');
$(selector).addClass('badge-secondary').removeClass('badge-dark').slideUp('1000');
}
$('#yesterday').click(function (e) {
e.preventDefault();
updateClasses(this, '#today,#tomorrow');
$('.yesterday').slideDown('slow');
});
$('#today').click(function (e) {
e.preventDefault();
updateClasses(this, '#yesterday,#tomorrow');
$('.today').slideDown('slow');
});
$('#tomorrow').click(function (e) {
e.preventDefault();
updateClasses(this, '#yesterday,#today');
$('.tomorrow').slideDown('slow');
});
Something like this:
$('#yesterday, #today, #tommorow').click(function(e) {
e.preventDefault();
$(this).addClass('badge-dark').removeClass('badge-secondary');
if ( $(this).is("#yesterday") ) {
$('#today,#tomorrow').addClass('badge-secondary').removeClass('badge-dark');
$('.yesterday').slideDown('slow');
$('.today,.tomorrow').slideUp('1000');
} else if ( $(this).is("#today") ) {
$('#yesterday,#tomorrow').addClass('badge-secondary').removeClass('badge-dark');
$('.today').slideDown('slow');
$('.yesterday,.tomorrow').slideUp('1000');
} else if ( $(this).is("#tomorrow") ) {
$('#yesterday,#today').addClass('badge-secondary').removeClass('badge-dark');
$('.tomorrow').slideDown('slow');
$('.yesterday,.today').slideUp('1000');
}
});
I can't think about an easier way to do it:
Using your class badge as the selector for your .click() function.
Using $(this) to change classes on the clicked element, and $('.badge').not($(this)) to target all others.
Getting the class name to show, according to the element you clicked.
Doing the same as point #2 to display/hide the wanted elements.
Here is a working snippet where I added some styling:
$('.badge').click(function(e) {
e.preventDefault();
$('.badge').not($(this)).removeClass('badge-dark').addClass('badge-secondary'); // Resets all except…
$(this).removeClass('badge-secondary').addClass('badge-dark'); // … the one clicked
var classToShow = '.' + $(this).attr('id'); // Get this id
$('.days').not(classToShow).slideUp('1000'); // Hide all except…
$(classToShow).slideDown('slow'); // … the one wanted
});
p {
font-size: 22px;
}
.badge-secondary {
opacity: 0.5;
}
.badge a {
color: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p align="center">
<span class="badge badge-secondary" id="yesterday">Yesterday</span>
<span class="badge badge-dark" id="today">Today</span>
<span class="badge badge-secondary" id="tomorrow">Tomorrow</span>
</p>
<p class="days yesterday">Yesterday…</p>
<p class="days today">Today…</p>
<p class="days tomorrow">Tomorrow…</p>
Hope it helps!

jQuery carousel dots on click always going to first item

I'm building a carousel with basic jquery - I'm using the .css() rule to simply toggle opacity between each slide.
The way I want to do this is on click of each dot I want to check if the specific class exists and if it does hide all other items and show that one. So far I have:
$('.dot').click(function() {
$('.review-module--reviews').children().css('opacity', 0);
if ($('.dot').hasClass('dot1')) {
$('.review-one').css('opacity', 1);
$('.dot1').addClass('dot-active');
} else if ($('.dot').hasClass('dot2')) {
$('.review-two').css('opacity', 1);
$('.dot2').addClass('dot-active');
} else {
$('.review-three').css('opacity', 1);
$('.dot3').addClass('dot-active');
}
});
HTML:
<div class="review-module">
<div class="review-module--reviews">
<div class="review-one">
</div>
<div class="review-two">
</div>
<div class="review-three">
</div>
</div>
<span class="slider-dots">
<div class="dot dot1"></div>
<div class="dot dot2"></div>
<div class="dot dot3"></div>
</span>
</div>
However when I click on dots 2 and 3, it always targets the dot1 slide in the DOM. The 'dot-active' class gets added successfully to dot1 but on click of 2 and 3, that class does not get added.
I also tried explicity checking for a true value in the if statement like so:
if ($('.dot').hasClass('dot1') === true)
Is this the best way to do this? Or should I consider a different thought process?
The error is in this code:
if ($('.dot').hasClass('dotX'))
What you're actually doing here is fetching the list of all .dot elements and checking if the first one has the dotX class. As you can imagine, this will always pick up the first .dot element, which has the dot1 class.
What you probably mean to do is to check if the element that was clicked on has the dotX class, for which you need to check only that element.
Either do so by using the current scope of the click handler:
if ($(this).hasClass('dotX'))
or by checking the target of the click event:
$('.dot').click(function(e) {
$('.review-module--reviews').children().css('opacity', 0);
if ($(e.target).hasClass('dot1')) {
Try this may be it can help you -
JAVASCRIPT CODE-
$('.dot').click(function() {
$('.review-module--reviews').children().css('opacity', 0);
$('.dot').removeClass('dot-active');
if ($(this).hasClass('dot1')) {
$('.review-one').css('opacity', 1);
$(this).addClass('dot-active');
} else if ($(this).hasClass('dot2')) {
$('.review-two').css('opacity', 1);
$(this).addClass('dot-active');
} else {
$('.review-three').css('opacity', 1);
$(this).addClass('dot-active');
}
});
I suggest to use data-* attributes instead so give every .dot a data-review that refer to the related review div :
$('.review-module--reviews div').hide(); //Hide all the slides
$('.dot').click(function() {
var review = $(this).data('review');
$('.review-module--reviews div').hide(); //Hide all slides
$('.slider-dots .dot').removeClass('dot-active'); //Remove 'dot-active' class from all the dots
$(this).addClass('dot-active'); //Active the clicked dot
$('.review-'+review).show(); //Show the related slide
});
Then on click just get the review using jQuery method .data() and show the div with related class.
Hope this helps.
$('.review-module--reviews div').hide();
$('.dot').click(function() {
var review = $(this).data('review');
$('.review-module--reviews div').hide();
$('.slider-dots .dot').removeClass('dot-active');
$(this).addClass('dot-active');
$('.review-'+review).show();
});
.dot-active{
color: green;
font-weight:bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="slider-dots">
<div class="dot dot1" data-review="one">dot1</div>
<div class="dot dot2" data-review="two">dot2</div>
<div class="dot dot3" data-review="three">dot3</div>
</span>
<br>
<div class="review-module">
<div class="review-module--reviews">
<div class="review-one">
Review-one
</div>
<div class="review-two">
Review-two
</div>
<div class="review-three">
Review-three
</div>
</div>
</div>

Need help to identify why removing element and its contents in jQuery is not working

Can anybody tell me what I'm doing wrong with this jQuery code here?
$('.deleter').click(function() {
var toDelete = $(this).attr('stringStorage');
$('.urls').text($('.urls').text().replace(toDelete, ''));
$(this).remove();
});
.deleter {
display: inline-block;
margin-right: 10px;
background-color: red;
color: white;
cursor: pointer;
}
.deleter:hover { background-color: orange; }
br { line-height: 22px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="urls">
<span class="deleter" stringStorage="www.firsturl.com">x</span>www.firsturl.com<br>
<span class="deleter" stringStorage="www.anothereurl.com">x</span>www.anothereurl.com<br>
<span class="deleter" stringStorage="www.athirdurl.com">x</span>www.athirdurl.com<br>
</div>
It works fine at removing the .deleter element:
https://jsfiddle.net/Hastig/ku0t7mey/5/
But once $('.urls').text($('.urls').text().replace(toDelete, '')); in the element .deleter is removed but the contents (x) are left behind:
https://jsfiddle.net/Hastig/ku0t7mey/4/
UPDATE
I can get the whole function to work with this solution here.
But I will leave this question open for anyone who can answer why the code I used seems to remove all html elements within the targeted element.
https://jsfiddle.net/Hastig/ku0t7mey/6/
You can use .nextSibling, .textContent to set #text node adjacent to clicked .deleter element to empty string "".
$('.deleter').click(function(e) {
var toDelete = $(this).data('stringStorage');
this.nextSibling.textContent = "";
$(this).remove();
});
You can also substitute using data-* attribute for custom attribute at html
<div class="urls">
<span class="deleter" data-string-storage="www.firsturl.com">x</span>www.firsturl.com<br>
<span class="deleter" data-string-storage="www.anothereurl.com">x</span>www.anothereurl.com<br>
<span class="deleter" data-string-storage="www.athirdurl.com">x</span>www.athirdurl.com<br>
</div>
jsfiddle https://jsfiddle.net/ku0t7mey/8/
you could alternatively use .contents(), .filter(), .trim(), .add() to remove the #text node at same call where this is removed from document
$(".urls").contents().filter(function() {
return this.nodeType === 3 && this.nodeValue.trim() === toDelete
}).add(this).remove();
https://jsfiddle.net/ku0t7mey/12/
Check this: https://jsfiddle.net/ku0t7mey/7/
Modify the HTML like:
<div class="urls">
<div><span class="deleter" stringStorage="www.firsturl.com">x</span>www.firsturl.com</div>
<div> <span class="deleter" stringStorage="www.anothereurl.com">x</span>www.anothereurl.com</div>
<div><span class="deleter" stringStorage="www.athirdurl.com">x</span>www.athirdurl.com</div>sss
</div>
JS like:
$('.deleter').click(function() {
var toDelete = $(this).attr('stringStorage');
$(this).parent().remove();
});
Try this
jsfiddle
HTML
<div class="urls">
<div class="delete">
<span class="deleter" stringStorage="www.firsturl.com">x</span>www.firsturl.com<br>
</div>
<div class="delete">
<span class="deleter" stringStorage="www.anothereurl.com">x</span>www.anothereurl.com<br>
</div>
<div class="delete">
<span class="deleter" stringStorage="www.athirdurl.com">x</span>www.athirdurl.com<br>
</div>
</div>
SCRIPT
$('.delete').click(function() {
var toDelete = $(this).attr('stringStorage');
$(this).remove();
});

How to toggle between 2 icons

I have to toggle between two icons based on some criteria. How do I do this in jQuery?
<a href='' id="home" onclick="myfunction(this)" data-toggle="toggle">
<span class="fa fa-train"></span>
</a>
myfunction($this) {
// ...
if ($($this).hasClass("fa fa-train")) {
$($this).removeClass("fa fa-train");
$($this).addClass("fa fa-car");
}
else {
$($this).addClass("fa fa-car");
$($this).addClass("fa fa-train");
}
// ...
}
clicked anchor element do not have class added, its child span does :
function myfunction($this) {
$($this).find('span').toggleClass('fa-train fa-car');
}
Do something like this
$('a#home').on('click', function(){
var childSpan = $(this).find('span');
if(childSpan.hasClass('fa-train')){
childSpan.removeClass('fa-train');
childSpan.addClass('fa-car');
}
else if(childSpan.hasClass('fa-car')){
childSpan.removeClass('fa-car');
childSpan.addClass('fa-train');
}});
you are using this which will check the a tag if has class . while you should check in the span next to a tag .you should use like this
myfunction($this) {
// ...
if ($($this).next('span').hasClass("fa fa-train")) {
$($this).next('span').removeClass("fa fa-train");
$($this).next('span').addClass("fa fa-car");
}
else {
$($this).next('span').addClass("fa fa-car");
$($this).next('span').addClass("fa fa-train");
}
// ...
}
With a condition in one line:
$($this)
.addClass((condition=(Math.random() > .5)) ? 'fa-car' : 'fa-train')
.removeClass(condition ? 'fa-train': 'fa-car')
Note: This will not work if you "use strict" and of course your code will be less readable.
Thanks everyone, yes i had to search for 'span' and add toggle class. hasClass is also good way to check beforehand that the class exist or not.
This is a concept that I came with which is a bit logical. Instead of using complicated language, what this does is it hides the add button and makes a times button while showing the message that was hidden. It is fairly simple JQuery.
$(document).ready(function() {
$("#addCross").click(function() {
document.getElementById("addCross").style.display = "none";
document.getElementById("addAdd").style.display = "inline-block";
document.getElementById("hello").style.display = "block";
});
$("#addAdd").click(function() {
document.getElementById("addCross").style.display = "inline-block";
document.getElementById("addAdd").style.display = "none";
document.getElementById("hello").style.display = "none";
});
});
/*
Unoptional CSS
Just to make the buttons look better in the snippet.
*/
button {
background: transparent;
border: none;
}
button:focus {
outline: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://kit.fontawesome.com/9b271ce18a.js" crossorigin="anonymous"></script>
<div>
<label>Press the Button: </label>
<button id="addCross"><i class="fas fa-plus"></i>
<button id="addAdd" style="display: none;"><i class="fas fa-times"></i></button>
<div style="display: none;" id="hello">
<p>Hello. I was hidden by the Magic of JQuery.</p>
<label>This design also makes a cool rotating add sign if you look closely. Ha Ha!!</label>
</div>

Categories