5

I have Office 365 Business plan, from SharePoint private root site collection. I need to use CSR files with my List views, but when I open the view web part properties, I can't find the "JS Link" property.

enter image description here

Note: this issue appear with default Office 365 root site, but when I create new site collection this issue doesn't appear. also when I remove the site and create another root site, this issue doesn't appear.

Update: I create a new office 365 trial subscription, and I opened the root SharePoint site, and it has this issue. so, to solve this issue, I delete the site and created again. but I can't delete the original one, because it has a lot of data.

5

In SharePoint Admin Center you have to change the "Custom Script" option to "Allow". After this change, system will take around 24 hours to affect the site collection settings. Then that JS Link option will show up.

  • Allow users to run custom script on personal sites
  • Allow users to run custom script on self-service created sites

O365 Admin--> SharePoint --> Settings

If you want it to be run right away after these settings then use the below mentioned PowerShell commands

Connect-SPOService -Url https://sitename-admin.sharepoint.com/ -credential admin@sitename.onmicrosoft.com

Set-SPOSite -Identity https://sitename.sharepoint.com/ -DenyAddAndCustomizePages $false

echo "Successfully completed."

pause
  • 1
    I tried it and it is mot working, and this is not personal or self-service site, it is team site collection created by admin – jobin Mar 25 '15 at 15:33
  • It is strange,your solution working and you are right. but I wait more than 24 hours. thank you, I'm sorry because the 50 bounties want to Andrey and not for you. anyway he deserve it because his answer go beyond the solution and touch root of problem. – jobin Apr 2 '15 at 16:10
  • 1
    @jobin thanks for your kind words :) Btw, are you completely sure these were the ones that actually fixed the problem, or was it some MS patch that was applied at same time and closed a bug? According to my investigation, these two is the closest we have in o365 tenant administration to "AllowContributorsToEditScriptableParts" on-prem setting, yes, and they can be the reason, but in SharePoint it is sooooo hard to say for sure, you know :) – Andrey Markeev Apr 2 '15 at 19:49
  • not sure, I'll subscribe to new office 365 and check if the issue fixed, and I'll update you here – jobin Apr 3 '15 at 6:10
  • @AndreyMarkeev, yes it tried it again, this solution works – jobin Apr 4 '15 at 8:06
13
+50

I investigated the source code (the most credible source!!) of XsltListViewWebPart in dotPeek and it turns out there can be two reasons for this behavior:

  1. Check that you have Contributor permissions on the web (in particular, "AddAndCustomizePages" permission is needed)
  2. If you have, I'm afraid you should contact MSFT and tell them that the web application that you're running your tenant on has wrong value set for "Scriptable Web Parts" setting: https://technet.microsoft.com/en-us/library/hh272821(v=office.14).aspx

Also, if you hit the former case, please check out Workarounds section below.

If you're interested of how I came up with such results, then here's the story:

In a galaxy far, far away...

XsltListViewWebPart has 5 custom web part properties:

private static List<CustomWebPartProperty> customXlvProps = new List<CustomWebPartProperty>()
{
  new CustomWebPartProperty()
  {
    PropertyName = "ServerRender",
    PropertyDescription = "ServerRenderDescription",
    Catetory = "Miscellaneous",
    RequiresDesignerPermission = false,
    IsCSROnly = false,
    V14Hidden = true
  },
  new CustomWebPartProperty()
  {
    PropertyName = "DisableViewSelectorMenu",
    PropertyDescription = "DisableViewSelectorMenu",
    Catetory = "Miscellaneous",
    RequiresDesignerPermission = false,
    IsCSROnly = true
  },
  new CustomWebPartProperty()
  {
    PropertyName = "DisableSaveAsNewViewButton",
    PropertyDescription = "DisableSaveAsNewViewButton",
    Catetory = "Miscellaneous",
    RequiresDesignerPermission = false,
    IsCSROnly = true
  },
  new CustomWebPartProperty()
  {
    PropertyName = "InplaceSearchEnabled",
    PropertyDescription = "InplaceSearchEnabled",
    Catetory = "Miscellaneous",
    RequiresDesignerPermission = false,
    IsCSROnly = true
  },
  new CustomWebPartProperty()
  {
    PropertyName = "JSLink",
    PropertyDescription = "JSLinkDescription",
    Catetory = "Miscellaneous",
    RequiresDesignerPermission = true,
    propertyType = SPClientWebPartElement.ClientWebPartPropertyType.String,
    V14Hidden = true
  }
};

As you see, each property has some parameters, in particular we're interested in parameters that can lead to webpart not being displayed. There're three of those:

  1. RequiresDesignerPermission
  2. IsCSROnly
  3. V14Hidden

On your screenshot, however, I can see that all properties are shown except of JSLink. From this I can infer that IsCSROnly and V14Hidden are not what we need, because ServerRender has V14Hidden=true - and it is shown, and other properties have IsCSROnly=true and they're shown.

This leaves us with RequiresDesignerPermission.

But I don't quite trust SharePoint, and can't rely on nice property names, as they can be misleading. Thus I double-checked the code. Just in case :)

So the customXlvProps field is only used in one place, here:

List<SPEditorPartProperty> IWebPartToolPaneCustomProperties.GetToolPaneCustomProperties(bool excludeSharedProperties)
{
  return new CustomWebpartPropertyHelper((WebPart) this, XsltListViewWebPart.customXlvProps, this.ClientRender)
             .GetToolPaneCustomProperties(excludeSharedProperties);
}

CustomWebpartPropertyHelper is a short class. Constructor doesn't do anything intelligent, just assigns parameters to local class fields.

Now, the GetToolPaneCustomProperties contains the following code:

  List<SPEditorPartProperty> list1 = new List<SPEditorPartProperty>();
  foreach (CustomWebPartProperty customWebPartProperty in this._customWebPartProps)
  {
    if ((!customWebPartProperty.IsCSROnly || this._bClientRender) && (!customWebPartProperty.V14Hidden || SPUtility.IsCompatibilityLevel15Up))
    {

      // skipped for clarity...

      // if property type is string, the following code is run:

      editorPartProperty = (SPEditorPartProperty) 
        new SPEditorPartStringProperty(
            customWebPartProperty.PropertyName, 
            @string,
            customWebPartProperty.RequiresDesignerPermission);

      // skipped for clarity...

      editorPartProperty.Description = WebPartPageResource.GetString(customWebPartProperty.PropertyDescription);
      editorPartProperty.Category = WebPartPageResource.GetString(customWebPartProperty.Catetory);
      editorPartProperty.SyncChanges += new SPEditorPartProperty.SyncChangesHandler(this.ToolPane_OnSyncChanges);
      editorPartProperty.ApplyChanges += new SPEditorPartProperty.ApplyChangesHandler(this.ToolPane_OnApply);
      list1.Add(editorPartProperty);
    }
  }
  return list1;

So I can infer that JSLink property is actually added to this particular list, and RequiresDesignerPermission is checked on some later stage.

Let's follow it and peek into the SPEditorPartStringProperty class.

This class is a very small thing that is nothing interesting by itself, but it derives from SPEditorPartProperty, which has the RequiresDesignerPermission property!

After some more digging I found, that this property is used only in one place in Microsoft.SharePoint assembly: in CreateChildControls method of the CustomPropertyToolPart class. This method contains the following code:

      foreach (ExtendedPropertyInfo propInfo in this.m_propsCol.Values)
      {
        SPEditorPartProperty propertySheetProperty = PropertySheetProperty.CreatePropertySheetProperty(this.TargetWebPart, propInfo, true, (string) null, (SPEditorPartChoicePropertyItem[]) null);
        propertySheetProperty.SyncChanges += new SPEditorPartProperty.SyncChangesHandler(this.OnSyncChanges);
        propertySheetProperty.ApplyChanges += new SPEditorPartProperty.ApplyChangesHandler(this.OnApply);
        if (SPWebPartManager.CanUserScript(this.Web) || !propertySheetProperty.RequiresDesignerPermission)
          list.Add(propertySheetProperty);
      }

So as you can see, the property is NOT added if it has RequiresDesignerPermission==true AND SPWebPartManager.CanUserScript(this.Web)==true.

Ok, let's see what CanUserScript does:

internal static bool CanUserScript(SPWeb web)
{
  return web.AllowContributorsToEditScriptableParts || 
  ((SPSecurableObject) web).DoesUserHavePermissions(SPBasePermissions.AddAndCustomizePages);
}

Aha! So here is the first reason: check for AddAndCustomizePages permission.

And finally, let's see what is this AllowContributorsToEditScriptableParts:

internal bool AllowContributorsToEditScriptableParts
{
  get
  {
    return this.Site.WebApplication.AllowContributorsToEditScriptableParts;
  }
}

Alright, so it gets the value from WebApplication properties. Based on my investigation, there isn't any possibility to access or change this property for a tenant. Of course, O365 code is different from On-Premise code, so I cannot say this with 100 percent certainty, but tenant administrator portal is not that big, and I intently went through all the settings in there, and there isn't anything similar there except of the Custom Script setting, which only applies for self-service and personal sites, and which you reported that you already tried.

Workarounds

If you have the permissions, then you'll have to deal with MSFT to resolve the issue, and unfortunately this often is just a waste of time. So if you need a solution for this problem, please try workarounds that I explain below.

Use SharePoint Designer for changing JSLink

Open your list in SharePoint Designer, then click to the view, and in the page editor you should be able to find the JSLink tag. Change its contents and that's it.

Use JSOM or CSOM for changing JSLink

JSOM code is something like this:

var wpId = // please put GUID of your webpart here.
// you should be able to find this GUID by inspecting the page

var jsLinkString = // please put the path to your js file here, same as you 
// would put it into JSLink webpart property

var context = SP.ClientContext.get_current();
var page = context.get_web().getFileByServerRelativeUrl(_spPageContextInfo.serverRequestPath);
var wpm = page.getLimitedWebPartManager(SP.WebParts.PersonalizationScope.shared);
var webpartDef = wpm.get_webParts().getById(new SP.Guid(wpId));
var webpart = webpartDef.get_webPart();
var properties = webpart.get_properties();
context.load(properties);

context.executeQueryAsync(function () {
   properties.set_item("JSLink", jsLinkString);
   webpartDef.saveWebPartChanges();
   context.executeQueryAsync(function () {
       alert('done');
   },
   function() {
       alert('error on step 2');
   });

},
function() {
  alert('error');
});

Also similar code can be used for CSOM or PowerShell (also via CSOM, of course). And consider setting JSLink of Field or ContentType, as the code for this will be much simpler.

Use any other method to deploy script to the page

CSR customizations can be of course deployed to page using any other method, as they actually don't depend on JSLink anyhow. If you didn't know about this, I recommend this article:

(Disclaimer: I'm the author of this article)

So actually you can deploy CSR customizations using even ScriptEditorWebPart or CEWP, although in this case Minimal Download Strategy may not work. Best way probably would be to use ScriptLink custom action, although it means that script will be deployed everywhere throughout the site of course. Custom action can be added using No-code Sandbox Solution, JSOM or CSOM.

Use Cisar

Cisar is a tool I wrote for creating CSR customizations fast. It is a Live Edit for CSR: so you write code, and instantly see how it your list form or list view transforms according to what you write. The tool is opensource and available on GitHub (technically it is a Chrome extension).

If you write CSR customizations a lot, as do I, it may be of help. And it attaches files to webparts on page via JSLink automatically, using JSOM, so you don't need to care about opening that.

  • 1
    +1 Great answer! – Vadim Gremyachev Mar 27 '15 at 18:31
  • @Andrey, thank you for your detailed answer, first I'm using admin account to manage the SharePoint site, second this is not a special case, I created 3 new office 365 subscription (trial) and this issue appear with all of them. – jobin Mar 28 '15 at 15:42
  • but if I delete the root site and create a new one, this will solve the issue – jobin Mar 28 '15 at 16:27
  • 1
    @jobin well I guess there's something wrong with their tenant template then. Anyway, seems to be their bug. Have you tried some of the workarounds? – Andrey Markeev Mar 28 '15 at 19:15
  • 1
    Almost seems like TOO much detail, but I'll give you +1 anyway. Takes a little digging, but the right takeaways are in there. – Omegacron Apr 2 '15 at 16:38
1

Recently i also stumbled upon the similar issue and tend to believe it is related with SP.PermissionKind.AddAndCustomizePages permission level as Andrey pointed out in his answer.

This behavior is caused by Custom Script feature, basically the issue occurs when the Custom Script feature is turned off

How to verify?

You could verify the site permissions for a current user using the following console app:

using (var ctx = GetContext(webUri, userName, password))
{
    var rootWeb = ctx.Site.RootWeb;
    ctx.Load(rootWeb, w => w.EffectiveBasePermissions);
    ctx.ExecuteQuery();
    var permissions = rootWeb.EffectiveBasePermissions;
    foreach (var permission in Enum.GetValues(typeof(PermissionKind)).Cast<PermissionKind>())
    {
        var permissionName = Enum.GetName(typeof(PermissionKind), permission);
        var hasPermission = permissions.Has(permission);
        Console.WriteLine("Permission: {0}, HasPermission: {1}", permissionName, hasPermission);
    }   
}

where

public static ClientContext GetContext(Uri webUri, string userName, string password)
{
    var securePassword = new SecureString();
    foreach (var ch in password) securePassword.AppendChar(ch);
    return new ClientContext(webUri) {Credentials = new SharePointOnlineCredentials(userName, securePassword)};
}

When Custom Script feature is turned off, SP.PermissionKind.AddAndCustomizePages will be returned as False, no matter whether you are site collection administrator or not(!).

enter image description here

Solution

According to Turn scripting capabilities on or off:

For self-service created sites, custom scripting is disabled by default

Solution: enable Allow users to run custom scripts on self-service created sites

Manual way

To enable or disable scripting from the SharePoint admin center

  1. Sign in to Office 365 with your work or school account.
  2. Go to the SharePoint admin center.
  3. Select Settings.
  4. Under Custom Script choose:

    • Prevent users from running custom script on personal sites or Allow users to run custom script on personal sites.

    • Prevent users from running custom script on user created sites or Allow users to run custom script on self-service created sites.

    enter image description here

  5. Select OK. It takes about 24 hours for the change to take effect.

Programmatic way

Since any change to the scripting setting made through the SharePoint Online admin center may take up to 24 hours to take effect, you could enable scripting on a particular site collection immediately via CSOM API (SharePoint Online Client Components SDK) as demonstrated below:

public static void DisableDenyAddAndCustomizePages(ClientContext ctx, string siteUrl)
{
    var tenant = new Tenant(ctx);
    var siteProperties = tenant.GetSitePropertiesByUrl(siteUrl, true);
    ctx.Load(siteProperties);
    ctx.ExecuteQuery();

    siteProperties.DenyAddAndCustomizePages = DenyAddAndCustomizePagesStatus.Disabled;
    var result = siteProperties.Update();
    ctx.Load(result);
    ctx.ExecuteQuery();
    while (!result.IsComplete)
    {
        Thread.Sleep(result.PollingInterval);
        ctx.Load(result);
        ctx.ExecuteQuery();
    }
}

Usage

using (var ctx = GetContext(webUri, userName, password))
{
    using (var tenantAdminCtx = GetContext(tenantAdminUri, userName, password))
    {                  
         DisableDenyAddAndCustomizePages(tenantAdminCtx,webUri.ToString());
    }
 }

Alternatively you could use the following PowerShell command:

Set-SPOsite <SiteURL> -DenyAddAndCustomizePages 0
1

Alright, So it seems there are 2 ways to achieve the "Miscellaneous" tab for edit web part properties. JSLink is available under this tab only.

  1. As suggested by very first answer - you can enable it from site admin center. (But It can take up to 24 hours for the change to take effect.)
  2. you can directly run this powershell commands to activate at your site level. (This will be reflected immediately)

    Connect-SPOService -url https://your_tenant_name-admin.sharepoint.com

    Set-SPOSite https://your_tenant_name.sharepoint.com/sites/mysite -DenyAddAndCustomizePages 0

You can read more at : MSDNReference : allow-or-prevent-custom-script

-1

Check if the JavaScript Display Template Site Content Type is available (Site Settings -> Site Content Types). Also you need to add this Content Type to the Master page gallery as List content type.

  • 1
    what is the relation between "JavaScript Display Template Site Content Type" and JS Link propriety for web part?! anyway I'll try it – jobin Mar 25 '15 at 16:28
  • Java Script Display Template is what JSLink is for. – Gwny Mar 26 '15 at 12:16
  • Unfortunately, there is no "site content type" option under site setting, but I open it using _layouts/15/mngctype.aspx, and the "JavaScript Display Template" is there – jobin Mar 31 '15 at 18:46
-1

Please check that "JavaScript Display Template" is available under site content type in your site collection. if it is not available than you are not able to get "JS Link" Property.

To Support the new “JS Link Property” Microsoft has added a new Content type JavaScript Display Template. Adding JavaScript Files as JavaScript Display Template provides users few Site Columns like Target element(view,webpart etc..), Source Site etc. that can help users to specify the metadata Properties of the JavaScript File that is going to be used in a JS Link property for a particular List or Web part.

  • Unfortunately, there is no "site content type" option under site setting, but I went to _layouts/15/mngctype.aspx, and the "JavaScript Display Template" is there – jobin Mar 31 '15 at 18:39
  • There is an option in site setting under "Web Designer Galleries" for site content type. – Hardik Apr 1 '15 at 10:31
  • _layouts/15/mngctype.aspx the same – jobin Apr 1 '15 at 10:49
-2

I think you create your list collection site, you need to create it in the subsite, otherwise you will not have the possibility to use JSLINK.

For my case :

https://NameSite.sharepoint.com**/sites/Dev/** 

it works well.

But with :

https://NameSite.sharepoint.com 

it does not work

  • Please include some description or hints about the solution as the link to the article may get broken later. – user19105 Mar 13 '15 at 9:57
  • The link is broken. Can you give your answer right here, instead? – Denis Molodtsov Mar 13 '15 at 9:57
  • Yes, this is true, I can't created on the root, but this is the question. why I can't create it on the root? – jobin Mar 31 '15 at 18:36
  • you can see that : In SharePoint Admin Center you have to enable "Custom Script" options to "Allow". After this change, system will take around 24 hours to affect the site collection settings. Then that JS Link option will show-up. Allow users to run custom script on personal sites Allow users to run custom script on self-service created sites O365 Admin--> SharePoint --> Settings – Lasri Apr 1 '15 at 19:23

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.