After a few busy weeks working on my first 100% JavaScript 2013 App (watch this space for more!!) I’ve come to realise that the MSDN documentation on JSOM and CSOM still is pretty sparse!
A couple of simple examples exist in the usual place (e.g. JSOM CreateProjects) but when you get to the details you’ll find a lot missing. For example updating Custom Fields; if you look at the MSDN page covering PS.DraftProject, the method you need (draftProject.setCustomFieldValue()) is not even listed! (UPDATE 7/08: It is covered here but with no detail; PS.Project.setCustomFieldValue)
JavaScript PS.DraftProject.setCustomFieldValue Method
Here’s the missing method definition that you’ll see when using PS.debug.js:
PS.DraftProject.setCustomFieldValue(FieldName, Value);
Hey wow, that simple hey? No, unfortunately the definition is a bit misleading; easy to assume that FieldName references the custom field name used else where like in the OData fields, but in fact this refers to the InternalName from the PS.CustomField object.
An example InternalName is: Custom_a1737ae3b4fce211940b00155d000a03
So first thing you need to do is get that name, it is just the field GUID prefixed with “Custom_”, but I like to do things more dynamically so I’ll use projContext.get_customFields(); to cache that information.
Example JavaScript update of Custom Field Value
Firstly lets get those InternalName values into an array for later use.
Cache the field details with a GetCustomFields Function
var projContext; var customFields; var customFieldData = []; SP.SOD.executeOrDelayUntilScriptLoaded(GetCustomFields, "PS.js"); function GetCustomFields() { // Initialize the current client context and get the projects collection projContext = PS.ProjectContext.get_current(); customFields = projContext.get_customFields(); projContext.load(customFields); // Run the request on the server. projContext.executeQueryAsync(getCFComplete, getCFFailed); } function getCFComplete(response) { var cfEnumerator = customFields.getEnumerator(); // Save the details of each CF for later while (cfEnumerator.moveNext()) { var cf = cfEnumerator.get_current(); customFieldData.push({ Id: cf.get_id(), Name: cf.get_name(), InternalName: cf.get_internalName() }); } // Now update the project updateProject(); }
Note the last line there; updateProject() as this is all asynchronous you need to call the update only once you have the customFieldData array ready.
Update the Project Custom Field Function
function updateProject() { var projectId = "9C585CC0-3FC0-4133-9F2A-1FB96587CF0D"; var project = projects.getById(projectId); var draftProject = project.checkOut(); var fieldName = "My Custom Field"; // Update custom field var cfData = $.grep(customFieldData, function (val) { return val.Name === fieldName; }); if (cfData.length > 0) { draftProject.setCustomFieldValue(cfData[0].InternalName, "Some new value"); } //Publish the change var publishJob = draftProject.publish(true); //Monitor the job projContext.waitForQueueAsync(publishJob, 30, function (response) { if (response !== 4) { // handle errors } } }
This simple example assumes the FieldType is text, but you get the idea, also to work with Lookup Tables you’ll need to look at the cf.get_lookupEntries() values in the getCFComplete() function but hopefully the above will get you started.
Hi,
I am not able to set the Lookup values for a Custom Field I tried using the Inter
Hi Parth,
I’m am just about to write a follow-up to this on lookup tables as it took me a lot of trial an error to figure out how to do those! Come back in a day or so. :)
Martin
See part 2 of this on updating Lookup Table values here:
https://nearbaseline.com/2013/08/updating-lookup-table-values-using-jsom/
Any ideas on how can I edit an enterprise resource (more precisely, adding a calendar exception) through JSOM? Thanks! :)
Hi Gonzalo,
Unfortunately not much I can add to the above on updating resources, and resource calendars would be very different to custom fields so not sure how much this helps you do that either.
Martin
Hi Martin,
Thanks for your quick response.
Have you ever tried updating enterprise resources? Method .update() returns undefined whenever I try to edit the collection. I have created this post (http://sharepoint.stackexchange.com/questions/76825/ps-enterpriseresourcecollection-update-returns-undefined) that describes my problem in detail. If you could look at it I would be very grateful. Thanks in advance.
Gonzalo
Hi Martin
I have a very peculiar problem and maybe very trivial…
I need to retrieve the value of a few of the custom fields but an unable to do so. It seems, there is a method to set the values, but there is no method or property in either CustomField of CustomFieldCollection classes to get the value of a field (at least I could not find one).
I am working on a custom dashboard where I need these values. Any help would certainly be useful.
Thanks,
Hi Ritzzz,
From memory what you need to use is PS.DraftProject.get_fieldValues():
http://msdn.microsoft.com/en-us/library/office/jj668152(v=office.15).aspx
However typically the JS MSDN documentation is useless, so have a look at the CSOM link: http://msdn.microsoft.com/en-us/library/office/microsoft.projectserver.client.draftproject.fieldvalues_di_pj14mref(v=office.15)
The objects in JSOM / CSOM are the same underlying objects so applying the same patterns to your JSOM code as the CSOM document suggests generally works.
Failing that from my personal experience, forget JSOM and go direct to REST. For reading data from Projects using JavaScript it is faster and easier. Here’s an example I use in my ID app to get a custom field value:
$http.get(url, {
responseType: ‘json’,
headers: { “ACCEPT”: “application/json;odata=verbose” }})
.success(function (res, status, xhr) {
var xmlName = idConfig.idCfProperties.InternalName.replace(“_”, “_x005f_”);
deferred.resolve(res.d[xmlName]);
})
.error(function (data, errorCode, errorMessage) {
deferred.reject(“Get custom field data error: ” + errorMessage);
});