I have written this code to get the value of the Timer in a div :
var timerGenerator = (function() {
var time = {
centiSec: 0,
secondes: 0,
minutes: 0,
hours: 0
};
var container = document.createElement("div");
var timeDisplay = function() {
function smoothDisplay(value) {
return (value < 10 ? '0' : '') + value;
}
return "" + smoothDisplay(this.hours) + ":" + smoothDisplay(this.minutes) + ":" + smoothDisplay(this.secondes) + "." + smoothDisplay(this.centiSec);
};
var boundTimeDisplay = timeDisplay.bind(time);
var timeUpdate = function() {
container.innerHTML = boundTimeDisplay();
//console.log(container);
this.centiSec++;
if(this.centiSec === 100) {
this.centiSec = 0;
this.secondes++;
}
if(this.secondes === 60) {
this.secondes = 0;
this.minutes++;
}
if(this.minutes === 60) {
this.minutes = 0;
this.hours++;
}
};
var boundTimeUpdate = timeUpdate.bind(time);
window.setInterval(boundTimeUpdate,10);
console.log(container);
return container;
})();
This code works when I link the var timerGenartor with a div. But, now I would like to return the var container into a string. So I changed my code to this : (I just changed the initialization of container and this value)
var timerGenerator = (function() {
var time = {
centiSec: 0,
secondes: 0,
minutes: 0,
hours: 0
};
var container = "";
var timeDisplay = function() {
function smoothDisplay(value) {
return (value < 10 ? '0' : '') + value;
}
return "" + smoothDisplay(this.hours) + ":" + smoothDisplay(this.minutes) + ":" + smoothDisplay(this.secondes) + "." + smoothDisplay(this.centiSec);
};
var boundTimeDisplay = timeDisplay.bind(time);
var timeUpdate = function() {
container = boundTimeDisplay();
//console.log(container);
this.centiSec++;
if(this.centiSec === 100) {
this.centiSec = 0;
this.secondes++;
}
if(this.secondes === 60) {
this.secondes = 0;
this.minutes++;
}
if(this.minutes === 60) {
this.minutes = 0;
this.hours++;
}
};
var boundTimeUpdate = timeUpdate.bind(time);
window.setInterval(boundTimeUpdate,10);
console.log(container);
return container;
})();
With this modification nothing is returned or display in the console and I don't understand why. However, the comment "console.log" gives me good the timer. So, why the first console.log displays the good result and not the second one ?
The working code as you expected with two JS functions
// JS 1
var timerGenerator = (function() {
var time = {
centiSec: 0,
secondes: 0,
minutes: 0,
hours: 0
};
var container = "";
var timeDisplay = function() {
function smoothDisplay(value) {
return (value < 10 ? '0' : '') + value;
}
return "" + smoothDisplay(this.hours) + ":" + smoothDisplay(this.minutes) + ":" + smoothDisplay(this.secondes) + "." + smoothDisplay(this.centiSec);
};
var boundTimeDisplay = timeDisplay.bind(time);
var timeUpdate = function() {
container = boundTimeDisplay();
//console.log(container);
this.centiSec++;
if(this.centiSec === 100) {
this.centiSec = 0;
this.secondes++;
}
if(this.secondes === 60) {
this.secondes = 0;
this.minutes++;
}
if(this.minutes === 60) {
this.minutes = 0;
this.hours++;
}
return container;
};
var boundTimeUpdate = timeUpdate.bind(time);
return boundTimeUpdate;
})();
// JS 2
var spanGenerator = (function() {
var container = document.createElement('span');
window.setInterval(function(){
container.innerHTML = timerGenerator();
}, 10);
return container;
})();
document.getElementById('timer').appendChild(spanGenerator);
<div id="timer"></div>
It can be because your container is empty as it is initialized in timeUpdate function which is eventually called 10ms later(for the first time) because of the setInterval. U will have to call the timeUpdate function before putting it in setInterval.
Counter = function ()
{
var _count;
_count = 0;
this.AddCounter = function()
{
_count++;
};
this.Reset = function ()
{
_count = 10;
};
Object.defineProperty( Counter, 'Value', {
get : function(){ return _count; },
set : function(){ _count = Value; },
configurable: true } );
}
Clock = function ()
{
var second = new Counter();
var minute = new Counter ();
var hour = new Counter();
this.Reset = function()
{
second.Reset();
minute.Reset();
hour.Reset();
};
this.Tick = function()
{
second.AddCounter();
if (second.Value == 60)
{
second.Reset();
minute.AddCounter();
if (minute.Value == 60)
{
minute.Reset();
hour.AddCounter();
}
}
};
this.ReadClock = function()
{
var sz = 0;
var mz = 0;
var hz = 0;
if (second.Value == 9)
{sz = null;}
if (minute.Value == 9)
{mz = null;}
if (hour.Value == 9)
{hz = null;}
document.getElementById("clock").innerHTML = ("" + hz + hour.Value + ":" + mz + minute.Value + ":" + sz +second.Value);
};
}
function Init()
{
var myClock = new Clock();
myClock.Tick();
myClock.ReadClock();
}
window.onload = Init;
The result I'm getting is:
0undefined:0undefined:0undefined
I think the issue is something to do with my Get/Set Property.
Also struggling to get the clock to tick, but that might be solvable once I put the Tick() function in a for loop.
You're creating the accessor property on the Counter constructor function (i.e. Counter.Value), not on the currently created instance:
function Counter() {
var _count = 0;
this.AddCounter = function() {
_count++;
};
this.Reset = function() {
_count = 10;
};
Object.defineProperty(this, 'Value', {
// ^^^^
get: function(){ return _count; },
set: function(val){ _count = val; },
configurable: true
});
}
I am building a custom mp3 player for a entertainment web site and i need to add songs continuously even when playing a song. to do that i'm using this function.
var temp = [];
var tempObj = [];
function popUp(file,thumb,trackName,trackArtist,trackAlbum) {
var validate = true;
if (temp.length>0) {
for (var x = 0; x < temp.length; x++) {
if (temp[x]['trackName'] == trackName) {
validate = false;
}
}
}
if (validate==true){
// Save data to object
tempObj = { file: file, thumb: thumb, trackName: trackName, trackArtist: trackArtist, trackAlbum: trackAlbum };
temp.push(tempObj); // push object to existing array
$("#player").jAudio({playlist: temp});
}
}
Problem is that to add songs to player we need to run that "jAudio()" function. because of that every time "popUp()" function called it calling the "jAudio()" function. if any one have a solution, please shear it..
This is the JAudio API.
!function (t) {
function i(i, a) {
this.settings = t.extend(!0, r, a), this.$context = i, this.domAudio = this.$context.find("audio")[0], this.$domPlaylist = this.$context.find(".jAudio--playlist"), this.$domControls = this.$context.find(".jAudio--controls"), this.$domVolumeBar = this.$context.find(".jAudio--volume"), this.$domDetails = this.$context.find(".jAudio--details"), this.$domStatusBar = this.$context.find(".jAudio--status-bar"), this.$domProgressBar = this.$context.find(".jAudio--progress-bar-wrapper"), this.$domTime = this.$context.find(".jAudio--time"), this.$domElapsedTime = this.$context.find(".jAudio--time-elapsed"), this.$domTotalTime = this.$context.find(".jAudio--time-total"), this.$domThumb = this.$context.find(".jAudio--thumb"), this.currentState = "pause", this.currentTrack = this.settings.defaultTrack, this.timer = void 0, this.init()
}
function a(t, i) {
for (var t = String(t); t.length < i;)t = "0" + t;
return t
}
var e = "jAudio", r = {
playlist: [],
defaultAlbum: void 0,
defaultArtist: void 0,
defaultTrack: 0,
autoPlay: !1,
debug: !1
};
i.prototype = {
init: function () {
var t = this;
t.renderPlaylist(), t.preLoadTrack(), t.highlightTrack(), t.updateTotalTime(), t.events(), t.debug(), t.domAudio.volume = .2
}, play: function () {
var t = this, i = t.$domControls.find("#btn-play");
t.currentState = "play", t.domAudio.play(), clearInterval(t.timer), t.timer = setInterval(t.run.bind(t), 50), i.data("action", "pause"), i.attr("id", "btn-pause"), i.toggleClass("active")
}, pause: function () {
var t = this, i = t.$domControls.find("#btn-pause");
t.domAudio.pause(), clearInterval(t.timer), t.currentState = "pause", i.data("action", "play"), i.attr("id", "btn-play"), i.toggleClass("active")
}, stop: function () {
var t = this;
t.domAudio.pause(), t.domAudio.currentTime = 0, t.animateProgressBarPosition(), clearInterval(t.timer), t.updateElapsedTime(), t.currentState = "stop"
}, prev: function () {
var t, i = this;
t = 0 === i.currentTrack ? i.settings.playlist.length - 1 : i.currentTrack - 1, i.changeTrack(t)
}, next: function () {
var t, i = this;
t = i.currentTrack === i.settings.playlist.length - 1 ? 0 : i.currentTrack + 1, i.changeTrack(t)
}, preLoadTrack: function () {
var t = this;
t.changeTrack(t.settings.defaultTrack), t.settings.autoPlay && t.play()
}, changeTrack: function (t) {
var i = this;
i.currentTrack = t, i.domAudio.src = i.settings.playlist[t].file, i.highlightTrack(), i.updateThumb(), i.renderDetails(), "play" === i.currentState && i.play()
}, events: function () {
var i = this;
i.$domControls.on("click", "button", function () {
var a = t(this).data("action");
switch (a) {
case"prev":
i.prev.call(i);
break;
case"next":
i.next.call(i);
break;
case"pause":
i.pause.call(i);
break;
case"stop":
i.stop.call(i);
break;
case"play":
i.play.call(i)
}
}), i.$domPlaylist.on("click", ".jAudio--playlist-item", function () {
var a = t(this), e = (a.data("track"), a.index());
i.currentTrack !== e && i.changeTrack(e)
}), i.$domProgressBar.on("click", function (t) {
i.updateProgressBar(t), i.updateElapsedTime()
}), t(i.domAudio).on("loadedmetadata", function () {
i.animateProgressBarPosition.call(i), i.updateElapsedTime.call(i), i.updateTotalTime.call(i)
})
}, getAudioSeconds: function (t) {
var t = t % 60;
return t = a(Math.floor(t), 2), t = 60 > t ? t : "00"
}, getAudioMinutes: function (t) {
var t = t / 60;
return t = a(Math.floor(t), 2), t = 60 > t ? t : "00"
}, highlightTrack: function () {
var t = this, i = t.$domPlaylist.children(), a = "active";
i.removeClass(a), i.eq(t.currentTrack).addClass(a)
}, renderDetails: function () {
var t = this, i = t.settings.playlist[t.currentTrack], a = (i.file, i.thumb, i.trackName), e = i.trackArtist, r = (i.trackAlbum, "");
r += "<p>", r += "<span>" + a + "</span>", r += "<span>" + e + "</span>", r += "</p>", t.$domDetails.html(r)
}, renderPlaylist: function () {
var i = this, a = "";
t.each(i.settings.playlist, function (t, i) {
{
var e = i.file, r = i.thumb, o = i.trackName, s = i.trackArtist;
i.trackAlbum
}
trackDuration = "00:00", a += "<div class='jAudio--playlist-item' data-track='" + e + "'>", a += "<div class='jAudio--playlist-thumb'><img src='" + r + "'></div>", a += "<div class='jAudio--playlist-meta-text'>", a += "<h4>" + o + "</h4>", a += "<p>" + s + "</p>", a += "</div>", a += "</div>"
}), i.$domPlaylist.html(a)
}, run: function () {
var t = this;
t.animateProgressBarPosition(), t.updateElapsedTime(), t.domAudio.ended && t.next()
}, animateProgressBarPosition: function () {
var t = this, i = 100 * t.domAudio.currentTime / t.domAudio.duration + "%", a = {width: i};
t.$domProgressBar.children().eq(0).css(a)
}, updateProgressBar: function (t) {
var i, a, e, r = this;
t.offsetX && (i = t.offsetX), void 0 === i && t.layerX && (i = t.layerX), a = i / r.$domProgressBar.width(), e = r.domAudio.duration * a, r.domAudio.currentTime = e, r.animateProgressBarPosition()
}, updateElapsedTime: function () {
var t = this, i = t.domAudio.currentTime, a = t.getAudioMinutes(i), e = t.getAudioSeconds(i), r = a + ":" + e;
t.$domElapsedTime.text(r)
}, updateTotalTime: function () {
var t = this, i = t.domAudio.duration, a = t.getAudioMinutes(i), e = t.getAudioSeconds(i), r = a + ":" + e;
t.$domTotalTime.text(r)
}, updateThumb: function () {
var t = this, i = t.settings.playlist[t.currentTrack].thumb, a = {"background-image": "url(" + i + ")"};
t.$domThumb.css(a)
}, debug: function () {
var t = this;
t.settings.debug && console.log(t)
}
}, t.fn[e] = function (a) {
var e = function () {
return new i(t(this), a)
};
t(this).each(e)
}
}(jQuery);
// initialize
(function () {
}());
This is old, but if you are willing to go a little nasty, I have a working workaround. Forgive me for the nasty approach, in the end though - it works.
We are gonna make use of window here to use as a global scope across the functions.
init: function()
{
var self = this;
self.renderPlaylist();
self.preLoadTrack();
self.highlightTrack();
self.updateTotalTime();
self.events();
self.debug();
self.domAudio.volume = 0.05;
window.jAudioCore = self; // This line returns the self
},
Now you can change the playlist accordingly, anytime, just by changing window.playlist global variable, everywhere in the code.
renderPlaylist: function()
{
var self = this,
template = "";
$.each(window.playlist, function(i, a) //added window.playlist as the parameter
Your renderPlaylist function should look the one above.
To test this here's a simple code for you to use :
(function(){
window.playlist = [
{
file: "http://192.168.1.99:5000/mpeg",
thumb: "https://i.ytimg.com/vi/Kd57YHWqrsI/mqdefault.jpg",
trackName: "Carnival Of Rust",
trackArtist: "Poets Of The Fall",
trackAlbum: "Single",
trackDuration:"04:06",
},
{
file: "http://127.0.0.1:5000/mpeg",
thumb: "https://i.ytimg.com/vi/Kd57YHWqrsI/mqdefault.jpg",
trackName: "Carnival Of Rust",
trackArtist: "Poets Of The Fall",
trackAlbum: "Single",
trackDuration:"04:06",
}
];
var t = {
playlist: [], // this is no longer needed, you can remove it from the source code later
debug:true
}
$(".jAudio").jAudio(t);
setTimeout(function(){
window.playlist.push({
file: "http://127.0.0.1:5000/mpeg",
thumb: "https://i.ytimg.com/vi/Kd57YHWqrsI/mqdefault.jpg",
trackName: "Carnival Of Rust",
trackArtist: "Poets Of The Fall",
trackAlbum: "Single",
trackDuration:"04:06",
});
window.jAudioCore.renderPlaylist(); // renders the playlists
window.jAudioCore.preLoadTrack(); // will preload the current track
window.jAudioCore.highlightTrack(); // will highlight in the css
},3000);
})();
As I said, in the end, it works dynamically without refresh. There might be some underlying bugs, I couldn't test much on this. Cheers.
so heres my folder structure for the client:
https://s3.amazonaws.com/f.cl.ly/items/0I0S063e3U0A2o2s3k21/Image%202014-12-05%20at%206.42.17%20PM.png
The problem is I have two states for tournaments... One Live and One noLive.
The use all the exact same views ect but could potentially have very different functionality.
Is there a trick were I can use two completely different controllers for the same view based on the data the view needs to load in iron router or something?
-thanks
For reference here is my:
routes.js for tourneys:
/* Tournaments / Browse section */
Router.route('/tournaments/:_id', function () {
this.fastRender = true;
// add the subscription handle to our waitlist
this.wait(Meteor.subscribe('campaigns'));
// this.ready() is true if all items in the wait list are ready
// console.log("Tournaments.findOne({_id: this.params._id}:", Campaigns.findOne({_id: this.params._id}));
if (this.ready()) {
this.render('tournament', {
data: function () {
return Campaigns.findOne({_id: this.params._id});
}
});
} else {
this.render('loading');
}
});
tournaments.js:
/* Globals */
Template.tournament.rendered = function () {
var self = this;
var participants = $('.participant-id');
var currentParticipant;
var nextRound;
var thisMatch;
var nextMatch;
var bracket;
participants.map(function(index, value){
if ($(value).text() === Meteor.userId()) {
if ($(value).parent().find('.participant-status').text() === 'undetermined') {
nextRound = $(value).parent().find('.participant-round').text();
thisMatch = $(value).parent().find('.participant-match').text();
bracket = $(value).parent().parent().parent().find('.participant');
};
};
});
nextRound = parseInt(nextRound) + 1;
nextMatch = Math.round(parseInt(thisMatch)/2) - 1;
if (parseInt(thisMatch) % 2 != 0) {
currentParticipant = 0;
}else{
currentParticipant = 1;
}
var winnerOptions = '';
var winnerBox = $('<div class="select-winner">');
bracket.map(function(index, value) {
winnerOptions += '<span class="winner-option"> '+$(value).find('.participant-title').text()+' <div class="winner-info"> '+$(value).find('a').html()+' </div> </span>'
});
winnerBox.append(winnerOptions);
$($($('.round'+nextRound).find('li')[nextMatch]).find('.participant')[currentParticipant]).removeClass('loser').addClass('undetermined');
$($($('.round'+nextRound).find('li')[nextMatch]).find('.participant')[currentParticipant]).find('a').addClass('tooltip').html(winnerBox);
var tournamentStartTime = function(){
var d = new Date();
var n = d.getTime();
var currentTime = TimeSync.serverTime(n);
var startTime = self.data.card.startTime;
var difference = startTime - currentTime;
var hoursDifference = Math.floor(difference/1000/60/60);
difference -= hoursDifference*1000*60*60
var minutesDifference = Math.floor(difference/1000/60);
difference -= minutesDifference*1000*60
var secondsDifference = Math.floor(difference/1000);
/* if ends (make tournament live server side?) */
if (hoursDifference < 0 || minutesDifference < 0 || secondsDifference < 0) {
Meteor.clearInterval(tStartTime);
Session.set("tournamentStartTime", false);
}else{
if (hoursDifference < 10) {hoursDifference = "0"+hoursDifference;}
if (minutesDifference < 10) {minutesDifference = "0"+minutesDifference;}
if (secondsDifference < 10) {secondsDifference = "0"+secondsDifference;}
var formattedTime = hoursDifference + ':' + minutesDifference + ':' + secondsDifference;
Session.set("tournamentStartTime", formattedTime);
}
};
Session.set("tournamentStartTime", '00:00:00');
tournamentStartTime();
var tStartTime = Meteor.setInterval(tournamentStartTime, 1000);
};
Template.tournament.events({
// Select winner from 2 options in tooltip
// Then previous round is given winner class on correct person
'click .winner-option': function(event){
// var self = $(event.target)
// var winner = self.text()
// self.parent().hide()
// self.closest('.participant').removeClass('undetermined')
// self.parent().siblings('.participant-title').text(winner)
// var classes = self.closest('ul').prev().attr('class')
// $('.' + classes.substring(0, classes.indexOf(' ')) + ' .participant-title').each(function() {
// if ($(this).text() === winner) {
// $(this).parent().parent().removeClass('loser').addClass('winner')
// }
// // else {
// // $(this).parent().parent().removeClass('winner').addClass('loser')
// // }
// });
// // $(.previousULClass .
$('#theaterMode').show();
}
});
Template.tournament.helpers({
round: function() {
var tournament = this.tournament.brackets;
var rounds = tournament.length;
var results = [];
tournament.map(function(value, index){
var currentRound = index + 1;
results.push({rounds: rounds, currentRound: currentRound, matches: value});
});
// console.log("results:", results);
return results;
},
match: function(){
// console.log("matches:", this.matches);
return this.matches;
},
participant: function(){
var results = [];
// console.log("this:", this);
this.map(function (value, index) {
// console.log("value, index:", value, index);
var type = value['win'];
var obj = {
id: value['id'],
rank: value['id'].slice(0,3),
displayName: value['displayName'],
thisRound: value['round'],
thisMatch: value['match'],
status: type
};
if (type === true || type === 'undetermined') {
obj.winner = true;
}else{
obj.loser = true;
}
results.push(obj);
});
// console.log("results:", results);
return results;
},
tournamentStartTime: function(){
return Session.get('tournamentStartTime');
}
});
How do you recognize which state is current? You should post some code, routes.js, tournament.js and your view.blade, for better understanding what you really wanna do and for figure out, what the best pratice is. :)