Build up and array with variable property name - javascript

My HTML looks like this:
<label data-plural="foos" data-id="1">Foo</label>
<label data-plural="bars" data-id="2">Bar</label>
I have this code:
var commands = new Array();
$('label.ptype').each(function(k,v) {
var category = $(v).data('plural');
var cmd = 'show ' + category;
var id = $(v).data('id');
commands.push({cmd : function() { window.alert(id + " " + category); exploreId(id, category); }});
});
console.log(commands);
I would like to have in the commands array:
[
{ 'show foos': function() { window.alert('1 foos'); exploreId(1, 'foos'); },
{ 'show bars': function() { window.alert('2 bars'); exploreId(2, 'bars'); }
]
But what I am getting is literally
[ { cmd: function() ... }, { cmd: function() ... } ]
So what is a good way to build the desired array?

In ES5, you have to take apart the object construction:
var command = {};
command[cmd] = function() { window.alert(id + " " + category); exploreId(id, category); };
commands.push(command);
In ES2015, you can use [ ] notation in the object initializer:
commands.push({ [cmd] : function() { window.alert(id + " " + category); exploreId(id, category); }});
That new feature ("computed property names") is supported by Firefox and Chrome and Safari, but not Internet Explorer. (It may be in Edge but I can't find anything explicit and I'm too lazy to fire up my VM :)

For simplicity, readability and execution speed, use the [] instead of new Array();.
You can use a temporary object, an push it into commands (Works on Chrome, Firefox and IE):
var commands = [];
$('label').each(function(k,v) {
var category = $(v).data('plural');
var id = $(v).data('id');
var temp = {};
temp['show ' + category] = function() { window.alert(id + " " + category); exploreId(id, category); };
commands.push(temp);
});
console.log(commands);
console.log(commands[0]['show foos']());//run function
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label data-plural="foos" data-id="1">Foo</label>
<label data-plural="bars" data-id="2">Bar</label>
Fiddle: https://jsfiddle.net/ghorg12110/h0ekmreu/

Related

javascript error in nifi executeScript

I am having an issue getting the javascript script for the executeScript nifi process to work and would appreciate help with this. The goal is to pass a flowfile which will contain a json object. I need to parse this json without knowing the content/fields prior and pass this along to write it out to the flowfile that is being passed out to the next process that is MergeContent and counts the number flowfiles.
Tried testing the script and got the following error:
nifi.script.ExecuteScript - ExecuteScript[id=bd6842e9-e3a4-4d88-a59d-
7da1d74d109b] ExecuteScript[id=bd6842e9-e3a4-4d88-a59d-7da1d74d109b]
failed to process due to
org.apache.nifi.processor.exception.ProcessException:
javax.script.ScriptException: <eval>:21:17 Expected : but found value
let value = json[key];
^ in <eval> at line number 21 at column number 17; rolling
back session: org.apache.nifi.processor.exception.ProcessException:
javax.script.ScriptException: <eval>:21:17 Expected : but found value
I am not very familiar with javascript so would appreciate the help.
flowFile = session.get();
if (flowFile != null) {
var StreamCallback =
Java.type("org.apache.nifi.processor.io.StreamCallback");
var IOUtils = Java.type("org.apache.commons.io.IOUtils");
var StandardCharsets = Java.type("java.nio.charset.StandardCharsets");
var transformed_message = {};
var error = false;
var line = "ops_testQueue";
flowFile = session.write(flowFile, new StreamCallback(function
(inputStream, outputStream) {
var content = IOUtils.toString(inputStream,
StandardCharsets.UTF_8); // message or content
var message_content = {};
try {
message_content = JSON.parse(content);
if(Array.isArray(message_content)){
}
Object.keys(message_content).forEach((key) => {
var value = json[key];
result.push(key + '=' + value);
var jkey = "," + "\"" + key + "\"" + '=' + value
});
line = line + jkey +
" value=" + "1"
+ " " + Date.now() * 1000000;
// Write output content
if (transformed_message) {
outputStream.write(line.getBytes(StandardCharsets.UTF_8));
}
} catch (e) {
error = true;
outputStream.write(content.getBytes(StandardCharsets.UTF_8));
}
}));
if (transformed_message.post_state) {
flowFile = session.putAttribute(flowFile, "type",
transformed_message.type);
}
if (error) {
session.transfer(flowFile, REL_FAILURE)
} else {
session.transfer(flowFile, REL_SUCCESS)
}
}
EDIT:
input to executeScript:
{"pID":"1029409411108724738",
"contentType":"text",
"published":"2018-08-14 16:48:23Z",
"crawled":"2018-08-14 12:48:33-04:00",
"ID":"765"}
output from executeScript:
ops_testQueue,"ID"=765 value=1 1534265314969999870
Am I missing something?
I saw a couple of things here:
I don't know if Nashorn (Java's JS Engine) supports the full lambda
syntax, I was able to get it to work by making the lambda a function
(see script below).
You refer to a json variable to get the value from a key, but I think you want message_content.
result is not defined, so you get an error when you push to it.
Here's an edited version of your script that I got to work the way I think you want it (but please correct me if I'm wrong):
flowFile = session.get();
if (flowFile != null) {
var StreamCallback =
Java.type("org.apache.nifi.processor.io.StreamCallback");
var IOUtils = Java.type("org.apache.commons.io.IOUtils");
var StandardCharsets = Java.type("java.nio.charset.StandardCharsets");
var transformed_message = {};
var error = false;
var line = "ops_testQueue";
flowFile = session.write(flowFile, new StreamCallback(function
(inputStream, outputStream) {
var content = IOUtils.toString(inputStream,
StandardCharsets.UTF_8); // message or content
var message_content = {};
try {
message_content = JSON.parse(content);
if(Array.isArray(message_content)){
}
var jkey = "";
Object.keys(message_content).forEach(function(key) {
var value = message_content[key];
//result.push(key + '=' + value);
jkey = "," + "\"" + key + "\"" + '=' + value
});
line = line + jkey +
" value=" + "1"
+ " " + Date.now() * 1000000;
// Write output content
if (transformed_message) {
outputStream.write(line.getBytes(StandardCharsets.UTF_8));
}
} catch (e) {
error = true;
log.error(e);
outputStream.write(content.getBytes(StandardCharsets.UTF_8));
}
}));
if (transformed_message.post_state) {
flowFile = session.putAttribute(flowFile, "type",
transformed_message.type);
}
if (error) {
session.transfer(flowFile, REL_FAILURE)
} else {
session.transfer(flowFile, REL_SUCCESS)
}
}

How to refresh a div to load new record when theres new record in Database

I have a div in a page where I show a list of records which are stored in my Database ( firebase). Whenever there is a new record in the database, I want the div to auto load in the new record without refreshing the whole page. So how can I do that?
Javascript code on showing records
query.on("child_added", function(messageSnapshot) {
var keys = Object.keys(messageSnapshot);
var messageData = messageSnapshot.val();
var key = messageSnapshot.getKey();
console.log("key is " + messageSnapshot.getKey());
console.log("messagesnapshot is " + messageSnapshot);
var obj = {
key: key,
};
arr.push(obj);
ref.child(key + "/User Information").once('value').then(function(snapshot) {
var name = snapshot.val().firstName
s = "<li><a href='#'>" + no + '. ' + name + ' ' + key + "</a></li>";
no++;
sources.push(s);
// for ( property in messageSnapshot) {
// console.log( property ); // Outputs: foo, fiz or fiz, foo
//}
console.log("arr.length is " + arr.length);
}).then(function(pagination) {
Pagination();
});
});
function Pagination() {
var arrLength = arr.length;
var container = $("#mylist");
// var sources = function () {
// var result = [];
//
// for (var i = 1; i < arrLength; i++) {
// result.push(i);
// }
//
// return result;
// }();
var options = {
dataSource: sources,
pageSize: 10,
callback: function(data, pagination) {
//window.console && console.log(response, pagination);
var dataHtml = '';
$.each(data, function(index, item) {
dataHtml += item;
});
console.log(dataHtml);
container.prev().html(dataHtml);
}
};
//$.pagination(container, options);
container.addHook('beforeInit', function() {
window.console && console.log('beforeInit...');
});
container.pagination(options);
container.addHook('beforePageOnClick', function() {
window.console && console.log('beforePageOnClick...');
//return false
});
return container;
}
Html code div
<div data-role="page" id="pageone">
<div data-role="header">
<button onclick="goBack()">Back</button>
<h1>Pending Transaction</h1>
</div>
<div id="mylist"></div>
</div>
At first your local code must be aware of changes in the Database, so the plain answer is:
Your JS-Code must periodically ask your DB for changes, if changes are available you can call that changes and update your content via an AJAX-Request and put it into the div#mylist
This "periodically ask" is called long polling, aspnet has for example the framework called SignalR

Proper approach for complex / nested JavaScript-object creation within another object

The following code is meant to be a short example for a simple construct of a reusable object. This is a very simple, one level depth object, put as many props and methods as you like and just assign them.
function someDesiredReusableType(optionally, pass, ctor, pars, here) {
//core obj to return
var DesiredTypeCrtor = {
propSkiingLocation: "canada",
OrderTickets: function(optionally){
var tryRoomWView = optionaly;
print(
"Dear " + ctor +", your request for " +
propSkiingLocation + " is now being processed: an " +
tryRoomWView + " request was notified, we understand you have " + pars + " for cross country transportation, confirmation email will be sent " + here + " as soon as we process your order. }
}
};
return DesiredTypeCrtor
}
Here is an example of this use:
var DesrVacSkC = someDesiredReusableType("could really help!",null, "mr. Bean", "my mini", "Fun#bbc.co.uk")
//oh..almost forgot
DesrVacSkC.OrderTickets();
As this imaginative object, is actually not as simple as I did use in my code, it does work as is (didn't try this actual one, as it's just an example.)
But this next setup that is similarly using the same approach is buggy somewhat.
This is an example for an object I have successfully and in a blink of an eye implemented as a nested object using the exact same approach as the buggy object, which I do not understand why they Applied the not with same approach by the browser.
//this is an important one, a smart property / value holder I came up with and does work perfectly, as a nested member.
function Rprp(parVal) {
var cretdprp = {
propVal: parVal,
propValAsint: parseInt(parVal)
};
return cretdprp;
}
But the next one, here below, does not, as it lacks the proper approach for the initialization of ownedFefCollCore
Uncaught TypeError: Cannot read property 'HElmTColl' of undefined
//this is an important one, that was started as a very good one, with adding it to the object below, up until I have added ownedFefCollCore member.
function CreateFileEditForm_Manager() {
//as i do usually base/inner/creator and a return obj
var Repo = {
CsDataLocals:
{
GetCurLastfileId:Rprp($("#HLocModelData_LastFileId").val())
},
FormFldNames:
{ JRdrData_FileName: "JRdrData_FileName" },
//this is my bugg ! with and without new keyword & as function or Object!!
ownedFefCollCore: new FefCollCore(),
//and this is the line that chrome get's is anger on --> all day long
FeFDivWFldsColl: this.ownedFefCollCore.HElmTColl,
FeFDivWFlds_IdColl: this.ownedFefCollCore.HElmT_IdColl,
FeFDivWFldsCollAdd: function (parId, parFefDivWrpDivflds) {
this.ownedFefCollCore.CollAdd(parId, parFefDivWrpDivflds);
},
/ ........
//some more code was removed trying to keep it as short as possible
}
//fefa stands for fileRecord Edit Form , core just says nothing, is there to imply the 'thing' is to be shared between variation of instances from the base object
I found the following approach in my research for less error prone constructs, but even this one does not correct the bug. And it was found among some others, such as this Object.create()
var FefCore = JClassProto({
initialize: function () {
this.HElmTColl = new Array();//was originally [] ...
//i changed because i wanted to eliminate any doubt that it's one of the reasons my code is ... Somewhere undefined , now i know (pretty sure they might be little different but both are ok.) it's not it.
this.HElmT_IdColl = new Array();
this.CollAdd = function (parId, parHElmT) {
this.HElmTColl.push(parHElmT);
this.HElmT_IdColl.push(parId);
}
this.Coll_Remove = function (parHElmT) {
this.HElmTColl.pop(parHElmT);
}
// this is the first move, if a new object(which is an element in the array) about to be created,
// call this to make sure not exist for i create do
this.ElmObjCanCreate = function (parId) {
return this.getIndexOfValuInDivWFldsColl(parId) < 0;
}
this.HElmTColl_FindById = function (parId) {
var collindexofCurFileReadyDivWrpFlds = this.getIndexOfValuInDivWFldsColl(parId);
return this.HElmTColl[collindexofCurFileReadyDivWrpFlds];
}
this.getIndexOfValuInHElmTColl = function (parId) {
return $.inArray(parId, this.HElmT_IdColl);
}
}
});
And last but not least, my original code (right after the attempt to create it as a base /shared object).
function FefCollCore() {
this.Cr = {
HElmTColl: new Array(),
HElmT_IdColl: new Array(),
CollAdd: function (parId, parHElmT) {
this.HElmTColl.push(parHElmT);
this.HElmT_IdColl.push(parId);
},
Coll_Remove: function (parHElmT) {
this.HElmTColl.pop(parHElmT);
},
CollNeedCreate: function (parId) {
return this.getIndexOfValuInDivWFldsColl(parId) < 0;
},
HElmTColl_FindById: function (parId) {
var collindexofCurFileReadyDivWrpFlds = this.getIndexOfValuInDivWFldsColl(parId);
return this.HElmTColl[collindexofCurFileReadyDivWrpFlds];
},
getIndexOfValuInHElmTColl: function (parId) {
return $.inArray(parId, this.HElmT_IdColl);
}
};
return this.Cr;
}
//and this is the line that chrome get's is anger on --> all day long
FeFDivWFldsColl: this.ownedFefCollCore.HElmTColl,
If interpret Question correctly, you could try to set FeFDivWFldsColl as a function that returns this.ownedFefCollCore.HElmTColl
var FefCore = function() {
this.e = new Array();
this.e.push(2);
}
function CreateFileEditForm_Manager() {
var Repo = {
a: 0,
b: 1,
c: new FefCore(),
// set `FeFDivWFldsColl` value as a function
d: function() {
// `this.c` : `new FefCore()` , `this.c.e` : `new Array()`
return this.c.e
}
};
return Repo
}
var Fef = new CreateFileEditForm_Manager();
console.log(Fef.d())
var cont = "...see console";
var DivEmptyhtml = document.createElement('div');
var elmst = document.createElement('style');
function stringcss (){
return ".cssEmptyhtml{ \r\n\tmargin:auto; margin-top:10px; margin-bottom:20px;"+
" text-align:center; top:10px;"+
" width:40%; padding: 5px; height: 100px; " +
"background-color:rgb(96,116,243); "+
"color: #B5fee8; "+
"background-image:" +
" linear-gradient(to right bottom, #2983bC 24%, #284a4b 77%);"+
" box-shadow: 8px 10px 50px 20px rgb(55, 55, 55); "+
" -webkit-border-radius:10px;border-radius:10px; }";
}
//elmst.innerHTML = stringcss();
DivEmptyhtml.innerHTML = cont;
DivEmptyhtml.className = "cssEmptyhtml";
DivEmptyhtml.attributes["id"] ="DivEmptyhtml";
$("head").append(elmst);
$("body").append(DivEmptyhtml);
$(elmst).attr("id","elmst");
//$(".cssEmptyhtml").attr("style",stringcss());
$(elmst).text(stringcss());
var strS, strF, message;
var indx = 123;
var count = 135;
indx = ++count - 1;
var init = true;
//now me
var programSteps = 0;
var starting = "starting";
console.log(starting);
function Log(strLine) {
var d = new Date,
DS = d.getSeconds(),
Dms = d.getMilliseconds().toString();
console.log("[step#" + (++programSteps) + "] " + DS + "." + Dms.substring(0, 2) + "> " + strLine);
}
//...see console
function LogObj(p_type) {
function Fnl_t_t() {
this.obj = "\r\n\t\t";
}
function Fnl_5xt() {
this.obj = "\r\n\t\t\t\t";
}
var obj = {
doNewLineBold: function(boolPrint, value, value2, value3, value4) {
var nlttcopy = this.backnl_t_t.obj;
this._nl_t_t = lnobj1.backnl_5xt.obj+ "|========> [ " + value;
this._nl_t_t += value2 != "" ? " " + value2 : "";
this._nl_t_t += value3 != "" ? " " + value3 : "";
this._nl_t_t += value4 != "" ? " " + value4 : "";
this._nl_t_t += " ] <=============|" + nlttcopy;
if (boolPrint) {
Log(this._nl_t_t);
return "";
} else return this._nl_t_t;
},
doLineBold: function(boolPrint, value, value2, value3, value4) {
var nlttcopy = this.backnl_t_t.obj;
this._nl_t_t = "|========> [ " + value;
this._nl_t_t += value2 != "" ? " " + value2 : "";
this._nl_t_t += value3 != "" ? " " + value3 : "";
this._nl_t_t += value4 != "" ? " " + value4 : "";
this._nl_t_t += " ] <=============|" + nlttcopy;
if (boolPrint) {
Log(this._nl_t_t);
return "";
} else return this._nl_t_t;
},
_type: {
val: p_type,
formated: ""
},
doformatedHeader: function() {
var splts = this._type.val.split(' ');
for (var i = 0; i < splts.length; i++) {
this._type.formated += splts[i] + this.ErowR;
}
return "|========> [ " + this._type.formated +
" ] <=============|" + this.backnl_5xt.obj;
},
doformatedTail: function() {
return this.backnl_5xt.obj + "|========> [ END_ " + this._type.formated + "_END] <=============|" + this.backnl_t_t.obj;
},
_nl_t_t: function() {
return "\r\n\t\t";
},
backnl_5xt: new Fnl_5xt(),
backnl_t_t: new Fnl_t_t(),
ErowR: ">",
nlArowR : new Fnl_5xt().obj + ">"
};
return obj;
}
var lnobj1 = LogObj("listWcounter1() arr"); //create object #1
var lnobj2 = LogObj("listWcounter2() arr"); //make sure #2 is not a-copy
var header1 = lnobj1.doformatedHeader();
var Tail1 = lnobj1.doformatedTail();
var header2 = lnobj2.doformatedHeader();
var Tail2 = lnobj2.doformatedTail();
var nlarowR1 = lnobj1.backnl_5xt.obj + lnobj1.ErowR;
var nlarowR2 = lnobj2.backnl_t_t.obj + lnobj2.ErowR;
Log(header1 + lnobj1.ErowR + " starting1... " + nlarowR1 + " is init1 ok?, and index1 is Ok? " + indx + Tail1);
Log(header2 + lnobj2.ErowR + " starting2... " + nlarowR1 + " is init2 ok?, and index2 is Ok? " + indx + Tail2);
var newbold = lnobj1.doLineBold(0, "a", "b", "c", "d") + lnobj1.backnl_5xt.obj;
Log("newbold looks Like: " + newbold);
lnobj1.doLineBold(1, "A", "B", "C", "D");
lnobj1.doNewLineBold(1, "e", "f", "g", "h");
Log(lnobj1.nlArowR);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

JSON.stringify fails on a newly created object (node, javascript)

Ok, this one has to be a very easy question, but I just started learning node. I am also new to javascript, so, please show no mercy on pointing out wrong directions below.
In particular I have two files:
one has a class that creates some slave servers in different ports
the other one is the "main" file that generates the slaves
When I attempt to print out what I have just initialized I get two weird errors:
connections property is deprecated. Use getConnections() method, and then
it crashes when I attempt to apply JSON.stringify in the new object (Converting circular structure to JSON)
Code for slaves in file "slave.js":
var http = require ("http");
function Slave () {
}
Slave.prototype.ID = undefined;
Slave.prototype.coordinator = false;
Slave.prototype.httpServer = undefined;
Slave.prototype.thePort = undefined;
Slave.prototype.isCoordinator = function () { return this.coordinator; }
/*****************************************************************/
function handle_incoming_request (req, res) {
console.log("INCOMING REQUEST: " + req.method + " " + req.url);
res.writeHead (200, { "Content-Type" : "application/json" });
res.end( JSON.stringify({ "error" : null }) + "\n" );
}
exports.createSlave = function (id, coordinatorK, port) {
var temp = new Slave ();
temp.ID = id;
temp.coordinator = coordinatorK;
temp.thePort = port;
temp.httpServer = http.createServer(handle_incoming_request);
temp.httpServer.listen (temp.thePort);
console.log ("Slave (" + (temp.isCoordinator() ? "coordinator" : "regular") + ") with ID " + temp.ID + " is listening to port " + temp.thePort);
console.log ("--------------------------------------------");
return temp;
}
Now, the main file.
var http = require ("http");
var url = require ("url");
var a = require ("./slave.js");
var i, temp;
var myArray = new Array ();
for (i = 0; i < 4; i++) {
var newID = i + 1;
var newPort = 8000 + i + 1;
var coordinatorIndicator = false;
if ((i % 4) == 0) {
coordinatorIndicator = true; // Say, this is going to be a coordinator
}
temp = a.createSlave (newID, coordinatorIndicator, newPort);
console.log ("New slave is : " + temp);
console.log ("Stringified is: " + JSON.stringify(temp));
myArray.push(temp);
}
You're trying to stringify the result of http.createServer(...). That'll not be what you want to do, so when you create that property, make it non-enumerable by defining it using Object.defineProperty().
exports.createSlave = function (id, coordinatorK, port) {
var temp = new Slave ();
temp.ID = id;
temp.coordinator = coordinatorK;
temp.thePort = port;
Object.defineProperty(temp, "httpServer", {
value: http.createServer(handle_incoming_request),
enumerable: false, // this is actually the default, so you could remove it
configurable: true,
writeable: true
});
temp.httpServer.listen (temp.thePort);
return temp;
}
This way JSON.stringify won't reach that property curing its enumeration of the object.
Issue is the with the property httpServer of temp object having circular reference. You can either set it non enumerable using Ecmascript5 property definision as mentioned in the previous answer or you can use the replacer function of JSON.stringify to customize it not to stringify the httpServer property.
console.log ("Stringified is: " + JSON.stringify(temp, function(key, value){
if(key === 'httpServer') return undefined;
return value;
}));

Swapping out an array (nested?) for values from an XML doc (client side scripting only)

I'm an absolute newbie with javascript, but I'm just trying to tweak JPlayer to use an XML file for the playlist instead of the hard-coded playlist. So, here's the bit of code that creates the playlist:
//<![CDATA[
$(document).ready(function(){
var Playlist = function(instance, playlist, options) {
var self = this;
this.instance = instance; // String: To associate specific HTML with this playlist
this.playlist = playlist; // Array of Objects: The playlist
this.options = options; // Object: The jPlayer constructor options for this playlist
this.current = 0;
this.cssId = {
jPlayer: "jquery_jplayer_",
interface: "jp_interface_",
playlist: "jp_playlist_"
};
this.cssSelector = {};
$.each(this.cssId, function(entity, id) {
self.cssSelector[entity] = "#" + id + self.instance;
});
if(!this.options.cssSelectorAncestor) {
this.options.cssSelectorAncestor = this.cssSelector.interface;
}
$(this.cssSelector.jPlayer).jPlayer(this.options);
$(this.cssSelector.interface + " .jp-previous").click(function() {
self.playlistPrev();
$(this).blur();
return false;
});
$(this.cssSelector.interface + " .jp-next").click(function() {
self.playlistNext();
$(this).blur();
return false;
});
};
Playlist.prototype = {
displayPlaylist: function() {
var self = this;
$(this.cssSelector.playlist + " ul").empty();
for (i=0; i < this.playlist.length; i++) {
var listItem = (i === this.playlist.length-1) ? "<li class='jp-playlist-last'>" : "<li>";
listItem += "<a href='#' id='" + this.cssId.playlist + this.instance + "_item_" + i +"' tabindex='1'>"+ this.playlist[i].name +"</a>";
// Create links to free media
if(this.playlist[i].free) {
var first = true;
listItem += "<div class='jp-free-media'>(";
$.each(this.playlist[i], function(property,value) {
if($.jPlayer.prototype.format[property]) { // Check property is a media format.
if(first) {
first = false;
} else {
listItem += " | ";
}
listItem += "<a id='" + self.cssId.playlist + self.instance + "_item_" + i + "_" + property + "' href='" + value + "' tabindex='1'>" + property + "</a>";
}
});
listItem += ")</span>";
}
listItem += "</li>";
// Associate playlist items with their media
$(this.cssSelector.playlist + " ul").append(listItem);
$(this.cssSelector.playlist + "_item_" + i).data("index", i).click(function() {
var index = $(this).data("index");
if(self.current !== index) {
self.playlistChange(index);
} else {
$(self.cssSelector.jPlayer).jPlayer("play");
}
$(this).blur();
return false;
});
// Disable free media links to force access via right click
if(this.playlist[i].free) {
$.each(this.playlist[i], function(property,value) {
if($.jPlayer.prototype.format[property]) { // Check property is a media format.
$(self.cssSelector.playlist + "_item_" + i + "_" + property).data("index", i).click(function() {
var index = $(this).data("index");
$(self.cssSelector.playlist + "_item_" + index).click();
$(this).blur();
return false;
});
}
});
}
}
},
playlistInit: function(autoplay) {
if(autoplay) {
this.playlistChange(this.current);
} else {
this.playlistConfig(this.current);
}
},
playlistConfig: function(index) {
$(this.cssSelector.playlist + "_item_" + this.current).removeClass("jp-playlist-current").parent().removeClass("jp-playlist-current");
$(this.cssSelector.playlist + "_item_" + index).addClass("jp-playlist-current").parent().addClass("jp-playlist-current");
this.current = index;
$(this.cssSelector.jPlayer).jPlayer("setMedia", this.playlist[this.current]);
},
playlistChange: function(index) {
this.playlistConfig(index);
$(this.cssSelector.jPlayer).jPlayer("play");
},
playlistNext: function() {
var index = (this.current + 1 < this.playlist.length) ? this.current + 1 : 0;
this.playlistChange(index);
},
playlistPrev: function() {
var index = (this.current - 1 >= 0) ? this.current - 1 : this.playlist.length - 1;
this.playlistChange(index);
}
};
var mediaPlaylist = new Playlist("1", [
{
name:"song1",
mp3: "song1.mp3",
poster: "http://www.jplayer.org/video/poster/Incredibles_Teaser_640x272.png"
},
{
name:"song2",
mp3: "song2.mp3",
poster: "http://www.jplayer.org/video/poster/Incredibles_Teaser_640x272.png"
},
{
name:"song3",
mp3: "song3.mp3",
poster: "http://www.jplayer.org/video/poster/Incredibles_Teaser_640x272.png"**
}
], {
ready: function() {
mediaPlaylist.displayPlaylist();
mediaPlaylist.playlistInit(false); // Parameter is a boolean for autoplay.
},
ended: function() {
mediaPlaylist.playlistNext();
},
swfPath: "js",
supplied: "ogv, m4v, oga, mp3"
});
});
The part that starts with "var mediaPlaylist" is the only section i need to change. Instead of having the keys/values as name: songname, mp3: mp3, etc., I want it to pull these values from an XML file, or better yet, just push them into the array from an XML that looks like:
<song>songname</song>
<mp3>file.mp3</mp3>
The thing that's mostly confusing me here is how that function/array is set up...too many curly braces and brackets to wrap my head around. How do I get into this without breaking it?
If you have a server side XML playlist file in the form:
<?xml version="1.0" encoding="UTF-8"?>
<playlist>
<entry>
<song>songname</song>
<mp3>file.mp3</mp3>
</entry>
<entry>
<song>songname2</song>
<mp3>file2.mp3</mp3>
</entry>
</playlist>
then you can load this from the client via AJAX and create a JSON array from the XML. The following example uses the jQuery JavaScript framework and also the jquery-json plugin (only to format the Array nicely as JSON). You should be able to run this on Chrome or Firefox as both have a console (accessed by pressing F12 in the browser) in which I am outputting the JSON array.
Note: You could change console.log(...) to alert(...) if you don't use either of those browsers.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript" src="http://jquery-json.googlecode.com/files/jquery.json-2.2.min.js"></script>
<script type="text/javascript">
$(function() {
var Playlist = function(instance, playlist, options) {
var self = this;
this.instance = instance;
this.playlist = playlist;
this.options = options;
};
function getPlaylist(callback) {
var songs = new Array();
$.ajax({
dataType:'xml',
url:'songs.xml',
success : function (xml) {
$(xml).find('entry').each(function() {
songs.push({name: $(this).find('song').text(), mp3: $(this).find('mp3').text()});
});
callback(songs);
}
});
}
getPlaylist(function(songs) {
var playlistFromXML = jQuery.toJSON(songs);
var mediaPlaylist = new Playlist('1', playlistFromXML, null);
console.log(mediaPlaylist);
// etc...
});
});
</script>
</head><body></body></html>
Credit to How to return an array from jQuery ajax success function properly? answer as I used that approach to return a value from the jQuery $.ajax success method.
You will have to refactor the var mediaPlaylist = new Playlist() constructor into the callback function though as you cannot return the playlist value from the callback (see How can I catch the return value from the result() callback function that I'm using?)
Hope this helps :-)

Categories