Showing posts with label SharePoint 2010. Show all posts
Showing posts with label SharePoint 2010. Show all posts

10/27/2015

SharePoint: Sort and Filter on One Column While Displaying Another

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.

image

But if you want just the months or years in the dropdown, then maybe something like this:

image        image

 

It's not to hard to do in SharePoint 2010, and fairly easy in SharePoint 2013

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.

 

Steps for SharePoint 2010

The basic steps:

  • Create a new list named "Event Announcements".
  • Add a Date and Time column named "EventDate".
  • Add a Calculated column named "Event Date" to display a YYYY-MM version of the date that can be used to filter by month.
  • Use SharePoint Designer to display the full date in the calculated column by hand customizing the XSLT.

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:

  1. Go to your site and create a test list. For this example an Announcements list would be a good choice.
  2. Create a new column named "EventDate". (You will enter your date data here.) 
    1. In the List ribbon click Create Column.
    2. Enter "EventDate" as the name.
    3. Set the type to Date and Time.
    4. Set Date and Time Format to Date & Time.
    5. Click OK.
  3. Create a new column named "Event Date". (This column will control the filter grouping.)
    1. In the List ribbon click Create Column.
    2. Enter "Event Date" as the name.
    3. Set the type to Calculated.
    4. Enter this formula:
         =TEXT([EventDate],"yyyy-mm")
      or for years instead of months:
         =TEXT([EventDate],"yyyy")
    5. Set The data type returned from this formula to Single line of text.
    6. Click OK.
  4. Add some sample data with dates spread across two or three different months.
     
  5. Open SharePoint Designer 2010 and open your site.
  6. Click Lists and Libraries and click your list.
  7. Find and click your view (I used All Items).
  8. If the screen is not in Split view click Split at the bottom of the screen.
  9. In the Code view pane click in the web part code. (The code without the yellow background.)
  10. In the List View Tools / Design ribbon click Customize XSLT and Customize Entire View.
    image
  11. In the design view click on any one of the dates in the EventDate column.
       image
  12. Verify the field name by looking up a few lines for FieldRef_ValueOf. My field is EventDate.
       image
  13. In the design view click on any one of the dates in the Event Date column. (the calculated column)  This will highlight a line in the Code view.
  14. Edit the "value-of" element to change from this:
      <xsl:value-of select="$thisNode/@*[name()=current()/@Name]"/>
    to this:
      <xsl:value-of select="$thisNode/@*[name()='EventDate']"/>
    Note that you are replacing the expression "current()/@Name" to the name of the field wrapped in single quotes. I.e. 'EventDate'. EventDate is column from which you want to copy the data.
  15. Save the file.
  16. Return to the browser and test the view. You can edit the view and remove the EventDate column as we only need the Event Date column.
       image

 

Steps for SharePoint 2013

The basic steps:

  • Create the test list and columns. (Same steps as for 2010)
  • Create the JS Link JavaScript file.
  • Upload or save the file to a SharePoint library.
  • Edit the view's web part and link to the JS File.

Steps:

  1. Go to your site and create a test list. For this example an Announcements list would be a good choice.
  2. Create a new column named "EventDate". (You will enter your date data here.) 
    1. In the List ribbon click Create Column.
    2. Enter "EventDate" as the name.
    3. Set the type to Date and Time.
    4. Set Date and Time Format to Date & Time.
    5. Click OK.
  3. Create a new column named "Event Date". (This column will control the filter grouping.)
    1. In the List ribbon click Create Column.
    2. Enter "Event Date" as the name.
    3. Set the type to Calculated.
    4. Enter this formula:
         =TEXT([EventDate],"yyyy-mm")
      or for years instead of months:
         =TEXT([EventDate],"yyyy")
    5. Set The data type returned from this formula to Single line of text.
    6. Click OK.
  4. Add some sample data with dates spread across two or three different months.
     
  5. Open SharePoint Designer 2013 and your site.
  6. In the Navigation area click Site Assets. (or any other library)
  7. Right-click in any empty space in the file area and select New and HTML.
  8. Right-click the new file and rename it to GroupByMonthJSLink.js (any name will do)
  9. Click the new file and then click Edit File.
  10. Select all of the HTML and delete it.
  11. Enter the JavaScript listed below.
  12. Save the file.
  13. Go to the new list.
  14. Click Settings (gear) and Edit Page.
  15. In the list’s web part click the dropdown and click Edit Web Part.
  16. In the web part properties panel expand Miscellaneous.
  17. Enter the following path into the JS Link box:
    ~site/SiteAssets/GroupByMonthJSLink.js
    Note: "~site" points to current site/subsites URL while "~sitecollection" points to the top level site's URL.
  18. Click Apply. (You should see the change to the Event Date column.)
  19. Click OK
  20. In the Page ribbon click Stop Editing.
  21. Test! You can edit the view and remove the EventDate column as we only need the Event Date column.
       image

 

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

 

.

10/25/2015

SharePoint: Launch a Site Workflow from a Link or Button

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:

Start a Site Workflow

  1. Click Site Actions (2010) or Settings (gear) (2013).
  2. Click View All Site Content (2010) or Site Contents (2013).
  3. Click Site Workflows.
  4. Click the workflow!
  5. If displayed, complete the workflow initiation form. (2010 workflows always display an Initiation Form, even if has only OK and Cancel buttons.)

 

Launching a workflow from a link, button or Quick Launch

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.

image

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%2Easpx

For 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

 

Steps to Create Links for Workflows in General

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.

Copying the URL or JavaScript:

  1. For SharePoint 2010: Click Site Actions, View All Site Content. (or click All Site Content in the Quick Launch area)
    For SharePoint 2013: Click Settings (gear) and Site Contents. (or click Site Contents in the Quick Launch area)
  2. Click Site Workflows. (top right corner of page)
  3. Right-click the workflow and click Copy Shortcut. (or right-click the workflow, click Properties and copy the URL from there.
  4. If the copied link is a URL and not JavaScript:  (JavaScript will only be found for SharePoint 2013 style workflows that do not have an Initiation Form.)
    1. Paste the URL in to Notepad or other text editor.
    2. Remove the absolute part of the path (the http://servername). This is not required, but is a best practice.
      https://yourServerName/sites/yourSite/_layouts/15/IniWrkflIP.aspx?TemplateID={b5760949-b13a-4348-a309-65a01f8fbde7}&Source=https%3A%2F%2FyourServerName%2Fsites%2Ftraining%2F%5Flayouts%2F15%2Fworkflow%2Easpx
    3. Edit the URL after &Source to the URL where you want the user to land after starting the workflow. (Usually the same page they started from, but could be an "after the workflow instructions" page.)
      /sites/yourSite/_layouts/15/IniWrkflIP.aspx?TemplateID={b5760949-b13a-4348-a309-65a01f8fbde7}&Source=%2Fsites%2Ftraining%2FSitePages%2FFurthreInstructions%2Easpx
      Notes: %2F  = "/" and %2E = "."
    4. Copy the edited URL.

 

Adding a link via Quick Launch

I won't add all of the details here, but basically:

  • For 2010 team sites: Site Actions, Site Settings, Quick Launch
  • For 2010 publishing sites: Site Actions, Site Settings, Navigation, Current Navigation
  • For 2013 team sites: Settings (gear), Site Settings, Quick Launch
    or click EDIT LINKS in the Quick Launch area, click +link 
  • For 2013 publishing sites: Settings (gear), Site Settings, Navigation, Current Navigation

 

Adding Links via HTML

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>

 

Adding Links via JavaScript

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:

  1. Open SharePoint Designer 2013 and the open your site.
  2. If you are directly editing a page, open that page for editing. (You may need to click Advanced Mode in the ribbon.)
  3. If you are using a Content Editor Web Part for the code:
    1. Click Site Assets (could also use Site Pages or any other library).
    2. Right-click in the white space in the file list area and click HTML.
    3. Select all of the HTML and delete it.
  4. Add a link to the workflowservices.js library:
      <script type="text/javascript" src="/_layouts/15/sp.workflowservices.js"></script>
  5. Add a control to fire the JavaScript that you copied from the workflow page:

    <input type="Button" onclick="javascript:StartWorkflow4('7032d6a6-66e0-4c22-9483-2971b90b0e64', '', '')" value="click me">

    <button type="Button" onclick="javascript:StartWorkflow4('7032d6a6-66e0-4c22-9483-2971b90b0e64', '', '')">click me</button>

    <a href="" onclick="javascript:StartWorkflow4('7032d6a6-66e0-4c22-9483-2971b90b0e64', '', '') ; return false;">click me</a>
  6. Visit the Site Workflow page: Settings (gear), Site Contents, Site Workflows.
  7. Either use the browser's View Source command or press F12 and use the DOM explorer to view the HTML of the page.
  8. Search for StartWorkflow4.
  9. Browse backwards from there and find the previous <script… tag and copy from that <script tag to the matching </script> tag.
  10. Paste this into your SharePoint Designer file.
  11. Save the file.
  12. If you are directly editing a page, go to a browser and test the link.
  13. If you are using a Content Editor Web Part for the code:
    1. Go to the browser, navigate to the page where you would like to have the link.
    2. Edit the page.
    3. Insert a Content Editor Web Part.
    4. Edit the web part and in the properties panel enter the URL to your code page. Something like:
      https://yourServer/Sites/yourSite/SiteAssets/WorkFlowLinkCode.html
    5. Click OK in the properties panel.
    6. Save the page and test the link.

 

Enjoy!

 

 

Note: The OffWFCommon Feature

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

 

.

10/23/2015

SharePoint: Set a Calculated Hyperlink Column from a Workflow

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:

  • You have a list with a course ID column named ID.
  • You have a course title column named Title.
  • You have an empty Hyperlink column named TheLink.

 

Steps:

  1. Open your site in SharePoint Designer 2010 or 2013 as appropriate.
  2. Click Lists and Libraries and click your list.
  3. Click the List Workflow button in the ribbon.
  4. Name your workflow and in SPD 2013 set the Platform Type to SharePoint 2010 or 2013 as desired..
  5. Click OK.
  6. Click the Action dropdown and click Set Workflow Variable.
    image
  7. Click workflow variable and create a new variable with a name like "LinkText", set the Type to String and click OK.
    image
  8. Click value and click the "" button.
  9. Create a string that will build your URL and your description, separated by a comma and a space. Click Add or Change Lookup to insert data from other columns. Then click OK.
    image
  10. Click the Action dropdown and click Update List Item. (for 2013: Set Field in Current Item)
    image
  11. Click this item, click Add, and select your hyperlink column. (for 2013: Click field and pick your hyperlink column and then click value and pick your variable.)
    image
  12. Click the fx button, select Workflow Variables and Parameters and then select your variable and click OK.
    image
  13. Click OK.
  14. Click Publish (in the ribbon).
  15. Test the workflow.
    1. Return to your list.
    2. Checkmark a list item.
    3. Click the ITEMS tab and click Workflows.
    4. Click the name of your workflow and click Start.
    5. Click the URL column and confirm that the link works.
  16. You will probably want to return to Designer and change the Workflow Settings to start the workflow when an item is created and when an item is changed.

 

 

.

10/17/2015

SharePoint: This service isn't available right now. User has Empty Lookup Column

 

The following screen captures are from SP 2013. SP 2010 behaves in the same way except for the error message.

 

Scenario:

  • You grant Contribute or Edit permissions to a user to a list or library, but not to the site.
  • When they visit the list/library, one column is blank that should have data.
  • When they edit an item the field is blank and the dropdown is empty.
  • When they click LIBRARY, Quick Edit, and then click the dropdown for the column the get the following error: (Clicking the link does nothing.)
        image
       Note: SP 2010 just displays an empty dropdown in the Datasheet View with no message about a "service" or other error.

    when they should be getting this:
        image

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:

  • If the lookup column is Required, then the user cannot edit anything in the list/library.
  • If the lookup column is not Required, then when the user edits the item, the data in the lookup column is deleted!

 

.

10/14/2015

SharePoint PreCancelAction

 

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!

 

PreSaveAction

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>

 

PreCancelAction

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!  Smile

.

10/13/2015

SharePoint: 64 bit IE and Office is not generally a good idea!

 

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.

2010

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

 

2013

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

 

 

.

10/08/2015

SharePoint Column Validation Examples

Update 11/2/2015… added "Date must be the first day of the month" and "Date must be the last day of the month".
The following applies to SharePoint 2007, 2010 and 2013.

Column Validation

SharePoint does not include column types for phone numbers or part numbers, nor does it include support for Regular Expressions to test for character patterns. It does support Excel style functions that we can use to create useful column validation formulas.
Below you will find column validation examples for:
  • OR
  • AND
  • Length (LEN)
  • Pattern matching using SEARCH and FIND
  • Date testing

General Validation Formula Rules:

  • Formula must return True or False.
  • Column validations can only be added to Single Line of Text, Number, Choice (Drop-Down menu or Radio buttons, but not Checkboxes), Currency and Date and Time columns.
  • Expressions are generally Excel compatible, but not all Excel functions can be used.
  • Field names without special symbols can be entered as is or in square brackets
          = Price * [Qty]  > 100
  • Field namess with spaces or symbols must be enclosed in square brackets
          =OR( [Sales Region] = 1, [Sales Region] = 1)
  • The text comparisons are not case sensitive.
          =OR( status = "a", status="c")     is true for either "A" or "a" or "C" or "c".
  • In a column validation the formula cannot refer to another column.
  • In a list / library validation the formula can refer to other columns in the same item.

Examples using "OR":

The OR function accepts two or more Boolean tests that each return True or False. OR returns True if any one of the tests is True.
=OR(YourFieldName="A",YourFieldName="C",YourFieldName="E")
=OR(State="OH", State="IN", State="KY", State="MI")
=OR(Qty=5, Qty=10, Qty=20)

Examples using "AND":

The AND function accepts two or more Boolean tests that each return True or False. AND returns True if all of the tests are True.
=AND(YourFieldName>"A", YourFieldName<"M")     YourFieldName value must be between A and M.
=AND(Qty>5, Qty<100, Qty<>47)      Qty must be between 5 and 100, but not 47.

Examples using "LEN":

As an example, if your part numbers are always 9 characters long:
    =LEN(YourFieldName) = 9
If the part numbers can be 9 or 12 characters long:
    =OR( LEN(YourFieldName) = 9, LEN(YourFieldName) = 12 )

Examples for Pattern Matching

The SEARCH function:  (online help)
  • Matches a pattern using "*" and "?". "*" equals zero more characters and "?" equals exactly one character.
  • To match an asterisks or question mark character prefix the symbols with "~". 
    Example: "a~?b?c" matches "a?bxc" but not "axbxc". 
  • An "*" is assumed to be appended to the end of the match pattern. To limit the length use the AND and LEN functions.
  • The comparison is not case sensitive.
  • If there is a match, the function returns the position of the match. If the every character is to be matched you would typically test for "=1" or maybe ">0". 
  • If there is no match, the function returns ERROR, therefore it must be wrapped inside of an ISERROR function. As we will have a match if there is no error, the ISERROR must be wrapped inside of a NOT function. (online help for ISERROR)
Examples:
Must start with an "a" or "A" and the third character must be a "c" or "C":
   =NOT(ISERROR( SEARCH("A?C",YourFieldName)=1 ))
   Matches: abc   AbC  aXc  a6c aBcDEF
   Does not match:   bbb   abb  ac  a
Match a phone number pattern of xxx-xxx-xxxx: (note: user could type letters or digits or type extra characters.)
   =NOT(ISERROR( SEARCH("???-???-????",YourFieldName)=1 ))
   Matches: 123-123-1234    aaa-aaa-aaaa   123-123-12344444
Match a phone number pattern of xxx-xxx-xxxx and limit the length:
   =AND( NOT(ISERROR(SEARCH("???-???-????",YourFieldName,1))), LEN(YourFieldName)=12 )
   Matches: 123-123-1234
   Does not match: 123-123-12345

Match a phone number and make sure only digits have been used:
The first example here is not a true pattern match. It just extracts the characters we think should be digits and tries to multiply them by any number. If that fails, then one or more of the characters is not a number. (online help for CONCATENATE and MID)
=NOT(ISERROR(1*CONCATENATE(MID(YourFieldName,1,3),MID(YourFieldName,5,3),MID(YourFieldName,9,4))))
   Matches: 123-123-1234    123x123x1234   123-123-1234xxxxx
   Does not match: abc-123-1234
The second example combines the earlier pattern match with a numeric test:
   =AND(NOT(ISERROR(SEARCH("???-???-????",YourFieldName,1))),LEN(YourFieldName)=12, NOT(ISERROR(1*CONCATENATE(MID(YourFieldName,1,3),MID(YourFieldName,5,3),MID(YourFieldName,9,4)))))

The FIND Function:  (online help)
The FIND function is similar to the SEARCH function with two differences;
  • FIND is case sensitive.
  • FIND does not support wild cards.

Examples Using Dates

You can create rules to limit date ranges by using the TODAY() function or the DATEVALUE() function.
Date must be in the future:
    =YourFieldName>TODAY()
Date must be in the future by "x" days:
    =YourFieldName>TODAY() + 3I.e. If today is the 7th, then valid dates start on the 11th.
Test against a particular date:  (online help for DATEVALUE)
    =YourFieldName>datevalue("1/1/2015")
Date must be between now and the end of the current year:  (online help for YEAR)
    =YourFieldName < DATEVALUE( "12/31/" & YEAR(TODAY()) )This example calculates a DATEVALUE by building a string to represent a future date.
Date must be within the next 30 days:
    =AND(YourFieldName >= TODAY(),YourFieldName <= TODAY()+30)
Date must be a Monday:   (1 = Sunday, 2 = Monday, 3 = Tuesday, …)   (online help for WEEKDAY)
    =WEEKDAY(YourFieldName)=2
Date must be the last day of the month:
=DATE(YEAR(yourDateColumn),MONTH(yourDateColumn),DAY(yourDateColumn))=DATE(YEAR(yourDateColumn),MONTH(yourDateColumn)+1,0)
Date must be the first day of the month:
=DATE(YEAR(yourDateColumn),MONTH(yourDateColumn),DAY(yourDateColumn))=DATE(YEAR(yourDateColumn),MONTH(yourDateColumn),1)
Note: Some of the more "fun" Excel date functions like WEEKNUM, NETWORKDAYS and EOMONTH are not supported in SharePoint.

Not so useful tests!   Smile

Value must be greater than PI.  (3.14159265358979 more or less…)
    =YourFieldName > PI()
And some square roots:
    =YourFieldName > SQRT(2)
And of course you need a little trig:
    =TAN(RADIANS(YourFieldName)) > 1

.

9/20/2015

Upload a File to SharePoint Using PowerShell

 

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!

 

An Upload with Metadata Script

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)

 

Upload an Attachment with a New List Item

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();

 

 

Looking for a PowerShell course for SharePoint administrators and auditors?

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

.

6/17/2015

SharePoint 2013 Search Weirdness – Part 3: When do Daily and Weekly Search Alerts Get Sent?

 

A continuation of the "Search Weirdness" series!


 

Search Alerts are Different!

Unlike list and library alerts:

  • You cannot create them for other people. There's no place to type an email address.
  • You cannot request an immediate alert.
  • You cannot pick a time:

List / Library alert options:

image

Search Alert options:

image

 

So when are they run?

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.

 

But that's for an on-premises SharePoint installation. Office 365 is different!

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…

 

.

4/22/2015

SharePoint Cincy - Let the SharePoint Search Genie Out of the Bottle!

 

Search Genie?

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.

SharePoint Cincy!

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!

 

Let the SharePoint Search Genie Out of the Bottle!

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.

.

4/08/2015

Setting a SharePoint Group's Description Using PowerShell

 

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

 

.

4/07/2015

PowerShell: Finding all SharePoint Lists with Lookup Columns

 

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.

 

Find all Lookup Columns

This will find all Lookup columns in the entire farm!

Notes:

  • Many of the out of the box lists are "custom" lists and will have fields that look like user added columns. Exclude those with the $TTNExcludeLists variable.
  • Field that are Hidden or FromBaseType are not typically user created and are excluded in this example.
$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

 

TypeDisplayName

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

 

.

3/10/2015

SharePoint 2013 Items Removed with Search Result Removal Return from the Dead!

 

In SharePoint 2010, Removed was Removed!

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:

image 

The auto-created Crawl Rule:

image

SharePoint 2010 had a interesting bug here. Uppercase letters in the URL would cause the the removal request to be ignored!


 

In SharePoint 2013 and Office 365, Removed is Just a Temporary Thing! Maybe only a few seconds!

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.

image

 

Removal Straight from the Crawl Logs

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.

image

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.

image

 

References:

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

3/02/2015

SharePoint: Create a View for Only Last Month

 

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.

 

Just Last Month Please

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.

 

Create two new columns

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)

    image

 

Create the View

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.

    image

Display and test the view!

 

How does it work?

=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!)

 

What about next month?

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)

 

What an easy way to create these?

Fire up Excel! (And see this article: http://techtrainingnotes.blogspot.com/2010/08/sharepoint-creating-calculated-column.html)

Have fun!

 

.

2/22/2015

Add JavaScript to Quick Launch in a 2010 Publishing Site

 

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:

    image

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!

    image

And there you go!

For a SharePoint 2013 workaround using PowerShell see:

 

.

Working with Quick Launch from PowerShell

 

The following will work with both SharePoint 2010 and 2013. It will also work with SharePoint 2007 if you "manually" create the SPWeb object.

The basic steps to add a new link to Quick Launch:

  1. Get the SPWeb object for your site.
  2. Get the SPWeb.Navigation.QuickLaunch object.
  3. Create a new node .
  4. Add the new node to an existing node (like "Lists" or "Libraries") or the root of Quick Launch.
  5. Done… No need to call Update() on anything!

Note: This will work with publishing sites as long as you are not using Managed Metadata Navigation.

 

Get your web object and the QuickLaunch object:

$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}.

 

Create a new node object:

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.

 

Add the node to 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)

 

Delete a link?

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()

 

Bulk updates?

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()  }

 

What about a Publishing Site?

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".

image

 

References:

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

2/15/2015

SharePoint Search Tip: Search for "title" where there is no "title"!

 

Title:somekeywords

image

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?

 

Everything has a Title?

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:

  • Some libraries and lists have an obvious Title column, so they are searchable on "Title". While libraries have a Title column, it is often not populated by users. Search will index the "Title" as the title field, when not blank, and otherwise index the "Name" column as "Title", so we can still search using "title:keyword".
  • Asset libraries have a "Title" column listed in the Library Properties page, but it's not listed on the Edit Properties page of videos, but we can still search using "title:keyword".
  • Custom lists where you have renamed the default title. Even after being renamed, it's still "Title" internally.
  • Lists with no displayed title column:
    • A Contacts list's "Last Name" column is internally named "Title". I.e. a search for title:smith works but a search for title:"mike smith" does not as "Mike" is not in the "Title/Last Name" column.
    • A Task list's "Task Name" column is internally named "Title".
    • A Discussion list's "Subject" column is internally named "Title".
    • A Categories list's "Category" column is internally named "Title".
    • A Content and Structure Reports list's "Report Title" column is internally named "Title".
    • A Links list has a hidden Title column that is auto-populated with the text from the "description" of the link.
    • A list created by importing an Excel file makes the first text column the clickable link column for the list. While the displayed name is whatever was imported, the internal name is "Title".

What does not have a Title?

  • Site Pages libraries.
  • Wiki libraries.
  • Visio Repository Site Process Diagrams libraries.
  • An external list (External Content Type) may not have a "Title" column.

 

Bottom line?

Almost every list is searchable using "title:somekeywords".

 

 

About the Links List

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:

image

 

.

Note to spammers!

Spammers, don't waste your time... all posts are moderated. If your comment includes unrelated links, is advertising, or just pure spam, it will never be seen.