how to use JSOM to modify permissions for multiple list retrieved by a CAML query
-
07-10-2020 - |
Frage
Using SharePoint 2010 JSOM I know how to get a list item by it's ID, break its inheritance, then add a user to it's permission list with contribute access.
What I cannot figure out is if I get multiple list items using a CAML query then what do I do? The data doesn't get loaded until the executeQueryAsync
so I can't iterate through the items.
Do I have to call executeQueryAsync
twice? Once to get the list items and the 2nd to act on all of them?
This code works for one item where I know the ID:
ExecuteOrDelayUntilScriptLoaded(function()
{
var clientContext = new SP.ClientContext();
// get the contribute role
var roleContribute = clientContext.get_site().get_rootWeb().get_roleDefinitions().getByName("Contribute");
var contributeBinding = SP.RoleDefinitionBindingCollection.newObject(clientContext);
contributeBinding.add(roleContribute);
// get the viewers group
// we want to add users to that to make sure they have the necessary bare minimum access to the site
// it's not possible to get a group by name so we have to use the group ID
var viewersGroup = clientContext.get_web().get_siteGroups().getById(8);
// get the list
var list = clientContext.get_web().get_lists().getByTitle('user permission list');
// get a list item
var listItem = list.getItemById(1);
// break it's inheritence
listItem.breakRoleInheritance(false);
// create a new user
var userCreationInformation = new SP.UserCreationInformation();
userCreationInformation.set_loginName("domain\id");
// add the user to the viewers group
var addedUser = viewersGroup.get_users().add(userCreationInformation);
// give them contribute access to the lis item
listItem.get_roleAssignments().add(addedUser, contributeBinding);
clientContext.executeQueryAsync(Function.createDelegate(this, function()
{
alert("success");
}), Function.createDelegate(this, function()
{
alert("error");
}));
}, "sp.js");
I know I can use this to get a list of items:
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml("<View><Query><Where><Or><Eq><FieldRef Name='ID'/><Value Type='Number'>1</Value></Eq><Eq><FieldRef Name='ID'/><Value Type='Number'>4</Value></Eq></Or></Where></Query><RowLimit>10</RowLimit></View>");
var listItems = list.getItems(camlQuery);
And then after executeQueryAsync
I can use listItems.getEnumerator()
to iterate through them.
Is there a way to iterate through them before the executeQueryAsync
to break the inheritance and add users?
P.S. If someone knows a "better" way to do what I am trying I am all ears. :)
Lösung
Do I have to call executeQueryAsync twice? Once to get the list items and the 2nd to act on all of them?
Yes. Your first query gets the list of items (declare them in the parent scope, obviously, so that they are accessible on the success callback), and in the function of success callback, you can iterate through them to fire individual queries to modify the permissions.
A word of caution though, SharePoint has a limit of number of items on which you would be allowed to break inheritance. It is at 50K for SharePoint 2013, MSDN
Is there a way to iterate through them before the executeQueryAsync to break the inheritance and add users?
I doubt. You cannot iterate through a collection before loading it, right?
P.S. If someone knows a "better" way to do what I am trying I am all ears.
As I mentioned, the limit of 50K is there and it is quite easy to hit it in a couple of years. I would prefer to have some combination of views and event receivers to manage the read/view and edit permissions.