3

Before I describe the problem, I want to clarify that what I'm looking for is A generic way of updating various attributes/properties using JSOM.

I'm using an Office 365 dev account testing a SharePoint 2013 app. I'm trying to use JSOM to change a list column's attributes. Maybe I'm missing something here but what's the trick using JSOM on SharePoint 2013 to get/set specific list field attributes? For instance, I want to change the "Show field" in an "Attendees" column in a OOTB calendar list to be "Work email" instead of "Name (with presence)".

Before you jump the gun and tell me about get_Title() and get_required() and the other built in functions, let me clarify that I'm looking for something more generic where I can specify the exact attribute that maybe doesn't have a built-in function (like the "Show Field" example above).

I've tried using the get_schemaXml() and set_schemaXml() functions to get/set the XML directly like Anatoly Mironov does in his post. While this doesn't kick back errors, it also doesn't update anything. Does Office 365 even allow overwriting of XML schemas? Or is something out of whack w/ my code:

function testColPropChange(listName, fieldName, newTitle) {
     var subSiteUrl = 'https://tester.sharepoint.com/testSub';
     this.context = SP.ClientContext.get_current();
     var appContextSite = new SP.AppContextSite(this.context, subSiteUrl);
     this.web = appContextSite.get_web();
     var oList = this.web.get_lists().getByTitle(listName);
     var field = oList.get_fields().getByInternalNameOrTitle(fieldName);

     this.context.load(field, "SchemaXml");
     this.context.executeQueryAsync(Function.createDelegate(this, loadSuccess), Function.createDelegate(this, errorHandler));


    function loadSuccess() {
        var schema = field.get_schemaXml();
        var s1 = schema.replace('Required=/"FALSE/"','Required=/"TRUE/"');
        field.set_schemaXml(s1);
        field.update();
        this.context.executeQueryAsync(
           Function.createDelegate(this, schemaChanged), 
           Function.createDelegate(this, errorHandler));
    }
}

It's a simple query but I could still have jacked it up somewhere.

There has to be a simpler way of updating list column attributes using JSOM. Please advise.

======= UPDATE =========

While Rob's solution works for the instance I discussed above, I'm reopening this thread b/c I think it deserves more discussion.

I have many different properties other than the one mentioned that I can't seem to find a way to update (no native get/set methods). I've run across several but the two that I can remember off the top of my head are:

  • "SelectionMode" (aka UserSelectionScope) on a people field
  • "NavigateForFormsPage" on any list (to open forms in dialog instead of new page)

These props can be easily modified using C# or PowerShell with simple dot notation, so one would think it would be easy to change these in JSOM as well. But intellesense doesn't find anything. So what's the equivelant of obj.prop in JSOM? Anybody? Buehler... Buehler...

  • Don't confuse the Server Object Model with the Client Object Model. The latter is most definitely a subset for the former. You are going to find many property and methods that exist on types in the Server Object Model that are not available on the associated types in the Client Object Model. – Rob Windsor Aug 23 '13 at 18:30
  • Knowing how to effectively Google search helps. For types in the managed CSOM use "SharePoint Client <type name> class", for types in the JavaScript CSOM use "SharePoint JavaScript <type name> object". Using this quickly got me to the documentation on SelectionMode msdn.microsoft.com/EN-US/library/jj245488.aspx – Rob Windsor Aug 23 '13 at 18:34
  • One final note: the documentation on the JavaScript CSOM types is sparse and often incomplete. There are going to be times where you're going to have to resort to reading the code that implements it. The main files are SP.js, SP.Core.js and SP.Runtime.js which can be found in the _layouts folder – Rob Windsor Aug 23 '13 at 18:39
  • aahhh... I was looking at the wrong object (fieldUser not field). I wonder if the other props that I don't have a get/set for are just under another non-intuitive object – Josey Aug 23 '13 at 18:47
  • I'm an idiot. SharePoint Manager clearly gives the CSOM object type at the very end of a given field's prop list. doh! – Josey Aug 23 '13 at 18:56
7
+50

You need to cast the field object to the specific field type. In the case of the Attendees field in a calendar it's User of Group (SP.FieldUser). Once you have the specific field type you can usually get the property you need. In the case of the "Show field" for the User or Group field it's LookupField.

You can do the cast by calling the CastTo method of the ClientContext object.

var context = SP.ClientContext.get_current();
var hostContext = new SP.AppContextSite(context, hostUrl);
var web = hostContext.get_web();
var list = web.get_lists().getByTitle("Test Calendar");
var field = list.get_fields().getByInternalNameOrTitle("Attendees");

var userField = context.castTo(field, SP.FieldUser);
userField.set_lookupField("EMail");
userField.update();
context.executeQueryAsync(success, fail);
  • That works for that instance, Rob. Thanks! Side question, how do you know what the internal property option names were? As in, how did you know to use "EMail" instead of the default display name of "Work email"? – Josey Aug 15 '13 at 19:00
  • 1
    I knew the LookupField property had to be set to the name of the field from the User Information List who's value I wanted to display. So I used SharePoint Manager to find the Work Email field on that list and then get the internal name. See bit.ly/VKGcfx for more details on the User Information List and bit.ly/142NuTK for more details on how the get the internal name of a field. – Rob Windsor Aug 15 '13 at 19:25
  • I just downloaded the SharePoint Manager 2013 Online for office 365 and it has changed my world. Thanks for the tip Rob. – Josey Aug 20 '13 at 16:54
0

You need to break this into smaller chunks to stand a chance of being able to solve the issue. There are too many moving parts here. For example, try to set a column's schema XML to a hard-coded value. Does that work? If so, great. Next, working backwards from there, verify that you are actually getting the values you expect in your field and schema variables. Next, verify that the string replace operation is actually returning the results you expect.

If all that is working as you think it should, look at the event handlers. Is the loadSuccess event handler getting fired? Is the schemaChanged event handler getting fired? You didn't mention the actual path your code was taking, and that's an important thing to leave out.

When JSOM code fails there are two places where it might manifest itself:

First and most promiently, an executeQueryAsync call will return an error, and you can usually get a good handle on the problem by examining the error message returned to the error handler. Define your error handlers like this:

function errorHandler(sender, args)
{
    alert(args.get_message());
}

The alert will let you know right away what the issue is.

The second place you see errors in JSOM is when you try to access a property that is not loaded. This will become evident as a JavaScript error: the property has not been initialized. This means you are looking for something a previous call did not explicitly ask for. I would look at your field and schema variables to make sure they are being properly set.

  • The load succeeds so my errorHandler doesn't kick back any errors and I don't get a property initialization error. I'll hardcode a schema and get back with you on how that goes. But my core question here is how do you update properties of list columns without using the built-in "get_x/set_x" functions – Josey Aug 15 '13 at 18:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.