12/15/2010

Want to be a pilot? (Shameless book plug…)

 

Need a last minute gift?  Always wanted to be a pilot?  Want something to read on the plane?

 

Timothy O'Connor, a fellow trainer at MAX Technical Training, has just completed a book for the “sport pilot” titled:

You Can Afford To Be A Pilot: How To Become A Pilot And Fly For Fun On A Middle Income Budget 

The purpose of this book is not to teach ground school or flight training, but is intended to teach the reader how to shop for these services and, once purchased, how to keep them affordable, efficient and useful. Certified FAA Instructor Timothy O’Connor uses his twenty years of experience with technical subjects and adult training to bring flying to people on a middle-income budget. Learn about the new Sport Pilot Certificate license, Ultralights, Light Sport Aircraft, Experimental Aircraft, How to pass the FAA Exams, the steps involved in learning to fly, getting the best flying lessons, how to choose instructors ( a CFI ) and more on a budget.  Read more at the links below…

 

By the way, Tim is a pilot, a Certified Flight Instructor and in his spare time, a Microsoft Certified Trainer. Both he and his wife own airplanes (yes, plural). 

 

The hardcopy version is available from Amazon:

            

 

EBook versions are available from here for $8.99:

https://www.smashwords.com/books/view/31207

 

 

If you run into Tim, tell him he owes me a sales commission, or at least a cup of MAX coffee…

 

.

SharePoint: How to get the SharePoint version from JavaScript

 

Update: I found a JavaScript function that returns the version number. Content below has been updated.

 

Simple question:

I’m writing some JavaScript that will run almost identically in SharePoint 2007 and SharePoint 2010. How can I write an IF statement to test the version?

 

So far I have found no simple answer, but I have found a few that work. Each has an “if” or a “risk”, so pick one that works for you.  If you know a better way, please post a comment below.  I propose three methods:

  • Method 1: Check the “_fV4UI” variable
  • Method 2: Check for an element with “V4” or “s4” in its ID or style
  • Method 3: Get the EXACT (almost) version number
  • Method 4: Call a SharePoint 2010 ECMAScript Class Library Object Method

 

SharePoint Versions: (that I’m interested in…)

  • 2007, also called 3.0 or V3, also called version 12
  • 2010, also called 4.0 or V4, also called version 14
  • and one day 201x, called 5.0 or V5? also called version 15?
  • would also love to get WSS vs MOSS and Foundation vs Server

It would be nice if:

  • something in the page had the version number?  (14.xxx)  (I can’t find it)
  • there’s a JavaScript function in one of the core libraries somewhere? (I can’t find one)  (Update: actually there is in 2010)

Solution requirements:

  • Must be available in all site pages, and ideally in all application pages
  • Must be in all templates
  • Must still be there after major master page branding surgery
  • Should still be useful

A few quick ideas:

  • Look for one of the many controls with a tag with “V4” embedded or one of the CSS classes with “V4” embedded. (Risk? Minimal, but site branders who have really hacked the master page or the styles could mess this up.)
  • Look for a unique JavaScript variable (see _fV4UI below). (Risk? Minimal, but a web search for “_fV4UI” finds a number of articles that mention deleting this from the master pages.)

Method 1: Check the “_fV4UI” variable

 

SharePoint 2010 pages have a JavaScript variable named “_fV4UI” that indicates if the page is using the “V4” navigation (Ribbon).  After an upgrade from SP 2007 this variable will be set to “false”. When the user interface is upgraded to the ribbon this will be set to “true”.

So:

  • if _fV4UI does not exist we probably have SP 2007
  • if _fV4UI does exist we probably have SP 2010
  • will there be a _fV5UI in the next version?  (can only wait and see)

The code:

<script type="text/javascript">
  if ( typeof _fV4UI == "undefined" ) 
  {
    // 2007 code here
  }
  else
  {
    // 2010 code here
  }  
</script>

Pros:

  • Probably the easiest test to do
  • Very simple code
    Can even be reduced to one line:

         var SPversion = (typeof _fV4UI == "undefined") ? "12" : "14";

Cons:

  • Your code must be placed after where SharePoint initializes this variable. Be aware that a number of blog articles mention removing the first instance listed below.

    This is where I found it in a Team Site:
    • Line 13 in the <HEAD> section  (this is the only one you will see in the master page)
    • Line 100 in the <BODY> section  (auto generated by a control)
    • Line 1033 near the end of the page  (auto generated by a control)

 

Method 2: Check for an element with “V4” or “s4” in its ID or style

 

The challenge here is, which one? You will need to pick an element that will reliably exist in all branded and unbranded pages.  Just about everything in the master page is up for grabs when custom branded. (Yes, I have seen branded sites without a title, Quick Launch, Tabs, Search, View All Files and Recycle Bin!) 

The control you pick needs to be towards the top of the page and most likely left behind in a branded master page. So let’s pick one… (let me know if there is a better one)  Both SP 2007 and SP 2010 have a hidden <SPAN> or <DIV> named TurnOnAccessibility. In 2010 this DIV has a style named “s4-notdlg”, which SP 2007 will never have, so let’s test for that:

The code:

<script type="text/javascript">
  if ( document.getElementById("TurnOnAccessibility").className == ""  ) 
  {
    // 2007 code here
  }
  else
  {
    // 2010 code here
  }  
</script>

Pros:

  • Easy to test
  • The tag we are testing is at the very top of the page

Cons:

  • This will probably be one of the first things a brander will remove (mostly as they have no idea what it is for)

What is TurnOnAccessibility for? The dropdown menus in SharePoint, such as the Welcome menu or Site Actions, are dynamically generated and somewhat meaningless to a user with vision problems who is using a screen reading program. When “more accessible mode” is enabled, clicking what usually is a dropdown menu will open a popup window with all of the menu options listed.

 

Method 3: Getting the EXACT (almost) version number

 

Now this is what I really want, and it is sent by SharePoint for every page request, but as part of the HTTP Header.  But… most of what’s in that header is not available to JavaScript.

Here’s what’s sent from SharePoint 2010 in the header:

image

Is that version number right?
    14.0.0.4762  reported in the header
    14.0.4763.1000 reported in Central Admin for SharePoint
    14.0.4763.1000 also reported in CA as the database schema version

This number is what is found in IIS under HTTP Response Headers.

image

Anybody know why it does not match any other SP 2010 version number? 

 

Ok, the number is not the correct version, but it is close!

 

SharePoint 2007 reports:

image

At least this is the correct version!

 

So if JavaScript cannot read this header value, how do we get it? Depends on which browser you are using, so I’m using a routine from an MSDN article to deal with the browser version.

 

The code:

<script type="text/javascript">

  /*
    The following copied from:
    http://msdn.microsoft.com/en-us/library/ms537505(v=vs.85).aspx
  */
  var xmlHttp = null;
  if (window.XMLHttpRequest) {
    // If IE7, Mozilla, Safari, and so on: Use native object.
    xmlHttp = new XMLHttpRequest();
  }
  else
  {
    if (window.ActiveXObject) {
       // ...otherwise, use the ActiveX control for IE5.x and IE6.
       xmlHttp = new ActiveXObject('MSXML2.XMLHTTP.3.0');
    }
  }
  /*
    end copy
  */

  xmlHttp.open('HEAD', location.href, false);
  xmlHttp.send();
  var headers =  xmlHttp.getAllResponseHeaders();
  var SPVersion = xmlHttp.getResponseHeader("MicrosoftSharePointTeamServices");

  if ( SPVersion.substring(0,2) == "12"  ) 
  {
    // 2007 code here
  }
  else
  {
    // 2010 code here
  }  

</script>

Note: The XMLHttpRequest call is usually setup with an asynchronous callback as the URL called is usually not the same URL that contains the calling JavaScript.  The example above does not seem to need this as it appears the header is read from the current copy of the page (“location.href”). Test this in your environment!

 

It would be a good idea to wrap this code as a function and add this to a custom JavaScript library that you would load in the master page. You can then call it as needed from other routines.

function getSharePointMajorVersion()
{
 // The following copied from: http://msdn.microsoft.com/en-us/library/ms537505(v=vs.85).aspx
  var xmlHttp = null;
  if (window.XMLHttpRequest) {
    // If IE7, Mozilla, Safari, and so on: Use native object.
    xmlHttp = new XMLHttpRequest();
  }
  else  {
    if (window.ActiveXObject) {
       // ...otherwise, use the ActiveX control for IE5.x and IE6.
       xmlHttp = new ActiveXObject('MSXML2.XMLHTTP.3.0');
    }
  }
  //  end copy

  xmlHttp.open('HEAD', location.href, false);
  xmlHttp.send();
  var SPVersion = xmlHttp.getResponseHeader("MicrosoftSharePointTeamServices");

  return  SPVersion.substring(0,2) 
}  

 

Pros:

  • Gets the version number, so should also work with the “next version” of SharePoint (15?)
  • Should work regardless of “branded” master page changes
  • Works with the browsers I test with: IE6, IE7, IE8 and FireFox 3.5.10

Cons:

  • A lot of code for a just to see if we are in 2007 or 2010
  • The version number returned is stored in the IIS settings and could get changed independent of SharePoint (I don’t know if service packs update this)
  • The SharePoint 2010 version returned is not 100% correct (but the major version “14” is correct)

 

Method 4: Call a SharePoint 2010 ECMAScript Class Library Object Method

SharePoint 2010 supports a JavaScript client object model that can access lists, libraries and other content. Once of the classes is called SP.ClientSchemaVersions and it has a property called currentVersion that returns a version number. This number is not the version of SharePoint itself, but appears to be the version of the library as it returns “14.0.0.0” only.

So:

  • if “SP.ClientSchemaVersions.currentVersion”does not exist we probably have SP 2007
  • if “SP.ClientSchemaVersions.currentVersion” does exist and starts with “14” then we probably have SharePoint 2010
  • And… if we are lucky “SP.ClientSchemaVersions.currentVersion” will return “15.something” for the next version.

The Code:

<script type="text/javascript">

function SampleFunction()
{
  var SPversion = "12"; 

  try { SPversion = SP.ClientSchemaVersions.currentVersion.substring(0,2) } 
  catch (e) {}

  if (SPversion == "12")
  {
      // 2007 code here
  }
  else
  {
      // 2010 (and later) code here
  }
}

ExecuteOrDelayUntilScriptLoaded( SampleFunction, "sp.js" );

</script>

 

Pros:

  • Gets the version number, so should also work with the “next version” of SharePoint (15?)
  • Should work regardless of “branded” master page changes
  • Works with the browsers I test with: IE6, IE7, IE8 and FireFox 3.5.10

Cons:

  • A lot of code for a just to see if we are in 2007 or 2010
  • The version number returned is for the script library, not SharePoint (but that should be OK)
  • Our code can only be run after the page is fully loaded and the “sp.js” library has been loaded (that’s why we need the ExecuteOrDelayUntilScriptLoaded call)
  • Our code must be wrapped up in a JavaScript function  (SampleFunction in the example above)

 

My Preference?

Right now it is Method 1, Check the “_fV4UI” variable.  It’s simple and light weight. But just remember the variable initialization could get deleted by someone working on the master page.

 

 

 

 Know a better way?  Post a comment below!

 

.

12/12/2010

Visio Services: there are no addresses available for this application

 

While doing a demo for Visio Services in SharePoint 2010 I got the following “perfectly clear and obvious” error message.

image

 

The fix was quite simple… go start the Visio service in Central Administration! 

 

This error occurs for other services, such as the Document ID services and BCS, and the solution is generally the same: start the service and/or make sure the configuration is correct.

 

.

12/02/2010

Cincinnati SharePoint User Group

Reminder! The Cincinnati SharePoint User Group meeting is tonight!

http://www.cincinnatispug.org/

December's Presentation


SharePoint 2010 Disaster Recovery: New Capabilities, New Possibilities!

Disaster recovery planning for a SharePoint 2010 environment is something that must be performed to insure your data and the continuity of business operations. Microsoft made significant enhancements to the disaster recovery landscape with SharePoint 2010, and we'll be taking a good look at how the platform has evolved in this session. We'll dive inside the improvements to the native backup and restore capabilities that are present in the SharePoint 2007 platform to see what has been changed and enhanced. We'll also look at the array of exciting new capabilities that have been integrated into the SharePoint 2010 platform, such as unattended content database recovery, SQL Server snapshot integration, and configuration-only backup and restore. By the time we're done, you will possess a solid understanding of how the disaster recovery landscape has changed with SharePoint 2010.

Presenter: Sean P. McDonough

Sean is a Product Manager for SharePoint Products at Idera, a Microsoft gold certified partner and creator of tools for SharePoint, SQL Server, and PowerShell.

11/20/2010

SharePoint Changes Files as they are Uploaded

 

I love the questions in MSDN forums!  They lead me down new paths in SharePoint that I would have never tried.

Such a simple question: "if a document is uploaded to doc library, will the checksum of the document change". (http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/4b184d0a-8fce-4ec7-a9d9-7badf205b85e)

Well, I know of a few cases where it can, but I'll come back to that. Here's the very weird thing I discovered... I uploaded the same file (a 2003 Word document) three different ways, and got two different file sizes in the library, and when downloaded they were all different from the the originally uploaded file.  SharePoint changed the files!

 

Test using a Word 2003 (.doc) document

(File size from right-clicking the file in Windows Explorer and selecting Properties)

  • Original file on disk (C:):
       139,264 bytes
     
  • File uploaded by clicking "Upload" in the library and then checking it's size from Open with Windows Explorer: 
       140,288 bytes
  • File uploaded with "Upload Multiple":
       139,776 bytes
  • File uploaded by dragging from C: (Windows Explorer) to Open with Windows Explorer:
       139,264 bytes  (but I think this is the original file size due to some caching – when I reopened the Open with Windows Explorer it changed to 139,776)

Now I downloaded the file using drag and drop from Open with Windows Explorer:

  • File uploaded by clicking "Upload"
      140,288  )
  • File uploaded by clicking "Upload Multiple"
      139,776 
  • File uploaded with dragging from C: (Windows Explorer) to Open with Windows Explorer:
      139,776 

Next I wrote some .Net code to access the documents via the API and the size reported from SPFileItem.File.Length is the same as the downloaded numbers (140,288, 139,776, 139,776).

Remember... the original file on C: was 139,264 bytes.

Now I opened each of the "uploaded and then downloaded" files in a HEX viewer:

  • The file uploaded by clicking "Upload Multiple" and and the file uploaded with dragging from C: (Windows Explorer) to Open with Windows Explorer:
      All bytes identical until the end of the file where there is what looks like random bytes (different in both files) and an incomplete fragment of an XML structure (same in both files).  (junk in the upload buffer???)
     
  • File uploaded by clicking "Upload"
      First byte changed from 00 to D0
      bytes/text added at the end of the file with metadata from the library columns!

So... I don't think you can rely on the check sum of the file!

 

Test using a TXT or PDF file

A simple text (.TXT) was unchanged by SharePoint and always reported the same file length no matter how I uploaded or downloaded it. The same for a PDF.

 

Test using an Excel 2003 file

Size on drive C:  22,528 bytes

Size inside of SharePoint: 30,208 bytes   (regardless of how it was uploaded or downloaded)

 

Test using an Excel 2007 file

Size on drive C:  16,501 bytes

Size inside of SharePoint: 19,076 bytes   (regardless of how it was uploaded or downloaded)

This one get even more interesting!  Office 2007 files are actually ZIP files. It looks like SharePoint unzipped the file, added some folders and some files and then rezipped the file. Here’s the before and after:

image

 

What’s changed?

  • New folder in the root of the zip file called “[trash]” that contains two tiny files “0001.dat” and “0002.dat”.
  • The file sizes in “_rels” have changed
  • The “docProps” folder has a new file named “custom.xml”
  • The “docProps\core.xml” file has been changed to include the SharePoint content type
  • and probably some other things I missed

 

Now back to how (I used to know) files can be different after upload...

  • If you are using Information Rights Management - the IRM wrapper is removed on upload (so files can be indexed for search) and reapplied on download.
  • If you have fields bound between an Office document (Word, etc) and the columns in the library, a user who edits the library columns will also be changing the content of the file.

 

Summary (or at least some guesses)

  • SharePoint modifies Office 2003 documents by appending to the end of “uploaded” files, but not for Upload Multiple or Explorer drag and drop.
     
  • SharePoint modifies Office 2007 documents by modifying the files in the “DOCX/XLSX” ZIP files, and for all ways they are uploaded.
     
  • SharePoint does not appear to modify non-Office files

 

If you know anything about this, please post a comment and share!

.

11/06/2010

SharePoint 2010: Don’t install the October Cumulative Updates for SharePoint Server 2010 and Project Server 2010

 

Update:

The SharePoint team has posted an update and some workarounds…

http://blogs.msdn.com/b/sharepoint/archive/2010/11/06/details-and-workaround.aspx

 

 

The SharePoint team has just released an announcement on their blog site about the October updates for SharePoint 2010 and Project Server 2010.

Microsoft has discovered a critical issue in the recently released October Cumulative Updates for SharePoint Server 2010 and Project Server 2010, and we have removed the files from download availability.  If you have already downloaded the CU, do not install it.  If you have installed the CU, please contact Microsoft Support for assistance. 

Monitor their blog for updates, what to if you have already installed it, and when a fix is coming…

http://blogs.msdn.com/b/sharepoint/archive/2010/11/05/critical-information-about-the-sharepoint-server-2010-october-cumulative-update.aspx

 

.

10/26/2010

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

 

Note: The following works for both SharePoint 2007 and 2010.

The 2013 version of this can be found here: http://techtrainingnotes.blogspot.com/2015/06/sharepoint-2013-create-quote-of-day-web.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

 

This web part is another simple Content Query Web Part solution.

  • 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
  • Uses a Rich Text field so you can include formatting

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 Site Actions, Create
  2. 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
  5. Click OK
  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
    image
  8. Create a new view by clicking the “View:” dropdown and click Create View
  9. Create the view as a Standard view and name it something like “Web Part View”. Un-checkmark all columns except for “Quote” column (the “Body” column if using an announcements list)
  10. In 2010, expand the Tabular View section and uncheckmark "Allow individual item checkboxes"
  11. Click OK

 

 

Add the Quotes list web part to the page

  1. Go to the page where you want to add the “Quote of the Day”
  2. Click Site Actions, Edit Page
  3. Click add a web part and add the web part for the quotes list
  4. In the web part click Edit and Modify Shared Web Part
  5. Select the view you created above (“Web Part View”)
  6. Click OK

image

 

The Content Editor Web Part

  1. Add a Content Editor Web Part (CEWP) and move it so it is below the quotes web part 
  2. Click the CEWP’s dropdown menu and select Modify Shared Web Part
  3. In the Appearance section add a title for the web part (perhaps “Quote of the Day”)
  4. Now you have two choices:
    • Click the Source Editor button and copy and paste the JavaScript that you will find later in this article
                    or (good idea for 2007 and the best practice for 2010!)
    • Create the JavaScript in your favorite HTML editor (Visual Studio, SharePoint Designer, Notepad, etc), upload it to a library and enter the path to the file in the Content Editor Web Part’s  “Content Link” box.

      This second choice is preferred for a few reasons:
      • You can use your editor’s Intellisense, copy and paste,  and other features to help write the code
      • You can write the code and upload to a library once, then use it in multiple Content Editor Web Parts   (…edit in one place…update in many…)
      • Easier to backup, share with other site owners and document

 

ID’ing your Web Part

To write JavaScript to interact with the HTML of a web part you need to indentify the web part’s HTML. SharePoint’s web parts have a custom attribute named “title”.  This title consists of two parts: the title entered in the Appearance section of the web part’s properties and the description entered in the list’s “Title, Description and Navigation” settings. Note that when you have a description, the title attribute includes a “-“ as separator.

Examples:

Web Part Title List Description HTML “title”
Quotes none entered Quotes
Quotes Cool words of wisdom Quotes - Cool words of wisdom
     

So how do you find it, just to make sure…

Display the SharePoint page with the list’s web part (probably your site’s home page), use the browser’s “View Source” feature (In IE 6 click the View menu, then click Source) and search for the name of the web part. What you are looking for should be something like this:

  image_thumb9

Or like this if there is no list description:

  image_thumb10

 

The JavaScript

Copy and paste the following JavaScript into your Content Editor Web Part. (see the two options described above)

 

<!-- add your own formatting here... -->

<span name="QuoteText" id="QuoteText"></span>



<script>
// another CEWP trick from http://TechTrainingNotes.blogspot.com
//
// 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;


  //Find the quotes web part and hide it
  var x = document.getElementsByTagName("TD"); // find all of the table cells

  var i=0;
  for (i=0;i<x.length;i++) 
  {
    if (x[i].title == quotesWebPartName)
    {
      // tables in tables in tables... ah SharePoint!
      QuoteList = x[i].parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;

      // hide the links list web part
      QuoteList.style.display="none"; 
      break;
    } 
  }

  if (!QuoteList)
  {
    document.all("QuoteText").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++;
//alert("quotes " + links[i].childNodes[0].innerHTML)

    }
  }
  
  if (quoteCount==0)
  {
    document.all("QuoteText").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.all("QuoteText").innerHTML= QuoteList.getElementsByTagName("TR")[QuoteArray[id]].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();
  }

</script>

 

.

10/20/2010

Special Edition: Live Chat to Learn More About SharePoint from the MVP Experts and the Microsoft Certified Masters!

 

Wednesday, October 27th between 9:00 AM and 10:00 AM PDT!
(12:00 Noon Cincinnati time!)

 

Do you have questions about SharePoint? Want to learn more about SharePoint 2010?  In this special event the Microsoft Certified Masters (MCM) for SharePoint will be joining the SharePoint MVPs from around the world for their monthly live chat. These popular Q&A events are a great opportunity to tap into the vast knowledge of these industry professionals who are regarded as the best in their field.

Please join us on Wednesday, October 27th between 9:00 AM and 10:00 AM PDT! (12:00 Noon Cincinnati time!) Learn more and add these chats to your calendar by visiting the MSDN event page http://msdn.microsoft.com/en-us/chats/default.aspx.

So who are the SharePoint MCMs? The Microsoft Certified Master (MCM) programs offer exclusive, advanced training and certification on Microsoft server technologies to seasoned IT professionals. The SharePoint MCMs are a growing community of 50+ members who have completed the program, validating their skills as technology experts who successfully design and implement solutions that meet the most complex business requirements. SharePoint MCMs include partners, MVPs, and internal Microsoft consultants, architects, and engineers. If you think you have what it takes to become a Microsoft Certified Master, learn more about Microsoft’s advanced training programs here.

How can I connect with a SharePoint MCM?

• Attend one of the many conferences where they’re attending or speaking

• Peruse the MCM Directory

• Learn from their experiences via the MCM blog roll on The Master Blog

• Find them answering questions in the forums

 

http://blogs.msdn.com/b/mvpawardprogram/archive/2010/10/19/special-edition-live-chat-to-learn-more-about-sharepoint-from-the-mvp-experts-and-the-microsoft-certified-masters.aspx

Twitter: #spmvpchat

Facebook Event:
http://www.facebook.com/event.php?eid=140173309363782&num_event_invites=0#!/event.php?eid=140173309363782

.

10/19/2010

SharePoint: Add Colors, Borders and Fonts to Web Parts

This example is for SharePoint 2007. A 2010 version using all CSS is here:

http://techtrainingnotes.blogspot.com/2011/06/sharepoint-2010-add-colors-borders-and.html

A version of this article using CSS instead of JavaScript can be found here:
http://techtrainingnotes.blogspot.com/2011/06/sharepoint-2007-use-css-to-add-colors.html

 

A picture is worth a thousand words… so here’s the first thousand:

image

 

See the big Links list web part!  Let’s see how to do that…

 

 

Web Part HTML

SharePoint web parts are rendered as HTML tables. All we need to know to change a web part is something about the HTML used and some way to find the web part using JavaScript.

 

The Content Editor Web Part

This little article is another one of those Content Editor and JavaScript tricks that I keep coming up with. So lets start with the Content Editor Part first.

  1. Edit the page (Site Actions, Edit Page) and add a Content Editor Web Part
  2. Drag the new web part so it is below the web part you want to change (adding it as the last web part in the right most column will also work)
  3. Click the new web part’s dropdown menu and select Modify Shared Web Part
  4. Now you have two choices:
    • Click the Source Editor button and copy and paste the JavaScript that you will find later in this article
                    or
    • Create the JavaScript in your favorite HTML editor (Visual Studio, SharePoint Designer, Notepad, etc), upload it to a library and enter the path to the file in the Content Editor Web Part’s  “Content Link” box.

      This second choice is preferred for a few reasons:
      • You can use your editor’s Intellisense, copy and paste,  and other features to help write the code
      • You can write the code and upload to a library once, then use it in multiple Content Editor Web Parts   (…edit in one place…update in many…)
      • Easier to backup, share with other site owners and document

Hide the Content Editor Web Part

When you are all done with this project, hide the CEWP by editing it and setting it’s Chrome to “None”. Chrome is in the Appearance section.

 

ID’ing your Web Part

To write JavaScript to interact with the HTML of a web part you need to indentify the web part’s HTML. SharePoint’s web parts have a custom attribute named “title”.  This title consists of two parts: the title entered in the Appearance section of the web part’s properties and the description entered in the list’s “Title, Description and Navigation” settings. Note that when you have a description, the title includes a “-“ as separator.

Examples:

Web Part Title List Description HTML “title”
Vendor Links none entered Vendor Links
Vendor Links Preferred Vendors Vendor Links - Preferred Vendors
     

As the list’s description can be changed at any time, we probably should check for just the web part’s title. The JavaScript checks for part of the title by using:   title.substring(0,5)=="Links"

So how do you find it, just to make sure…

Display the SharePoint page with the list’s web part (probably your site’s home page), use the browser’s “View Source” feature (In IE 6 click the View menu, then click Source) and search for the name of the web part. What you are looking for should be something like this:

image

Or like this if there is no list description:

image

 

The JavaScript

The JavaScript has two jobs, find the “TD” tag with your title and then “drill” up or down from that TD to the HTML you want to change. So the first block of sample code just finds the TD tag.

Note: This can be done with less “code” by using jQuery. The downside is that you also have to upload a jQuery library to your site. (If I get a chance I’ll return here and add the jQuery version also.)

When you copy and paste the code, use the example at the bottom of the page, or download from here.

<script type="text/javascript">

// Yet another JavaScript trick from TechTrainingNotes.blogspot.com!
// Add colors, fonts, borders and backgrounds to web parts

var x = document.getElementsByTagName("TD");
for (var i=0; i<x.length; i++)
{

  if (x[i].title.substring(0,5)=="Links")
  {
    var td = x[i];  // this is the cell with our title

    // change the title bar
    td.bgColor="red";

    // add other things to change here!

    
    break; // we found our TD, so don't process any more TDs
  }
}

</script>

The above example just sets the title area background to red.

image

 

What else can you do?

Now that we have the TD with our title, we can now start “drilling” up or down by using “.parentNode” and “childNode”, or use “.nextSibling” to find the next same level tag.

Here’s some examples… but what you can do is only limited by your puzzle solving skills and your knowledge of HTML and CSS.

 

Change the title size and font
    td.childNodes[0].childNodes[0].style.fontSize="30px";
    td.childNodes[0].childNodes[0].style.fontFamily="Comic Sans MS";

Change the background images for the title area
    td.childNodes[0].style.backgroundImage="url(/_layouts/images/helpicon.gif)"

 

Change the title text color
    td.childNodes[0].childNodes[0].style.color="white";

 

Change the title area including dropdown
    td.parentNode.bgColor="red";

 

Change the entire web part’s background
    td.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.bgColor="red";

 

Change background for all but the title bar
    td.parentNode.parentNode.parentNode.parentNode.parentNode.nextSibling.bgColor="lightgrey";

 

Change the background image for all but the title bar
    //td.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.backgroundImage="url(/_layouts/images/helpicon.gif)"

 

Change the border for the entire web part
    td.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.border="3px solid green";

 

Change all of the links
    var txt = td.parentNode.parentNode.parentNode.parentNode.parentNode.nextSibling.getElementsByTagName("A");
    for (var j=0; j<txt.length; j++)
    {
      if (txt[j].innerText != "Add new link")
      {
        txt[j].style.fontSize="14px";
        txt[j].style.fontWeight="bold";
      }
    }

 

Here’s the JavaScript that was used to create the sample at the beginning of the article:
(Commented out line (“//”) were not needed for the example)

image

 

You can download the code from here.

<script type="text/javascript">


// Yet another JavaScript trick from TechTrainingNotes.blogspot.com!
// Add colors, fonts, borders and backgrounds to web parts

var x = document.getElementsByTagName("TD");
for (var i=0; i<x.length; i++)
{

  if (x[i].title.substring(0,5)=="Links")
  {
    var td = x[i];
    // change the title bar
    //td.bgColor="red";

    // change the title size and font
    td.childNodes[0].childNodes[0].style.fontSize="30px";
    td.childNodes[0].childNodes[0].style.fontFamily="Comic Sans MS";
    
    // change the background images for the title area
    //td.childNodes[0].style.backgroundImage="url(/_layouts/images/helpicon.gif)"

    // change the title text color
    td.childNodes[0].childNodes[0].style.color="white";

    // change the title area including dropdown
    td.parentNode.bgColor="red";
    
    // change the entire web part
    //td.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.bgColor="red";

    // change background for all but the title bar
    td.parentNode.parentNode.parentNode.parentNode.parentNode.nextSibling.bgColor="lightgrey";

    // change the background image for all but the title bar
        //td.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.backgroundImage="url(/_layouts/images/helpicon.gif)"

    // Change the border for the entire web part
    td.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.border="3px solid green";

    // change all of the links
    var txt = td.parentNode.parentNode.parentNode.parentNode.parentNode.nextSibling.getElementsByTagName("A");
    for (var j=0; j<txt.length; j++)
    {
      if (txt[j].innerText != "Add new link")
      {
        txt[j].style.fontSize="14px";
        txt[j].style.fontWeight="bold";
      }
    }
    
    
    break; // we found our TD, so don't process any more TDs

  }
}
</script>

 

 

Have fun!

 

.

10/10/2010

Classroom Helicopter!

 

Update 12/16/10… prices sure keep changing on this little helicopter!  The link below has varied from apx $20 to $40 over the last few days.  Click the link below and then do a search for “S107 helicopter” to see if there are any better prices.

---

 

I have occasionally brought a “toy” helicopter to class. I bought it on a trip to North Canton, OH at the MAPS aviation museum. When I bought it I was just looking for a toy for the extended hotel stay, and I was intrigued that it was mostly metal, not plastic. But I found it to be amazing stable. The first time I flew it, it just lifted off and hovered! No fighting it, no bouncing off the walls, just a perfect hover. Months later I have only broken one part, the little tail rotor, and there was a spare one in the box! (Don’t tell anybody, but this big kid took the indoor heli outdoors to see how high it would go. When it got up about 100’, which was probably the range of the IR radio, it turned itself off and fell and hit the roof. Nothing was broken!

Several people have asked about it and I had no idea where they could find one.  Turns out is was real easy… it’s available from Amazon.com and about 1000 places on the web.

       

 

Don’t blame me for the time you waste with this thing… or that you had to get three more for the kids.

 

MAPS

If you ever get to the Akron / Canton area, look up the MAPS museum.  It’s nicely hidden on the back side of the Akron airport, should you visit you will need to do a bit of looking to find it.

While I’m a bit spoiled by being near the U.S. Air Force Museum in Dayton, MAPS is worth the visit for both the aircraft, and the chance to talk to the folks who restore them.

http://www.mapsairmuseum.org/

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.