Break List Item Permission Inheritance using Power Automate

Ahamed Fazil Buhari
 
Senior Developer
November 3, 2022
 
Rate this article
 
Views
2009

In this article we will see, how to easily break SharePoint list item permission with couple of Power Automate actions. Without further intro, as a first step we need to get SharePoint user Id for the user who we would like to give access,

 

And to handle the response data, we can parse the JSON (schema can be generated from sample response)

 

Now we can break the permission by providing list name, item ID in breakroleinheritance api call

Once the break role inheritance is done, then we can provide permission to specific user (user that we resolved in step 1) with any role you would like. In the below example I give full control and the roledefid for full control is 1073741829.

Below you can find different role ids and its definition.

Role identifier valueRole definition
1073741924View Only
1073741825Limited Access
1073741826Reader
1073741827Contributor
1073741830Edit
1073741828Designer
1073741829Full Control

 

With this simple for actions, we can easily break list permission and give unique access.

 

Happy Coding

Fazil

 

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

How to subscribe List/Library for notifications in SPFx webpart

Ahamed Fazil Buhari
 
Senior Developer
June 24, 2021
 
Rate this article
 
Views
2326

If our webpart is dealing with SharePoint list or libraries and it needs real time notification whenever property change or item update in a list/library without page refresh then we can make use of List & Library subscriptions. This notification can monitor changes on lists in current sites, other site collection/site and even from other geo site. This concept is introduced in SPFx v1.7.0 but that supports only Libraries but not lists. From version 1.12.1 of SharePoint Framework we can now subscribe to both lists and libraries.

The official Microsoft documentation for Subscribe to list notification can be found in here. By the time I write this article, SPFx v1.12.1 is the latest and you can check your currently installed yeoman generator package in your system by using the below npm command.

npm ls @microsoft/generator-sharepoint -g --depth=0

And if you want to add latest one you can add by running the below command

npm install @microsoft/generator-sharepoint@latest -g

or if you want to add specific version then you can use this (in my case I need to use version 1.12.1)

npm install @microsoft/generator-sharepoint@1.12.1 -g

As a Prerequisites, we need to install @microsoft/sp-list-subscription npm package by following command,

npm install @microsoft/sp-list-subscription –save –save-exact

With the instance of ListSubscriptionFactory class we can call createSubscription to register for callbacks on notification. This process is explained in detail in MS doc Subscribe to list notification.

We keep listSubscriptionFactory object in appContext, (to know more about using useContext in spfx you can refer here – Skeleton Code For Global State Management Using UseContext, UseReducer In SPFx Solution) and with useEffect hook to subscribe to for list/library notification.

 

useEffect(() => {
        let listSub: IListSubscription;
        console.log("Subscribing");
        const subscribeForTicketList = async () => {
            listSub = await appContext.listSubscriptionFactory.createSubscription({
                listId: Guid.parse(appContext.properties.ticketListId),
                callbacks: {
                    notification: async () => {
                        console.log("Something changed in Ticket list - Reload");
                        await loadTickets();
                    }
                }
            });
        };
        subscribeForTicketList();
        return () => {
            console.log("Remove subscription");
            appContext.listSubscriptionFactory.deleteSubscription(listSub);
        };
    }, []);

Complete code is available in the github

Happy coding,

Fazil

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

Step by Step procedure to Create a Custom Action for Delete Button on SharePoint List Form Ribbon using JavaScript

Sriram
 
Technology Specialist
August 21, 2018
 
Rate this article
 
Views
5314

Recently I came up with requirement to change delete action’s confirmation message. Are you sure you want to send the item(s) to the Recycle Bin? to Are you sure you want to Cancel the Request? Also when clicking on the Delete icon, it should not delete the item; instead it should update the status of the item.

clip_image002

I have followed below approch to solve this problem.

Replace the ‘Delete Item’ button on the Ribbon bar with a copied ‘Delete Item’ button and then use ECMAScript and Sharepoint Client Object Model to remove the item and implement business logics.

Below are the steps to impelemet above functionality.

  1. Create 2 JS files for ViewForm and Edit Form,
  2. In the JS file under document.ready place the below code.

 

 $(document).ready(function(){
 //for view form
 var button = document.getElementById("Ribbon.ListForm.Display.Manage.DeleteItem-Medium");
 if (button != null) {
     var $button = $(button);
     var html = $button.html();
     $button.after("<div id='deleteIcon' OnMouseOver='ApplyCSSFunction()'><a style='cursor:pointer;'>" + html + "</a></div>").hide().next().click(function (e) {
 		DeleteCurrentItem();
     });
     $(".ms-cui-ctl-mediumlabel:eq(3)").css("vertical-align","top");
 	$(".ms-cui-ctl-mediumlabel:eq(3)").css("margin-left","4px");
 $('.ms-cui-ctl-mediumlabel:eq(3)').text("Cancel Request");
 	}
 
 $("#deleteIcon").mouseleave(function() {
  	  $("#deleteIcon").css("border-style","none");
         });
 });
 

 

  1. Write your business logic in DeleteCurrentItem() method.

 

 function DeleteCurrentItem()
 {
 $("#deleteIcon").css("border-style","none");
 var deleteConfirm = confirm("Are you sure you want to cancel this request?");
 if(deleteConfirm)
 {
  var deleteItemID=getParameterByName('ID');
  DeleteItem(deleteItemID);
 }
 }
 

 

  1. We need to change the highlighted line on the above code to make it work in Edit form.

View Form:

var button = document.getElementById(“Ribbon.ListForm.Display.Manage.DeleteItem-Medium”);

Edit Form:

var button = document.getElementById(“Ribbon.ListForm.Edit.Actions.DeleteItem-Large”);

Output:

clip_image004

Author Info

Sriram
 
Technology Specialist
 
Rate this article
 
Sriram T has been working in IT industry for over 6 years He holds Bachelor's degree in Computer Science Engineering. Sriram write articles and blogs related to SharePoint 2013, SharePoint ...read more
 

PowerShell tip to Identify lists with InfoPath Forms associated in SharePoint 2016 by using the Property “_ipfs_infopathenabled”

Sathish Nadarajan
 
Solution Architect
February 15, 2018
 
Rate this article
 
Views
4282

 

To identify whether a list is associated with InfoPath Form or not, we have a Property called _ipfs_infopathenabled, which will have a value of True. If the list is not attached, the property itself will not be available.

And specifically, the infopath can be associated to any of the content type. Hence, we need to iterate through the content types in the list and identify whether any of the content type is having the property or not.

 function AddPowerShellSnapin()
 {
     try
     {
         Add-PSSnapin "Microsoft.SharePoint.PowerShell"
         Write-Host "Adding PowerShell Snap-in" -ForegroundColor Yellow
         # Try to get the PowerShell Snappin.  If not, then adding the PowerShell snappin on the Catch Block
         Get-PSSnapin "Microsoft.SharePoint.PowerShell" 
     }
     catch
     {
         if($Error[0].Exception.Message.Contains("No Windows PowerShell snap-ins matching the pattern 'Microsoft.SharePoint.PowerShell' were found"))
         {
             Add-PSSnapin "Microsoft.SharePoint.PowerShell"
         }
     }
     
     Write-Host "Finished Adding PowerShell Snap-in" -ForegroundColor Green
     
 }
 
 function IsInfoPathUsed($List)
 {
     $InfoPath_Used = "False"   
         
     foreach($contentType in $list.ContentTypes)
 	{
 		$InfoPath_Used = $contentType.ResourceFolder.Properties[“_ipfs_infopathenabled”]
 		if($InfoPath_Used -eq "True")
 		{
 			break;
 		}
 	}	
     
     return $InfoPath_Used
 }
 
 AddPowerShellSnapin
 
 $Web =  Get-SPWeb "http://sathishserver:555/sites/developersite"
          
         # Get the Lists    
         $Lists = $Web.Lists
         
         # Iterate through the Lists
         foreach($List in $Lists)
         {
             write-Host "Get Lists With InfoPath in -" + $List.Title
              
                 $IsInfoPathUsed = IsInfoPathUsed($List)
                 if($IsInfoPathUsed -eq "True")
                 {
                     $output = $_.SiteCollectionURL + "," + $Web.Url + "," + $List.Title + "," + $List.DefaultViewUrl 
                     Add-Content $ListsWithInfoPath_CSV_Path $output
                 }
           } 
 

Happy Coding,

Sathish Nadarajan.

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

Remove Attachments on SharePoint List Item using Angular

Ahamed Fazil Buhari
 
Senior Developer
December 4, 2017
 
Rate this article
 
Views
3805

Hello everyone,

In this article we will see how to delete attachments in SharePoint List Item using Angular. In my previous article we have seen, Get All Attachments From SharePoint List Item Using AngularJS and How To Handle Multiple File Selection And Validation On Input File Type Using AngularJS. Once we get all the files in the variable scope.attachedFile. We cannot upload attachment when we are updating some field in the item. To achieve this, we need to update item in separate and upload or remove file in separate. We can make use of promise $q in angular to upload file in list item once the item has been successfully created or updated.

Here I’ve created separate service for updating list item and uploading attachment in SharePoint list item. The service name is List_Context and Utilities service to get supporting components for CRUD header,

Utilities.js

 (function () {
     'use strict';
     var serviceId = 'Utilities';
 
     var Utilities = function () {
 
         var service = this;
         service.spHostUrl = _spPageContextInfo.siteAbsoluteUrl + _spPageContextInfo.webServerRelativeUrl;
 
         return {
             getRequestHeader: getRequestHeader,
             updateRequestHeader: updateRequestHeader,
             deleteRequestHeader: deleteRequestHeader
         };
 
         function getRequestHeader() {
             var getHeader = {
                 'headers': {
                     'accept': 'application/json;odata=verbose'
                 }
             };
             return getHeader;
         }
 
         function updateRequestHeader() {
             var updateHeader = {
                 'headers': {
                     "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                     'content-type': 'application/json;odata=verbose',
                     'accept': 'application/json;odata=verbose',
                     "IF-MATCH": "*",
                     "X-HTTP-Method": "MERGE"
                 }
             };
             return updateHeader;
         }
 
         function deleteRequestHeader() {
             var deleteHeader = {
                 'headers': {
                     "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                     'content-type': 'application/json;odata=verbose',
                     "IF-MATCH": "*"
                 }
             };
             return deleteHeader;
         }
     }
     var module = angular.module("Mainapp");
     module.factory(serviceId, Utilities);
 }());
 

List_Context.js

 (function () {
     'use strict';
     var serviceId = 'List_Context';
 
     var List_Context = function ($http, $q, Utilities) {
 
         return {
             getListData: getListData,
             updateListData: updateListData,
             checkFileExistsAndRemove: checkFileExistsAndRemove,
             uploadFileSP: uploadFileSP,
             getFileBuffer: getFileBuffer,
             deleteFile: deleteFile
         };
 
         function getListData(urlValue) {
             var deferred = $q.defer();
             $http.get(urlValue, Utilities.getRequestHeader())
                         .then(function (response) {
                             deferred.resolve(response.data.d);
                         }, function (error) {
                             deferred.reject(error);
                         });
             return deferred.promise;
         };
 
         function updateListData(listId, itemId, itemData, listName) {
             var deferred = $q.defer();
             var updateURL = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetById('" + listId + "')/Items" + '(' + itemId + ')';
             var entityFullName = getEntityTypeFullName(listName);
             var item = $.extend({
                 '__metadata': {
                     'type': entityFullName
                 }
             }, itemData);
             var jsonData = JSON.stringify(item);
 
             $http.post(updateURL, jsonData, Utilities.updateRequestHeader())
                         .then(function (response) {
                             deferred.resolve(response.data.d);
                         }, function (error) {
                             deferred.reject(error);
                         });
             return deferred.promise;
         };
 
         function checkFileExistsAndRemove(fileURL) {
             var deferred = $q.defer();
             var fullFileURL = _spPageContextInfo.webAbsoluteUrl + "/_api/web/getFileByServerRelativeUrl('" + fileURL + "')";
             $http.get(fullFileURL, Utilities.getRequestHeader())
                         .then(function (response) {
                             deleteFile(fullFileURL)
                             .then(function (response) {
                                 deferred.resolve(response);
                             });
                         }, function (error) {
                             console.log('File does not exist');
                             deferred.reject(error);
                         });
             return deferred.promise;
         }
 
         function uploadFileSP(listName, itemID, bufferVal, fileName) {
             var urlValue = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('" + listName + "')/items(" + itemID + ")/AttachmentFiles/add(FileName='" + fileName + "')";
 
             $.ajax({
                 url: urlValue,
                 type: "POST",
                 data: bufferVal,
                 async: false,
                 processData: false,
                 headers: {
                     "accept": "application/json;odata=verbose",
                     "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
                     "Content-Type": undefined
                 },
                 success: fileSuccess,
                 error: fileError
             });
             function fileSuccess(data) {
                 console.log('File Added Successfully.');
             }
             function fileError(error) {
                 console.log(error.statusText + "nn" + error.responseText);
             }
         }
 
         function getFileBuffer(file) {
             var deferred = $.Deferred();
             var reader = new FileReader();
             reader.onloadend = function (e) {
                 deferred.resolve(e.target.result);
             }
             reader.onerror = function (e) {
                 deferred.reject(e.target.error);
             }
             reader.readAsArrayBuffer(file);
             return deferred.promise();
         }
 
         function deleteFile(fileURL) {
             var deferred = $q.defer();
             $http.delete(fileURL, Utilities.deleteRequestHeader())
                          .then(function (response) {
                              console.log('Deleted the attachment.');
                              deferred.resolve(response);
                          }, function (error) {
                              deferred.reject(error);
                          });
             return deferred.promise;
         }
     };
 
     //Supporting function 
     function getEntityTypeFullName(listName) {
         return "SP.Data." + listName.replace(' ', '_x0020_') + "ListItem";
     }
 
     var module = angular.module("Mainapp");
     module.factory(serviceId, ['$http', '$q', 'Utilities', List_Context])
 }());
 

Main.js

 (function () {
     'use strict';
 
     var controllerId = 'Mycontroller';
     var app = angular.module("Myapp", []);
 
     var Mycontroller = function ($scope, $q, List_Context, Utilities) {
         function SaveData() {
             var updatingVals = {};
             updatingVals['Title'] = "TEST Title";
             var filesAdd = {};
             //Please refer previous article to know how to get attachment value in attachedFile scope variable
             //https://www.sharepointpals.com/post/Get-all-attachments-from-SharePoint-List-Item-using-AngularJS
             filesAdd = $scope.attachedFile;
             var listID = "BF6BCA2E5-12B5-452F-8EA6-B6789AF4CDEB";
             var listItemID = 10;
             var listName = "MyList";
             SP_WaitScreen();
             var promises = [];
             List_Context.updateListData(listID, listItemID, updatingVals, listName)
                     .then(function (value) {
                         //Please refer previous article to see how to get removeFile values - 
                         //https://www.sharepointpals.com/post/How-to-handle-multiple-file-selection-and-validation-on-input-file-type-using-AngularJS
                         angular.forEach($scope.removeFile, function (filePath, key) {
                             promises.push(List_Context.checkFileExistsAndRemove(filePath));
                         });
                     }, function (reason) {
                         SP_WaitScreen_Close();
                         window.open(window.parent.location.reload(true), "_parent", "");
                     });
         }        
 
         //OOTB Wait modal dailog
         function SP_WaitScreen() {
             SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () {
                 window.parent.eval("window.waitDialog = SP.UI.ModalDialog.showWaitScreenWithNoClose('Working on it...', '');");
             });
         }
         function SP_WaitScreen_Close() {
             if (window.frameElement != null) {
                 if (window.parent.waitDialog != null) {
                     window.parent.waitDialog.close();
                 }
             }
         }
     }
     app.controller(controllerId, Mycontroller);
     app.config(['$compileProvider', function ($compileProvider) {
         $compileProvider.aHrefSanitizationWhitelist(/^s*(https?|file|blob):/);
     }]);
 });
 
 <script type="text/javascript" src="../../../../SiteAssets/js/Scripts/jquery.min.js"></script>
 <script type="text/javascript" src="../../../../SiteAssets/js/Scripts/jquery.SPServices-2014.02.min.js"></script>
 <script type="text/javascript" src="../../../../SiteAssets/js/Scripts/angular.min.js"></script>
 <script type="text/javascript" src="../../../../SiteAssets/js/sppals/Controllers/Main.js"></script>
 
 <!--Services-->
 <script type="text/javascript" src="../../../../SiteAssets/js/sppals/Services/List_Context.js"></script>
 <script type="text/javascript" src="../../../../SiteAssets/js/sppals/Services/Utilities.js"></script>
 <div id="divNew" ng-app="Myapp">
     <ng-form id="EditForm" name="EditForm">
         <div ng-controller="Mycontroller">         
                                 <div>Attach Memo:</div>
                                 <div>
                                     <span id="attach">
                                         <input id="uploadFileID" type="file" ng-file-model="files" />
                                                                                 
                                         <p class="attach-Text" ng-repeat="file in attachedFile">
                                             <a target="_blank" href="{{file.ServerRelativeUrl}}" ng-href="{{file.ServerRelativeUrl}}">{{file.FileName}}</a>                                             
                                             <a title='Click to Remove' ng-click="removeFile(attachedFile, $index)">
                                                 <img class="deleteIcon" src='../../../../SiteAssets/img/Delete_icon.png' />
                                             </a>
                                         </p>                                        
                                     </span>                               
                                 </div>
             <input type="button" id="btnSave" ng-click="SaveButtonClick()" title="Click to Save" value="Save" />
         </div>
     </ng-form>    
 </div>
 

Happy Coding

Ahamed

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

How to Create View in SharePoint Office 365 Programmatically using Patterns and Practices PNP

Sathish Nadarajan
 
Solution Architect
September 15, 2017
 
Rate this article
 
Views
3476

A small code snippet to create View for a List or document library in SharePoint Office 365 using Patterns and Practices Programmatically.

1. Create a List called “Test List”

2. In that list, I have added two columns called Column1, Column2.

3. Now, I am going to create two Views

a. All Items Test

b. Created by Me

4. The XML for the views with the filter option, columns to be displayed etc., will be as below.

 <?xml version="1.0" encoding="utf-8" ?>
 <ListViews>
   <List Type='GenericList'>
     <View Name='All Items Test' ViewTypeKind='Html' OrderedView='TRUE' ViewFields='Edit,Column1,Column2,Author,Created,Editor,Modified' RowLimit='30' DefaultView='TRUE'>
       <ViewQuery>
         <!--<OrderBy>
           <FieldRef Name='URL'  Ascending='FALSE'/>
         </OrderBy>-->
       </ViewQuery>
     </View>
     <View Name='Created By Me' ViewTypeKind='Html' OrderedView='TRUE' ViewFields='Edit,Column1,Column2,Author,Created,Editor,Modified' RowLimit='30' DefaultView='FALSE'>
       <ViewQuery>
         <Where>
           <Eq>
             <FieldRef Name='Author' />
             <Value Type='Integer'>
               <UserID Type='Integer' />
             </Value>
           </Eq>
         </Where>
         <OrderBy>
           <FieldRef Name='Created'  Ascending='FALSE'/>
         </OrderBy>
       </ViewQuery>
     </View>   
   </List>
 </ListViews>
 

Now, the C# code to create both the views are as below.

 using Microsoft.SharePoint.Client;
 using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Reflection;
 
 namespace Office365.Console
 {
     class Program
     {
         static void Main(string[] args)
         {
             CreateView();
         }
 
         private static string testLists_Views = string.Empty;
         public static string TestLists_Views
         {
             get
             {
                 if (string.IsNullOrEmpty(testLists_Views))
                 {
                     using (var stream = Assembly.GetAssembly(typeof(Program)).GetManifestResourceStream("Office365.Console.Resources.TestList.ViewXml.xml"))
                     {
                         using (var reader = new StreamReader(stream))
                         {
                             testLists_Views = reader.ReadToEnd();
                         }
                     }
                 }
 
                 return testLists_Views;
             }
         }
 
         public static void CreateView()
         {
             OfficeDevPnP.Core.AuthenticationManager authMgr = new OfficeDevPnP.Core.AuthenticationManager();
 
 
 
             string siteUrl = "https://********.sharepoint.com/sites/DeveloperSite/";
              
             string userName = "sathish@********.onmicrosoft.com";
             string password = "**************";
 
             
             using (var clientContext = authMgr.GetSharePointOnlineAuthenticatedContextTenant(siteUrl, userName, password))
             {
                 try
                 {
                     Site site = clientContext.Site;
                     Web web = clientContext.Web;
                     PropertyValues properties = clientContext.Web.AllProperties;
 
                     clientContext.Load(site);
                     clientContext.Load(web);
                     clientContext.Load(web.Lists);
                     clientContext.Load(properties);
                     clientContext.ExecuteQuery();
 
                     List list = web.Lists.GetByTitle("Test List");
                     clientContext.Load(list);
                     clientContext.ExecuteQuery();
 
 
                     list.CreateViewsFromXMLString(TestLists_Views);
                     clientContext.Load(list.Views);
                     clientContext.ExecuteQuery();
                 }
                 catch (Exception ex)
                 {
                     System.Console.ForegroundColor = ConsoleColor.Red;
                     System.Console.WriteLine("Exception Occured : " + ex.Message);
                     System.IO.File.AppendAllText("C:\Temp\Exception.txt", ex.Message + " - " + siteUrl + Environment.NewLine);
                 }
 
 
             }
 
 
             System.Console.WriteLine("Completed....");
             System.Console.WriteLine("Press Any Key to Exit ....");
             System.Console.ReadLine();
         }
          
 
          
          
     }
 }
 

The solution structure will be as below.

clip_image002

The XML, I made it as “Embedded Resource”, so that, the deliverable should not contain this XML.

This is not necessary. But based on our requirement, we can choose this.

clip_image003

Happy Coding,

Sathish Nadarajan.

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

How to Break Inherit Permission and Grant Access to Specific User’s on SharePoint List/Library Items or Folders (Multiple) using SPServices and JavaScript

Ahamed Fazil Buhari
 
Senior Developer
February 4, 2017
 
Rate this article
 
Views
5882

When we want to grant access to folders or documents or simply for an item to a specific user, we go ahead and break the Inheritance and provide access to the specified user. If we want to achieve this by OOTB functionality then we can do it by Select an Item -> Document Permission (under Documents tab).

image

In permission window, Break the Inheritance and grant access to the specific user as per your requirement.

image

Same can be done in SharePoint 2013 environment, by selecting an Item and click on Shared With (under Files tab) and click on Advance in the permission popup.

image

Use the below script to give access to Multiple Folders or Library Documents to specific users and stop Inherit Permission

 var folderID = {};
 // Use SPServices or REST API to get all the item ID's
 $().SPServices({
     operation: "GetListItems",
     async: false,
     listName: "Shared Document",
     CAMLQuery: "<< Query based on your req. >>",
     completefunc: function (xData, Status) {
         $(xData.responseXML).SPFilterNode("z:row").each(function () {
         var folderVal = $(this).attr("ows_ID"); || '';
         if (folderVal != '') {
             var folder_ID = {};
             folder_ID["folderID"] = folderVal;
             folderID[folderVal] = folder_ID;            
         }
     }
 });
 

folderID, is a JSON object and it holds all the item ID’s which needs to break Inherit Permission and give access to specified users.

 ItemPermission(folderID, User1);
 ItemPermission(folderID, User2);
 
 function ItemPermission(folderID, userID) {
     SP.SOD.executeFunc("sp.js", 'SP.ClientContext', breakInheritanceChangeUser(folderID, userID));
 }
 
 function breakInheritanceChangeUser(folderID, userID, clearSubscops) {
     var context = SP.ClientContext.get_current();
     var oList = context.get_web().get_lists().getByTitle('Shared Document');
 
     $.each(folderID, function (key, value) {
 
         var folderID_int = parseInt(value.folderID);
         var oListItem = oList.getItemById(folderID_int);
 
         if (clearSubscops)
             oListItem.breakRoleInheritance(false, clearSubscops);
         else
             oListItem.breakRoleInheritance(false);
 
         var oUser = context.get_web().ensureUser(userID);
 
         var collRoleDefinitionBinding = SP.RoleDefinitionBindingCollection.newObject(context);
         collRoleDefinitionBinding.add(context.get_web().get_roleDefinitions().getByType(SP.RoleType.administrator));
         oListItem.get_roleAssignments().add(oUser, collRoleDefinitionBinding);
 
         context.load(oUser);
         context.load(oListItem);
 
         context.executeQueryAsync(onQuerySucceeded, onQueryFailed);
     });
 }
 
 function onQuerySucceeded(sender, args) {
 
 console.log('Role inheritance broken and given access to specific users');
 }
 
 function onQueryFailed(sender, args) {
 
 console.log('Request failed.');
 }

The below script can be used to remove the user from Item Permission list. We can use the same method to get the folder or item ID’s and store that in a JSON object

 ItemPermissionBreak(folderID, user1);
 ItemPermissionBreak(folderID, user2);
 
 
 function ItemPermissionBreak(folderID, userID){
     SP.SOD.executeFunc("sp.js", 'SP.ClientContext', breakUserPermission(folderID, userID));
 }
 
 function breakUserPermission(folderID, userID) {
     var context = SP.ClientContext.get_current();
     var oList = context.get_web().get_lists().getByTitle('Shared Document');
 
     $.each(folderID, function (key, value) {
 
         var folderID_int = parseInt(value.folderID);
         var oListItem = oList.getItemById(folderID_int);
 
         var oUser = context.get_web().ensureUser(userID);
 
         oListItem.get_roleAssignments().getByPrincipal(oUser).deleteObject();
 
         context.load(oUser);
         context.load(oListItem);
 
         context.executeQueryAsync(onQuerySucceeded, onQueryFailed);
     });
 
 }
 function onQuerySucceeded(sender, args) {
 
 console.log('User Permission has been removed');
 }
 
 function onQueryFailed(sender, args) {
 
 console.log('Request failed.');
 }
 

To know more about, BreakRoleInheritance please click here to refer in msdn site.

Happy Coding

Ahamed

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

How to Get all the SharePoint Choice Columns to Update Choice Options using JavaScript (Client Side Object Model) without going to List Settings

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Views
8555

Hello everyone, in this article we are going to look at the script to update the Choice Options in a SharePoint list. Here, I’m going to use SPServices to retrieve all the SharePoint Lists in that site and to get the Choice Columns in those Lists.

For example, If you want to edit any Choice Column in a List, then you need to go to that List -> List Settings -> click on that ‘Choice Column’ -> edit the ‘Options’ -> click on ‘OK’. This is how we do just like the below screenshot

image

Let’s say if you have more number of SharePoint Lists and there’s more number of Choice columns in those Lists. In this case it will be tedious process if you want to edit some of the Choice field and it will be time consuming. To overcome this, I’ve developed a script to retrieve all the SharePoint lists, Choice column in those lists in a single page and from there you can Insert, Delete, and Update the choices available for that dropdown.

image

HTML tags used for the above page is given below, Please make sure that you are using SharePoint page where ‘sp.js’ will be loaded.

——————X—————X——————

 <script type="text/javascript" src="../SiteAssets/jquery-1.10.2.js"></script>
 <script type="text/javascript" src="../SiteAssets/jquery.SPServices-2014.02.min.js"></script>
 <script type="text/javascript" src="../SiteAssets/Lists_Choice.js"></script>
 <div class="container">
     <h2>Choice Column Update</h2>         
 	This section is for PMO admins to update the Options in Choice columns
 	<br/><br/>
 	<table class="table1" width="100%">		        
 		<tr>
 		    <td><lable>Select the SharePoint List </lable>	</td>
 			<td><select id="ddlLists"></select></td>		            
 		</tr>
 
 		<tr>
 		    <td width="30%"><lable>Select the Dropdown Column from the above Selected List</lable></td>
 			<td><select id="ddlChoice"></select></td>		            
 		</tr>
 		<tr>
 		    <td><label>Options available for the above Selected Dropdown Column</label></td>
 			<td><textarea title="Drop Down Values" ID="txtDD" data-validate="required;textbox"></textarea>
 			<br/>Type each choice on a separate line</td>		            
 		</tr>		       
 		<tr>
 		    <td></td>
 			<td> <input type="button" id="Button1" onclick="ExecuteOrDelayUntilScriptLoaded(UpdateChoices, 'sp.js');" title="Click to Update" value="Update" style="float: none !important" />
 			<input type="button" id="btnrefresh" onclick="javascript: location.reload(true);" title="Click to Refresh" value="Refresh" style="float: none !important" /> 
 			</td>
 		    <td></td>
 		</tr>       
 	</table>
 </div>

——————X—————X——————

Please make sure that jquery.SPServices-2014.02.min.js and jquery-1.10.2.js files are referred in the page. Add the below script in the Lists_Choice.js file,

——————X—————X——————

 (function () {
 	$(document).ready(function () {
 		$("title").html("Choice Column Update");
 		$('#ddlLists').append("<option value=''>" + "--Select List--" + "</option>");
 		$('#ddlChoice').append("<option value=''>" + "--Select Choice--" + "</option>");
 		GetAllLists();
 		GetAllChoice();	
 		
 		ChoiceValues();
 	});
 } ());
 
 //To get all the Lists in the SharePoint site using SPServices and append the values to <select id="ddlLists"> tag
 function GetAllLists() {
 
 	$().SPServices({ 
 		operation: "GetListCollection", 
 		completefunc: function( xData, Status ) {	 
 			if (Status == "success") {
 			    $( xData.responseXML ).find("Lists > List").each(function() {
 			        var $node = $(this);					        
 			        //If you want only specific Lists, then make use of this "IF" and specify the List name
 			        if( ["Custom",
 			        	  "Phone",
 						].indexOf($node.attr("Title")) >= 0) {
 						
 				        appendField = $("#ddlLists");
 						$(appendField).append("<option value='" + $node.attr("Title") + "'>" + $node.attr("Title") + "</option>");
 					}
 			    });
 			}
 		} 
 	});
 	
 }
 
 //To get all the Choice columns based on the selected List using SPServices and append the values to <select id="ddlChoice"> tag
 function GetAllChoice() {
 	
 	$('#ddlLists').change(function() {
 		var listName = $(this).val();
 		$('#ddlChoice').empty();
 		$('#txtDD').empty();
 		$('#ddlChoice').append("<option value=''>" + "--Select Choice--" + "</option>");
 
 		$().SPServices({
 		  operation: "GetList",
 		  listName: listName,
 		  completefunc: function (xData, Status) {
 		    $(xData.responseXML).find("Fields > Field").each(function() {
 		        if($(this).attr("Type") === "Choice") {
 		        	$('#ddlChoice').append("<option value='" + $(this).attr("DisplayName") + "'>" + $(this).attr("DisplayName") + "</option>");		          
 		        }
 		     });
 		   }
 		});
 	});	
 }
 
 //Append the Choice values in a <textbox id="txtDD"> Textbox based on the selected choice
 function ChoiceValues() {
 	
 	$('#ddlChoice').change(function() {
 		var listName = $('#ddlLists :selected').val();
 		var choiceName = $(this).val();	
 		$('#txtDD').empty();
 		
 		$().SPServices({
 			operation: "GetList",
 			listName: listName,
 			completefunc: function (xData, Status) {
 			$(xData.responseXML).find("Field[DisplayName='" + choiceName +"'] CHOICE").each(function() {		            				    
 			    $('#txtDD').append($(this).text() + "n");	    
 			 });
 			}
 		});	
 	});
 }
 
 //Updating the Choice value using JS Client Object Model
 function UpdateChoices() {
 	
 	var listName = $('#ddlLists :selected').val() || "";
 	var choiceName = $('#ddlChoice :selected').val() || "";
 	var newOptions = $('#txtDD').val() || "";
 	
 	if(listName != "" && choiceName != "" && newOptions != "") {
 
 		var newOptionsArray = [];
 		var lines = newOptions.split(/n/);
 		
 		for (var i=0; i < lines.length; i++) {
 		  //Avoiding empty lines
 		  if (/S/.test(lines[i])) {
 		    newOptionsArray.push($.trim(lines[i]));
 		  }
 		}		
 	    
 		var context = new SP.ClientContext.get_current();
 		var web = context.get_web();
 		var cldList = web.get_lists().getByTitle(listName);
 		var categoryField = cldList.get_fields().getByInternalNameOrTitle(choiceName);
 		var categoryChoiceField = context.castTo(categoryField, SP.FieldChoice);
 		context.load(categoryChoiceField);
 		 
 		context.executeQueryAsync(function () {	  		    
 		    categoryChoiceField.set_choices(newOptionsArray);		      
 		    categoryChoiceField.updateAndPushChanges();
 		    context.executeQueryAsync(function () { 
 		        alert(choiceName + ' choice column updated successfully.');
 		    }, 
 		    function () { 
 		        alert('Error in updating the choice column');
 		    });
 		    
 		}, function () { 
 			alert('Error in updating the choice column');
 		});	
 	}
 	else {
 		alert('Please select the list and choice');
 	}
 }

——————X—————X——————

Now I can easily update any dropdown options available in the SharePoint lists.

image

After click on Update it will update the Dropdown options in that list.

image

I hope this article will be helpful for the readers who needs to Insert, Delete and Update dropdown choice columns quickly and easily. Thank you for reading.

Happy Coding

Ahamed

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

How to Enable Enterprise Metadata and Keywords Settings in SharePoint Office 365 Lists Programmatically using CSOM C#

Sathish Nadarajan
 
Solution Architect
January 5, 2017
 
Rate this article
 
Views
5782

In this article, let us see how to enable Enterprise Metadata and Keywords Settings in SharePoint Office 365 Lists Programmatically using CSOM C#

To do that Manually, we need to go to the List settings, click on the below highlighted link as shown in the figure.

 

image

 

Select the Check Box.

 

image

 

The New column called “Enterprise Keywords” will be added to the list.

To do this through program, we need to do the reverse way. If we Add the column “Enterprise Keywords”, then the “Enterprise Keywords” settings will be enabled automatically.

Hence, the code to add the field to the list is as follows.

 namespace Sathish.Demo
 {
     using Microsoft.SharePoint.Client;
     using System;
 
     class Program
     {
         static void Main(string[] args)
         {
             EnableEnterpriseKeywords();
         }
 
         public static void EnableEnterpriseKeywords()
         {
             OfficeDevPnP.Core.AuthenticationManager authMgr = new OfficeDevPnP.Core.AuthenticationManager();
             
             string siteUrl = "https://*******.sharepoint.com/sites/CommunitySite";
             string userName = "Sathish@******";
             string password = "******************";
 
             using (var clientContext = authMgr.GetSharePointOnlineAuthenticatedContextTenant(siteUrl, userName, password))
             {
                 try
                 {
                     Web web = clientContext.Web;
                     
                     clientContext.Load(web);
                     clientContext.Load(web.Lists);
                     clientContext.ExecuteQuery();
 
                     List list = web.Lists.GetByTitle("Documents");
 
                     if (!list.FieldExistsByName("Enterprise Keywords"))
                     {
                         var field = clientContext.Site.RootWeb.Fields.GetByInternalNameOrTitle("Enterprise Keywords");
                         list.Fields.Add(field);
                         clientContext.Load(list);
                     }
 
                      
 
                     clientContext.ExecuteQuery();
 
                 }
                 catch (Exception ex)
                 {
                     System.Console.ForegroundColor = ConsoleColor.Red;
                     System.Console.WriteLine("Exception Occured : " + ex.Message);
                     System.IO.File.AppendAllText("C:\Temp\Exception.txt", ex.Message + " - " + siteUrl + Environment.NewLine);
                 }
             }
 
             System.Console.WriteLine("Completed....");
             System.Console.WriteLine("Press Any Key to Exit ....");
             System.Console.ReadLine();
         }
     }
 }
 

The output will be like this.

 

image

 

Happy Coding,

Sathish Nadarajan.

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

Remove Back-to-site Link in the published NINTEX Form in Office 365

Sriram Varadarajan
 
Solution Architect
October 31, 2016
 
Rate this article
 
Views
4018

Adding a Nintex form to Office 365 list creates a navigation link named “Back to Site” which may not be required in all scenarios. In this blog post , we can see how to remove that auto-generated link from a list form.

Let’s assume we have got a list where we want to add a NINTEX FORM. Here is what we’re expected to do:

· Navigate to list

· Click the Ribbon

· Select Nintex Forms

This will take us to the NINTEX tenant as below

clip_image002

Here we will add our FORM and once done we will publish it.

After successful publishing, when you click the NEW ITEM button of our list

clip_image004

This will take us to the NINTEX form which we have just created above.

clip_image006

Here come our actual requirements; our demand is to hide the BACK TO SITE link in the top navigation bar.

As of now we have got 2 options to achieve this:

Option 1:

1. Navigate to the List and click on the List Tab.

2. Then click on the List Settings. 

3. In the Settings page, under General Settings, click on Advanced Settings.

4. In the Advanced Settings page, scroll down to find the Dialogs Option. Select Yes to open the forms in dialog. Once selected, click OK to save the changes.

5. Navigate back to the list and test the functionality with New, Display and Edit Item.

Limitation:

The redirect Url property of the Nintex form works when the form is not opened as Pop Up. If the above List is being called from Another Form as a redirect URL it mightn’t work as of now (this is a known issue and NINTEX is working on it)

Option 2:

1. Navigate to the List and click on the List Tab

2. Then click on the “Nintex Form’.

3. In the Nintex form, click ‘Form Settings’ from top ribbon.

4. Then click ‘Custom CSS’ and add the below line inside the editor window.

5. nf-ribbon-fixed-top {visibility: collapse;}       //To hide the save and cancel ribbon bar

6. nf-ribbon-fixed-chromeTop {visibility: collapse;}  //To hide the ‘Back to Site’ title bar

7. Then click save button.

8. Once saved click publish link from top ribbon.

Limitation:

This may not work if Nintex changes their CSS Class names in the future. Till then we can use this solution Smile

Author Info

Sriram Varadarajan
 
Solution Architect
 
Rate this article
 
Sriram is a Technology Evangelist with 15+ years experience in Microsoft Technologies. He is an enterprise architect working for large pharmaceutical organization which has presence globally with largest Microsoft implementation ...read more
 

Leave a comment