Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I have added a property bag to SPList. Since the SPList doesn't support property bag, I have added my custom property to SPList.RootFolder.Properties. I would like to retrieve this property using ECMA script. I couldn't find a getter method in ECMA script for SP.Folder for retrieving the properties.

I have tried the below, but this returns default properties like Name of folder and Item count, but doesn't return any other property and also custom properties that are added. I have tried rootFolder.get_properties(), but it throws exception that method is not supported.

function addToPlaylist() {
    var ctx = SP.ClientContext.get_current();
    var listId = SP.ListOperation.Selection.getSelectedList();

    //get propertybag
    var web = ctx.get_web();
    this.list = web.get_lists().getById(listId);
    this.rootFolder = list.get_rootFolder();
    ctx.load(rootFolder);
    ctx.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onQuerySucceeded(sender, args) {
    this.props = this.rootFolder.get_objectData().get_properties();
}

function onQueryFailed(sender, args) {
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

Any help is appreciated.

share|improve this question
add comment

3 Answers 3

The key is

clientContext.load(rootFolder, 'Properties');

function retrieveSpecificListProperties() {
    var clientContext = new SP.ClientContext();
    var rootFolder = clientContext.get_web().get_lists().getById('{F87D7E27-C692-49A2-ABC4-DC620766E0A8}').get_rootFolder();

    //rootFolder.get_properties().set_item('property_name', '1');
    //rootFolder.update();

    clientContext.load(rootFolder, 'Properties');

    clientContext.executeQueryAsync(
        function () {
            console.log(rootFolder.get_properties().get_fieldValues()['property_name']);
        },
        function (sender, args) { console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace()); }
    );
}

retrieveSpecificListProperties();
share|improve this answer
add comment

It seems that folder.get_properties() is only available in SP 2013 which means that retrieving properties from a folder property bag is easy (as shown above)...if you are in SP2013 that is. I don't think you can do this in the 2010 CSOM/JSOM. I think this was an oversight by the SP2010 dev team which has now been put right. You can of course do this easily with server side code.

It's easy enough to read data from the web property bag but then if your property data only has a scope which is only relevant for the list and you are saving it at the web then you will have to find a way to clear things up i.e. remove unnessary properties, when say the list is deleted.

share|improve this answer
add comment

So having done some further investigation on this I cannot find any way to retrieve a custom property from a folder property bag using ECMA script in SP2010 - that object model simply just does not give us access to what we need. As indicated in my previous answer it seems that this limitation has been addressed in SP2013 but that's not very useful if the application is required for 2010.

Accessing folder properties is simple if you are using the SharePoint sever OM but that's not helpful if you only have have ECMA script at your disposal. So we're stuffed, or are we - time to think laterally.

If I correctly understand the intent behind the original question then what we are trying to do is find a way to save a simple property, say a string for some kind of configuratiuon purpose, at the list level. However, we have already established that we can't save this custom property in the usual place i.e. the property bag of the root folder because we need to access it via ECMA script and sadly that that doesn't give the access we need for SP2010. So, why not save this property elsewhere i.e. somewhere which can be accessed by the ECMA OM, but where?

Well in my previous answer I suggested that we could elevate the property and save it in the web property bag and this would work just fine because ECMA does give us what we need to access the AllProperties of the web. However, there is a real risk that we would end up filling the web property bag with garbage as you would have to find a way to remove the unneccessary key/values when the list is deleted. Now this clean up task could be done in several ways including attaching event receivers to the list or maybe a custom timer job - all of which seems like a lot of effort and complexity for such a simple task.

So if the web property bag won't cut it then how about missappropriating an existing list property for our purposes. Surely we could find a spare string property of the list that serves not real prupose that we could grab and use/abuse to save our custom property value. Well, sadly no such 'conveniently unused' read/write string property exists on an SPList object (at least I couldn't find one). I briefly thought about abusing the List's Description field but that's no good because we might want to use that for it's intended purpose and it also shows up in the UI and can indeed be changed in the UI, all of which makes it an unlikley candidate. The only time when abusing the Description field might work is if the list is hidden and therefore has no UI to speak of.

So we're done for, - well not quite. If we can't find a property of the list to abuse how about a property of a View for the list. Ok, so assumming that we have access to the OM to create a new view (which is likely because we must somehow have had access to add custom properties to the root folder which was the original plan) then creating a custom View to store a custom property has an immediate advantage in that we can make the view hidden to end users who will never know that it exists and the view will be deleted when the list is deleted i.e. it's a self cleaning solution.

So a View is a good candidate but which property to use? Sadly an SPView has no Description property so we have to look wider and the best candidate I can find is the Toolbar property. The Toolbar property is a read/write string property that will have no impact on the View because our View will be hidden and have no use for a UI and so need for a tool bar property. And yeeha - the ECMA OM gives us a .get_toolbar() method which can be applied on a View object to get at the value!

So all we have to do now is to save our custom property to the Toobar field of a hidden view on the list (rather than the property bag of the root folder). There are lots of ways to do this but I've chosen to abstract the process out to a custom static utilites class which provides me we a few useful extension methods as shown below:

    public static bool HasView(this SPList List, string Title)
    {
        return (List.Views.ToIEnumerable().Where(V => V.Title == Title).FirstOrDefault() != null);
    }

    private static SPView GetConfigView(this SPList List, string ViewName)
    {
        if (List.HasView(ViewName))
            return List.Views[ViewName];
        else
        {
            SPField fldTitle = List.Fields[SPBuiltInFieldId.Title];
            StringCollection ViewFields = new StringCollection(){fldTitle.InternalName};
            string strBasicQry = "<OrderBy><FieldRef Name='LinkTitle'/></OrderBy>";
            SPView ConfigView = List.Views.Add(ViewName, ViewFields, strBasicQry, 1, false, false);
            ConfigView.Hidden = true;
            ConfigView.Update();
            return ConfigView;
        }            
    }

    public static void SetPropertyString(this SPList List, string Key, string Value)
    {
        SPView ConfigView = List.GetConfigView(Key);
        ConfigView.Toolbar = Value;
        ConfigView.Update();
    }

    public static string GetPropertyString(this SPList List, string Key)
    {
        if (List.HasView(Key))
            return List.Views[Key].Toolbar;
        else
            return string.Empty;
    }

The code is fairly simple. The list.HasView("View Title") extension method simply returns a boolean value which indicates whether the list has a view with the specified title.

The list.GetConfigView("View Name") method either returns the View with the matching name, or if one can't be found then simply create a new one using the supplied title which is in effect the Key to our custom property.

All that remains is to create a couple of accessor methods which get and set data to and from the Toolbar property of the view.

The calling code (from the SP Server OM) looks like this:

 const string KEY = "MY_CUSTOM_PROPERTY_KEY";
 SPList List = Web.Lists["My list"];

 //Save the property string to the KEY
 List.SetPropertyString(KEY, "Custom String Value");

 //Retreiving the property string
 string propValue = List.GetPropertyString(KEY);

To get at the property using ECMA script might look something like the following:

var ctx = SP.ClientContext.get_current();

var web = ctx.get_web();

var listId = SP.ListOperation.Selection.getSelectedList();

var list = web.get_lists().getById(listId);

var configView = list.get_views().getByTitle('KEY_CUSTOM_PROPERTY_KEY');

ctx.load(configView);

var configString = configView.get_toolbar();

Now for a few pros and cons:

Pros - It works!

  • It's supported, we are just using the standard OM and object properties albeit that we are bending the rule slightly.

  • It performs well. Actually this is probably better (perfomance wise) than adding custom properties to the object property bags.

  • The complexity can easily be abstracted so that the calling code uses this capability with just a couple of accessor method calls.

  • You can create as may custom properties as you like.

  • It's a self cleaning solution i.e. your custom properties live and die with the list

Cons

  • Well we are bending things just a little by abusing the Toolbar property for our own nefarious purpose.

  • Creating an entire View for a single property string seems a bit excessive - and it is! If you need 6 property strings you'll end up with 6 hidden views. Of course you could do something creative with a single property string so by saving and XML fragment or a delimited set of property/value pairs in a single string.

  • You also need to take care that the view titles you use as properties keys are not likely to be in use currently or required some time in the future.

In summary I think that this is reasonable workaround for an obvious limitation in the ECMA 2010 OM but I think I would use this approach sparingly i.e. only in circumstances when I only have the ECMA OM at my disposal and I need to access custom properties. Lateral thinking applied!

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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