I was wondering how to add a album cover on my spotify-app?
With this code I can reveal the album title, but how can I show the album cover!?
function updatePageWithAlbumName() {
var header = document.getElementById("album");
// This will be null if nothing is playing.
var playerTrackInfo = sp.trackPlayer.getNowPlayingTrack();
if (playerTrackInfo == null) {
header.innerText = "Geen album!";
} else {
var track = playerTrackInfo.track;
header.innerText = track.album.name;
}
}
Please don't use any of the sp. APIs - they're private and going away soon.
The public API is documented here: http://developer.spotify.com/download/spotify-apps-api/preview/reference/
You can show an album cover like this:
<img src="[cover URI]">
Edit: To get the cover URI of the current track:
var sp = getSpotifyApi(1);
var models = sp.require('sp://import/scripts/api/models');
var currentTrackCoverUri = models.player.track.album.cover;
I would like to point out that the property seems to be called "image" and not "cover".
So the snippet provided by iKenndac would be rewritten as
var sp = getSpotifyApi(1);
var models = sp.require('sp://import/scripts/api/models');
var currentTrackCoverUri = models.player.track.album.image;
Not sure if this is dependant on my Spotify version, I'm running 0.8.10.3.g07d01e81.
The UX guidelines requires you to present an album cover with playability when appropriate. This can be done with the solution from another topic: Views.player album cover
Related
I have really big problem, i mean im working in a company where we are using NetSuite as our business platform and now they updated our account with new APIs.
Developer before me wrote this code
for(var k = 0; k < ResultsPPCI.length; k++){
EmployeePPCI = ResultsPPCI[k].getValue('internalid'); //get the value
// log('Internal ID', EmployeePPCI);
// Merge, send, and associate an email with Purchase Order record (id=1000)
var mergeValuesPPCI = {};
mergeValuesPPCI.NLEMPFIRST = nlapiLookupField('employee', EmployeePPCI, 'firstname');
mergeValuesPPCI.NLEMPLAST = nlapiLookupField('employee', EmployeePPCI, 'lastname');
mergeValuesPPCI.NLSUPPLIER = nlapiLookupField('customer', cust, 'companyname');
mergeValuesPPCI.NLPRODUCTCODE = productcodehtml;
var emailBodyPPCI = nlapiMergeRecord(65, 'purchaseorder', poID, null, null, mergeValuesPPCI);
var recordsPPCI = {};
recordsPPCI['transaction'] = poID;
nlapiSendEmail(EmployeePPCI, EmployeePPCI, emailBodyPPCI.getName(), emailBodyPPCI.getValue(), null, null, recordsPPCI);
// log('EmployeePPCI',EmployeePPCI);
nlapiLogExecution('AUDIT', 'Potentional Problem', 'Email Sent');
}
I have problem now because nlapiMergeRecord is deprecated and it wont work. But i really cant find any working example online for hours... The most important part here is actually body of this email that has to be sent. In this case it is productcodehtml or mergeValuesPPCI.NLPRODUCTCODE.
This is how my template looks like :
<p>The QA Release has been submitted by <nlsupplier> for ${transaction.tranId}.</nlsupplier></p>
<p>The following item(s) have a short shelf life:</p>
<nlproductcode></nlproductcode>
Please can you help me with converting this code to new method? How can i connect nlproductcode from template with mergeValuesPPCI.NLPRODUCTCOD from my code?
Thanks in advance!
You can use kotnMergeTemplate as a drop in replacement for nlapiMergeRecord
e.g.:
kotnMergeTemplate(65, 'purchaseorder', poID, null, null, mergeValuesPPCI);
the nlobjEmailMerger does not take custom values so you'd have to post process the results. Again you can look at the example in my script where you'd get the merged string and then run:
var oldCustFieldPatt = /<(nl[^ >]+)>(\s*<\/\1>)?/ig;
content = content.replace(oldCustFieldPatt, function(a,m){
return mergeValuesPPCI[m.toUpperCase()] || mergeValuesPPCI[m.toLowerCase()] || '';
});
You can use the new nlapiCreateEmailMerger(templateId)
First you need to create your email template in netsuite and get the internal id.
Then:
Use nlapiCreateEmailMerger(templateId) to create an nlobjEmailMerger object.
var emailMerger = nlapiCreateEmailMerger(templateId);
Use the nlobjEmailMerger.merge() method to perform the mail merge.
var mergeResult = emailMerger.merge();
Use the nlobjMergeResult methods to obtain the e-mail distribution’s subject and body in string format.
var emailBody = mergeResult.getBody();
Send your email
nlapiSendEmail(senderInternalId, 'receiver#email.com','subject',emailBody, null, null, null);
Good luck!
case : Update field after select the customer name:
setting : 1 setting view that consist of database path :
DbServer: ServerOne/pcs
Directory: office
Database name : Customer.nsf
this xpages have a datasource inside, it call "document1"
// get the database path :
var vw3:NotesView=database.getView("Setting Path");
var doc3:NotesDocument=vw3.getFirstDocument();
var server:string = doc3.getItemValueString("DbServer");
var DName:string=doc3.getItemValueString("DbName");
var Directory:string=doc3.getItemValueString("Directory");
var DBName:string= Directory+"\\" +DName;
var db:NotesDatabase = session.getDatabase(server, DBName, false);
var vw:NotesView = db.getView("All Customer");
var doc:NotesDocument=vw.getDocumentByKey(document1.getValue("Customer"),true);
if (doc !=null) {
document1.setValue("Contact", doc.getItemValueString("Contact"));
document1.setValue("Telephone", doc.getItemValueString("Phone"));
document1.setValue("Fax", doc.getItemValueString("Fax"));
document1.setValue("Email", doc.getItemValueString("Email"));
}
Problem :
The field doesn't update and get the value from "customer" database.
I see a series of problems in your code:
Bind your input field to a scope variable, not to the document itself. It is a search string in the beginning, not part of the new document.
You don't check for the case that the customer wasn't found, so you never know if that was the issue.
I would rather use an URL and resolve instead of server / path / database (but that's a little style
So something like (typed off my head, will contain typos):
var vw3:NotesView=database.getView("Setting Path");
var vwe3 = vw3.getFirstEntry();
var db = session.resolve(vwe.entries[0]);
var vw:NotesView = db.getView("All Customer");
var doc:NotesDocument=vw.getDocumentByKey(viewScope.customer,true);
if (doc !=null) {
viewScope.result = doc.getUniversalID();
document1.setValue("Contact", doc.getItemValueString("Contact"));
document1.setValue("Telephone", doc.getItemValueString("Phone"));
document1.setValue("Fax", doc.getItemValueString("Fax"));
document1.setValue("Email", doc.getItemValueString("Email"));
doc.recycle()l
} else {
viewScope.result = "Not found!";
}
// ADD recycle() calls here!!!
Bind a display only field to viewScope.result, so you have a better idea what is happening. Your view must be sorted and indexed by customer name.
Of course you could use the OpenNTF dialog list control instead.
I have a piece of code that selects the initial state (snapshot) of the active document.
I wonder if there exist a short way to achieve the same goal.
Here is the actual script:
var myDoc = app.activeDocument.name;
var doc = app.activeDocument.historyStates.length;
alert("History States : " + doc);
function firstStep(enabled, withDialog) {
if (enabled != undefined && !enabled)
return;
var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
var desc1 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putName(cTID('SnpS'), myDoc);
desc1.putReference(cTID('null'), ref1);
executeAction(cTID('slct'), desc1, dialogMode);
alert("Selected Initial State");
};
firstStep();
Thanks in advance
Something along these lines should work for you:
docRef.activeHistoryState = docRef.historyStates.getByName('Snapshot 0');
I am writing a simple test app to experiment with the functionality of node.js and couchdb, so far i am loving it, but i ran in a snag. i have looked for and wide but can't seem to find an answer. My test server(a simple address book) does 2 things:
if the user goes to localhost:8000/{id} then my app returns the name and address of the user with that id.
if the user goes to localhost:8000/ then my app needs to return a list a names that are hyperlinks and takes them to the page localhost:8000/{id}.
I was able to get the first requirement working. i cant not seem to find how to retrieve a list of all names from my couchdb. that is what i need help with. here is my code:
var http = require('http');
var cradle = require('cradle');
var conn = new(cradle.Connection)();
var db = conn.database('users');
function getUserByID(id) {
var rv = "";
db.get(id, function(err,doc) {
rv = doc.name;
rv += " lives at " + doc.Address;
});
return rv;
}
function GetAllUsers() {
var rv = ""
return rv;
}
var server = http.createServer(function(req,res) {
res.writeHead(200, {'Content-Type':'text/plain'});
var rv = "" ;
var id = req.url.substr(1);
if (id != "")
rv = getUserByID(id);
else
rv = GetAllUsers();
res.end(rv);
});
server.listen(8000);
console.log("server is runnig");
As you can see, I need to fill in the GetAllUsers() function. Any help would be appreciated. Thanks in advance.
I would expect you to be doing something like (using nano, which is a library I authored):
var db = require('nano')('http://localhost:5984/my_db')
, per_page = 10
, params = {include_docs: true, limit: per_page, descending: true}
;
db.list(params, function(error,body,headers) {
console.log(body);
});
I'm not pretty sure what you are trying to accomplish with http over there but feel free to head to my blog if you are looking for some more examples. Just wrote a blog post for people getting started with node and couch
As said above it will come a time when you will need to create your own view. Check up the CouchDB API Wiki, then scan thru the book, check what are design documents, then if you like you can go and check the test code I have for view generation and querying.
You can create a CouchDB view which will list the users. Here are several resources on CouchDB views which you should read in order to get a bigger picture on this topic:
Introduction to CouchDB Views
Finding Your Data with Views
View Cookbook for SQL Jockeys
HTTP View API
So let's say you have documents structured like this:
{
"_id": generated by CouchDB,
"_rev": generated by CouchDB,
"type": "user",
"name": "Johny Bravo",
"isHyperlink": true
}
Then you can create a CouchDB view (the map part) which would look like this:
// view map function definition
function(doc) {
// first check if the doc has type and isHyperlink fields
if(doc.type && doc.isHyperlink) {
// now check if the type is user and isHyperlink is true (this can also inclided in the statement above)
if((doc.type === "user") && (doc.isHyperlink === true)) {
// if the above statements are correct then emit name as it's key and document as value (you can change what is emitted to whatever you want, this is just for example)
emit(doc.name, doc);
}
}
}
When a view is created you can query it from your node.js application:
// query a view
db.view('location of your view', function (err, res) {
// loop through each row returned by the view
res.forEach(function (row) {
// print out to console it's name and isHyperlink flag
console.log(row.name + " - " + row.isHyperlink);
});
});
This is just an example. First I would recommend to go through the resources above and learn the basics of CouchDB views and it's capabilities.
Has anyone discovered a way to extend or modify the functionality of the SharePoint Datasheet view (the view used when you edit a list in Datasheet mode, the one that looks like a basic Excel worksheet)?
I need to do several things to it, if possible, but I have yet to find a decent non-hackish way to change any functionality in it.
EDIT: An example of what I wish to do is to enable cascading filtering on lookup fields - so a choice in one field limits the available choices in another. There is a method to do this in the standard view form, but the datasheet view is completely seperate.
Regards
Moo
I don't think you can modify it in any non-hackish way, but you can create a new datasheet view from scratch. You do this by creating a new ActiveX control, and exposing it as a COM object, and modifying the web.config file to make reference to the new ActiveX control.
There's an example here:
Creating a custom datasheet control.
Actually, you can do this. Here is a code snippet I stripped out of someplace where I am doing just what you asked. I tried to remove specifics.
var gridFieldOverrideExample = (function (){
function fieldView(ctx){
var val=ctx.CurrentItem[curFieldName];
var spanId=curFieldName+"span"+ctx.CurrentItem.ID;
if (ctx.inGridMode){
handleGridField(ctx, spanId);
}
return "<span id='"+spanId+"'>"+val+"</span>";
}
function handleGridField(ctx, spanID){
window.SP.SOD.executeOrDelayUntilScriptLoaded(function(){
window.SP.GanttControl.WaitForGanttCreation(function (ganttChart){
var gridColumn = null;
var editID = "EDIT_"+curFieldName+"_GRID_FIELD";
var columns = ganttChart.get_Columns();
for(var i=0;i<columns.length;i++){
if(columns[i].columnKey == curFieldName){
gridColumn = columns[i];
break;
}
}
if (gridColumn){
gridColumn.fnGetEditControlName = function(record, fieldKey){
return editID;
};
window.SP.JsGrid.PropertyType.Utils.RegisterEditControl(editID, function (ctx) {
editorInstance = new SP.JsGrid.EditControl.EditBoxEditControl(ctx, null);
editorInstance.NewValue = "";
editorInstance.SetValue = function (value) {
_cellContext = editorInstance.GetCellContext();
_cellContext.SetCurrentValue({ localized: value });
};
editorInstance.Unbind = function () {
//This happens when the grid cell loses focus - hide controls here, do cleanup, etc.
}
//Below I grabbed a reference to the original 'BindToCell' function so I can prepend to it by overwriting the event.
var origbtc = editorInstance.BindToCell;
editorInstance.BindToCell = function(cellContext){
if ((cellContext.record) &&
(cellContext.record.properties) &&
(cellContext.record.properties.ID) &&
(cellContext.record.properties.ID.dataValue)){
editorInstance.ItemID = cellContext.record.properties.ID.dataValue;
}
origbtc(cellContext);
};
//Below I grabbed a reference to the original 'OnBeginEdit' function so I can prepend to it by overwriting the event.
var origbte = editorInstance.OnBeginEdit;
editorInstance.TargetID;
editorInstance.OnBeginEdit = function (cellContext){
this.TargetID = cellContext.target.ID;
/*
. . .
Here is where you would include any custom rendering
. . .
*/
origbte(cellContext);
};
return editorInstance;
}, []);
}
});
},"spgantt.js");
}
return{
fieldView : fieldView
}
})();
(function () {
function OverrideFields(){
var overrideContext = {};
overrideContext.Templates = overrideContext.Templates || {};
overrideContext.Templates.Fields = {
'FieldToOverride' : {
'View': gridFieldOverrideExample.fieldView
}
};
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext);
}
ExecuteOrDelayUntilScriptLoaded(OverrideFields, 'clienttemplates.js');
})();
Also, there are a couple of other examples out there. Sorry, I don't have the links anymore: