Jplayer not changing track - jplayer

Having an issue with Jplayer changing a track when a link is clicked. It still plays the demo track from the player and doesn't play harry.mp3 or harry2.mp3
<tr><td>Tracklist:</td></tr>
<script>$('#mp31').click(function()
`{ $("#jp-player").jPlayer({ ready: function () { $(this).jPlayer("setMedia", { mp3: "/harry.mp3", }); }, swfPath: "/js", supplied: "mp3" }); });` </script>
<tr><td>1. </td><td>TestFriend</a> (Techno)</td></tr>
<script>$('#mp32').click(function(){ $("#jp-player").jPlayer({ ready: function () { $(this).jPlayer("setMedia", { mp3: "/harry2.mp3", }); }, swfPath: "/js", supplied: "mp3" }); }); </script><tr><td>2. </td><td>TestEnemy</a> (Ambient)</td></tr>
Can anyone please help, it's doing my head in.
CP

You have two instances of jplayer. According to your scenario, you should have only one. Also, take care of your typos. Finally, you could try with something like this:
<tr>
<td>Tracklist:</td>
</tr>
<tr>
<td>1.</td>
<td><a class="song" href="http://my-website.com/mp31.mp3" id="mp31">Test</a>Friend</a> (Techno)</td>
</tr>
<tr>
<td>2.</td>
<td><a class="song" href="http://my-website.com/mp32.mp3" id="mp32">Test</a>Enemy</a> (Ambient)</td>
</tr>
The code above show you a list of <a> elements with the mp3 url that you want to play, so, by this way yo can update the player once the click them:
<script>
$("#jp-player").jPlayer({
ready: function () {
$(this).jPlayer("setMedia", {
mp3: "/harry.mp3"
});
},
swfPath: "/js", supplied: "mp3"
});
$('.song').click(function (e) {
e.preventDefault();
// get the song url from the href attribute
var song = $(this).attr('href');
$("#jp-player").jPlayer({
ready: function () {
$(this).jPlayer("setMedia", {
mp3: song
});
},
swfPath: "/js", supplied: "mp3"
});
});
</script>

Related

Node js for loop unable to access variable it print undefiend

I am using Node js and use sendmail function
i declare variable htmlVal i try to access outside but it print undefiend only
function myFunction(){
var htmlVal;
Report.find({}, function (err, reports) {
if (err) return res.status(500).send("There was a problem finding the users.");
for(let reportData of reports){
User.find({name:reportData.name}, function (err, users) {
if (err) return res.status(500).send("There was a problem finding the users.");
for (let item of users) {
htmlVal = `<table width="100%" cellpadding="2" cellspacing="0" style="border-style:solid; border-width:1px; border-color:#000000;">
<tr width="100%" cellpadding="2" cellspacing="0">
<th style="text-align:center; border:1px solid #000; padding:10px;border-right:1px solid #000">Name</th>
</tr>
<tr width="100%" cellpadding="2" cellspacing="0">
<td style="text-align:center;padding:10px;border:1px solid #000">`+item.name+`</td>
</tr>
</table>`;
}
});
}
});
console.log(htmlVal);
const sendmail = require('sendmail')({
silent:true, 
})
sendmail({
from: 'mymail#gmail.com',
to: 'mymail#gmail.com',
subject: 'Attendance of the Day',
html: htmlVal
}, function(err, reply) {
console.log(err && err.stack);
console.dir(reply);
})
}
I am using this htmlVal for send email but it send empty only
because i am unable to access htmlVal outside
how to access it outside
You need something like this.
let htmlVal;
async.series([
function(callback) {
Report.find({}, function (err, reports) {
if (err) return res.status(500).send("There was a problem finding the users.");
async.eachSeries(reports, function (value, key, callbackFE) {
User.find({name:value.name}, function (err, users) {
if (err) return res.status(500).send("There was a problem finding the users.");
for (let item of users) {
htmlVal = `<html></html`;
}
callbackFE();
});
}, function (err) {
if (err) console.error(err.message);
callback(null, htmlVal);
});
});
}], function(err, htmlVal) {
console.log(htmlVal);
const sendmail = require('sendmail')({
silent:true,
})
sendmail({
from: 'mymail#gmail.com',
to: 'mymail#gmail.com',
subject: 'Attendance of the Day',
html: htmlVal
}, function(err, reply) {
console.log(err && err.stack);
console.dir(reply);
});
});
The main issue you're encountering is that Report.find is an async function, as well as User.find, but you're sending your email synchronously.
Or in other words you're sending the email before the report is rendered.
In this case, since you have a second async query and loop inside of Report.find you're probably going to want to use the async library and then compose your async methods together.
Read about the eachSeries function and then render your html inside of the Reports.find callback instead of immediately after calling Report.find.
If my understanding is correct, you are using the variable htmlVar even before a value is getting assigned to it.
sendmail function will get called before the value is assigned to htmlVar because Report.find is a asynchronous function. Either you need to move the sendmail function call inside the callback function or use async/await.

implement voting system using node.js, mongodb and ejs

I'm pretty new to node.JS and ejs. I have searched how to implement real-time voting system like Stackoverflow voting using the mentioned technology. But I don't have any Idea how to do it.
here is my front-end code:
<% for (var i = 0; i < gamePasses.length; i++) {%>
<form dir="ltr">
<tr>
<td>
<%= i + 1 %>
</td>
<td>
<%= gamePasses[i].teamName %>
</td>
<td>
<%= gamePasses[i].password %>
</td>
<td>
<%= gamePasses[i].votes %>
</td>
<td onclick="vote('<%= gamePasses[i].password %>')">
<i class="material-icons">
thumb_up
</i>
</td>
</tr>
</form>
<% } %>
<script>
function vote(pass) {
$.post('/user/vote/' + pass)
}
function passSubmit() {
$.post('/user/gamePassword', {
gamePassword: $('#password').val()
}).done(() => {
window.location.assign('/user/scoreboard')
})
}
</script>
back-end code:
uter.post('/vote/:gamePassword', (req, res) => {
gamePassword = req.params.gamePassword;
gamePassModel.find({password: gamePassword}, (err, result) => {
if (err) console.log(err)
else {
result.votes += 1
result.save((err) => {
if (err) console.log(err)
})
}
})
})
This code problems are:
Doesn't support real-time voting
each user can votes many times
I will be thankful if anyone could help me
For prohibit multiple vote from the same user, you can think something like this. Didn't test it but the logic should works.
uter.post('/vote/:gamePassword', (req, res) => {
gamePassword = req.params.gamePassword;
//you can retrieve the voter id the way you want (in this case I assumed the query string contains it)
let voterId = req.query.voterId
gamePassModel.find({password: gamePassword}, (err, result) => {
if (err) console.log(err)
else {
//votes in not a number anymore. Now it's an array of IDs, you have to change the model (in Mongoose, I suppose)
if(~result.votes.indexOf(voterId)) {
result.votes.push(voterId)
//I'm pretty sure you cannot call save() like you do on this object, but this is not part of the question here, check the mongoose docs
result.save((err) => {
if (err) res.json({error:err});
})
} else res.json({ error: "you already voted" });
}
})
})
Now when you want to get the total vote of something, you have to make a count query (still assuming mongodb/mongoose https://mongoosejs.com/docs/api.html#model_Model.count)

Trying to get data to display in a table

I'm working on my first node project using express and sequelize, and I'm not understanding how the page rendering works
I have the following function in my one of my models(sequelize):
getGreetings: function (req, res) {
Greeting.findAll({
}).then(function (data) {
console.log('Returned data for greetings: ' + data);
res.send({greetings:data});
})
}
Here is my route:
var Greeting = require('../models/greetings');
router.get('/', function(req, res) {
res.render('index', function(){
Greeting.getGreetings(req, res);
});
});
and my ejs table I want to display the data in:
<tbody>
<% for(var i=0; i < greetings.length; i++) { %>
<tr>
<td><%= greetings[i].name %></td>
<td><%= greetings[i].message %></td>
</tr>
<% } %>
</tbody>
This isn't displaying any of the html, but rather echoing out the json data. Can someone help explain why my html table isn't being populated?
but rather echoing out the json data.
This is because getGreetings() is always setting that as the response, by using res.send():
res.send({greetings:data});
To provide greetings to your view, you'll have to instead provide the data within the locals given to res.render():
res.render('index', { greetings: data });
The two methods don't cooperate with each other. Each is defined to end the response itself, so you'll only be able to use one per response.
If you revise getGreetings to return the promise created by .findAll():
getGreetings: function (req) {
return Greeting.findAll({
// ...
});
}
Then, the route handler can bind to it and decide how to make use of the result itself – whether it should use res.send() or res.render():
var Greeting = require('../models/greetings');
router.get('/', function(req, res) {
Greeting.getGreetings(req).then(function (greetings) {
res.render('index', { greetings: greetings });
});
});

Need help using EJS

I am exploring the use of the EJS templating system and am unsure of how to use it to get SQL data to be available to be rendered in a view.
In my app.js I have something like this:
conn.query("select name,age from people", function(err, people, moreResultSets) {
for (var i=0;i<people.length;i++){
console.log(people[i].NAME, "\t\t", people[i].AGE);
}
conn.close(function(){
console.log("Connection Closed");
});
});
And I have the following code to route the proper view:
app.get('/test1', function(req, res) {
res.render('pages/test1');
})
My confusion lies in making the people data available from the query
statement to be rendered in the view. All of the examples I have seen
have the variables defined locally inside the app.get code block and I
am unclear how to jump from that to my situation.
Thank you for any assistance you can provide!
-Andy
Render after you have the data.
app.get('/test1', function (req, res) {
conn.query("select name,age from people", function (err, people, moreResultSets) {
res.render('pages/test1', {
people: people
});
conn.close(function () {
console.log('Connection Closed');
});
});
});
HTML
<% if (people) { %>
<% for (var i = 0; i < people.length; i++) { %>
<div><%= people[i].name %></div>
<% } %>
<% } else { %>
<div>No people found</div>
<% } %>

NodeJS and socket.io chat customization

I have a basic chat system working with NodeJS, express, and socket.io. Now I want to have the server insert the date into the chat stream every 5 seconds. Since this isn't initiated by the user, I am having trouble with the basic request. I am new to NodeJS and maybe it is just a syntax thing that I don't understand. Anyways, with this current code, the date only gets inserted after someone sends a chat message through. I want this to happen automatically on the server side. If no one is chatting, the date will still come through to the client every 5 seconds. My problem most likely stems from the comment section title: "How do I get my periodic timer in here..." Instead I am trying to insert it at the bottom where it says - "//***This section sends out the notification..." Do I structure the functions differently or something? Thanks in advance.
Server.js
var express = require('express'),
app = express()
, http = require('http')
, server = http.createServer(app)
, io = require('socket.io').listen(server);
// listen for new web clients:
server.listen(8080);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
app.get('/sio/socket.io.js', function (req, res) {
res.sendfile('/root/nodejs/node-v0.10.0/node_modules/socket.io/lib/socket.io.js');
});
//How do I get my periodic timer in here so it can send the date every 5 seconds?
io.sockets.on('connection', function (socket) {
socket.on('sendMessage', function (data) {
socket.broadcast.emit('message', data);
socket.emit('message', { text: '<strong>'+data.text+'</strong>' });
});
});
// Periodic Running
var coolerInterval = function(func, interval, triggerOnceEvery) {
var startTime = new Date().getTime(),
nextTick = startTime,
count = 0;
triggerOnceEvery = triggerOnceEvery || 1;
var internalInterval = function() {
nextTick += interval;
count++;
if(count == triggerOnceEvery) {
func();
count = 0;
}
setTimeout(internalInterval, nextTick - new Date().getTime());
};
internalInterval();
};
coolerInterval(function() {
showdate = new Date().getTime();
console.log( showdate );
//Go ahead and send a notification to everyone.
//***This section sends out the notification that a pick was made
io.sockets.on('connection', function (socket) {
socket.on('sendMessage', function (data) {
socket.broadcast.emit('message', showdate);
});
});
//***End sending out notification.
}, 1000, 5);
//End Periodic
Here is the html in the browser - index.html
<html>
<body>
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
var socket = io.connect('http://dev.mysite.com:8080');
socket.on('message', function (data) {
$('#chat').append(data.text + '<br />');
});
$('#send').click(function () {
socket.emit('sendMessage', { text: $('#text').val() });
$('text').val('');
});
});
</script>
<div id="chat" style="width: 500px; height: 300px; border: 1px solid black">
</div>
<input type="text" name="text" id="text">
<input type="button" name="send" id="send" value="send">
</body>
</html>
It's much simpler than you're making it. You can just setInterval() to 5 seconds, and call io.sockets.emit(), which will send the message to all connected sockets.
setInterval(function() {
io.sockets.emit('message', (new Date()).getTime());
}, 5000);
Do this on line 18, and delete everything below there.

Resources