Javascript/jQuery - Timezone Change Script with Multiple Fields - javascript

I have written a javascript for changing the "timezone" of a field on my website using a dropdown select menu.
You can see the script here: http://jsfiddle.net/dTb76/14/
However, I have reached the limits of what I know how to do - I need the script to modify several "time" fields, however, at the moment it can only work with one field.
I've been trying to figure out what changes to make for days, however I have not been having much luck. Best I can tell, I need some kind of "foreach" statement, telling it to store the original time for each field and then modify it by whatever is selected in the select, however I am not sure how to implement that in jQuery/javascript.
Would appreciate help.

You just need to use $.each JQuery function:
$('#modTime').change(function() {
var times = $('.time');
$.each(times, function(index, value) {
var curTime = $(value).text();
curTimeHH = parseInt(curTime.split(':')[0],10);
$(value).attr('originalTime', curTime);
var modifyBy = parseInt($('#modTime').val(),10);
curTimeHH = parseInt(curTime,10) + modifyBy;
if (curTimeHH === 0) {
$(value).text('24:00');
} else if (curTimeHH > 24) {
curTimeHH = curTimeHH - 24;
$(value).text('0'+curTimeHH + ':00');
} else if (curTimeHH < 0) {
curTimeHH = curTimeHH + 24;
$(value).text(curTimeHH + ':00');
} else {
$(value).text(curTimeHH + ':00');
}
});
});​
Edit:
To retrieve the 'original time' of every field, you could do something like:
var times = $('.time');
$.each(times, function(index, value) {
var originalTime = $(value).attr('originalTime');
...
});

You'll want to use jQuery's each() method to iterate through each of your .time elements. This will allow you to grab the current time for each specific element and do your calculations on a per-element basis; otherwise, $('.time').text() and things like that will always return the value of the first element selected, which is what you're seeing.
This should get you started:
$('#modTime').change(
function(){
var modifyBy = parseInt($(this).val(),10); // Here, this refers to your select element, the element whose change event handler we're now in
$('.time').each(function(){ // each() iterates through each .time element found in the DOM individually; that's what you'd like to do
var $this = $(this), // Refers to the current .time element
curTime = $this.text(),
curTimeHH = parseInt(curTime.split(':')[0],10),
curTimeHH = parseInt(curTime,10) + modifyBy;
$this.attr('originalTime',curTime);
if (curTimeHH == 0) {
$this.text('24:00');
} else if (curTimeHH > 24) {
curTimeHH = curTimeHH - 24;
$this.text('0'+curTimeHH + ':00');
} else if (curTimeHH < 0) {
curTimeHH = curTimeHH + 24;
$this.text(curTimeHH + ':00');
} else {
$this.text(curTimeHH + ':00');
}
});
});

Related

How can I modify a variable on another site?

My son is doing times tables practice on this page, a timed test in which he gets 10 seconds for each sum.
https://www.timestables.com/speed-test/ - this is not my site or code, I have no direct control over the source code.
I want to give him a little more time per sum but I cannot find a way to modify the relevant code and make it work with 20 seconds instead of 10.
It looks to me like the relevant variable is maxTime (milliseconds) in this function, but nothing I do using the Chrome Developer Tools will modify this in a live running page to give 20 seconds instead of 10.
function startSom(){
vraagnr = vraagnr + 1;
if(vraagnr <= totaalSommen)
{
bezig = true;
$('#pbar_innerdiv').stop();
$('#pbar_innerdiv').css("width","100%");
$('#pbar_innerdiv').css("backgroundColor","#33BF00");
$('#pbar_innerdiv').css("borderColor","#33BF00");
if(mobiel){
$("#antwVak").html("");
}
else{
$("#antwoordI").val("");
$("#antwoordI").focus();
}
$('#pbar_innerdiv').stop();
start = new Date();
maxTime = 10000;
timeoutVal = Math.floor(maxTime/100);
var somT = sommen[vraagnr-1].split(",");
$('#somVak').html(somT[1]+"×"+somT[0]+"=");
$('#voortgangVak').html("Question "+vraagnr+" / "+totaalSommen+"<br />"+ punten + " points");
animateUpdate();
started = false;
}
else
{
showEindScherm();
}
}
Can anyone suggest what to do please?
You can copy the entire method, pase it into chrome devtools and change
function startSom() {
to
window.startSom = function() {
And obviously change your time from 10000 to 20000. This changes the amount of time it allows you to answer, but not the moving progress bar which will still only take 10 seconds.
Please paste this:
window.startSom = function(){
vraagnr = vraagnr + 1;
if(vraagnr <= totaalSommen)
{
bezig = true;
$('#pbar_innerdiv').stop();
$('#pbar_innerdiv').css("width","100%");
$('#pbar_innerdiv').css("backgroundColor","#33BF00");
$('#pbar_innerdiv').css("borderColor","#33BF00");
if(mobiel){
$("#antwVak").html("");
}
else{
$("#antwoordI").val("");
$("#antwoordI").focus();
}
$('#pbar_innerdiv').stop();
start = new Date();
maxTime = 20000;
timeoutVal = Math.floor(maxTime/100);
var somT = sommen[vraagnr-1].split(",");
$('#somVak').html(somT[1]+"×"+somT[0]+"=");
$('#voortgangVak').html("Question "+vraagnr+" / "+totaalSommen+"<br />"+ punten + " points");
animateUpdate();
started = false;
}
else
{
showEindScherm();
}
}
Here:
And if you want to make the progress bar following the new max Time, also paste this:
window.animateUpdate = function() {
if(bezig)
{
var now = new Date();
var timeDiff = now.getTime() - start.getTime();
if(!started){
$('#pbar_innerdiv').css("width", (100) + "%");
$('#pbar_innerdiv').animate({width: 0 + "%"},20000);
started = true;
}
perc = Math.round((timeDiff/maxTime)*100);
console.log(perc);
if(perc == 33)
{
$('#pbar_innerdiv').css("backgroundColor", "#FF9500");
$('#pbar_innerdiv').css("borderColor", "#FF9500");
}
if(perc== 66)
{
$('#pbar_innerdiv').css("backgroundColor", "#FF0000");
$('#pbar_innerdiv').css("borderColor", "#FF0000");
}
if (perc <= 100) {
//updateProgress(perc);
setTimeout(animateUpdate, timeoutVal);
}
else
{
bezig = false;
showTeLaat();
//alert("tijd is om");
}
}
}
There is a possibility to change files persistently in chrome devtools: Overrides.
If the script is in a seperate file you can change the maxTime directly there or if it is in a file, which needs to be reloaded you can edit any other .js and add an eventlistener there to change the startSom method on page load.

Firing javascript event based on time of day

I'm looking for help to see if there is an easy quick way to fire a JS event based on the time of day a website opens in the browser.
Essentially what I want to do is between 5pm-5am of the users local time zone have this script fire. The script is currently wired to a button that simply flips the class of the body of the page to "night mode". I would like the two to work in harmony, automate based on time and the ability to override with the button if you want the dark or light theme.
function toggleClass(element, className) {
if (!element || !className) {
return;
}
var classString = element.className,
nameIndex = classString.indexOf(className);
if (nameIndex == -1) {
classString += ' ' + className;
} else {
classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length);
}
element.className = classString;
}
document.getElementById('day-btn').addEventListener('click', function() {
toggleClass(document.getElementById('body'), 'night');
});
https://jsfiddle.net/simpson/57xe333n/2/
var time = new Date();
element = document.getElementById('body');
className = "night";
console.log(time.getHours());
if(time.getHours() > 17 || time.getHours < 5) {
if (!element || !className) {
return;
}
var classString = element.className,
nameIndex = classString.indexOf(className);
if (nameIndex == -1) {
classString += ' ' + className;
} else {
classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length);
}
element.className = classString;
}
This uses JS's built in Date functionalities which pull from the system. It runs a getHours() function which returns an int(0-23). The if statement (time.getHours() > 17 || time.getHours < 5) will then only run the code and change the theme if it is after 5pm or before 5 am. Hope this can get you started.

Unable to target ID via Javascript

My mission is to tweak this website https://www.mintpal.com/market/XC/BTC# so it will show a different color for the value if it sees "buy orders" over 2.00000000 BTC.
As an example, you check the image http://i.imgur.com/hZBGiTu.png ( the example worked because i targeted them each one separately with "#buyTotal-0-00126011" and so on.
I only want that td#buyTotal pane to be changed.
I tried to target it with the following:
1 - var cell = $('td') - it works, but it changes the values globally
2 - var cell = $('#buyTotal' + price + value.total) - not working
3 - var cell = $('td#buyTotal') - not working.
The code should look similar to this in the end...
var cell = $('td#buyTotal')
cell.each(function() {
var cell_value = $(this).html();
if ((cell_value >= 0) && (cell_value >=2.00000000)) {
$(this).css({'background' : '#FF0000'});
} else if ((cell_value >= 3) && (cell_value >=5.00000000)) {
$(this).css({'background' : '#FF0000'});
} else if (cell_value >= 8.00000000) {
$(this).css({'background' : '#FF0000'});
}
});
You can also access this as a shortcut ' mintpal.com/assets/js/market.js '
If i omitted something, please let me know. Thanks....
Edit: I'm only playing with the code inspector/console on the website. What i want is extremely simple. It's just that i cannot target the id. I updated the photo also.
This will require regex.
var cells = document.querySelectorAll('*[id^="buyTotal"]');
for(var i = 0; i < cells.length; i++) {
if(cells[i].innerHTML > 2) { cells[i].style.backgroundColor = 'red'; }
}

jQuery "keyup" crashing page when checking 'Word Count'

I have a word counter running on a DIV and after typing in a few words, the page crashes. The browser continues to work (par scrolling) and no errors are showing in Chrome's console. Not sure where I'm going wrong...
It all started when I passed "wordCount(q);" in "keyup". I only passed it there as it would split-out "NaN" instead of a number to countdown from.
JS:
wordCount();
$('#group_3_1').click(function(){
var spliced = 200;
wordCount(spliced);
}) ;
$('#group_3_2').click(function(){
var spliced = 600;
wordCount(spliced);
}) ;
function wordCount(q) {
var content_text = $('.message1').text(),
char_count = content_text.length;
if (char_count != 0)
var word_count = q - content_text.replace(/[^\w ]/g, "").split(/\s+/).length;
$('.word_count').html(word_count + " words remaining...");
$('.message1').keyup(function() {
wordCount(q);
});
try
{
if (new Number( word_count ) < 0) {
$(".word_count").attr("id","bad");
}
else {
$(".word_count").attr("id","good");
}
} catch (error)
{
//
}
};
HTML:
<input type="checkbox" name="entry.3.group" value="1/6" class="size1" id="group_3_1">
<input type="checkbox" name="entry.3.group" value="1/4" class="size1" id="group_3_2">
<div id="entry.8.single" class="message1" style="height: 400px; overflow-y:scroll; overflow-x:hidden;" contenteditable="true"> </div>
<span class="word_count" id="good"></span>
Thanks in advanced!
This is causing an infinite loop if (new Number(word_count) < 0) {.
Your code is a mess altogether. Just study and start with more basic concepts and start over. If you want to describe your project to me in a comment, I would be glad to show you a good, clean, readable approach.
Update:
Part of having a good architecture in your code is to keep different parts of your logic separate. No part of your code should know about or use anything that isn't directly relevant to it. Notice in my word counter that anything it does it immediately relevant to its word-counter-ness. Does a word counter care about what happens with the count? Nope. It just counts and sends the result away (wherever you tell it to, via the callback function). This isn't the only approach, but I just wanted to give you an idea of how to approach things more sensefully.
Live demo here (click).
/* what am I creating? A word counter.
* How do I want to use it?
* -Call a function, passing in an element and a callback function
* -Bind the word counter to that element
* -When the word count changes, pass the new count to the callback function
*/
window.onload = function() {
var countDiv = document.getElementById('count');
wordCounter.bind(countDiv, displayCount);
//you can pass in whatever function you want. I made one called displayCount, for example
};
var wordCounter = {
current : 0,
bind : function(elem, callback) {
this.ensureEditable(elem);
this.handleIfChanged(elem, callback);
var that = this;
elem.addEventListener('keyup', function(e) {
that.handleIfChanged(elem, callback);
});
},
handleIfChanged : function(elem, callback) {
var count = this.countWords(elem);
if (count !== this.current) {
this.current = count;
callback(count);
}
},
countWords : function(elem) {
var text = elem.textContent;
var words = text.match(/(\w+\b)/g);
return (words) ? words.length : 0;
},
ensureEditable : function(elem) {
if (
elem.getAttribute('contenteditable') !== 'true' &&
elem.nodeName !== 'TEXTAREA' &&
elem.nodeName !== 'INPUT'
) {
elem.setAttribute('contenteditable', true);
}
}
};
var display = document.getElementById('display');
function displayCount(count) {
//this function is called every time the word count changes
//do whatever you want...the word counter doesn't care.
display.textContent = 'Word count is: '+count;
}
I would do probably something like this
http://jsfiddle.net/6WW7Z/2/
var wordsLimit = 50;
$('#group_3_1').click(function () {
wordsLimit = 200;
wordCount();
});
$('#group_3_2').click(function () {
wordsLimit = 600;
wordCount();
});
$('.message1').keydown(function () {
wordCount();
});
function wordCount() {
var text = $('.message1').text(),
textLength = text.length,
wordsCount = 0,
wordsRemaining = wordsLimit;
if(textLength > 0) {
wordsCount = text.replace(/[^\w ]/g, '').split(/\s+/).length;
wordsRemaining = wordsRemaining - wordsCount;
}
$('.word_count')
.html(wordsRemaining + " words remaining...")
.attr('id', (parseInt(wordsRemaining) < 0 ? 'bad' : 'good'));
};
wordCount();
It's not perfect and complete but it may show you direction how to do this. You should use change event on checkboxes to change wordsLimit if checked/unchecked. For styling valid/invalid words remaining message use classes rather than ids.
I think you should use radio in place of checkboxes because you can limit 200 or 600 only at a time.
Try this like,
wordCount();
$('input[name="entry.3.group"]').click(function () {
wordCount();
$('.word_count').html($(this).data('val') + " words remaining...");
});
$('.message1').keyup(function () {
wordCount();
});
function wordCount() {
var q = $('input[name="entry.3.group"]:checked').data('val');
var content_text = $('.message1').text(),
char_count = content_text.length;
if (char_count != 0) var word_count = q - content_text.replace(/[^\w ]/g, "").split(/\s+/).length;
$('.word_count').html(word_count + " words remaining...");
try {
if (Number(word_count) < 0) {
$(".word_count").attr("id", "bad");
} else {
$(".word_count").attr("id", "good");
}
} catch (error) {
//
}
};
Also you can add if your span has bad id then key up should return false;
See Demo

Unable to get proper element count on drop

I have noticed at several attempts to get a count of dropped elements it always returns one less than the number found, but if I try the same command via Chromes console I get the propper response.
I assume the DOM is not updated when this script runs so I threw a timeout/try again mechanism but still with no avail. What am I missing?
Expected Result size = 10
Actual Result size = 9
Code
var asmCount = 0;
function storeValues(values, tryNumber){
var size = values.length,
tryNumber = (!isNaN(tryNumber)) ? tryNumber : 1
;
console.log('full boat:' + size + ', try #'+ tryNumber + ' ' + typeof(tryNumber));
if(tryNumber > 60){
console.log('too many tries');
return;
}
if(size < 10){
console.log('missing entries');
tryNumber = tryNumber + 1;
setTimeout(storeValues($('.asm-ranking .receiver .asm-value'), tryNumber) , 500);
} else if(size > 10){
console.log('too many entries, something broke');
} else {
console.log('just right, lets do this shit.');
//$.each(values, function(k,v){ console.log($(v).data('id'));});
}
}
$('.asm-ranking .receiver').droppable({
drop: function(event,ui){
var _self = this,
receiverCount = $('.asm-ranking .receiver li').length
;
//console.log('event',event);
//console.log('ui', ui);
asmCount++;
console.log(asmCount + ' / ' + receiverCount);
if(receiverCount == asmCount){
storeValues($('.asm-ranking .receiver .asm-value'), 1); // give DOM time to catch up, then store
}
}
});
for some reason when I wrapped my jQuery notation in with document ready
$(document).ready(function{ ... })
it works as expected.

Categories