Jquery Countdowntimer shows same timer for multiple spans in error - javascript

I have a table with games detail. and I want to add a countdowntimer for every game.
I'm using the jquery-countdownTimer plugin
My Html:
<span class="given_date" data-gamestart="2016/3/11 15:30"></span>
<span class="given_date" data-gamestart="2016/3/13 18:00"></span>
<span class="given_date" data-gamestart="2016/3/15 17:45"></span>
<span class="given_date" data-gamestart="2016/3/22 19:45"></span>
and i user a this plugin to make the count down.
My js:
$('.given_date').countdowntimer({
dateAndTime : "2016/3/10 17:05"
});
A jsFiddle example
My issue is, even though I provide a different time for each span, all of the timers show the same value and countdown in sync
Why does each span not show it's own timer based on my provided values?

Your issue is that your elements do not have ids.
This plugin uses the below code to set the timers then display their values. Note the window['regexpMatchFormat_' + $this.attr('id')]. This uses the id of each element to create a unique global variable to keep track of the timers. If your elements have no ids, you end up repeatedly overwriting your first timer
//Code for starting the timers.
if (options.regexpMatchFormat != undefined && options.regexpReplaceWith != undefined && options.timeSeparator == undefined) {
window['regexpMatchFormat_' + $this.attr('id')] = options.regexpMatchFormat;
window['regexpReplaceWith_' + $this.attr('id')] = options.regexpReplaceWith;
}
//Function for displaying the timer.
function html($this, content) {
var processedContent = content;
if (typeof window['regexpMatchFormat_' + $this.attr('id')] !== 'undefined' &&
typeof window['regexpReplaceWith_' + $this.attr('id')] !== 'undefined') {
var regexp = new RegExp(window['regexpMatchFormat_' + $this.attr('id')]);
processedContent = content.replace(regexp,
window['regexpReplaceWith_' + $this.attr('id')]);
}
$this.html(processedContent);
}
Working jsFiddle
This is why you should always link to the plugin you are using ;)

The best way is to loop through the spans with jQuery's .each() and set up the countdowntimer within that loop. Something like this:
$('.given_date').each(function() {
$(this).countdowntimer({
dateAndTime : this.getAttribute("data-gamestart")
});
});

Related

Check is class exist longer than X in javascript

I wrote simple monitor which check few things on my networks and display status - I am fetching statuses using ajax.
When something is wrong I am adding class error to div which is displaying current status.
Later I add player with error sound when class error is present it plays music. I set 3 second interval and thats all.
But not always error mean error, sometimes I recive false warning.
Now I am looking for way to play sound when class error exists longer than XX seconds.
I suppose I have to wrote function with interval 1s, add every hit 1 to temp variable and check is variable bigger than else clean temp variable, but maybe is there more elegant way.
i guess it should work
$('.error').each(function(){
var e = $(this)
setTimeout(function(){
if (e.attr('class') == 'error'){
e.attr('class','error-with-sound');
}
},2000);
});
You should take two vars store the current time at their respective events.
var oldTime, newTime;
// Now when you are adding the class
$(something).addClass("someclass");
oldTime = new Date().getTime(); // Store the timestamp.
//And when you are removing the class
$(something).removeClass("someclass");
newTime = new Date().getTime(); // Store the timestamp.
// Now you check whether class was added for more then XX Seconds
var _diff = (newTime - oldTime)/1000; // Diference is in seconds.
There is no direct way for that, you can add timestamps in your class with separator something like error_1448953716457 and later you can split that and can compare with current timestamps
$('#na').click(function () {
var t = new Date().getTime();
$('h1').addClass("error_" + t);
});
$('#nr').click(function () {
var t = new Date().getTime();
$("[class^=error]").each(function (e) {
$("span").html("Diff. Seconds : " + ((t - ($(this).attr('class').split(' ').pop().split('_')[1])) / 1000).toString());
});
});
input {
width:100px;
}
.error {
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<h1>.addClass()</h1>
<input id="na" value="Add Class1" type="button" />
<br/>
<input id="nr" value="Calculate Diff" type="button" />
<span></span>
If you want to track .error elements on the page, set an independent interval that looks for those elements and tracks the ones it has seen before by setting an attribute or data value in jquery.
Remember to clearInterval(interval) if you no longer need to check for .error elements.
(function ($) {
// set constants in milliseconds as desired
var INTERVAL_LENGTH = 100, // how often to check DOM for error elements
NOTIFY_AFTER = 3000; // handle error after this length
// check for .error elements and handle those that have been around for a while
var interval = setInterval(function () {
var now = Date.now();
$(".error").each(function () {
var t = $(this).data('error-time');
if(t) {
if(now - t > NOTIFY_AFTER) {
handleErrorElement(this);
}
}
else {
$(this).data('error-time', now);
}
});
}, INTERVAL_LENGTH);
function handleErrorElement(elem) {
// do what you need for error elements visible past a threshold
console.log("handling error element: ", elem);
}
})(jQuery);

setTimeout executes itself right away/on clear

I'm making a webpage where user events are logged in.
To test the feature I made a small, independant webpage with a teaxtarea and a text input. The events logged are those performed on the input element.
I want to prevent the same event text to be shown multiple times in a row, but I can't seem to prevent them from showing up!
I also want to add a line to separate event groups 0.5 seconds after no other event happened, but the line seems to appear on every event trigger, evenif I use clearTimeout with the timeout ID.
Basically: I don't want any line to be repeated. If the last line is a separator line, then it must not add another one. Yet it doesn't see to work.
JSFiddle Demo
Here is my code:
JavaScript
var timerID = 0;
function addSeparateLine()
{
document.getElementById('listeEvenements').value += "--------------------\n";
}
function show(newEventText)
{
var eventListField = document.getElementById('listeEvenements');
var eventList = [];
if (eventListField.value.length > 0)
{
eventList = eventListField.value.split("\n");
}
var eventCounter = eventList.length;
if (eventList[eventCounter - 2] == newEventText)
{
clearTimeout(timerID);
newEventText = "";
}
timerID = setTimeout(addSeparateLine, 500);
if (newEventText !== "")
{
eventListField.value += newEventText + "\n";
}
return true;
}
HTML
<fieldset id="conteneurLogEvenements">
<legend>Events called from HTML attribute</legend>
<textarea id="listeEvenements" rows="25"></textarea>
<input id="controleEcoute" type="text" onBlur="show('Blur');" onchange="show('Change');" onclick="show('Click');" onfocus="show('Focus');" onMousedown="show('MouseDown');" onMousemove="show('MouseMove');" onMouseover="show('MouseOver');" onkeydown="show('KeyDown');"
onkeypress="show('KeyPress');" onkeyup="show('KeyUp');" />
</fieldset>
http://jsfiddle.net/z6kb4/2/
It sounds like what you want is a line that prints after 500 milliseconds of inactivity, but what your code currently says to do is "print a line 500 milliseconds after any action, unless it gets canceled". You can get better results by structuring the code more closely to your intended goal.
Specifically, instead of scheduling a new timeout every time an event occurs, simply start a loop when the first event occurs that checks the time that has elapsed since the most recent event received and then prints a line when the elapsed time exceeds the desired threshold (500 milliseconds). Something like:
function addSeparateLine() {
var elapsed = new Date().getTime() - lastEventTime;
if (elapsed >= 500) {
document.getElementById('listeEvenements').value += "--------------------\n";
clearInterval(timerID);
timerID = -1;
}
}
...and then you schedule it like:
if(newEventText !== "") {
lastEventTime = new Date().getTime();
eventListField.value += newEventText+"\n";
if (timerID == -1) {
timerID = setInterval(addSeparateLine,100);
}
}
Working example here: http://jsfiddle.net/z6kb4/4/
Because you are not actually stopping the show function in any way. The clearTimeout only applies to the separator add. I have updated your fiddle. You need to wrap your function with
if (+new Date() - lastfire < 500) return;
and
lastfire = +new Date();
(before the last return--see the updated fiddle). Also, make sure to stick the global definition var lastfire = -1; somewhere up top.

jQuery getting tag's content dynamically

First of all, I know my question seems to be already asked many many times but I'm facing a weird issue.
Here's the situation :
I've got an integer (dynamically loaded) in this tag :
<i id="my_id">{{here's my integer}}</i>
What I want to do is to retrieve the integer inside my tag but this integer is set to 0 at first (When the page isn't fully loaded") and then 2 or 3 seconds later, this integer is set to its real value.
So I tried something like this :
var test = 0;
$('#my_id').change(function(){
test = $('#my_id').html();
});
console.log(test);
This always returns me 0. I tried many things to get the current value of my tag but I can't find a way to succeed. Can you please help me get this integer ?
Cordially, Rob.
The change event is only fired by input elements. You can try polling the value like so:
var intervalId = setInterval(function() {
var value = parseInt($('#my_id').text(), 10);
if(value > 0) {
clearInterval(intervalId);
//... do stuff
}
}, 250); //poll every 250ms
Another way is to fire a custom event when you change the value:
//Somewhere in your code where you set the value in the i tag:
$('#my_id').text(value);
$('#my_id').trigger("valueChanged");
//Elsewhere in your code
$('#my_id').on("valueChanged", function() {
var value = parseInt($(this).text(), 10);
if(value > 0) {
//... do stuff
}
});

Clear Var or Callback in Javascript

Sorry, i am not sure if I am asking the question correctly. When a date is changed by a user the date count down changes on the page. If the date is changed more than once it flashes all date changes. I guess it is storing the previous information somewhere. I have tried clearing the vars.
var deal_yeax = '';
as I would do in php with no luck
$('#deal_end').focusout(function() {
var deal_end = $("#deal_end").val();
var array = deal_end .split('-');
var deal_montx = array[0];
var deal_dax = array[1];
var deal_yeax = array[2];
deal_montx = deal_montx - 1;
$(function(){
ts = new Date(deal_yeax , deal_montx , deal_dax );
$(".h").countdown({
timestamp : ts,
callback : function(days, hours, minutes, seconds){
message_days = (days);
var message_hours = (hours);
$(".message_hours").text(message_hours + " Hours");
var message_minutes = (minutes);
$(".message_minutes").text(message_minutes + " Minutes");
var message_seconds = (seconds);
// Creat the display
if ( message_days < 1 && message_hours < 1 ) { $(".message_seconds").text(message_seconds + " Seconds"); }
else if ( message_days < 1 && message_hours > 1 ) { }
else if ( message_days == 1 ) { $(".message_days").text(message_days + " Day"); }
else { $(".message_days").text(message_days + " Days"); }
if ( message_days < 1 && message_hours < 1 && message_minutes < 1 && seconds < 1 ) {
$(".hide_my_buy_button").fadeOut("fast");
}
}
});
});
});
Everytime you "focusout" from #deal_end, you'll attach a countdown event to .h. Without knowing exactly how countdown(...) works (It'll be good if you provide the source so we can provide more help!), one way to fix the issue maybe to use JQuery's unbind(...) function to remove existing listeners on an event before adding a new one to it.
Here's an example on the issue:
<!-- HTML -->
<div>
<input id="text" />
<button id="clicker" />
</div>
<!-- Javascript -->
$('#text').focusout(function() {
var text = this.value;
// Everytime #text is "focused out", a new event is registered with #clicker.
$('#clicker').click(function() {
console.log('Value: ' + text);
});
});
... and here's how to solve the issue (It's just one of the many ways. This way is probably not the most elegant but anyhow.)
$('#text').focusout(function() {
var text = this.value;
$('#clicker').unbind('click');
// Everytime #text is "focused out", a new event is registered with #clicker.
$('#clicker').click(function() {
console.log('Value: ' + text);
});
});
Bottom line: It seems focusout(...) is adding a new countdown everytime it is triggered. That might be the problem you're having.
Not sure if this helps? Lemme know.
P.S. JSFiddle to go with it: http://jsfiddle.net/PE9eW/
The problem seems to be with .countdown function that you are using in your code to flash the date changes. When you assign a new count down object to $(".h") the plugin or the function probably assign some event handler or interval to it, but it doesn't seem to clear the old ones when it is called again and that is why it flashing all the dates for each countdown. So you will have to do it manually. I am not sure if you are using an external plugin or is it your own function but what you need to do is to clear the existing events or intervals that is assigned to your element when you call the function. I can be more helpful if you tell me which plugin you are using or maybe show the code if it is your own function. (referring to .countdown() )

javascript (jquery) script perfomance synchronous vs asynchronous

I have a javascript function that filter dom elements based on a input text changes, so:
$(".input").keyup(function(e) {
filter();
});
var cache = $(".dom");
var filter = function() {
cache.each(function() {
// if field contains some text show else hide
}
};
My problem happens when there are many dom elements to filter, the whole pages gets inaccessible because of the synchronous processing (like the example above). Im trying to come out with a solution that dont locks the entire page with synchronous processing.
The problem is NOT related to the filter logic (it's completely trivial), it's NOT related to the jquery or javascript itslef, it's related to the synchronous processing and the quantity of dom elements.
As JavaScript is single threaded, the only real way to sort this out is to split the long-running job into a series of shorter jobs, and use setTimeout() with a short time delay at the end of each section to kick off the next one. This gives your UI and other JavaScript events a chance to update.
You can update large set of dom nodes by placing them in a queue and process only a few elements on each setTimeout "tick". In pseudo-code:
on(event):
queue = DOM nodes to be updated
setTimeout(update)
update:
queue.slice(0, limit).each(...update a node...)
queue = queue.slice(limit) // remove processed nodes
if (queue.length > 0) setTimeout(update) // repeat...
See http://jsfiddle.net/Etsmm/2/ for a complete working example.
Upd: The first version had problems with Chrome (related to its' "display" bug), adding a fix as per this answer appears to have done the trick.
Or doing it elsewhere through an ajax request if's really too long ?
And, maybe, some kind of: first step, select all IDs to be hidden in an array, then, settimeout, then in a second step, hiding them like 50 per 50 ?
Also, maybe processing that having the container of all those elements himself hidden, and then, once done, reshowing it may be faster ?
For this kind of purposes I generally prefer Ben Alman's message queuing library. It has also different alternatives. This one is quite successful on throttling.
https://github.com/cowboy/jquery-message-queuing/
Here below a throttling sample
http://benalman.com/code/projects/jquery-message-queuing/examples/throttling/
thank you all for your help. I came up with a solution based on Ben Clayton response, but Im still looking for ideas and investigating the thg435 solution. Any comments will be apreciated.
<script type="text/javascript">
$(document).ready(function () {
var cache = $(".whatever");
var wait = 0;
var input = $("#input");
var regex = null;
input.keyup(function (e) {
go.index = 0;
clearTimeout(wait);
wait = setTimeout(go.start, 500);
});
var filter = function (i) {
var one = cache.eq(i - 1);
one.text().match(regex) ? one.show() : one.hide();
go.index++;
setTimeout(go.filter, 10);
};
go = {
index: 0,
filter: function () {
go.index == 0 || go.index > cache.length ? null : filter(go.index);
},
start: function () {
go.index = 1;
var search = input.val();
search = search.replace(new RegExp("[a]", "gi"), "[aàáâã]");
search = search.replace(new RegExp("[e]", "gi"), "[eéê]");
search = search.replace(new RegExp("[i]", "gi"), "[ií]");
search = search.replace(new RegExp("[o]", "gi"), "[oóô]");
search = search.replace(new RegExp("[u]", "gi"), "[uú]");
search = search.replace(new RegExp("[c]", "gi"), "[cç]");
regex = new RegExp(search, "gi");
go.filter();
}
}
});
</script>
<input type="text" id="input" />
<span class="whatever">lalala</span>
<span class="whatever">leléLÉ</span>
<span class="whatever">lololo</span>
<span class="whatever">lululu</span>

Categories