I have to customize sharepoint 2013 document set welcome page(document set properties web part) and
I am not able to find the document set home aspx page
Can I use any client context model to fetch the data and display doc set properties.
Just create a new content type inheriting from Document Set, add the extra columns and set which ones need to be shown on the welcome page via the Document Set settings link when editing the Content Type. Also under the Document Set settings page you can click on 'Customize the Welcome Page' which allows you to edit the page just like any other web part page.
On the second point the client context will need to be connected to the web that contains the list and specific document set you're after, the identity used to connect will need permissions to the document set.
Edit:
To customize the look and feel by injecting JavaScript/CSS you'll need to make use of the ScriptLink custom action.
This lets you inject a custom piece of JavaScript into all pages. In the script you'll need logic to determine if the custom CSS should be applied, and if so Inject it.
The C# for injecting a script block via ScriptLink Custom Action:
public void AddJsLink(ClientContext ctx, Web web)
{
string scenarioUrl = String.Format("{0}://{1}:{2}/Scripts", this.Request.Url.Scheme,
this.Request.Url.DnsSafeHost, this.Request.Url.Port);
string revision = Guid.NewGuid().ToString().Replace("-", "");
string jsLink = string.Format("{0}/{1}?rev={2}", scenarioUrl, "injectStyles.js", revision);
StringBuilder scripts = new StringBuilder(#"
var headID = document.getElementsByTagName('head')[0];
var");
scripts.AppendFormat(#"
newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = '{0}';
headID.appendChild(newScript);", jsLink);
string scriptBlock = scripts.ToString();
var existingActions = web.UserCustomActions;
ctx.Load(existingActions);
ctx.ExecuteQuery();
var actions = existingActions.ToArray();
foreach (var action in actions)
{
if (action.Description == "injectnavigation" &&
action.Location == "ScriptLink")
{
action.DeleteObject();
ctx.ExecuteQuery();
}
}
var newAction = existingActions.Add();
newAction.Description = "injectnavigation";
newAction.Location = "ScriptLink";
newAction.ScriptBlock = scriptBlock;
newAction.Update();
ctx.Load(web, s => s.UserCustomActions);
ctx.ExecuteQuery();
}
Then your JavaScript would have something like:
if(window.location.href.indexOf(patternToMatchToDocSetpage)>-1) {
var link = document.createElement("link");
link.href = "http://example.com/mystyle.css";
link.type = "text/css";
link.rel = "stylesheet";
document.getElementsByTagName("head")[0].appendChild(link);
}
I'd advise you to take a look at the relevant PnP sample on script link injection
Related
I am trying to create a custom action that can be chosen by right-clicking on a file in a any folder of a particular SharePoint Library. This custom action would copy the file into the same folder with the user's login name appended to the end of the file name.
I currently have an event receiver that will perform the custom action when a file is being updated but that's not when I want it to happen. I was able to add a custom action to the right-click file menu using SharePoint Designer but SharePoint Designer only lets the custom action trigger special SharePoint 2010 compatible workflows or load a web page. I need to make it so the event handler (or possibly a workflow) fires when the user chooses the custom action after right-clicking on the file. I'm not sure what approach or what kind of project or app I need to create in Visual Studio 2017 to get this functionality.
Your custom action should call javascript function or perform GET request to your SharePoint hosted WCF or ASMX WebService.
ASMX
Official MSDN Walktrought: Creating a Custom ASP.NET Web Service
For additional resources with more screenshots check this blog post: Walkthrough: Creating a Custom ASP.NET (ASMX) Web Service in SharePoint 2010
WCF
Official Technet Walkthrough: SharePoint 2013: Create a Custom WCF REST Service Hosted in SharePoint and Deployed in a WSP
Note: with GET request you will need web.AllowUnsafeUpdate = true
With javascript u need AJAX call ie jQuery.ajax()
/edit
To hook up web service and your custom action use SharePoint Desinger, delete or change your existing custom action, change type to Navigate to URL and in the textbox type:
javascript: (function() { console.log('Testing...' + {ItemId}); /* your web service call */ })();
Use {ItemId} alias to pass proper item id to your AJAX call.
On the other hand, on web service side use SPWorkflowManager class to start a workflow on item. Check the code belowe (link):
public void StartWorkflow(SPListItem listItem, SPSite spSite, string wfName) {
SPList parentList = listItem.ParentList;
SPWorkflowAssociationCollection associationCollection = parentList.WorkflowAssociations;
foreach (SPWorkflowAssociation association in associationCollection) {
if (association.Name == wfName){
association.AutoStartChange = true;
association.AutoStartCreate = false;
association.AssociationData = string.Empty;
spSite.WorkflowManager.StartWorkflow(listItem, association, association.AssociationData);
}
}
}
I found a way to do this using JavaScript, without SharePoint Designer. I put the following script in a Content Editor web part on the page where the listview webpart is and now I can right click on a file and get the option to "Get My Copy". If you have a Comments sub folder, the renamed copy will get put there.
<script type="text/javascript">
// adds the menu option to Get My Copy
function Custom_AddDocLibMenuItems(m, ctx)
{
var strDisplayText = "Get My Copy"; //Menu Item Text
var strAction = "copyFile()";
var strImagePath = ""; //Menu item Image path
CAMOpt(m, strDisplayText, strAction, strImagePath); // Add our new menu item
CAMSep(m); // add a separator to the menu
return false; // false means standard menu items should also be rendered
}
// append current user account to filename and copy to subfolder named Comments
function copyFile()
{
// get web and current user from context
var context = new SP.ClientContext.get_current();
var web = context.get_web();
this.currentUser = web.get_currentUser();
context.load(currentUser);
// load the folder
var currentFolder = decodeURIComponent(ctx.rootFolder);
var folderSrc = web.getFolderByServerRelativeUrl(currentFolder);
context.load(folderSrc,'Files');
context.executeQueryAsync(
function() {
// get the first (and hopefully only) file in the folder
var files = folderSrc.get_files();
var e = files.getEnumerator();
e.moveNext()
var file = e.get_current();
// get user account
var curUserAcct = currentUser.get_loginName();
curUserAcct = curUserAcct.substring(curUserAcct.indexOf("\\") + 1);
// get file without extension
var file_with_ext = file.get_name();
var name_without_ext = file_with_ext.substr(0, file_with_ext.lastIndexOf("."));
var destLibUrl = currentFolder + "/Comments/" + name_without_ext + " " + curUserAcct + ".docx";
file.copyTo(destLibUrl, true);
context.executeQueryAsync(
function() { alert("Success! File File successfully copied to: " + destLibUrl); },
function(sender, args) { alert("error: " + args.get_message()) }
);
},
function(sender, args){ alert("Something went wrong with getting current user or getting current folder '" + currentFolder + "'. " + args.get_message()); }
);
}
</script>
I am not able to create a list content type using the below snippet. It throws a ServerException with additional information - "The site content type has already been added to this list."
var list = clientContext.Web.Lists.GetByTitle("sometitle");
var documentCT = clientContext.Web.ContentTypes.GetById("0x0101");
clientContext.Load(list,l=> l.ContentTypes);
clientContext.Load(documentCT);
clientContext.ExecuteQuery();
var test = new ContentTypeCreationInformation(){
Name = "TestCT", ParentContentType =documentCT };
list.ContentTypes.Add(test);
list.Update();
clientContext.ExecuteQuery();
Basically, I want to create a list content type whose parent is the "Document" CT.
I encountered this same problem.
What is happening here is that you have added the content type to the list successfully but you haven't turned on "allow management of content types" in Library settings > Advanced Settings > First setting. You will not see the content type via the UI.
Once you turn on this setting you will see your content type was in fact added.
Here's how I create a library
public static List CreateLibrary(ClientContext context, string title, bool allowContentTypes)
{
ListCreationInformation lci = new ListCreationInformation
{
Description = "Library used to hold Dynamics CRM documents",
Title = title,
TemplateType = 101,
};
List lib = context.Web.Lists.Add(lci);
lib.ContentTypesEnabled = allowContentTypes ? true : false;
lib.Update();
context.Load(lib);
context.ExecuteQuery();
return lib;
}
For your case just add in the line:
list.ContentTypesEnabled = true;
Don't forget the list.Update(), I see you have it in your code but for anyone else, this part is essential before you use ExecuteQuery()
I created a webpart, then I created a second .cs page that will render custom html. It basically just a simple page to show an image. However in the second .cs page, I need to access custom settings in the Web Part. How can I access custom tool pane settings in the main web part when the link to the secondary page is clicked?
The second page is generated from VS 2010 and is in the layouts folder, looks like:
public partial class GetFile : LayoutsPageBase
{
I am thinking I have to inherit something from the web part in order to do this, but really not sure how?
You can access the Web part properties using the SPLimitedWebPartManager class by reading the web part collection and their properties on the page as shown below,
var web = SPContext.Current.Web;
var currentPageURL = "//URL of the page on which the Web part is present";
var page = web.GetFile(currentPageURL);
using (SPLimitedWebPartManager webPartManager = page.GetLimitedWebPartManager(PersonalizationScope.Shared))
{
try
{
var webPartList = from System.Web.UI.WebControls.WebParts.WebPart webPart in webPartManager.WebParts select webPart;
foreach (System.Web.UI.WebControls.WebParts.WebPart webPart in webPartList.ToList())
{
if (webPart.Title.ToLower() == "//Name of the web part for which you want to read the properties")
{
PropertyInfo[] wptProperties = webPart.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo property in wptProperties)
{
if (property.Name == "//Name of the web property which you want to get")
{
// Following code updates the web part property, you can also read it
property.SetValue(webPart, "value to be set", null);
webPartManager.SaveChanges(webPart);
break;
}
}
}
}
Response.Redirect(currentPageURL);
}
finally
{
webPartManager.Web.Dispose();
}
}
how to create document set in document library programmatically in sharepoint server 2010?
If you want to use client object model for this:
{
ClientContext clientContext = new ClientContext("http://<<SERVER_NAME>>");
Web site = clientContext.Web;
// Create a list.
ListCreationInformation listCreationInfo =
new ListCreationInformation();
listCreationInfo.Title = "Document Library";
listCreationInfo.TemplateType = (int)ListTemplateType.DocumentLibrary;
List list = site.Lists.Add(listCreationInfo);
// Enable Content Types on list
list.ContentTypesEnabled = true;
// Update List Configuration
list.Update();
// Send it to SharePoint
clientContext.ExecuteQuery();
// Get Content Type Document Set ID = 0x0120D520
ContentType ctx = clientContext.Site.RootWeb.AvailableContentTypes.GetById("0x0120D520");
// Add Existing To List
list.ContentTypes.AddExistingContentType(ctx);
// Execute
clientContext.ExecuteQuery();
}
http://msdn.microsoft.com/en-us/library/gg581064.aspx
Afterwards add an item of that contenttype.
I tried searching on the net to programmatically insert a List as a webpart in a webpart page but was not lucky enough.
Any thoughts or ideas how i could Programmatically insert a List as a webpart in a webpart page
Many Thanks!
First add these using statements.
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;
Then in your code
// First get the list
SPSite site = new SPSite("http://myserver");
SPWeb web = site.OpenWeb();
SPList list = web.Lists["MyCustomlist"];
// Create a webpart
ListViewWebPart wp = new ListViewWebPart();
wp.ZoneID = "Top"; // Replace this ith the correct zone on your page.
wp.ListName = list.ID.ToString("B").ToUpper();
wp.ViewGuid = list.DefaultView.ID.ToString("B").ToUpper();
// Get the web part collection
SPWebPartCollection coll =
web.GetWebPartCollection("default.aspx", // replace this with the correct page.
Storage.Shared);
// Add the web part
coll.Add(wp);
If you want to use a custom view, try playing with this:
SPView view = list.GetUncustomizedViewByBaseViewId(0);
wp.ListViewXml = view.HtmlSchemaXml;
Hope it helps,
W0ut
You need to perform two steps to add a web part to a page. First you have to create the list you want to show on the page. Therefore you can use the Add() method of the web site's list collection (SPListCollection).
To show the list on the web part page you have to add a ListViewWebPart to the web part page using the SPLimitedWebPartManager of the page.
To make this more re-usable as part of a feature receiver, you could pass in the splist and spview as part of a method:
static public void AddEventsListViewWebPart(PublishingPage page, string webPartZoneId, int zoneIndex, string webPartTitle, PartChromeType webPartChromeType, string listName, string viewname)
{
using (SPLimitedWebPartManager wpManager = page.ListItem.File.GetLimitedWebPartManager(PersonalizationScope.Shared))
{
SPWeb web = page.PublishingWeb.Web;
SPList myList = web.Lists.TryGetList(listName);
using (XsltListViewWebPart lvwp = new XsltListViewWebPart())
{
lvwp.ListName = myList.ID.ToString("B").ToUpperInvariant();
lvwp.Title = webPartTitle;
// Specify the view
SPView view = myList.Views[viewname];
lvwp.ViewGuid = view.ID.ToString("B").ToUpperInvariant();
lvwp.TitleUrl = view.Url;
lvwp.Toolbar = "None";
lvwp.ChromeType = webPartChromeType;
wpManager.AddWebPart(lvwp, webPartZoneId, zoneIndex);
}
}
}
And then call it during feature activation:
AddEventsListViewWebPart(welcomePage, "Right", 1, "Events", PartChromeType.TitleOnly, "Events", "Calendar");