Updated the following article to include SharePoint, 2007, 2010, 2013, 2016 and SharePoint Online.
http://techtrainingnotes.blogspot.com/2011/06/sharepoint-how-to-change-default-home.html
SharePoint, PowerShell, .Net and other stuff I spend too much time on...
Updated the following article to include SharePoint, 2007, 2010, 2013, 2016 and SharePoint Online.
http://techtrainingnotes.blogspot.com/2011/06/sharepoint-how-to-change-default-home.html
This article includes both 2010 and 2013 examples.
Let's say you wanted to display a Date/Time down to the minute or second, but you wanted the column heading to filter by days or months. By default the column filter dropdown displays one each of what ever it finds in the column, or in the case of dates, the nearest day.
But if you want just the months or years in the dropdown, then maybe something like this:
In SharePoint 2010 we still have a fully working SharePoint Designer that can easily edit web parts. In SharePoint 2013, Designer is pretty much broken for web part work, which is just as well as we should be looking at the newest tools in 2013 for our customizations. In this example we will be using JS Link for 2013.
The basic steps:
Note: Although the names of my columns differ only by a space, you can use any column names you like. I will use EventDate for data entry and Event Date for display.
Steps:
The basic steps:
Steps:
The JavaScript File
(function () { // do all of the setup work... var TTNctx = {}; TTNctx.Templates = {}; // configure the Event_x0020_Date field to copy the EventDate values // into the Event_x0020_Date column TTNctx.Templates.Fields = { "Event_x0020_Date":
{ "View": function (ctx) {return ctx.CurrentItem.EventDate} } }; // register the override SPClientTemplates.TemplateManager.RegisterTemplateOverrides(TTNctx); })(); // end of function
.
The following has been tested with SharePoint 2010 and 2013…
There are a lot of questions in the various forums on how to start a Site Workflow, mostly because it is a bit hard to find in SharePoint. For those looking for only that, here's the basic steps:
Instead of telling your users to go find the Site Workflows page it might be better just to give them a link or button to click. All we need is to know how (and where) to copy and paste the URL or JavaScript and then how to use that to create the link.
In SharePoint 2010 there are only two ways to launch a Site Workflow from a link, while in SharePoint 2013 there are four!
For 2010:
SharePoint 2010 Site Workflows have two possible URLs to launch workflows, one for workflows with InfoPath forms and one for workflows with ASPX forms. The kind of form you get depends on your edition of SharePoint. For Foundation, SharePoint Designer creates ASPX forms, while for Standard and Enterprise SharePoint Designer creates InfoPath (.XSN) forms. You can force ASPX forms by disabling the hidden "OffWFCommon" feature. (See note at the end of this article.)
For Foundation: (ASPX forms)
http://yourServer/sites/yourSite/Workflows/yourWorkflowName/yourWorkflowname.aspx?TemplateID={030c0f5b-f4be-4c32-9fe6-d1fbf18080e1}&Source=http%3A%2F%2FyourServer%2Fsites%2FyourSite%2F%5Flayouts%2Fworkflow%2Easpx
For Standard and Enterprise: (InfoPath forms)
http://yourServer/sites/yourSite/_layouts/IniWrkflIP.aspx?TemplateID={6bc58ac2-b39c-4e35-a644-43335e966291}&Source=http%3A%2F%2FyourServer%2Fsites%2FI%2F%5Flayouts%2Fworkflow%2Easpx
The GUID in the URL is the unique ID for your workflow.
For 2013:
SharePoint 2013 supports two kinds of workflows, 2010 and 2013. As a result we end up with three ways to launch a workflow. The first two are similar to the 2010 URLs listed above. Only SharePoint 2010 style workflows are available in Foundation. 2013 style workflows are only available in Standard and Enterprise if your server administrators have installed support for them.
For Foundation 2013 and SP 2010 style workflows: (ASPX forms)
I'm assuming (a dangerous thing to do!) that the URL is similar to 2010's. In any case we will just be copying the URL.
For Standard and Enterprise 2013 and SP 2010 style workflows: (InfoPath forms)
https://yourServer/sites/yourSite/_layouts/15/IniWrkflIP.aspx?TemplateID={b5760949-b13a-4348-a309-65a01f8fbde7}&Source=https%3A%2F%2FyourServer%2Fsites%2FyourSite%2F%5Flayouts%2F15%2Fworkflow%2EaspxFor SharePoint 2013 workflows without initiation forms started from a JavaScript function call:
javascript:StartWorkflow4('7032d6a6-66e0-4c22-9483-2971b90b0e64', '', '')
For SharePoint 2013 workflows with or without initiation forms started from a URL:
https://yourServer/sites/yourSite/wfsvc/20a711570d0549ff83adafde04bce160/WFInitForm.aspx?TemplateID={7032d6a6-66e0-4c22-9483-2971b90b0e64}&WF4=1&Source=https%3A%2F%2FyourServer%2Fsites%2FyourSite
No matter with version or edition, if you are working with hyperlinks to start workflows your links will be created by copying the URL to the workflow and using it to launch the workflow from Quick Launch, an anchor tag (<A>), an INPUT tag or a BUTTON tag.
I won't add all of the details here, but basically:
You can add custom HTML to Wiki pages, ASPX pages, Links lists and Content Editor Web Parts.
<input type="Button" onclick="window.location='yourCopiedUrlGoesHere'" value="click me">
<button type="Button" onclick="window.location='yourCopiedUrlGoesHere'" >click me</button>
<a href="yourCopiedUrlGoesHere">click me</a>
This option only applies to SharePoint 2013 and only for 2013 style workflows without Initiation Forms. (i.e. no user interaction before the workflow starts.) If you right-click a workflow link in Settings, Site Contents, Site Workflows (workflow.aspx), click Properties and see JavaScript instead of a URL it will probably look like this:
javascript:StartWorkflow4('7032d6a6-66e0-4c22-9483-2971b90b0e64', '', '')
The nice thing about launching a workflow from StartWorkflow4 is that it is done using a CSOM web service call and does not cause the user to move to another page. Just click, and the workflow starts. The problem for us is that the StartWorkflow4 function is not available from every page in SharePoint. It's only available from workflow.aspx. To duplicate the code from that page you will need to add a link to a SharePoint JavaScript library and copy some JavaScript code from the workflow.aspx page.
The following assumes you are editing an ASPX page in SharePoint Designer, or you have placed the code in a text file and linked to that text file from a Content Editor Web Part.
Steps:
Enjoy!
I have only done limited testing here… so buyer beware, and only do this on a test or dev farm.
I wanted to create a SharePoint Designer workflow that used ASPX forms instead of InfoPath forms as they were easier to customized for this project. I simply deactivated the OffWFCommon feature (by GUID), closed and reopened SharePoint Designer and then created a new workflow, which magically had ASPX forms. Not knowing what the side effects were, I reactivated the feature as soon as the workflow was written. This is a Site Collection level feature. As it is a hidden feature, you will need to use STSADM, PowerShell or code to activate or deactivate it.
Note: Even if it is on the server, activating this feature won't give you usable InfoPath forms on SharePoint Foundation!
Using STSADM:
stsadm -o deactivatefeature -id C9C9515D-E4E2-4001-9050-74F980F93160 -url <url>
Using PowerShell:
Disable-SPFeature -Identity c9c9515d-e4e2-4001-9050-74f980f93160 -url <url>
If you are curious, the feature lives here: (14 for 2010, 15 for 2013)
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\FEATURES\OffWFCommon
.
The following applies to SP 2010 and SP 2013 and should work in SP 2007.
You want a calculated column for a hyperlink, but can't create one. (you can't embed working HTML into the calculation.) So… you consider a workflow to create the data for a hyperlink column.
Some things in SharePoint are obvious, while others are not. Setting a calculated hyperlink field to a new URL from a workflow is one of the not so obvious. When you use the "Update List Item" action, click "this list", click Add and the "…" you get an Edit Hyperlink dialog box. While you can type manual text and URL entries, you can't build an expression. Your second choice is to click fx set a value from a variable. The problem is that this is not a simple string. The string in the variable needs to match this pattern, which includes a comma and one space:
http://yoururl, your display text
Assumptions for the walkthrough:
Steps:
.
The following screen captures are from SP 2013. SP 2010 behaves in the same way except for the error message.
Scenario:
The issue? It's a look up column, and the user does not have at least Read permissions to the lookup list. (Convenient that I named it "Lookup" huh?)
Other interesting side effects of not having permissions to the lookup list:
.
SharePoint does not have a PreCancelAction. I created what I needed for one project, and present it here for your creative uses and enhancements. No warranties and no support… but the price is right!
When you click Save from an ASPX list form SharePoint checks to see if you have added a PreSaveAction JavaScript function to the page. If you have included the function, it is called, your code run and then your code can return a True or False to allow the save to continue, or to cancel it. You can add this function directly to the page, via a Content Editor Web Part, and in 2013 as a JS Link. Do a web search to find examples of its use.
PreSaveAction sample:
<script type="text/javascript"> function PreSaveAction() { // do pre-save work here: validation, messages, etc. alert('Thank you for your suggestion!'); return true; // return true to continue with the save // or return false to cancel the save } </script>
I needed a popup message to stress "Changes not saved", so I put together some JavaScript that intercepts the cancel and displays a message to the user.
All of the examples below look for INPUT tags with a VALUE of "Cancel". You may want to change this line to match your language requirements. The code also only intercepts INPUT tags that include "STSNavigate" in their onclick code. This is to avoid intercepting the attachment dialog's cancel button. The code stores all of the original onclick code in a globally scoped array named TTNoriginalFunctions as each Cancel button on the form may have had unique code.
Warn the user on cancel:
This example does not call your functions, it just intercepts the Cancel buttons and runs the imbedded alert code.
var TTNoriginalFunctions = []; var TTNCounts = 0; var TTNinputs = document.getElementsByTagName("input") for (var i = 0; i<TTNinputs.length; i++) { if (TTNinputs[i].value == "Cancel") { if (TTNinputs[i].onclick) { if (String(TTNinputs[i].onclick).indexOf("STSNavigate")>-1) { TTNoriginalFunctions[TTNCounts] = TTNinputs[i].onclick; TTNinputs[i].onclick = new Function(" return function () { alert('Changes not saved'); TTNoriginalFunctions[" + TTNCounts + "]();}")(); TTNCounts++; } } } }
Callable as a function:
This is the same as the above, but wrapped up in a function that you can call it from your code. You pass in the custom code to run as a string. This uses "new Function" to build the code from a string.
var TTNoriginalFunctions = []; function TTNPreCancelAction(yourFunctionAsString) { var TTNCount = 0; var TTNinputs = document.getElementsByTagName("input") for (var i = 0; i<TTNinputs.length; i++) { if (TTNinputs[i].value == "Cancel") { if (TTNinputs[i].onclick) { if (String(TTNinputs[i].onclick).indexOf("STSNavigate")>-1) { TTNoriginalFunctions[TTNCount] = TTNinputs[i].onclick; TTNinputs[i].onclick = new Function(" return function () { " + yourFunctionAsString + "; TTNoriginalFunctions[" + TTNCount + "]();}")(); TTNCount++; } } } } } TTNPreCancelAction("alert('changes not saved')");
A solution that works more like SharePoint's PreSaveAction:
You could add the TTNPreCancelAction function listed below to your master page or an existing linked JavaScript library. You can then add a PreCancelAction function to forms as needed using SharePoint Designer edits, Content Editor Web Parts or JS Link, just like the PreSaveAction functions. Your PreCancelAction function must return "true" or "false".
// Add this function to a form function PreCancelAction() { alert('Changes not saved!'); return true; //return confirm('Are your sure? Data will be lost!') } // Add this code to each form, or once in the master page. var TTNoriginalFunctions = []; var TTNCount = 0; function TTNPreCancelAction() { var TTNinputs = document.getElementsByTagName("input") for (var i = 0; i<TTNinputs.length; i++) { if (TTNinputs[i].value == "Cancel") { if (TTNinputs[i].onclick) { if (String(TTNinputs[i].onclick).indexOf("STSNavigate")>-1) // ignore the Attachments Cancel! { TTNoriginalFunctions[TTNCount] = TTNinputs[i].onclick; TTNinputs[i].onclick = new Function(" return function () { if ('function'==typeof(PreCancelAction)) {if (!PreCancelAction()) {return false} }; TTNoriginalFunctions[" + TTNCount + "]();}")(); TTNCount++; } } } } } TTNPreCancelAction() //intercept the Cancel buttons
Have a better solution? Post a comment below!
.
64 bit programs have to be better than 32 bit programs, right? This is a question that keeps popping up in my classes and the various support forums, usually in the form of "xxxxx does not work in SharePoint". In general all client applications used with SharePoint should be 32 bit. This includes Word, Excel, IE, etc. The Office ActiveX controls used with SharePoint are all 32 bit.
Here's the SharePoint 2010 Browser Support article from TechNet:
https://technet.microsoft.com/en-us/library/cc288142(v=office.14).aspx
For specific things not supported in 64 bit see:
https://technet.microsoft.com/en-us/library/cc288142(v=office.14).aspx#activex
Things have gotten better with SharePoint2013 as there's less dependence on ActiveX controls. The Office 64 bit article (https://technet.microsoft.com/en-us/library/ee681792.aspx) says "We recommend the 32-bit version of Office for most users, because it's more compatible with most other applications, especially third-party add-ins."
For SharePoint 2013 the support browsers article says it a little differently, but has the same message: "Some functionality in SharePoint 2013 requires ActiveX controls. This produces limitations on browsers which do not support ActiveX. Currently only 32-bit versions of Internet Explorer support this functionality."
https://technet.microsoft.com/en-us/library/cc263526.aspx#activex
.
A while back I posted an article on downloading files from SharePoint using PowerShell (see here) that generated a few questions about uploading files. So… here's a few uploading scripts. Don't stop here though, there are many other examples on the web. Google/Bing is your friend!
This script not only uploads files, but lets you add metadata.
# Set a few variables $file = "C:\test\myTestFile.txt" $TTNwebUrl = "http://server/sites/yoursite" $library = "Team Documents" $overWriteExisting = $True #or add new version if versioning enabled # do a little SharePoint setup $web = Get-SPWeb $TTNwebUrl $files = $web.GetFolder($library).Files $fileNameForLibrary = $file.Substring($file.LastIndexOf("\")+1) # read the file $data = Get-ChildItem $file # add any needed metadata $metadata = @{ "Project ID" = "A-200"; "Region" = "North" } # or if no metadata needed: $metadata = @{} # do the upload (the following is one line) $newfile = $files.Add($library + "/" + $fileNameForLibrary, $data.OpenRead(), $metadata, $overWriteExisting)
And if you are a "one liner" PowerShell scripter:
(Get-SPWeb "http://server/sites/yoursite").GetFolder("Team Documents").Files.Add("Team Documents/myTestFile.txt", (Get-ChildItem "C:\test\myTestFile.txt").OpenRead(), $True)
And with metadata:
(Get-SPWeb "http://server/sites/yoursite").GetFolder("Team Documents").Files.Add("Team Documents/myTestFile.txt", (Get-ChildItem "C:\test\myTestFile.txt").OpenRead(), @{ "Project ID" = "A-200"; "Region" = "North" }, $True)
I generally recommend linking from a list item to a file in a library, but if you want to add attachments to a list item, here's a sample script:
# Set a few variables $TTNweb = Get-SPWeb "http://yourServer/sites/yourSite"; $list = $TTNweb.lists["yourListName"]; $filePath = "C:\SampleDocs\yourSampleFile.JPG"; # Create a new list item: $item = $list.items.Add(); $item["Title"] = "Test Title"; # set any addition metadata $item.Update(); # Upload the file: $bytes = [System.IO.File]::ReadAllBytes($filePath); $item.Attachments.Add([System.IO.Path]::GetFileName($filePath), $bytes); $item.Update();
SharePoint 2010 and 2013 Auditing and Site Content Administration using PowerShell
https://www.microsoft.com/en-us/learning/course.aspx?cid=55095A
Or you can attend my class in Cincinnati (locally or remotely)!
http://www.maxtrain.com/Classes/ClassInfo.aspx?Id=119394
.
A continuation of the "Search Weirdness" series!
Unlike list and library alerts:
List / Library alert options:
Search Alert options:
You would assume (always a dangerous thing to do) that Daily and Weekly summary search alerts would get created overnight. Turns out they get sent at an exact time, but a different one for each alert!
While working on a new SharePoint 2013 search class I was trying to find out which timer job created the alert emails and if I could set the time they are sent. TechNet documents only a single timer job, "Immediate Alerts", that runs every five minutes. While I could change that interval, I could not find an option for the "nightly jobs". Turns out there isn't any such thing.
I had always assumed (again, dangerous) that these ran overnight. The only documentation I had found in TechNet only said this:
"The daily alerts will have a 24-hour day, date, and time span calculated and stored in the respective database table. A weekly alert will have a seven-day day, date, and time span calculated and stored as part of the individual alert record."
It just says "calculated" and does not say "when". Then I ran across this blog article by Chris Domino and the light bulb went off:
http://www.chrisdomino.com/blog/post/The-Truth-About-How-Daily-SharePoint-Alerts-Actually-Work
When you create a daily alert it is scheduled to run every day at the time you created the alert. I.e. You created the alert at 2:00PM, it will processed every day shortly after 2:00PM. The same applies to weekly alerts. You created the alert at 2:00 PM on a Tuesday, it will be processed every Tuesday at 2:00 PM. I went out and looked as the SQL tables (never do this at home!) and there it was, to the minute, scheduled 24 hours or 7 days in the future.
In my Office 365 tenant my daily alerts are initially scheduled 17 hours in the future and then every 24 hours after that. My guess is that Office 365 is using GMT. So when I schedule a daily alert at 3:45 PM it runs 8:45 AM every day. Five hours off. Hum… would that mean my tenant is running in Central time? Don't know… just guessing…
Another day… another new thing to discover…
.
OK, that's a bit of a corny title, and a bit of a deception. My SharePoint Cincy presentation is really about the powerful things you can do with SharePoint 2013's search feature set… if you only had a Search Administrator.
If you've been to one of my governance classes or presentations then you have heard me lecture, practically preach, on why you need a Search Administrator. It's an easy job, only an hour or two a week, but it's also one of the most important jobs in the ongoing operation of SharePoint. Attend my presentation and meet the Genie!
SharePoint Cincy is this Friday! There's still time to register!
Oh, and there's another 21 sessions you might want to attend, and a lot of networking to do. See you Friday!
Mike Smith
MAX Technical Training - MVP
What’s the single most important thing you can do to make SharePoint 2013, on premises or in the cloud, work for your users? Make stuff easy to find! Some say that SharePoint search is easy. Just install it and let it do its thing, and in Office 365 you don’t even have to install it. But… your users can’t find anything, or they find thousands of unwanted things. They don’t know where to look, they can’t spell your CEO’s name, they can’t find their own expense report and they can’t even find the lunch menu! There’s a powerful genie hiding in search who can find what your users are searching for. All it needs is an Administrator to turn it loose! So let’s let the search genie out of the bottle and discover the power of SharePoint 2013 Search Administration.
.
The SharePoint Group object has a property named "Description", but it appears to be ignored. When you edit a group in the browser there is no "Description" field, but there is one named "About Me" that is a rich text field. Turns out there's a few secrets you need to know to set this seemly simple little property.
Secret #1: Many of the group's properties are stored in another object, the SPWeb.SiteUserInfoList object.
Secret #2: The internal name of "About Me" is "Notes".
The PowerShell:
#create the group as usual and then retrieve it... $web = $site.RootWeb; $group = $web.SiteGroups["Test Group with HTML desc"]; #find the group's SiteUserInfoList info... $groupInfo = $web.SiteUserInfoList.GetItemById($group.id); #update the text... $groupInfo["Notes"] = "<div>This is <strong>bold</strong> and this is <em>italics</em></div>"; #and save it... $groupInfo.Update();
For a C# example see the answer in this discussion: http://stackoverflow.com/questions/968819/change-description-of-a-sharepoint-group
.
Did you ever want to find all of the columns of a certain type? All Lookups, all Calculated or all Managed Metadata columns? All you have to do is look at the Fields object "TypeDisplayName" property. While the example script below is looking for Lookup columns, you could modify it to look for any kind of column.
This will find all Lookup columns in the entire farm!
Notes:
$TTNExcludeLists = "Solution Gallery", "Workflow Tasks", "Master Page Gallery" Get-SPSite -Limit All | Get-SPWeb -Limit All | Select -ExpandProperty Lists | Where { -Not ($TTNExcludeLists -Contains $_.Title) } | Select -ExpandProperty Fields | Where { $_.TypeDisplayName -eq "Lookup" -and $_.Hidden -eq $false -and $_.FromBaseType -eq $false } | Select {$_.ParentList.ParentWebUrl}, {$_.ParentList}, Title
If you would like to see the list of all of the column types used in your site or farm you can run a script like this:
Get-SPWeb "http://yourServer/sites/YourSite" | Select -ExpandProperty Lists | Select -ExpandProperty Fields | Select TypeDisplayName –Unique |
Sort
It may take a long time to run (WARNING!) but this will list all of the columns in the farm:
Get-SPSite -Limit All | Get-SPWeb -Limit All | Select -ExpandProperty Lists | Select -ExpandProperty Fields | Select TypeDisplayName -Unique|
Sort TypeDisplayName
Here's the list I got from my test farm:
TypeDisplayName
---------------
All Day Event
Attachments
Audience Targeting
Calculated
Channel Alias
Check Double Booking
Choice
Computed
Content Type Id
Content Type ID
Counter
Cross Project Link
Date and Time
Event Type
File
Free/Busy
Guid
Hold Status
Hyperlink or Picture
Integer
Lookup
Managed Metadata
Moderation Status
Multiple lines of text
Number
Number of Likes
Number of Ratings
Out of Policy
Outcome choice
Page Separator
Permission Level
Person or Group
Publishing HTML
Publishing Image
Publishing Schedule End Date
Publishing Schedule Start Date
Rating (0-5)
Recurrence
Related Items
Resources
Single line of text
Summary Links
ThreadIndex
User Agent Substrings
Variations
Yes/No
.
In SharePoint 2010 there's a search feature called "Search Result Removal" that made an item immediately disappear from user's search results. All you had to do was enter the URL to the problem item and click Remove Now. SharePoint then remove the item from the index and wrote a Crawl Rule to make sure the content was ignored by the crawler in all future searches.
The 2010 request to remove:
The auto-created Crawl Rule:
SharePoint 2010 had a interesting bug here. Uppercase letters in the URL would cause the the removal request to be ignored!
We don't have Crawl Rules in SharePoint 2013 and Office 365. When you request the removal of an item or a URL from the search index, it just deletes it from the index. But… on the next crawl it adds it back! That next crawl could be an hour away, or only seconds, depending on your crawl schedules and the luck of your timing.
Nowhere can I find any documentation that says this!
The screen for removal requests is similar to what we had with 2010, but with no mention about Crawl Rules.
Both versions let you browse the crawl logs, find a problem item, click the dropdown on the item and click Remove the Item From The Index. In the Crawl Logs you can remove one item at a time while the Removal pages will let you exclude and entire path.
In 2013 we are just told that the item will be removed. In 2010 we are also told that a crawl rule will be created.
Remove URLs from search results (SharePoint Server 2010
https://technet.microsoft.com/en-us/library/ff621095(v=office.14).aspx
Delete items from the search index or from search results in SharePoint Server 2013
https://technet.microsoft.com/en-us/library/jj219587.aspx
You have to learn some real tricks to get views filtered just the way you want, especially with dates. Dates are fun in that the filter can only compare a date column to an exact date or [Today]. Here's two examples that should get you a start on a wide range of date related filters.
What we need: Only the items where some date is during the last full month. Not 30 days ago, but between the first and last day of last month.
These two columns calculate the range of dates to show this item. So to figure this out, stop thinking about this month and last month and think about when do you want an item with a certain date displayed. If the item has a date of 2/14/2015 then we want it displayed from 3/1/2015 to 3/31/2015.
For this example the date column we are testing against is named TheDate. (Creative huh!)
Column 1: (to calculate the first day of the month after TheDate)
Name: StartDisplayDateForLastMonth
Type: Calculated
Formula: =DATE(YEAR(TheDate),MONTH(TheDate)+1,"1")
The data type returned from this formula is: (o) Date & Time
Date and Time Format: (o) Date Only
Column 2: (to calculate the last day of the month after TheDate)
Name: EndDisplayDateForLastMonth
Type: Calculated
Formula: =DATE(YEAR(TheDate),MONTH(TheDate)+2,0)
The data type returned from this formula is: (o) Date & Time
Date and Time Format: (o) Date Only
Here's a screen shot of the first column. (click to enlarge)
Create a view with your usual choice of columns, but not the two we just added. You may want to add these columns for test though.
Display and test the view!
=DATE(YEAR(TheDate),MONTH(TheDate)+1,"1")
DATE needs three values, a year number, a month number and a day number. The first two are easy, if you know a weird fact. YEAR() returns the year number (2015) and MONTH() returns the month number (3). Obviously MONTH()+1 is next month… but what about when it's December plus 1? That's the weird fact. Month 13 bumps up the year value! So DATE(2014,13,5) is 1/5/2015. The 1 at the end of the formula is for day "1" of the month. Don't believe me? Fire up Excel and play around with the DATE function.
=DATE(YEAR(TheDate),MONTH(TheDate)+2,0)This one depends on another weird fact… day zero is the last day of the previous month! DATE(2015,3,0) is actually 2/28/2015. And of course, DATE(2016,3,0) is 2/29/2016! So what we are doing here is calculating a date 2 months minus one day in the future.
Bonus! What's the date of the 250th day of the year? =DATE(2015,1,250) or 9/7/2015. (I guess that would also be January 250th, 2015!)
Just a slightly different formula.
For the start date: =DATE(YEAR(TheDate),MONTH(TheDate)-1,"1")
For the end date: =DATE(YEAR(TheDate),MONTH(TheDate),0)
Fire up Excel! (And see this article: http://techtrainingnotes.blogspot.com/2010/08/sharepoint-creating-calculated-column.html)
Have fun!
.
Note: The following will work in SharePoint 2010. For SharePoint 2013 you will need to use PowerShell. See here: http://techtrainingnotes.blogspot.com/2015/02/working-with-quick-launch-from.html
When you attempt to add a link that does not look like a URL to a SharePoint 2010 Publishing site you will get an error message like this one:
The example above works perfectly with a non-Publishing site. What's different? The dialog box being used to do the edit.
The Work Around?
Cheat! Use the old editor for Quick Launch! (This will not work in SharePoint 2013.)
Go to your publishing site and then edit the URL in the browser's address bar so it points to _layouts/quiklnch.aspx
Something like http://yourServer/sites/yourPublishingSite/_layouts/quiklnch.asp
Click New Navigation Link or New Heading and add your JavaScript!
And there you go!
For a SharePoint 2013 workaround using PowerShell see:
.
The following will work with both SharePoint 2010 and 2013. It will also work with SharePoint 2007 if you "manually" create the SPWeb object.
Note: This will work with publishing sites as long as you are not using Managed Metadata Navigation.
$web = Get-SPWeb http://yourServer/sites/yourSite
$quicklaunch = $web.Navigation.QuickLaunch
You can explore your existing Quick Launch from here. Just type $quicklaunch and press enter to see your headings / top level nodes. Type $quicklaunch | where {$_.title -eq "Lists"} to see the links in one of the headings. You could even list all of the headings and their children with this one: $quicklaunch | select -ExpandProperty Children | Select {$_.Parent.Title}, {$_.Title}.
Each item added to Quick Launch is an SPNavigationNode object. It has three parameters: the text to display, the URL to the linked resource and $true if the link is external to SharePoint or $false if the link is internal to SharePoint. It appears that the $true/$false in the third parameter is used to see if the URL is validated as a real SharePoint URL or not. I could still add SharePoint links by leaving it as $true.
Example for a SharePoint link: (note the $false)
$navnode = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Get help!", "/sites/helpsite", $false)
Example for Bing or link external to SharePoint:
$navnode = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Bing", http://www.bing.com, $true)
Example for JavaScript:
$navnode = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Say Hello!", "javascript:alert('hello')", $true)
Example for JavaScript to open a new dialog box:
(Note the "`" in front of the "$" is needed because "$" means something special in PowerShell. (a variable follows))
$navnode = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Add a new task", "JavaScript:var options=SP.UI.`$create_DialogOptions();options.url='/sites/Publishing/Lists/Tasks/NewForm.aspx?RootFolder=&IsDlg=1';options.height = 400;void(SP.UI.ModalDialog.showModalDialog(options))", $true)
For more on JavaScript in Quick Launch see SharePoint: JavaScript in Quick Launch and Top Link Bar! and SharePoint: Opening a 2010 Dialog Box from Quick Launch.
To add the new node as a "heading" just add it to the Quick Launch object:
$quicklaunch.AddAsFirst($navnode) or .AddAsLast
To add the new node as a child of a "heading" then use Where to find that heading:
$heading = $quicklaunch | where {$_.title -eq "Lists"}
$heading.Children.AddAsLast($navnode)
To add the new node after an existing node (i.e. not as First or Last) you will need to retrieve the existing node and then use the .Add method.
$existingLink = $heading.Children | where {$_.title -eq "Search the web with Bing"}
$navnode = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Search the web with Google", "http://www.google.com", $true)
$heading.Children.Add($navnode,$existingLink)
Sure… Just retrieve the node and then call Delete.
$heading | Select -ExpandProperty Children | where { $_.Title -eq "Tasks" } | ForEach { $_.Delete() }
If you know that there's exactly one node that matches the Where test then you can shorten it to this:
($heading | Select -ExpandProperty Children | where { $_.Title -eq "Goog
le" }).Delete()
Sure… with extreme caution! Danger! Will Robinson! Danger! Do the following at your own risk. No liability assumed, batteries not included!
Here's an example to add a Help link to every site in a site collection or to all site collections in the entire farm. (You way want to filter out the My Sites and the publishing sites!)
First confirm what you are about to change!
Get-SPSite http://sharepoint/sites/training | Get-SPWeb -Limit All | Select URL, Title
or
Get-SPSite -Limit All | Get-SPWeb -Limit All | Select URL, Title
Create the new link / node.
$navnode = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("HELP!", "http://yourServer/sites/yourHelpSite", $true)
Now add it to every site in a site collection!
Get-SPSite http://sharepoint/sites/training | Get-SPWeb -Limit All | ForEach { $_.Navigation.QuickLaunch.AddAsFirst($navnode) }
or for all site collections in the farm:
Get-SPSite -Limit All | Get-SPWeb -Limit All | ForEach { $_.Navigation.QuickLaunch.AddAsFirst($navnode) }
And if you want to delete all of those helpful links?
Get-SPSite http://sharepoint/sites/training | Get-SPWeb -Limit All | ForEach { ($_.Navigation.QuickLaunch | where {$_.Title -eq "Help!"}).Delete() }
Publishing Sites use the "Navigation" editor for links and it does not permit "URLs" that don't begin with "http". This means that you cannot add JavaScript to a Quick Launch link using that editor. For SharePoint 2010 you can use the workaround here, or for 2010 and 2013 you can use the PowerShell above. (PowerShell to the rescue!) For more on JavaScript in Quick Launch see SharePoint: JavaScript in Quick Launch and Top Link Bar! and SharePoint: Opening a 2010 Dialog Box from Quick Launch.
The PowerShell above will work as long as in your Navigation settings you have not selected "Managed Navigation" or "same as parent".
MSDN's article showing C# examples: (This is for 2010 but applies to 2007-2013.)
https://msdn.microsoft.com/en-us/library/office/ms427791(v=office.14).aspx
You find the strangest things in SharePoint when you are looking for something else! I'm writing the labs for a new SharePoint 2013 Search Administration class and was looking for a list that did not support a search on "title:sometext". The list I first tested that did not have a "Title" column actually did work with a search for "title:". Huh? So I next tried the Links List as this one has always been a problem with the Content Query Web Part due to not having a "Title" column. I found that I could search Links with "title:sometext"! How?
Almost…
Most SharePoint lists and libraries have a "Title" column. As "Title" is also an out of the box search Managed Property you can search these lists and libraries by using "title:airplane". If you browse around your sites though you will only find a few lists and libraries that have a "Title" column. For example: document libraries and announcements lists.
Out of the box lists and libraries that support a search on Title:
What does not have a Title?
Almost every list is searchable using "title:somekeywords".
A Links list is special… or a least different. While many lists have a visible column with a name other than "Title" and an internal name of "Title", the List list is a bit different. A links list does not seem to have a end user accessible Title column, which is why its always been a pain with the Content Query Web Part. But… it does have a "Title" column, it's just hidden and Read Only. If you do a search using "title:", you will find links! I guess its auto-populated and included just for searching. Here's the XML from the feature for the Links list:
.