Showing posts with label Content Editor Web Part Tricks. Show all posts
Showing posts with label Content Editor Web Part Tricks. Show all posts

11/24/2017

SharePoint: Running JavaScript Code Only When in Page Edit Mode


One of my old Content Editor Web Part “tricks” would not work when run in a Publishing page. I was hiding a web part when not in Page Edit mode. You can detect this mode by checking for ‘PageState.ViewModeIsEdit != "1"’. The PageState object is automatically created in normal site pages (“Wiki Pages”). It is also created in Publishing Pages, but only when the page has not been published. I.e. when the page is checked out, or in edit mode.

My code originally looked like this:

  if ( PageState.ViewModeIsEdit != "1" )
  {  …code to run when not in edit mode… }


As the PageState object does not exist in a Published page, I had to change it to this:

  if ( typeof PageState == 'undefined' || (PageState.ViewModeIsEdit != "1") )
  {  …code to run when not in edit mode… }


Of course… none of the above works in SharePoint Online “Modern UI” pages!


.

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

.

7/09/2015

SharePoint 2013: Hide List and Library Column Headings

 

This is an update to an older article to include support for SharePoint 2013.


Hiding Column Headings

I had a request to hide the column headings of a list displayed in a web part. First thought was that they wanted to hide the toolbar, but they were asking about the clickable column headings. I think they were wanting to make a page look more like a regular web page instead a page full of lists. By the way, this makes for a better way to display a view with only one column.

Note: This will of course remove the ability of the site visitor to sort and filter the web part.

Note: This will also work in the view page (view pages use web parts!), but in SharePoint 2010 and 2013 adding a web part to a view page will change how the ribbon gets displayed and will remove the View dropdown menu from the title area crumb trail.

Before:

image

After:

image

With Toolbar set to "No Toolbar":

image

Remove additional clutter…

You can edit the web part and then click "Edit the current view" further clean up the display of the list.

  • Remove the checkbox column: In the Tabular View section uncheck "Allow individual item checkboxes".
  • Remove the "…": In the Columns section uncheck "Name (linked to document with edit menu)" and checkmark "Name (linked to document)".
  • Remove the hyperlink: In the Columns section uncheck "Name (linked to document with edit menu)" and checkmark "Name (for use in forms)".
  • Remove any unneeded columns such as Modified or Modified By.

image

 

Steps:

  • Add your web part for the list or library to a page.
  • For a minimal look set the web part's Toolbar Type property to “No Toolbar”.
  • Copy the JavaScript below to a Notepad file (name it something like “HideHeading.html”) and upload this file to a library such as Site Assets.
  • In the library where you uploaded this file, click the "…" and copy the displayed URL. It should look something like this:
        https://yourServerDomain/sites/training/SiteAssets/HideColumnHeadings.html
  • Below your list / library web part add a Content Editor Web Part (CEWP).
    • If the CEWP displays it’s title bar then in the Appearance section set the Chrome to “none”.
    • Paste the URL copied above into the Content Link box.
    • In the web part properties editor, click OK.
    • In the PAGE ribbon, click Save.
  • Or (for SharePoint view pages)
    • Edit the view page in SharePoint Designer 2013. 
    • Copy and paste the Javascript to just before the end tag for PlaceHolderMain (just before </asp:Content>).
  • If you want to hide the column headings of multiple web parts modify the IF statement like this Three web parts

Web part summary name!

In SharePoint 2007, the summary name is usually just the list’s name: “Shared Documents”.

In SharePoint 2010, the summary name is usually the list’s name PLUS the list’s description. For example the default for Shared Documents is: “Shared Documents Share a document with the team by adding it to this document library.”  (including the period)

To find the correct name use your browser’s View Source option to display the HTML of the page and search for “summary=” and copy the text that follows. Or, use the browser's developer tools (usually F12) and search for "summary="

    <table  …  summary="Shared Documents Share a document with the team by adding it to this document library."   … >

 

The JavaScript

Need to change multiple web parts? Edit the line that contains "if (x[i].summary==""

Two web parts:
             if (x[i].summary=="Tasks" | x[i].summary=="Shared Documents"
Three web parts:
             if (x[i].summary=="Tasks" | x[i].summary=="Links" | x[i].summary=="Shared Documents"

<script type="text/javascript">
// CEWP trick from techtrainingnotes.blogspot.com!

// techtrainingnotes.blogspot.com/2015/07/sharepoint-hide-list-and-library-column.html
// Hide column headings in web parts

function TTNHideHeadings()
{
  //Find the list  (change "Documents" to your web part's "summary" name)
  var x = document.getElementsByTagName("TABLE"); // find all of the Tables 
  var y;
  for (var i=0;i<x.length;i++) 
  {
    if (x[i].summary=="Documents")  //find the table with this name
    {
      y = x[i].getElementsByTagName("TR");
      y[0].style.display="none";  //hide the first row
    } 
  }
}

try {
  // for 2010 and 2013
  ExecuteOrDelayUntilScriptLoaded( TTNHideHeadings, "sp.js" );
}
catch (e) {
  // for 2007
  _spBodyOnLoadFunctionNames.push('TTNHideHeadings');
}
  
</script>

6/16/2015

SharePoint 2013: Create a Quote of the Day Web Part (a CEWP trick!)

(Updated 11/24/17 to allow use in a Publishing page.)

This is a 2013 version of the 2007 and 2010 article found here: http://techtrainingnotes.blogspot.com/2010/10/sharepoint-create-quote-of-day-web-part.html


Quote of the Day / Tip of the Day

Want to display some “wise words” for your coworkers? You need a Quote of the Day web part!

image

You could display a picture or product of the day:

image


This web part is another simple Content Query Web Part solution similar to the ones found in my SharePoint 2010 Customization book. But… this one is for 2013!

  • Works from a normal SharePoint list.
  • Displays a random quote from the list.
  • Can display a new quote on each page view, or just one new quote a day.
  • Can be used to display quotes, product announcements or any kind of text, pictures or other content that you can add to a SharePoint rich text editor column.


Create the Quotes list

While you could use a Custom List, I used an Announcements list as it already had what I needed, a Title field and a Rich Text field.

  1. Go to Settings (gear) and click Add an App.
  2. Find and click Announcements.
  3. Add a name for the list such as “Quotes”.
  4. The description is optional, but is best left blank as it adds a little complication later on.  (I.e., don't click Advanced Options and add a description!)
  5. Click Create.
  6. If you are not using the Announcements list type then from the list’s Settings menu click Create Column and add a “Multiple Lines of Text” column. Name the column “Quote” (although any name will work) and click “Rich text (Bold, italics, text alignment).
  7. Add a few quotes by clicking "new announcement" or New from the ITEMs ribbon. You can use all of the rich text formatting options if you like. (Bold, colors, etc.)
  8. Create a new view by clicking the Create View link in the LIST ribbon.
  9. Create the view as a Standard view and name it something like “QuoteView”. Un-checkmark all columns except for “Quote” column (the “Body” column if using an announcements list).
  10. Expand the Tabular View section (scroll down to find it) and uncheck "Allow individual item checkboxes".
  11. Click OK.

You now have the list that will store the quotes. You will now add two web parts to a page. One which is the list of quotes, and the other which is a Content Editor Web Part with the JavaScript and HTML code.


Add the Quotes list web part to the page

  1. Go to the page where you want to add the “Quote of the Day”, most likely your home page. 
  2. Click Settings (gear), Edit Page.
  3. Click where you would like to add the quotes.
  4. In the INSERT ribbon click Web Part and add the web part for the quotes list.
  5. In the web part click dropdown arrow and then Edit Web Part.
  6. Select the view you created above (“QuoteView”).
  7. Click OK.

This web part will be hidden when the JavaScript runs.


The JavaScript and HTML file

  1. Open Notepad or your favorite HTML editor.
  2. Copy the sample code from below and paste into your editor.
  3. Either delete my sample <style> block (it displays the quote in red) or customize your own style.
  4. Find the line with "var quotesWebPartName=" and change "Quotes" to your list's name.
  5. (Optional) Find the line with "var OneQuotePerVisit = false" and change it to true so the user can only see one quote per day.
  6. Save the file.
  7. Upload the file to a library where all of your users have at least Read or View access. "Site Assets" is a good choice.
  8. Find the URL of the uploaded file by clicking the "…" next to the file name. Copy the URL so we can paste it into the CEWP below.


The Content Editor Web Part

  1. Add a Content Editor Web Part (CEWP) and move it so it is near the quotes web part. While the list web part can go anywhere, the CEWP must go where you would like to display the quote of the day. 
  2. Click the CEWP’s dropdown menu and select Edit Web Part.
  3. Paste the URL you copied earlier into the Content Link box.
  4. In the Appearance section add a title for the web part (perhaps “Quote of the Day”).
  5. At the bottom of the web part properties box click OK.
  6. Save your page and test! Refresh the page to see if the quote changes.



The JavaScript

Copy and paste the following JavaScript into Notepad or your favorite HTML editor. (see above)

<!-- add your own formatting here... (optional)-->
<style type='text/css'>
  #TTNQuoteText { color:red }
</style>


<!-- Quote will be displayed here -->
<span id="TTNQuoteText"></span>



<script type="text/javascript">

function TTNShowQuote()
{
// another CEWP trick from http://TechTrainingNotes.blogspot.com
// http://techtrainingnotes.blogspot.com/2010/10/sharepoint-create-quote-of-day-web-part.html

// name of the quotes library web part
  var quotesWebPartName="Quotes"; 


// set this to "true" so the user will see the same quote 
// for 12 hours or until they close and reopen the browser
  var OneQuotePerVisit = false;



// don't change these
  var QuoteList;
  var QuoteArray = [];
  var quoteCount = 0;

  var TTNTables = document.getElementsByTagName("TABLE");
  var i=0;
  for (i=0;i<TTNTables.length;i++) 
  {
    if (TTNTables[i].summary)
    {
    if (TTNTables[i].summary == quotesWebPartName)
    {
      // Get the table with the quotes
      QuoteList = TTNTables[i].getElementsByTagName("tbody")[0];

      // hide the links list web part, but only if not in edit mode
// 11/25/17 update to allow use in a Publishing page.
if ( typeof PageState == 'undefined' || (PageState.ViewModeIsEdit != "1") )
{ QuoteList.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.display="none"; } break; } } } if (!QuoteList) { document.getElementById("TTNQuoteText").innerHTML="Web Part '" + quotesWebPartName + "' not found!"; } //Count the quotes var links = QuoteList.getElementsByTagName("TR") // find all of the rows var url; var quoteCount = 0; for (i=0;i<links.length;i++) { //if (links[i].childNodes[0].className=="ms-vb2") //{ QuoteArray[quoteCount] = i; quoteCount++; //} } if (quoteCount==0) { document.getElementById("TTNQuoteText").innerHTML="No quotes found in web part '" + quotesWebPartName + "'!"; } var id=-1; // check for a cookie and use last ID if found if (OneQuotePerVisit) { // check for a cookie with the last quote ID if (document.cookie.length>0) { c_start=document.cookie.indexOf("LastQuoteDisplayedID="); if (c_start!=-1) { c_start=c_start + "LastQuoteDisplayedID".length+1; c_end=document.cookie.indexOf(";",c_start); if (c_end==-1) c_end=document.cookie.length; id = unescape(document.cookie.substring(c_start,c_end)); } } } if (id == -1) { // generate a random quote ID id = Math.floor(Math.random() * QuoteArray.length) } // display the quote document.getElementById("TTNQuoteText").innerHTML= QuoteList.getElementsByTagName("TR")[QuoteArray[id]].childNodes[0].childNodes[0].childNodes[0].innerHTML; if (OneQuotePerVisit) { // set a cookie so they see the same quote for xx hours (.5 = 1/2 day = 12 hours) var exdate = new Date(); exdate.setDate(exdate.getDate() + 1); document.cookie="LastQuoteDisplayedID=" + id //+ ";expires=" + exdate.toUTCString(); } } // add our function to the SharePoint OnLoad event _spBodyOnLoadFunctionNames.push("TTNShowQuote"); </script>


Only have about 100 more of these to update from 2007/2010 to 2013!



.

5/15/2013

Adding a scrolling list of messages to SharePoint

 

Tested in SP2010, SP2013, Office 365 2013 and should work in SP2007.

I have not offered up a cool SharePoint trick for a while… so here's one that takes a list and turns it into a scrolling "marquee" list like this one:

Release B.2 of the CRM system has been released!

Bugs have been found in B.2, please revert to B.1!

The "Dealing with procrastination" meeting has been rescheduled

Get Started with Microsoft SharePoint Foundation!

This uses the <MARQUEE> tag that may not work in every browser. But according to this page it works in at least these browsers: Chrome 1+, Firefox 7+, Internet Explorer 2, Opera 6+ and Safari 1+.

The code to do this was copied from one of my older tricks "SharePoint: Convert a Links list to a Dropdown list" with only two updates: change the dropdown list to a MARQUEE and to delay load the code so it will also work in SharePoint 2013.

The example below uses an Announcements list, but should work with any list as long as the view displays the "Title (linked to item with edit menu)" column.

How to get the ID of the web part…

The web part's ID has a name something like WebPartWPQ3. To find it:

  1. Use the browser's View, View Source or View Page Source option to display the HTML of the page
  2. Search for a slash followed by the name of the web part:  "/Announcements"
  3. Either read down from what you found looking for something like 'id="WebPartWPQ3"' (the number may be different)  Note: you are not looking for WebPartTitleWPQ3 or other similar names!
  4. Copy everything inside of the quotes, including any extra spaces or periods! Note that 2010 will include the list's name and the list's description while 2007 will only have the list's name.
      summary="Announcements Use this list to track upcoming events, status updates or other team news."

Steps:

  1. Create your Announcements list and add your announcements
  2. Add the announcement list’s web part to the page
  3. Find the name of the web part (see "How to get the ID of the web part" above)
  4. Create a Notepad file:
    1. Copy and paste the JavaScript code from below
    2. Edit the JavaScript to change the line with var LinkList = document.getElementById("WebPartWPQ5") and change "WebPartWPQ5" to your web part name found in step 3 above
    3. Customize the <marquee> tag to set any desired options (see: http://msdn.microsoft.com/en-us/library/aa259539(v=VS.60).aspx)
  5. Upload the Notepad file to a library ("Site Assets" is a good choice)
  6. Right-click the newly uploaded file and select Copy Shortcut (to get the URL to the file)
  7. Add a Content Editor Web Part (CEWP) to the page with the announcements web part, just under the announcements web part
  8. Modify the CEWP and
    1. set its title to whatever you like ("Site News!") (or set its Chrome to none to hide the title)
    2. paste the URL you copied in step 6 into the Content List box
    3. Click OK
  9. Save the page and test it!

Notes:

  • You can customize the <marquee> tag by changing its attributes or wrap it other HTML such as a DIV with a border or background.
  • <marquee> may not work in every browser, but will fall back to list a list of links if it is not supported.
  • There are four lines that start with "MyMarquee.innerHTML", but only one of them is not commented out ("//"). You can uncomment any one of these:
    • text only
    • text with hyperlinks
    • text with hyperlinks that open in a new window
    • text with hyperlinks that open in a SP 2010 style dialog box

 

The Code:

<!-- the MARQUEE tag for the items -->
<!-- customize as needed! –>
<marquee id="TTN_marquee" direction="up" height=48 scrollamount="1"></marquee>


<script type="text/javascript">
// CEWP trick from techtrainingnotes.blogspot.com! 
// http://techtrainingnotes.blogspot.com/2013/05/adding-scrolling-list-of-messages-to.html

// Change the web part name here!!! 
var TTNLinkListName = "WebPartWPQ3";



function TTNgetSPversion()
{  // returns 12 for 2007, 14 for 2010 and 15 for 2013
  var SPversion = "12"; 
  try { SPversion = SP.ClientSchemaVersions.currentVersion.substring(0,2) } 
  catch (e) {}
  return SPversion;
}

function TTNinEditMode()
{
    var editmode="";
    // test for wiki page mode
    try { editmode = document.getElementById("_wikiPageMode").value } 
    catch (e) {}
    if (editmode=="")
    {
      // test for web part page mode
      try { editmode=document.getElementById("MSOSPWebPartManager_DisplayModeName").value } 
      catch (e) {}
    }
    if (editmode=="Edit" || editmode=="Design")
      return true;
    else
      return false;
}

function TTNlist2marquee()
{
  var TTNLinkList = document.getElementById(TTNLinkListName);
  var spVersion = TTNgetSPversion();
  var editmode = TTNinEditMode();

  // hide the list, but only if not in edit mode
  if (TTNLinkList)
  {

    // are we in edit mode?
    var displaymode = "";
    if ( !editmode )
    {
       displaymode = "none";
    }

    // hide the list web part (based on SP version)
    if ( spVersion = 12 ) 
    {
      // 2007 code here
      TTNLinkList.parentNode.parentNode.parentNode.style.display=displaymode;
    }
    else
    {
      // 2010 and 2013 code here
      TTNLinkList.style.display=displaymode;
    }  

    
    //Copy all of the links from the list to the MARQUEE
    var MyMarquee = document.getElementById("TTN_marquee");

    var links = TTNLinkList.getElementsByTagName("A"); // find all of the links
    for ( i=0; i<links.length; i++ ) 
    {
      if (links[i].onfocus)
      {
        if (links[i].onfocus.toString().indexOf("OnLink(this)") > -1)
          { 
            // text only version of the marquee (no links)
            //MyMarquee.innerHTML += links[i].innerHTML + "<br>"; 

            // version with hyperlinks
            MyMarquee.innerHTML += "<a href='" + links[i].href + "'>" + links[i].innerHTML + "</a><br><br>";

            // open the link in a new window
            //MyMarquee.innerHTML += "<a href='" + links[i].href + "' target='newwin'>" + links[i].innerHTML + "</a><br><br>";

            // open the link in a SP 2010 dialog box
            //MyMarquee.innerHTML += "<a href='JavaScript:var options=SP.UI.$create_DialogOptions();options.url=\"" + links[i].href + "&IsDlg=1\";options.height = 400;void(SP.UI.ModalDialog.showModalDialog(options))'>" + links[i].innerHTML + "</a><br><br>";

          }
      }
    }
  }
  else
  {
    alert("Marquee list named '" + TTNLinkListName + "' not found");
  }

}

try {
  // for 2010 and 2013
  ExecuteOrDelayUntilScriptLoaded( TTNlist2marquee, "sp.js" );
}
catch (e) {
  // for 2007
  _spBodyOnLoadFunctionNames.push('TTNlist2marquee');
}

</script>
 
 
.

10/10/2012

SharePoint–Finding Column Display and Internal Names

 

Many customizer and developer projects require knowing the "internal names" for list and library fields. For example the task list field "% Complete" is internally named "PercentComplete".

Here are a few ways to find the internal name:

  • From the browser
  • From SharePoint Designer
  • Using PowerShell
  • Using a C# Console Application
  • Using the Client Side Object Model
  • Using JavaScript Client Side Object Model and a Content Editor Web Part

    Pretty much something for everyone!

 

From the browser

Permissions needed: Must have Site Owner (Full Control) or Design permissions

This could be a bit tedious if you wanted to check all of the fields, but for just one it's quick.

  1. Display the list or library and click the List or Library Ribbon
  2. Click List or Library Settings
  3. Scroll down to the list of columns and click the column name
  4. Note the URL for the page… the internal name is listed at the end: 
        http://………&Field=Author

 

From SharePoint Designer

Permissions needed: Must have Site Owner (Full Control) or Design permissions (may only need edit permissions in the library holding the web part page… To Do for Mike: need to test this!)

  1. In SharePoint Designer 2010 open your site and edit a web part page
  2. Click in a web part zone, click the Insert ribbon tab, click Data View and Empty Data View
  3. Click "Click here to select a data source" and pick your list
  4. In the Data Source Details pane mouse over the sample data (or the blank area below the field name) and the XSLT path the field will be displayed. The value after the "@" is the internal name.
    image

 

Using PowerShell

Permissions needed: Administrator access to the server and permissions to the site (PowerShell is an administrator's tool)

$web = Get-SPWeb http://sharepoint/sites/training/salestraining
$list = $web.Lists["Announcements"]
$list.fields | select Title, InternalName, Hidden, CanBeDeleted | sort title | ft -AutoSize

As you will most often be interested in the non-hidden fields, you can add a Where to filter them:

$list.fields | select Title, InternalName, Hidden, Sealed, CanBeDeleted | where {$_.Hidden -eq $false} | sort title | ft –AutoSize
 

Using a C# Console Application

Permissions needed: Administrator access to the server and permissions to the site (the code must run on the server)

using System;
using Microsoft.SharePoint;  // add a reference to Microsoft.SharePoint

// remember to change the Build Platform Target to x64!
namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            SPSite site = new SPSite("http://sharepoint/sites/Training/");
            SPWeb web = site.AllWebs["salestraining"];
            SPList list = web.Lists["Announcements"];

            Console.WriteLine("Title - Internal Name - Hidden - CanBeDeleted");
            foreach (SPField f in list.Fields)
            {
                Console.WriteLine("{0} - {1} - {2} - {3}", f.Title, f.InternalName, f.Hidden, f.CanBeDeleted);
            }
            site.Dispose();
            Console.ReadLine();
        }
    }
}

 

Using the Client Side Object Model

Permissions needed: May only need view permissions in the library holding the web part page… (To Do for Mike: need to test this!)

You can write and run Client Side Object Model (CSOM) code from your local PC and not need access to the SharePoint Servers. The following is a little console application with references added for Microsoft.SharePoint.Client and Microsoft.SharePoint.Client.Runtime.

using System;

using Microsoft.SharePoint.Client;

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "http://sharepoint/sites/training";
            ClientContext context = new ClientContext(url);
            Web web = context.Web;
            var list = web.Lists.GetByTitle("Announcements");

            context.Load(list.Fields);
            context.ExecuteQuery();

            Console.WriteLine(list.Fields.Count);
            foreach (Field f in list.Fields)
            {
                Console.WriteLine("{0} - {1} - {2} - {3}", f.Title, f.InternalName, f.Hidden, f.CanBeDeleted);
            }
            Console.ReadLine();
        }
    }
}

 

Using JavaScript Client Side Object Model and a Content Editor Web Part

Permissions needed: May only need view permissions to view the page… (To Do for Mike: need to test this!)

image

Steps:

  1. Open Notepad and copy and paste the code below
  2. Save the file as GetFieldName.htm
  3. Upload the file to a library (SiteAssets, Shared Documents, etc.)
  4. Right-click the uploaded file and copy the shortcut (the URL)
  5. Go to a web part page or the home page and add a Content Editor Web Part
  6. Edit the web part and set the Content Link to the URL of the file you just uploaded
  7. Save your changes and test!

                  image

<input type="text" id="ListName" value="Tasks"></input>
<button onclick='GetFieldList()'>Get Field List</button>

<script type="text/javascript">

function GetFieldList()
{
  var listname = document.getElementById("ListName").value;
  var ctx = SP.ClientContext.get_current();
  this.web = ctx.get_web();
  ctx.load(this.web);
  this.list = web.get_lists().getByTitle(listname);
  ctx.load(this.list);
  this.fields = this.list.get_fields();
  ctx.load(this.fields); 

  ctx.executeQueryAsync(Function.createDelegate(this, this.getListInfoSuccess), Function.createDelegate(this, this.getListInfoFail));
}

function getListInfoSuccess(sender, args) 
{
        var fieldEnumerator = this.fields.getEnumerator(); 
        var results="";
        while (fieldEnumerator.moveNext()) { 
            var oField = fieldEnumerator.get_current(); 
            if (!oField.get_hidden())
            results+= oField.get_title()
                + " - " + oField.get_internalName()
                + " - " + oField.get_hidden()
                + "\n";
        }
        alert(results);
}    
function getListInfoFail(sender, args) 
{
 alert('Something failed. Error:'+args.get_message());    
}

</script>

8/22/2012

SharePoint 2010 - Create a Calendar View without Hyperlinks

 

This article is one of the many tips in my book, SharePoint 2007 and 2010 Customization for the Site Owner, and presented here as a response to an MSDN forum question. So if this is useful to you… buy the book!

A 2007 version is here and in a lot more detail in my book.

 

We often need a calendar view that is just a "calendar view". I.e. no hyperlinks, just text.

In SharePoint 2010 the data for the calendar is asynchronously loaded using a SharePoint built-in JavaScript function called after the page is loaded. That means that the data we want to change is not yet in the browser when the JavaScript is loaded from within the Content Editor Web Part. To get our code to run at the right time we need to hook into the SharePoint function that loads the calendar items. This is a function named "SP.UI.ApplicationPages.CalendarNotify.$4a".We also need to delay the load of our code, and we can do that with a SharePoint feature named "_spBodyOnLoadFunctionNames.push".

Two Solutions!

Content Editor Web Part

Add a Content Editor Web Part as we have done in many of the other customizations. The problem with this approach is that SharePoint 2010 will no longer treat this page as a view. When this page is displayed you will see two changes:

  • The View dropdown list in the site title area is missing
  • The ribbon will not be displayed when the page is first loaded, but will be displayed when any event item is clicked.

SharePoint Designer

Add the custom JavaScript using SharePoint Designer. The page will then display as an ordinary view with no odd behavior.

I recommend the second approach.

 

Steps - Using SharePoint Designer
  1. Go to the calendar in the browser and create a new view (maybe "Calendar - No Links")
  2. Open your site in SharePoint Designer 2010
  3. Click Lists and Libraries in the Site Objects pane
  4. Click your calendar list and click the new view
  5. In the ribbon click the Advanced Mode link (so you can edit the entire page)
  6. Search for "</WebPartPages:WebPartZone>" and insert a new line just after this tag
    </WebPartPages:WebPartZone>
    your customization goes here (don't type this J )
    </asp:Content>
  7. Add the JavaScript from below
  8. Save your changes in SharePoint Designer
  9. Go to the calendar in a browser, select the new view and confirm that the hyperlinks have been removed

 

Steps - Using a Content Editor Web part
  1. Open Notepad and add the JavaScript from below and save the file (maybe "HideCalendarLinks.txt")
  2. Upload the file to a library (I use a library named CustomziationFiles)
  3. Right-click the new library file, click Properties and copy the URL to the file
  4. Go to the calendar in the browser and create a new view (maybe "Calendar - No Links")
  5. After the new calendar view has been displayed click Site Actions, Edit Page
  6. Add a Content Editor Web Part
  7. Move the new web part below the calendar web part
  8. Edit the web part and paste the URL to the text file uploaded earlier into the Content Link box
  9. Click OK to save the change, then in the Page tab of the ribbon click Stop Editing
  10. Go to the calendar, select the new view and confirm that the hyperlinks have been removed

 

Code to hide the links

Code note!  Prior to service pack 1 you will need to use SP.UI.ApplicationPages.CalendarNotify.$4a while after service page 1 you will need to use SP.UI.ApplicationPages.CalendarNotify.$4b.

<script type="text/javascript">

// TechTrainingNotes.blogspot.com
// Sample code from "SharePoint 2007 and 2010 Customization for the Site Owner"
// ISBN: 978-0982899205
// http://www.amazon.com/dp/0982899203/ref=as_li_ss_til?tag=tectranot-20&camp=213381&creative=390973&linkcode=as4&creativeasin=0982899203&adid=0cc7a0y6fv2nknxyqvff&


// load our function to the delayed load list
_spBodyOnLoadFunctionNames.push('hideCalendarEventLinkIntercept');

// hook into the existing SharePoint calendar load function
function hideCalendarEventLinkIntercept()
{
  var OldCalendarNotify4a = SP.UI.ApplicationPages.CalendarNotify.$4b;
  SP.UI.ApplicationPages.CalendarNotify.$4b = function () 
    {
      OldCalendarNotify4a();
      hideCalendarEventLinks();
    }
}

// hide the hyperlinks
function hideCalendarEventLinks()
{

  // find all DIVs
  var divs = document.getElementsByTagName("DIV");
  for (var i=0; i<divs.length; i++)
  {
    // find calendar item DIVs
    if (divs[i].className.toLowerCase() == "ms-acal-item")
    {
      // find the hyperlink
      var links = divs[i].getElementsByTagName("A");
      if (links.length == 1)
      {
        // replace the hyperlink with text
        links[0].parentNode.innerHTML = links[0].innerHTML
      }
    }

    // find "x more items" links and re-remove links on Expand/Contract
    if (divs[i].className.toLowerCase() == "ms-acal-ctrlitem")
    {
      var links = divs[i].getElementsByTagName("A");
      if (links.length == 1)
      {
        links[0].href = "javascript:hideCalendarEventLinks();void(0);"
      }
    }

  }
}

</script>

 

 

.

6/21/2012

SharePoint: Hide a web part for selected users

 

"Out of the box" there are no "deny permission" features in SharePoint, only grant permissions. If you have a group called Sales with 1000 users, and you would like to use the SharePoint Audience feature to display a web part for everyone in Sales except for Sam, Susan and Bob, you will have to create a new group with 997 users named "Sales except for Sam, Susan and Bob" (and then maintain two groups going forward. But there is a way…

Here's a trick that starts by using a Content Editor Web Part to hide another web part from everyone. By creating a group with our three problem people and using that as an Audience for this CEWP we can selectively hide another web part. 

Before we start, Audiences are not available in WSS 3.0 (2007) or SharePoint 2010 Foundation.

For this trick you need to do four things:

  • Create the group or audience of people to hide things from
  • Discover the ID of the web part you want to hide (see here for 2007 and 2010)
  • Write a bit of CSS to hide the web part
  • Add a Content Editor Web Part to hold or link to the CSS and audience filter it

 

Create the audience:

Your audience can be any AD group (Distribution/Security Group), any SharePoint group you create or a custom audience (Global Audiences) created by your server administrator. For testing proposes you make want to create a test SharePoint group named "TheNoSeeGroup".

The CSS:

The CSS is quite simple, just a "display:none" to hide the entire web part. As this will placed in a Content Editor Web Part that will only be seen by the "TheNoSeeGroup" this CSS will only be effective for those users. The trick here is to get the ID of the web part you want to hide.

    image

Discovering the ID of the web part to hide:

Go to the page with the web part to hide (such as Shared Documents) and use your browser's View Source option to see the page's HTML. Do a search for MSOZoneCell_WebPart and browse around to see if there's any hints that your found the right web part. If not, search again. For more help, go her for 2007 and here 2010. The ID will look something like MSOZoneCell_WebPart9. Note that if you delete and re-add the web part it may receive a new number.

 

Steps:

  1. Find your web part's ID  (MSOZoneCell_WebPart1, MSOZoneCell_WebPart2, etc)
  2. Open Notepad and add the CSS from above using your web part's ID
  3. Save the Notepad file and upload to a SharePoint library in your site (I used Site Assets and named the file HideWebPart.htm)
  4. Go to the library where you loaded the file, right-click the file and select Copy Shortcut (or better, right-click the file, click Properties and copy the URL from there)
  5. Go to the page with the web part you want to hide, edit the page and add a Content Editor Web Part (CEWP) above the web part you want to hide
        image
  6. Edit the CEWP and paste the URL copied earlier for the CSS Notepad file
        image
  7. Click OK… The Shared Documents web part should now be hidden (from everyone!)
  8. Edit the Content Editor Web Part again
  9. In the web part's properties panel expand the Advanced section, scroll to the bottom and select the audience to hide the web part from
        image
    Note that in 2010 the text box has no visible border!
          image
  10. Save your changes and test by have a group member, and a non-group member, log in and see if the web part is displayed.

Note for 2010: If you can't see the CEWP when you edit the page (to edit it or to delete it) it's because you are not in the right group! Either add yourself to the "hide from" group or use a trick from here to display a list of all of the web parts, append ?Contents=1 or &Contents=1 to the end of the page's URL.

.

5/08/2012

Adding JavaScript and CSS to SharePoint

 

Many of my Site Owner customization tips require adding CSS and JavaScript to individual pages, the Content Editor Web Part or to the master page. Instead of repeating those steps over and over I'll link to this page in the future. (This is an expansion of an earlier article found here.)

Where to put your JavaScript or CSS

Where to put your JavaScript or CSS

Where you put the JavaScript or CSS largely depends on what it does and if it needs to interact with a single list, a single page or an entire site. Here are some possibilities:

  • Content Editor Web Part - Use a CEWP when you want to add code to a single web page that is also a web part page. (See the Web Part chapter of my book for ways to see if a page is a web part page)
     
    Features:
    • Easy to use (Source Editor in 2007 and HTML editor in 2010)
    • Easy to reuse (Exportable - see the Web Part Must Knows chapter of my book for details)
    • Can be placed directly in the web part page that needs the JavaScript or CSS
    • JavaScript or CSS can also be added by linking to a text file stored in a SharePoint library. This file can have any extension, but using .HTM will let you open the file directly into SharePoint Designer.
  • Directly in a page - Use SharePoint Designer when you want to directly edit a Basic Page, Web Part page or a site page. You can add the JavaScript inside of <SCRIPT> tags, the CSS inside of <STYLE> tags, or link to a file that contains the code. Typically add your code just before the ending content tag for PlaceHolderMain. (</asp:Content>)
  • Master Page - Use SharePoint Designer to add code to a master page when you want to code to be available on every page in a site. You can add the JavaScript inside of <SCRIPT> tags or link to a file that contains the JavaScript. Typically add your CSS just before the </HEAD> section and your JavaScript just before the </BODY> tag.

 

CSS

CSS is typically added inside of a <STYLE> block. The following will change the title of a 2007 site:

       <!—the following overrides the SharePoint ms-sitietile Core CSS class --> 
       <style type="text/css"> 
           .ms-sitetitle 
           { 
             color:blue; 
             font-size:30pt;
           } 
       </style>

 

CSS can also be stored in a file in a library and linked:

     <link rel="stylesheet" type="text/css" 
           href="/sites/training/shared documents/mycustom.css" />

 

JavaScript

JavaScript is typically added inside of a <SCRIPT> block. The following will add a border around the site's icon:

<script type="text/javascript">
var siteImage = document.getElementById('GlobalTitleAreaImage');
if (siteImage != null)
{
  siteImage.style.border = 'dashed';
}
</script>

 

JavaScript can also be stored in a file in a library and linked:

<script type="text/javascript" language="javascript" 
            src="/sites/training/shared documents/mycustom.js"></script>

 

 

The CEWP in SharePoint 2007

The CEWP in SharePoint 2007 is a simple web part that includes four options to add content:

  • a Rich Text Editor with all of the HTML editing options you might expect
  • the Edit HTML Source button (image) inside of the Rich Text Editor toolbar
  • a Source Editor that is very simple text editor, so simple you many want to use another tool to write your code, and then just copy it to the Source Editor
  • a Content Link box to link to an external file containing your code - this file would typically be stored in a library
To add a Content Editor Web Part

1. Display any web part page, click Site Actions, Edit Page then Add a web part:

    image

To edit a Content Editor Web Part

1. Click the web part's edit button then select Modify Shared Web Part, then click the Source Editor button

    image

2. Or, if you have linked to a text file, then just open that text file directly from a library, make your edits and then save. No need to open the CEWP.

Tip: You can open linked code files from within SharePoint Designer by just expanding the library's folder and double-clicking the file. You will then be able to use SharePoint Designer's JavaScript, HTML and CSS editors with their color coding and auto completion features.

Hiding the CEWP title bar

The CEWP will often be used to store code and will not need a title or title bar displayed on the page.

  • In the properties editor, expand Appearance, click the Chrome Type dropdown and select None

image

 

The CEWP in SharePoint 2010

In 2010 it’s now just called "Content Editor" and is in the Media and Content section of Add a Web Part:

    image

The page with the new web part:

    image

How do you add HTML?

When you add this web part you get a "wiki style" editor for normal rich text editing. When you use the web part's edit dropdown and click Edit Web Part you will find that the Source Editor button is gone! So how do you add your JavaScript and CSS? You could just click the HTML button in the Ribbon (image), but read on for some fun issues with this option…

    image

When you add CSS or JavaScript you may get this nice little message:

    image

Consider this trivial example:

    image

Each time you go back into the HTML editor and click OK it adds another blank line after the script tag and removes line breaks elsewhere!

    image

It has even sometimes changes the capitalization. In one of my edits it changed color:red to COLOR:red.     Who knows why…

 

The fix? Just link to your code!

Both 2007 and 2010 offer the option to link from the CEWP to a text file with your content. To avoid the problem with the random edits made by 2010 just upload a text file containing the code to a library. Then in the CEWP just click the Edit Web Part option in the dropdown and add the link to the code file. This has added benefit of using any HTML, CSS and JavaScript editor such as Visual Studio or SharePoint Designer to edit your code.

To edit a Content Editor Web Part

1. If the CEWP includes displayable text, the just click anywhere in the web part to open up the editor ribbon and start typing.

2. If you have linked to a text file, then just open that text file from the library, make your edits and then save. No need to open the CEWP during each edit, just refresh the page to see the changes.

Tip: You can open linked code files from within SharePoint Designer. Click All Files, click the "push pin" to expand the list of files, expand the library, and double-click your file. You will then be able to use SharePoint Designer's JavaScript, HTML and CSS editors with their color coding and auto completion features.

 

Reusing a Content Editor Web Part Customization

You can easily reuse many CEWP customizations by exporting the web part to a file and then uploading it into another site. As the CEWP is just a container for text (HTML, JavaScript, CSS, etc) it will have few external dependencies and should be reusable in other pages and sites.

A few watch outs:

  • If the CEWP code has an absolute URL to an image, JavaScript file or other resource, then the links will still work, as long as the users of the new site have permissions to the linked files in the original site
  • If the CEWP code has relative URLs, then the new site will need the same files stored in libraries with the same library name and file names AND the same site URL (SharePoint relative URLs are relative to the site collection, not to the subsite)

 

Direct page edits using SharePoint Designer?

Almost everything you can do with the CEWP can also be done by adding your customizations directly to the page using SharePoint Designer.

Advantages of direct page edits:

  • Edits are completely hidden from site users, especially site members as there are no web parts they can edit or delete
  • Code added directly to a SharePoint 2010 view page will not break crumb trail and view menu features (See "The CEWP in SharePoint 2010" later in this chapter)
  • SharePoint Designer's editors make writing JavaScript, HTML and CSS easier with color coding and auto completion features

Disadvantages:

  • You must use SharePoint Designer - and your company may have a policy against this
  • The page will changed from un-customized (ghosted) to customized (un-ghosted), which has a small impact on performance (See chapter 6 for more details)
  • Customizations are harder to find by the next site owner who inherits your site
  • More steps are needed for each edit

To add code directly to a page:

Add your JavaScript code between the end tag for the Web Part Zone and the end tag for the PlaceHolderMain content tag (</asp:Content). (See chapter 6 of my book - "Editing a SharePoint Page")

    image

 

Editing the Master Page

JavaScript and CSS that impacts every page in the site needs to be added to the master page. CSS will typically be added in the <HEAD> section of the page. Links to JavaScript libraries will also be added to the <HEAD> section. JavaScript blocks will typically be added just before the </BODY> tag at the end of the master page.

For CSS, your custom styles can be added just after these two controls:

    <Sharepoint:CssLink runat="server"/>
    <SharePoint:Theme runat="server"/>

 

SharePoint 2007 Steps

Steps:

  1. Open your site in SharePoint Designer 2007
  2. Expand the _catalogs folder and expand the masterpage folder
  3. Double click the master page (typically default.master)
  4. If not already selected, click the Code button at the bottom of the window
  5. For CSS and linked files find the </HEAD> tag in the page
    For JavaScript script blocks, find the </BODY> tag in the page
SharePoint 2010 Steps

Steps:

  1. Open your site in SharePoint Designer 2010
  2. In the Navigation - Site Objects pane click Master Pages
  3. Right-click your site's master page (typically v4.master) and select "Edit in Advanced Mode"
  4. If not already selected, click the Code button at the bottom of the window
  5. For CSS and linked files find the </HEAD> tag in the page
    For JavaScript script blocks, find the </BODY> tag in the page

 

When will my scripts run?

A simple embedded script like the following will run as soon as the browser loads it.

<script type="text/javascript">
  alert('hello world!');
</script>

If the script is in the middle of the page, like it would be when loaded using a Content Editor Web Part, then the script will run before the page has been fully created by the browser. Most JavaScript for SharePoint projects will need to run after the HTML that it's going to interact with has been fully loaded, and quite often, after the entire page as been loaded.

To see how to deal with JavaScript running at the wrong time in SharePoint see Chapter 5's section on "Controlling when JavaScript Runs" in my book.

5/07/2012

SharePoint 2010, the Content Editor Web Part, and Broken Views…

 

The following is an excerpt from chapter 7 of my book SharePoint 2007 and 2010 Customization for the Site Owner. I keep getting questions on this so I thought I’d post it here. (You should still by the book!)

 

Adding a Content Editor Web Part to a view page like "Allitems.aspx" is a great way of customizing list and library views in SharePoint 2007. This generally had no negative impact, was easy to do and produced some major improvements with little work.

The Problem in 2010?

SharePoint 2010 treats view pages with added web parts as non-views and removes many view related features. I.e. adding a web part to a view breaks some things…

Here's a typical Task list All Tasks ("Allitems.aspx") view with the view menu clicked:

  image

Note these features:

  • The name of the view is displayed: Subsite 3 > Tasks > All Tasks
  • There are ribbon tabs for Browse, Items and List (or for a library, Documents and Library)
  • There is a dropdown arrow after "All Tasks" in the crumb trail

Here is the same view after the addition of a Content Editor Web Part (and the JavaScript to color code the task list):

  image

Note what's missing:

  • The name of the view in the crumb trail is missing
  • The ribbon tabs for Items and List are missing
  • The dropdown arrow after "All Tasks" in the crumb trail is missing
  • You can still get to the ribbon tabs, but you have to first click a row in the list:

        image

 

The Fix?

Don't add web parts to a 2010 view! (Duh) Instead, edit the page using SharePoint Designer 2010 and add your JavaScript code between the end tag for the Web Part Zone and the end tag for the PlaceHolderMain content tag.

    image

You can either embed the JavaScript:

    <script type="text/javascript">
        // js code here
    </script>

Or you can link to a text file with the JavaScript that you've uploaded to a library:

    <script src="../../SitePages/ColorCodedTaskList.txt" type="text/javascript"></script>

 

.

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.