<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CleverWorkarounds &#187; Branding</title>
	<atom:link href="http://www.cleverworkarounds.com/category/sharepoint/branding/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cleverworkarounds.com</link>
	<description>After much frustration, it seems DEFAULT is the way to go...</description>
	<lastBuildDate>Mon, 16 Aug 2010 22:56:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Also why I&#8217;ve been quiet&#8230;</title>
		<link>http://www.cleverworkarounds.com/2010/08/06/also-why-ive-been-quiet/</link>
		<comments>http://www.cleverworkarounds.com/2010/08/06/also-why-ive-been-quiet/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 06:16:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Assurance]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[Business Analysis]]></category>
		<category><![CDATA[Collaboration]]></category>
		<category><![CDATA[Governance]]></category>
		<category><![CDATA[Information Architecture]]></category>
		<category><![CDATA[Knowledge management]]></category>
		<category><![CDATA[Project Management]]></category>
		<category><![CDATA[Records Management]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Speaking presentation]]></category>
		<category><![CDATA[Strategy]]></category>
		<category><![CDATA[Training]]></category>
		<category><![CDATA[planning]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2010/08/06/also-why-ive-been-quiet/</guid>
		<description><![CDATA[I’m in an airport (again), typing this on my way back from my latest trip to New Zealand – a country I am loving more and more each time I go there. (Anywhere that I can go that uses the same power plugs as back home is a great place in my book). A while [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p>I’m in an airport (again), typing this on my way back from my latest trip to New Zealand – a country I am loving more and more each time I go there. (Anywhere that I can go that uses the same power plugs as back home is a great place in my book).</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2010/08/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2010/08/image_thumb.png" width="722" height="194" /></a> </p>
<p>A while back I posted about the <a href="http://www.cleverworkarounds.com/2010/06/07/why-ive-been-quiet/">book</a> I am writing with <a href="http://eight2late.wordpress.com/">Kailash Awati</a> (<a href="http://www.cleverworkarounds.com/2010/06/07/why-ive-been-quiet/">Beyond Best Practices</a>). If that project wasn’t taking enough time, dedication and brain cells, I have just finished an undertaking that has essentially consumed me for four months (some 450 man hours). This week it was delivered and the student responses far surpassed my expectations and made it all worthwhile.</p>
<p>I created a 4 day <strong>SharePoint 2010 Governance and Information Architecture </strong>training course as part of Microsoft New Zealand&#8217;s <a href="http://www.microsoft.com/nz/server/sharepoint/partner.mspx">Elite initiative</a>. (760 pages of SharePoint governance and IA goodness!) If you are not aware of the Elite initiative, it is a novel initiative by Microsoft in New Zealand to improve the quality of SharePoint practitioners in the Microsoft partner ecosystem. Now I tell you – Darryl Burling and his team down there at Microsoft have their ear to the ground – and really do listen to their customers. They initiated this program to allow local solution providers to take the next step beyond technical knowhow and turn it into deeper proficiency. </p>
<blockquote><p>The SharePoint Elite Partner Initiative is designed to recognise those New Zealand Partners who have built skills excellence and a track record for success with SharePoint into their business. When it comes to SharePoint, these are the elite &#8211; the best of the best. If you are looking for a partner who can help you plan and deploy your SharePoint implementation, these are the best in the business. </p>
</blockquote>
<p>This Elite program is unique in its focus and via the insight of those who conceived it, allowed me the flexibility to create a course that was a balance of technical labs, <a href="http://www.sevensigma.com.au/what-we-do/sensemaking.html">sensemaking</a>, governance, critical thinking and user engagement. I was going through the course feedback just now and the key trend from it all was that the students really enjoyed the softer stuff that I teach, more so than the “here is a SharePoint feature and look at what it can do!” type material (they can get that sort of material anywhere). </p>
<p>So all in all it was a great week, which made all the effort, sweat and tears leading up to it worth it.</p>
<p>So thanks attendees, it was a great 4 days. For other readers, hopefully the course might come to a city near you in the not too distant future.</p>
<p>&#160;</p>
<p>Thanks for reading</p>
<p>Paul Culmsee</p>
<p><a href="http://www.sevensigma.com.au">www.sevensigma.com.au</a></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2010/08/06/also-why-ive-been-quiet/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Review &#8211; Balsamiq Mockup Tool (for SharePoint)</title>
		<link>http://www.cleverworkarounds.com/2009/04/08/review-balsamiq-mockup-tool-for-sharepoint/</link>
		<comments>http://www.cleverworkarounds.com/2009/04/08/review-balsamiq-mockup-tool-for-sharepoint/#comments</comments>
		<pubDate>Tue, 07 Apr 2009 14:45:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Balsamiq Mockups]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[Reviews]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[planning]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2009/04/08/review-balsamiq-mockup-tool-for-sharepoint/</guid>
		<description><![CDATA[Hi It’s review week here at CleverworkArounds, and the next one on my list that I have been meaning to speak about is an application called Balsamiq Mockups. Mr Mindmapper himself, Ruven Gotz first turned me onto this application some time back, and I have found it very useful in taming RBO (rampant branding obsession). [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image2.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="274" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image-thumb1.png" width="439" border="0" /></a> </p>
<p>Hi</p>
<p>It’s review week here at CleverworkArounds, and the next one on my list that I have been meaning to speak about is an application called <a href="http://www.balsamiq.com/products/mockups">Balsamiq Mockups</a>. Mr Mindmapper himself, <a href="http://spinsiders.com/ruveng/">Ruven Gotz</a> first turned me onto this application some time back, and I have found it very useful in taming RBO (rampant branding obsession).</p>
<p>Although I have written various posts on SharePoint branding, most of the time I find it a tiresome task that for many sites, is pushed way too far up the priority list to the point that much more critical success factors are overlooked or given lip service. Now in saying that, I will admit straight up that although I know how branding *should* be done from a sustainable governance point of view, I suck royally at making a site look good myself and I compensate by relentlessly pummelling SharePoint branding governance best-practices onto completely unsuspecting web designers.</p>
<p>Such fun <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Balsamiq Mockups has adopted a visual based site wireframing approach that takes the opposite approach to the “Photoshop” approach to site design. A web designer using a tool like Photoshop will attempt to create an accurate visual representation of a site based on a stakeholder’s tastes (or lack thereof). The risk here with SharePoint is that the branding vision that is created using Photoshop can often be quite tricky to achieve in SharePoint without being “governance naughty”, particularly for collaborative sites that make extensive use of web parts, application pages and document libraries.</p>
<p>Some of the most difficult SharePoint recovery jobs that I have had to do were a direct result of seemingly innocent “customisations” that came from branding requirements. </p>
<p>So, how can Balsamiq help? </p>
<p>For a start, a complete design-challenged person like me can actually produce something useful <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>More importantly, however, it is designed on a completely different premise than the Photoshop style approach to design. This tool works on a principle of emulating hand-drawn designs, supplying you with a bunch of drag-and-drop widgets and interface elements which allow you to construct the basic structure of a site in minutes. Out of the box, there are around 70 elements that can be used to construct a web site and you can see the results of my 5 minute effort in the image at the start of this article.</p>
<p>Want to see how easy it is? Then check the video below (assuming your IT department has not blocked Youtube).</p>
<p> <object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/aJTuFRaIi_g&amp;hl=en&amp;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/aJTuFRaIi_g&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>
<p>Although the video shows how easy it is to create a mock up, you may be wondering if there are any SharePoint specific design elements. Out of the box there are not. But fear not, there is a flourishing community around this product that creates additional elements for you to use. SharePoint is <a href="http://mockupstogo.net/prebuilt-sharepoint-elements">well represented</a> here. </p>
<p>Want to drop a SharePoint document library onto the page? Too easy.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image3.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="208" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image-thumb2.png" width="640" border="0" /></a>&#160; </p>
<p>Did someone say calendar, tasks or search?</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image4.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="240" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image-thumb3.png" width="192" border="0" /></a> <a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image5.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="146" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image-thumb4.png" width="210" border="0" /></a> <a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image6.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="142" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image-thumb5.png" width="310" border="0" /></a> </p>
<p>This application does not take much of an investment in learning. One can pretty much learn the product just by watching the Youtube video and learning how to import other design elements is just a matter of clicking the help menu and choosing the “Download More Controls” option. </p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image7.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="109" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image-thumb6.png" width="244" border="0" /></a> </p>
<p>Would hard-core web designers may find the application cramps their artistic style? Maybe – I can only speculate. But for me, I spend most of my time in a PM, training, architect or advisory role. As a result, <a href="http://www.balsamiq.com/products/mockups">Balsamiq Mockups</a> is perfect for me because, it above all else, it is <strong>quick</strong> to produce results. I can flesh out a SharePoint basic site design without having to fiddle around with master pages, SharePoint designer or CSS files (and for that I am eternally grateful!)</p>
<p>I can then export the mockup to a PNG file and use that in documentation, presentations, and best of all, my <a href="Hi. My name is Paul Culmsee of Seven Sigma Business Solutions and welcome to my blog. For my bio, go to my about page. On this site, I discuss mainly SharePoint issues, with particular reference to strategy, governance and return on investment issues, but sometimes I end up writing techno-babble articles too  ">issue and dialogue maps</a> which makes great strides in achieving the all-important goal of shared understanding among project participants.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image8.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="404" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/04/image-thumb7.png" width="644" border="0" /></a> </p>
</p>
</p>
</p>
</p>
<p>Try <a href="http://www.balsamiq.com/products/mockups">Balsamiq Mockups</a> out. It’s a great tool to add to your armoury.</p>
<p>Thanks for reading</p>
<p>Paul Culmsee</p>
<p><a href="http://www.sevensigma.com.au">www.sevensigma.com.au</a></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2009/04/08/review-balsamiq-mockup-tool-for-sharepoint/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Free open source WCM for WSS</title>
		<link>http://www.cleverworkarounds.com/2008/10/31/free-open-source-wcm-for-wss/</link>
		<comments>http://www.cleverworkarounds.com/2008/10/31/free-open-source-wcm-for-wss/#comments</comments>
		<pubDate>Thu, 30 Oct 2008 23:23:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[Perth]]></category>
		<category><![CDATA[SharePoint]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/10/31/free-open-source-wcm-for-wss/</guid>
		<description><![CDATA[I have to say, Perth is home to some great SharePoint Talent. MVP Sezai is one prime example and Jeremy Thake is another. But there is also another colleague of mine who you may or may not know &#8211; Tommy Segoro, who is one of those mild-mannered guys who simply gets down to it and [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p>I have to say, Perth is home to some great SharePoint Talent. MVP <a href="http://sharepoint-sezai-moss-2007.blogspot.com/" target="_blank">Sezai</a> is one prime example and <a href="http://wss.made4the.net/default.aspx" target="_blank">Jeremy Thake</a> is another. </p>
<p>But there is also another colleague of mine who you may or may not know &#8211; Tommy Segoro, who is one of those mild-mannered guys who simply gets down to it and produces great things. </p>
<p>Tommy has released a free, open source CMS that sits on top of WSS. Publishing pages, page layouts, the page editing toolbar, all on WSS, without having to upgrade to MOSS at great expense to get the publishing feature.</p>
<p><a href="http://www.codeplex.com/completesharepoint">http://www.codeplex.com/completesharepoint</a></p>
<p><a href="http://www.completesharepoint.net/Home/Pages/Default.aspx">http://www.completesharepoint.net/Home/Pages/Default.aspx</a></p>
<p>check it out for yourself!</p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/10/31/free-open-source-wcm-for-wss/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why do SharePoint Projects Fail &#8211; Part 6</title>
		<link>http://www.cleverworkarounds.com/2008/05/12/why-do-sharepoint-projects-fail-part-6/</link>
		<comments>http://www.cleverworkarounds.com/2008/05/12/why-do-sharepoint-projects-fail-part-6/#comments</comments>
		<pubDate>Sun, 11 May 2008 14:16:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[Governance]]></category>
		<category><![CDATA[Project Management]]></category>
		<category><![CDATA[SDK]]></category>
		<category><![CDATA[STSDEV]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Web Parts]]></category>
		<category><![CDATA[Wicked Problems]]></category>
		<category><![CDATA[planning]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/05/12/why-do-sharepoint-projects-fail-part-6/</guid>
		<description><![CDATA[Hi again and welcome to part 6 of my series on the factors of why SharePoint projects fail. Joel Oleson&#8217;s write-up a while back gave me 5 minutes of fame, but like any contestant on Big Brother, I&#8217;ve had my time in the limelight, been voted out of the house (as in Joel&#8217;s front page) [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p><script type="text/javascript"><!--
google_ad_client = "pub-6551570212921028";
google_ad_width = 468;
google_ad_height = 60;
google_ad_format = "468x60_as";
google_ad_type = "text_image";
google_ad_channel = "";
google_ui_features = "rc:6";
//-->
</script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<p>Hi again and welcome to part 6 of my series on the factors of why SharePoint projects fail. Joel Oleson&#8217;s <a href="http://www.sharepointjoel.com/archive/2008/05/07/insights-why-sharepoint-projects-fail.aspx" target="_blank">write-up</a> a while back gave me 5 minutes of fame, but like any contestant on Big Brother, I&#8217;ve had my time in the limelight, been voted out of the house (as in Joel&#8217;s <a href="http://www.sharepointjoel.com/default.aspx" target="_blank">front page</a>) and I&#8217;m back to being an ordinary citizen again.</p>
<p>If you have followed events thus far, I covered off some <a href="http://www.cleverworkarounds.com/2008/04/11/why-do-sharepoint-projects-fail-part-1/" target="_blank">wicked problem theory</a>, before delving into the <a href="http://www.cleverworkarounds.com/2008/04/19/why-do-sharepoint-projects-fail-part-3/" target="_blank">bigger ticket</a> items that contribute to SharePoint project failure. In the <a href="http://www.cleverworkarounds.com/2008/04/27/why-do-sharepoint-projects-fail-part-5/" target="_blank">last post</a>, we pointed our virtual microscope at the infrastructure aspects that can cause a SharePoint problem to go off the rails.</p>
<p>Now we turn our magnifying glass onto application development issues and therefore application developers. Ah, what fun you can have with application developer stereotyping, eh! A strange breed indeed they are. As a group they have had a significant contribution to the bitter and twisted individual that I am today.</p>
<p>The CleverWorkarounds tequila shot rating is back!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a> <a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a> for a project manager in denial <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a><a href="http://images.google.com/imgres?imgurl=http://louisa123.files.wordpress.com/2007/10/redbull.jpg&amp;imgrefurl=http://louisa123.wordpress.com/2007/10/17/a-time-for-stress/&amp;h=480&amp;w=480&amp;sz=27&amp;hl=en&amp;start=6&amp;sig2=yadZAfpAiOwduFHe_8v0Bw&amp;tbnid=jcP1Z-h8tmYnvM:&amp;tbnh=129&amp;tbnw=129&amp;ei=SNwDSIrBKJiuiAHitLXbCg&amp;prev=/images%3Fq%3Dredbull%26imgsz%3Dsmall%257Cmedium%257Clarge%257Cxlarge%26gbv%3D2%26ndsp%3D18%26hl%3Den%26safe%3Doff%26sa%3DN"><img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" src="http://tbn0.google.com/images?q=tbn:jcP1Z-h8tmYnvM:http://louisa123.files.wordpress.com/2007/10/redbull.jpg" width="129" height="129" /></a>for the rest of us!</p>
</p>
<p><span id="more-752"></span></p>
<h2>Leave us sensitive developers alone already!</h2>
<p>Oh please.. I could make insultingly broad, sweeping generalisations about developers to make people laugh, but you guys hate each-other more than you do the rest of us! So any insult that I come up with will be water off a duck&#8217;s back and you will no doubt have a good come-back insult loaded up and ready to shoot me down <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Case in point? Go and read <a href="http://diveintomark.org/archives/2004/08/16/specs" target="_blank">this hilarious post</a> by Mark Pilgrim &#8211; an oldie but a real goodie. Warning: there is profanity there. I&#8217;d dearly like to repeat it here because it&#8217;s pure gold, but I wear a suit now and I am supposed to sound all &quot;impressive and wise&quot;. Got to keep up appearances <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Mark&#8217;s post is mandatory reading for anyone following this series. Stop now and read! (It&#8217;s cool &#8211; I&#8217;ll wait for you).</p>
<p>** cue elevator music **</p>
<p>All done? Excellent. Let&#8217;s move on!</p>
<p>Mark is the sort of developer who would be worth his weight in gold. What is great about the above post is that it is actually an excellent example of the social complexity of projects and why it is so incredibly challenging to get a project team (stakeholders and user reference group included) to see a <strong>common version of the truth</strong>. Although Mark nails his fellow developers to the wall here, an equally witty project manager, information worker or senior executive could write the same sort of post for their discipline area.</p>
<p>In common with what I said during the infrastructure oriented post, a lot of application development issues are simply a manifestation of wicked problems that have not been recognised earlier. Although everything I have outlined in posts 1-4 is where you will find your root causes, in an organisation with a low maturity level the project team likely has been largely oblivious to the warning signs up until this point. Suddenly once we are cutting code, problems start to become apparent and it&#8217;s all those damn developers fault of course!</p>
<p>So once again, for the rest of this post we have to do a suspension of belief. In <a href="http://www.cleverworkarounds.com/2008/04/27/why-do-sharepoint-projects-fail-part-5/" target="_blank">part 5</a> we went to Homer Simpson&#8217;s land of chocolate. So for this post, how about we can all pretend that we live in a world where teenyboppers do not exist and therefore people&#8217;s minds haven&#8217;t turned to jelly from being bombarded by crap music &#8211; so let&#8217;s blame Britney Spears for 99% of project failures.</p>
<h2>In the world without Britney Spears</h2>
<p>In this world, the stakeholders all agree with each-other. They have a tacit and deep understanding of the organisation&#8217;s vision, strategy and exactly how that strategy is to be executed. Therefore, they have clearly and unambiguously articulated this vision to the project team. This information in turn has been understood at all levels by the project team and after much investigation, soul searching and deep analysis, the entire team agrees completely that SharePoint is the perfect fit.</p>
<p>After reading all of the insightful information in the CleverworkArounds&#8217; &quot;<a href="http://www.cleverworkarounds.com/2007/11/17/learn-to-talk-to-your-cfo-in-their-language-part-1/">Learn to speak to your CFO</a>&quot; series <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> , a project management plan has been put together and agreed upon and signed off by all stakeholders. Scope, constraints and assumptions are reasonable and clear. A work breakdown structure has been developed and signed off with well developed budget and accurate, confident estimates.</p>
<p>What could possibly go wrong? <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h2>Thinking your developers are developers</h2>
<p>Jeremy Thake wrote about &quot;<a href="http://wss.made4the.net/Lists/Posts/Post.aspx?ID=669" target="_blank">organisational responsibility</a>&quot; recently, and my new &quot;homie&quot; Joel made his <a href="http://www.sharepointjoel.com/archive/2008/05/07/insights-why-sharepoint-projects-fail.aspx" target="_blank">feelings known</a> when he wrote about the folly of &quot;<strong>Thinking your developers are administrators</strong>&quot;. This needs to be analysed further however. I prefer to use the title &quot;Thinking your developers are developers&quot;. The world is rife with what one would term &quot;bad programming&quot;. The term is something of a misnomer though. I work with a great free WCM system called Joomla, and it has a devoted community of developers writing add-on modules for a dizzying array of options. Most are very well written, but some of these modules I have hacked away at the source and quite frankly they are pretty bad (and coming from a part time developer like me, that&#8217;s saying something).</p>
<h2>Wishing your developers are admins?</h2>
<p>That term &quot;bad programming&quot; is misleading and potentially unfair, because bad programming can contain tight, readable code that would satisfy industry standard conventions. In actual fact I&#8217;m not really all that fussed about the source code unless it&#8217;s *monumentally* stupid. Instead it is all about the <strong>thought process that went into the development</strong>. Here is a real world example from my past of what I mean.</p>
<p><em>A system developed by a former employer of mine relied extensively on DNS aliases, that our customers had to add into their DNS. So when our application looked for its </em><em>&quot;server&quot;, it queried DNS for that alias. I suggested that this was not a good idea, and we would be much better served via a registry setting that could override this, centrally controlled via group policy in Active Directory. The suggestion was met with general disinterest until s</em><em>ome time later, we had an install at a site with several physical locations.There would be a server at each location, but the customer&#8217;s Active Directory set-up was a single DNS namespace. Thus we could only add a DNS alias for 1 server, yet we had several sites where servers resided. The system couldn&#8217;t handle the fact that a DNS can spread over multiple sites.</em></p>
<p><em>One quickly convened meeting later and suddenly the penny dropped on the logic of my suggestion. (But it took a real world emergency for that to happen). The next problem was the developers immediately chose the wrong location for registry key. Microsoft have a <a href="http://support.microsoft.com/?id=323639" target="_blank">guide</a> that tells you *where* in the registry to place your modification and they didn&#8217;t know there were recommendations and didn&#8217;t think to check for such a recommendation. Fortunately I caught that one in time and got it sorted.</em></p>
<p>That example highlights that &quot;bad programming&quot; was actually more like lack of awareness of important external considerations. I named the title of this section, &quot;Wishing your developers are admins&quot;, more for the example that I cited than a statement of fact. Certainly, infrastructure administrators are very crap coders, (despite what they think of their efforts). But they do have a greater affinity for integration oriented governance issues than their pure development counterparts because of the nature of their role.</p>
<p>Sniggering infrastructure people who are feeling superior now should stop and take note. Experience has shown me time and time again that greater awareness about governance and integration rarely translates to actually running their environment to the ideals they espouse however <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  .</p>
<p><em>Read my <a href="http://www.cleverworkarounds.com/2008/02/17/selling-moss-a-choose-your-own-adventure-story/" target="_blank">Choose Your Own Adventure</a> post for a more offbeat and sarcastic take on that issue.</em></p>
<h2>Planting wicked seeds..</h2>
<p>In <a href="http://www.cleverworkarounds.com/2008/04/27/why-do-sharepoint-projects-fail-part-5/" target="_blank">part 5</a>, I had a section entitled &quot;Infrastructure and Product Skills&quot;, and I suggested that a lack of product awareness and skills among infrastructure designers did not always manifest themselves into pain and suffering until later down the track. In the application development discipline, this is even <strong>more</strong> of a problem, and the remainder of this post focuses pretty much on this area, since if things do go down this road, it is simply going to end up being one of the root causes of the <strong>next, even more wicked problem </strong>to try and solve.</p>
<p>The impact of a bad design decision today can in particular have far reaching consequences into the future. Microsoft have this problem at a level that would blow your mind if you have been around long enough know your history (and your security <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . Remember than in 1973, what Rittel said of wicked problems: &quot;<strong>There is no immediate and no ultimate test of a solution to a wicked problem</strong>&quot;, and by that he meant any solution, post implementation will generate &quot;waves of consequences&quot; that may yield utterly undesirable repercussions which outweigh the intended advantages.</p>
<p>The thoroughly depressing thing about that statement is the implication that a wicked problem can arise from the unexpected aftermath of a perfectly innocent &quot;non wicked&quot; problem!</p>
<p>So let&#8217;s see where SharePoint and the systems it relies upon makes life hard for developers and can blow out projects.</p>
<h2>The obvious way is usually the dumb way</h2>
<p>I am going to start by showing you some C# code. Non programmers, don&#8217;t be scared, it&#8217;s not too bad and in honour of Ms Spears I have kept the theme going. It is opening a SharePoint list programmatically, looking for anything with a title of &quot;Oops I did it again&quot; and if it matches that term, informs you that you must &quot;Wash your mouth out!&quot;.</p>
</p>
<pre class="csharpcode"><span class="kwrd">foreach</span> (SPListItem item <span class="kwrd">in</span> list.Items)


{

<span class="kwrd">if</span> (item.Title == <span class="str">&quot;Oops I did it again&quot;</span>) {

console.Writeline(<span class="str">&quot;Wash your mouth out!&quot;</span>);

}

}

</pre>
<p>
<style type="text/css">
.csharpcode, .csharpcode pre</style>
</p>
<p>{</p>
<p>font-size: small;</p>
<p>color: black;</p>
<p>font-family: consolas, &#8220;Courier New&#8221;, courier, monospace;</p>
<p>background-color: #ffffff;</p>
<p>/*white-space: pre;*/</p>
<p>}</p>
<p>.csharpcode pre { margin: 0em; }</p>
<p>.csharpcode .rem { color: #008000; }</p>
<p>.csharpcode .kwrd { color: #0000ff; }</p>
<p>.csharpcode .str { color: #006080; }</p>
<p>.csharpcode .op { color: #0000c0; }</p>
<p>.csharpcode .preproc { color: #cc6633; }</p>
<p>.csharpcode .asp { background-color: #ffff00; }</p>
<p>.csharpcode .html { color: #800000; }</p>
<p>.csharpcode .attr { color: #ff0000; }</p>
<p>.csharpcode .alt</p>
<p>{</p>
<p>background-color: #f4f4f4;</p>
<p>width: 100%;</p>
<p>margin: 0em;</p>
<p>}</p>
<p>.csharpcode .lnum { color: #606060; }</p>
</p>
<p>Easy enough &#8211; aren&#8217;t lists sooo easy to work with! Let&#8217;s just say you used this sort of logic in a web part that displays only list items that have &quot;Oops&quot; in the title. A few minutes later, you have coded and tested the web part, and it works a treat. Into the change control it goes, and into production it finds itself.</p>
<p>Fast forward 4 weeks and now the list has 400 items in it. Now a refresh of the page containing your web part is taking 10 seconds and getting worse. Naturally &#8216;the network&#8217; must be the problem, right? Of course it&#8217;s not. In this example every list item is being enumerated and a comparison is made. This is <a href="http://technet.microsoft.com/en-us/library/cc262813.aspx" target="_blank">well documented</a> as the most <strong>inefficient </strong>way to query a list.</p>
<p><em>Putting on my old Cisco hat for a second, I am going to repeat an oft said mantra that people who know me will have heard many times over the years and what all self respecting Cisco nerds know. <strong>It&#8217;s not the %$^%$ network alright! It&#8217;s never been the network, it&#8217;s your $%%$ code!</strong></em></p>
<p>You think the example above is made up? It&#8217;s not! On one SharePoint project where I was the information architect, a developer from a well respected Australian integrator did <strong>exactly</strong> what I described above, and proceeded to blame the infrastructure, the architecture, the network &#8211; basically anything that wasn&#8217;t their component. Of course, their development environment only had 10 items in the list and thus it seemed fine to them!</p>
<p>If you go back to my real-world example of the DNS/Registry issue, it was a design decision that was probably given half a thought at best, only to turn out to be a major constraint down the track. My SharePoint specific example above shows that for an inexperienced developer, even a &quot;hello-world&quot; style example is potentially a landmine just waiting for you to innocently step on. The issue is that, to the uninitiated, the SharePoint ecosystem has even more virtual land mines to avoid than being Lindsay Lohan&#8217;s publicist.</p>
<p>Simply put, if you do not have a broad depth of knowledge that can only come from time, pain and experience, you are inevitably going to get blown up time and time again. What&#8217;s that old saying? There are old SharePoint developers, and there are bold SharePoint developers, but there are never any old-bold SharePoint developers <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><em>If I listed all of the examples that I could think of, this post would get out of hand, so instead, Jeremy Thake sent me his </em><a href="http://www.diigo.com/user/Jthake/sharepoint%20performance" target="_blank"><em>diigo link</em></a><em> that aggregates blog posts tagged with &quot;SharePoint and performance&quot;. That should give you some idea of what developers are getting themselves into.</em></p>
<h2>Junk DNA</h2>
<p>John Kominetz <a href="http://kominetz.com/2007/11/20/the-elephant-and-the-blind-men/" target="_blank">wrote</a> a great blog post that is highly relevent to this discussion. It has nothing to do with SharePoint in the slightest, yet if you substituted the word &quot;Documentum&quot; with &quot;SharePoint&quot; we would all be nodding our heads in collective agreement. It examines Documentum, a product that was already a mature player in the ECM space way before SharePoint had even made it to a little red box on a Redmond whiteboard.</p>
<p>Kominetz looks at Documentum&#8217;s heritage and describes it in terms akin to a living organism. He makes the observation that its &quot;genome&quot; has evolved over many years and carries with it plenty of <a href="http://en.wikipedia.org/wiki/Junk_DNA">junk DNA</a> and &quot;evolutionary dead ends&quot;. This is completely unavoidable, despite what any idealistic whinger about &quot;bloatware&quot; would like to believe. Another Joel (are all Joel&#8217;s in this world clever?), has a blog that is mandatory reading for anyone who is prone to making idealistic statements about security, bloat or complexity. I urge you to read his &quot;<a href="http://www.joelonsoftware.com/items/2008/03/17.html" target="_blank">Martian Headsets</a>&quot;, &quot;<a href="http://www.joelonsoftware.com/items/2008/05/01.html" target="_blank">Architecture Astronaut</a>&quot; (where he picks on Groove <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ), as well as his &quot;<a href="http://www.joelonsoftware.com/articles/fog0000000069.html" target="_blank">Things you should never do</a>&quot; posts. Joel is a wise man, indeed.</p>
<p>Quick history lesson for the uninitiated. SharePoint actually started as SharePoint Team Services (STS) and actually used the <strong>file system </strong>as the content store. (<em>And I predict they will eventually go back to it too but that&#8217;s <a href="http://www.cleverworkarounds.com/2008/03/25/sharepoint-external-storage-api-crushing-my-dream/" target="_blank">another story</a></em>). Next Microsoft trotted out SharePoint Portal Server (SPS) where some bright spark thought that the Exchange &quot;web storage system&quot; (information store) would make a lovely document repository (probably because of the replication potential). Over the next couple of years there must have been a big ugly turf war between the Exchange storage team and the SQL team because, lo&#8217; and behold, with SharePoint Portal Server 2003, SQL Server was now the document store. In this major architectural change, we actually <strong>lost</strong> some functionality. In addition to this, the 2003 version leveraged the recently released&#160; .NET Framework, and provided a richer object model and platform for SharePoint to sit on (although then it was not a completely cohesive fit).</p>
<p>Roll on 2007 and we have a slew of new technologies and features, too many to name. And just to make it more interesting, Microsoft decided to change terminology (again) as ASP.NET was leveraged much more heavily. Thus, &quot;webs&quot; and &quot;areas&quot; are gone. But their evolutionary signature remains. Whether it&#8217;s the SDK, the choose-your-own-adventure Technet documentation, blogs or even the STSADM command, it is very easy to spend a lot of time going down the completely wrong path in the quest for a solution to a problem because you get mired in junk DNA. Worse still, you get there, realise you solved the problem the &#8216;old&#8217; way, say &quot;stuff it&quot; and deliver it as-is.</p>
<p><em>Web Parts are a great case in point. There are actually two types of web parts in the object model. The one that was introduced with SharePoint 2003 and the one that comes with ASP.NET 2.0 (which SharePoint 2007 uses). When I was writing my </em><a href="http://www.cleverworkarounds.com/freebies/" target="_blank"><em>hide control web part</em></a><em>, almost all the technet examples as well as blogs on the subject did not make it clear which type of web part and the distinction between them. It turned out of course I was using the right web part class, but following the wrong online documentation. A couple of XML irregularities had be scratching my head for hours.</em></p>
<h2>Infrastructure, security and governance awareness (again)</h2>
<p>I sort of covered this at a high level in the &quot;Wishing your developers are admins&quot; section and it&#8217;s been said before on many blogs that SharePoint blurs the lines between developer and administrator. Both sides have to shift ground (as do project managers and stakeholders too). Administrators really need to gain more development competencies and visa versa. I won&#8217;t spend too much time reinforcing what has already been said, but always remember this: Despite all the advances in Windows 200x, IIS, SQL Server, fancy multi-layered security, richer object model via ASP.NET Version x and the like, every developer has it in his/her power to render even a tightly managed SharePoint farm a train wreck. A lack of a simple null-check can render a site un-viewable. Choosing the wrong way to execute a query on content can chew excessive amounts of CPU and memory, an ill-thought design decision can cause a good idea to be lost in the frustration of the user experience. When it all comes down to it, it is the end user acceptance, adoption and evangelism that determines whether a project has been a success or failure.</p>
<p>But it goes beyond performance. What about security considerations? As developers, do you stop and ask yourself whether your chosen course of action has implications on security? What is your definition of security anyway? (Because it is just as much about smart, re-usable design as it is about using passwords with non alphanumeric characters in them &#8211; google &quot;<a href="http://www.google.com.au/search?hl=en&amp;q=the+CIA+triad&amp;meta=" target="_blank">the CIA triad</a>&quot;).</p>
<p>A major problem area I have seen that has manifested itself in project management time frames is the difference between the development and production environments. SharePoint development environments tend to have a short shelf-life due to the amount of crap you have to install, remove, reinstall, etc. Therefore, they are best served via a single Windows 2003 Virtual Machine with Office 2007, Visual Studio 2005, SharePoint Designer, Reporting Services, SQL Server and all of the other associated paraphernalia. Give each developer their own so they don&#8217;t kill each-other <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Without question, it is exceedingly likely that the developer is an administrator of their VM, and those that have a low security acumen tend to hit problems when they migrate their solution to the test or production environment. SharePoint has that many service accounts, application pools, web applications, site permissions, GAC DLL&#8217;s, .Net Trust levels, web.configs, etc that it is very easy for something to break into the transition to production.</p>
<p>Remember, everything works when you run it all as the administrator! You will not get much sympathy from your bitter and twisted infrastructure architect if you complain about it.</p>
<p><em>Project managers and stakeholders need to also be held to account here, as developers routinely cut corners when faced with unrealistic deadlines based on poor assumptions. But don&#8217;t worry developers, I&#8217;ll nail their asses in part 7!</em></p>
<h2>Solutions and Features</h2>
<p>The next two topics have caused me real-world pain. I had an argument with a developer a while back who felt extremely inconvenienced by my audacity to mandate that their web parts, DLL&#8217;s and web.config modifications be packaged up as a solution that activates the functionality via a feature.</p>
<p>But to be fair to the developer, if they have a low governance acumen, their point of view is completely understandable. SharePoint application development governance takes time to learn and is often not accounted for in project planning phases. Tools like STSDEV have gone a long way to improving the situation, but at the end of the day, developers who hate all the additional governance overhead associated with SharePoint are buck-passing risk to a place where it is ill afforded.</p>
<h2>Branding&#8230;</h2>
<p>Don&#8217;t get me started! <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  (I&#8217;m drinking a scotch as I write this so please forgive the vitriol <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  )</p>
<p>I&#8217;ll come back to branding in part 7 of this series, because to be fair, the developers are beholden to stakeholders who obsess over the location of a pixel. In many SharePoint <a href="http://www.cleverworkarounds.com/2007/11/14/sharepoint-branding-the-governance-of-it-all-part-7/" target="_blank">scenarios</a> (not all) this is mis-focused because their success criteria is not how good it looks, but how much the organisation has gained in <a href="http://www.cleverworkarounds.com/2007/11/17/learn-to-talk-to-your-cfo-in-their-language-part-1/" target="_blank">bottom line</a>.</p>
<p>But from a developer&#8217;s perspective, this is another area where I see <strong>serious</strong> abuse. My entire branding series came from the experience of having to clean up after a &quot;consultant&quot; who decided he did not have to research into the techniques to customise SharePoint in a sustainable, governable way. He completely butchered the _layouts files with no backup or consideration to the implications of future service packs or updates and ignored built in features like the site collection style library. Instead he reinvented his own solution. As I mentioned in the previous section, I asked him to package his work up into a solution for ease of deployment and rollback and I was met with resistance and tension.</p>
<p><em>The whole concept of &#8216;CleverWorkarounds&#8217;, comes from the pragmatic acceptance that hacks are a part of life. You can&#8217;t avoid them, and sometimes you are forced to resort to them. But there is a huge difference between a workaround and a &#8216;clever workaround&#8217;. Most of the various hacks and workarounds that I describe in the more technically focused articles of this blog (like the </em><a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/" target="_blank"><em>JavaScript</em></a><em> stuff) always come from the philosophical perspective of leaving a environment where the next administrator or developer doesn&#8217;t curse your name for eternity. </em></p>
<h2>Miscellaneous considerations&#8230;</h2>
<p>Jeez, branding got me riled up &#8211; I guess the scars are still fresh on that one! <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/05/image1.png"><img style="border-right-width: 0px; margin: 0px 20px 0px 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/05/image-thumb1.png" width="125" height="177" /></a></p>
<p><em>No-one can know everything. Everyone has governance deficiencies in one way or another. I remember in 2003, a shattered project manager came into my office. A client meeting had gone very badly, blown up in his face in fact. He came to me and his classic line to me was &quot;All I did was tell them to modify their Active Directory schema!&quot;. If you know Active Directory, you would know what sort of landmine he just stepped on. It&#8217;s like telling Mr T. that his &quot;bling&quot; really brings out his feminine side!</em></p>
<p>Thus, the branding hacks manifest themselves in other areas too. Pretty much any time you delve into the guts of the 12 Hive (tech guys and devs know what I&#8217;m referring to here), you have to be very mindful of governance, security and re-use. Ask yourself this question</p>
<p>Does the change I am making have <strong>any</strong> chance of being undone or unduly affected by a future patch or service pack?</p>
<p>Is the answer is yes, <strong>then stop and get some advice! </strong></p>
<p>Developers in general get frustrated with their project managers. The PM&#8217;s nag, don&#8217;t have a deep enough understanding of the intricacies and nuances of application development and set unreasonable deadlines based on what you see as incomplete requirements and assumptions. However, as I have said in the <a href="http://www.cleverworkarounds.com/2008/04/15/why-do-sharepoint-projects-fail-part-2/" target="_blank">second</a> post, their world is just as frustrating as yours. Shared understanding this is the key to dealing with it.</p>
<p>So, if your project manager gets upset because their deadlines stretch because you feel some more research is required to determine the best course of action, tell them to read this series from start to finish (whenever it finishes). Chances are they will be squirming with embarrassment way before they have even gotten to this post.</p>
<p>At the end of the day, it is in both your collective interest to keep the stakeholders happy and ensure that the project is successful.</p>
<h2>Conclusion</h2>
<p>This post covered a lot of material, and I appreciate you sticking with me. Judging from the reaction from Joel&#8217;s endorsement of the series, it also seems to have tapped into a common vein of frustration felt by many IT professionals all around the world.</p>
<p>The next post will round off the &quot;people&quot; aspects with an examination of the stakeholder and project sponsor and senior management perspective. Like the developer and infrastructure post, the key is to recognise that their perspective of the world is just as valid as yours, and just as much as you see them misinformed and contributing to a wicked problem scenario, you need to accept the fact that you do not have the full picture either.</p>
<p>Having said that, they get paid way more than we do and therefore that makes them fair game for some serious nailing to the wall <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Roll on part 7!</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-6551570212921028";
google_ad_width = 468;
google_ad_height = 60;
google_ad_format = "468x60_as";
google_ad_type = "text_image";
google_ad_channel = "";
google_ui_features = "rc:6";
//-->
</script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/05/12/why-do-sharepoint-projects-fail-part-6/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Free MOSS Web Part &#8211; Hide Controls via JavaScript</title>
		<link>http://www.cleverworkarounds.com/2008/03/13/free-mosswss-2007-web-part-hide-controls-via-javascript/</link>
		<comments>http://www.cleverworkarounds.com/2008/03/13/free-mosswss-2007-web-part-hide-controls-via-javascript/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 13:06:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Web Parts]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/03/13/free-mosswss-2007-web-part-hide-controls-via-javascript/</guid>
		<description><![CDATA[Note: version 0.2 posted with minor bugfix 15th March 08! Note2: Only works with MOSS 2007 sorry as you WSS guys do not have audiences targeting This is my small contribution to the SharePoint world. It is a web part that once added to a web part page, allows you to customise the display by [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p><!--adsense--></p>
<p><strong><em>Note: version 0.2 posted with minor bugfix 15th March 08!</em></strong></p>
<p><strong><em>Note2: Only works with MOSS 2007 sorry as you WSS guys do not have audiences targeting <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </em></strong></p>
<p>This is my small contribution to the SharePoint world. It is a web part that once added to a web part page, allows you to customise the display by adding JavaScript to selectively hide controls on the page . Ever needed to hide a field from display/edit for a certain audience? Well here is a way do it without requiring SharePoint Designer and having to break a page from it&#8217;s site definition (unghosting).</p>
<p>Before and after shots below (look ma &#8211; no top button!)</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image32.png"><img border="0" width="283" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb32.png" alt="image" height="145" /></a>  <a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image34.png"><img border="0" width="283" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb34.png" alt="image" height="145" /></a></p>
<p>To fully understand what is being done here, I suggest you read my series of articles on the use of JavaScript in SharePoint. <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a> in particular will show you how to safely add this web part to pages with editing disabled (NewForm.aspx, EditForm.aspx and DispForm.aspx)</p>
<p>The full series can be found here: <a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a>, <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a>, <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a>, <a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/">Part 4</a>, <a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/">Part 5</a> and <a href="http://www.cleverworkarounds.com/2008/03/12/more-sharepoint-branding-customisation-using-javascript-part-6/">Part 6</a>.</p>
<p><em>Kudos to <a href="http://wss.made4the.net/default.aspx">Jeremy Thake</a> for feedback and some code contribution. Despite being seriously metrosexual, he is otherwise otherwise very cool <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> .</em></p>
<p>Now two important warnings:</p>
<p><strong><em>Warning 1: This is an alpha quality release and I may never touch it again <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  So you very likely *will* break it. If there is enough interest, I am happy to pop it on codeplex</em></strong></p>
<p><strong><em>Warning 2: This web part should NOT be considered as a security measure and thus used in any security sensitive scenario (such as an extranet or WCM site). JavaScript by its very nature can be trivially interfered with and thus other methods (server side) should be employed in these scenarios to prevent interference at the browser.</em></strong></p>
<p>You can download by reading the disclaimer and clicking the button below..</p>
<p>THIS CODE IS PROVIDED UNDER THIS LICENSE ON AN &#8220;AS IS&#8221; BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER</p>
<p>Use at your own risk!</p>
<form action="http://www.cleverworkarounds.com/CleverWorkAroundsHideFields.wsp">
<input type="submit" /></form>
<p>To install perform the following commands</p>
<ol>
<li>stsadm.exe&#8221; -o addsolution -filename CleverWorkAroundsHideFields.wsp</li>
<li>stsadm.exe&#8221; -o execadmsvcjobs</li>
<li>stsadm.exe&#8221; -o deploysolution -name CleverWorkAroundsHideFields.wsp -immediate -allowgacdeployment -allcontenturls</li>
<li>stsadm.exe&#8221; -o execadmsvcjobs</li>
</ol>
<p>To remove/reinstall perform the following commands</p>
<ol>
<li>stsadm.exe&#8221; -o retractsolution -name CleverWorkAroundsHideFields.wsp -immediate -allcontenturls</li>
<li>stsadm.exe&#8221; -o execadmsvcjobs</li>
<li>stsadm.exe&#8221; -o deletesolution -name CleverWorkAroundsHideFields.wsp</li>
<li>stsadm.exe&#8221; -o execadmsvcjobs</li>
<li>stsadm.exe&#8221; -o addsolution -filename CleverWorkAroundsHideFields.wsp</li>
<li>stsadm.exe&#8221; -o execadmsvcjobs</li>
<li>stsadm.exe&#8221; -o deploysolution -name CleverWorkAroundsHideFields.wsp -immediate -allowgacdeployment -allcontenturls</li>
<li>stsadm.exe&#8221; -o execadmsvcjobs</li>
</ol>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/03/13/free-mosswss-2007-web-part-hide-controls-via-javascript/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>More SharePoint Branding &#8211; Customisation using JavaScript &#8211; Part 6</title>
		<link>http://www.cleverworkarounds.com/2008/03/12/more-sharepoint-branding-customisation-using-javascript-part-6/</link>
		<comments>http://www.cleverworkarounds.com/2008/03/12/more-sharepoint-branding-customisation-using-javascript-part-6/#comments</comments>
		<pubDate>Wed, 12 Mar 2008 13:09:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[STSDEV]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Web Parts]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/03/12/more-sharepoint-branding-customisation-using-javascript-part-6/</guid>
		<description><![CDATA[God help me, I&#8217;m up to part 6 of series about a technology I dislike and still going. For those of you that have just joined us, then you might want to go back to the very beginning of this series where I used JavaScript to improve the SharePoint user experience. Since then, I&#8217;ve been [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p><!--adsense--></p>
<p>God help me, I&#8217;m up to part 6 of series about a technology I dislike and still going. For those of you that have just joined us, then you might want to go back to the very beginning of this series where I used JavaScript to improve the SharePoint user experience. Since then, I&#8217;ve been trying to pick a path through the thorny maze of what you could term, &#8216;sustainable customisation&#8217;. </p>
<p>By that, I mean something that hopefully will not cause you grief and heartache the next time a service pack is applied!</p>
<p>So no mood for jokes this time &#8211; I want to get this over with so let&#8217;s get straight to it and finish this thing!</p>
<p>So where are we at?</p>
<ul>
<li><a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a> looked at how we can use JavaScript to deal with the issue of hiding form elements from the user in lists and document libraries.  </li>
<li><a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a> examined some of the issues with the part 1 JavaScript hacks and wrapped it into a web part using the content editor web part.  </li>
<li><a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a> then examined the various issues of adding this new web part to certain SharePoint pages (NewForm.aspx, EditForm.aspx and DispForm.aspx). I also covered using SharePoint Audience targeting to make the hiding/unhiding of form elements personalised to particular groups of users.  </li>
<li><a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/">Part 4</a> started to address a couple of remaining usability issues, and introduced &#8216;proper&#8217; web-part development using Visual Studio and STSDEV. I created a project to perform the same functionality in part 3, but would not requiring the user to have any JavaScript knowledge or experience.  </li>
<li><a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/">Part 5</a> then used STSDEV to create a solution package that allowed easy debugging, deployment and updating of the web part developed in part 4.</li>
</ul>
<p>So what could we possibly have left to cover? Basically this article will revisit the web part code and make some functionality improvements and then I will cover off some remaining quirks/issues that you should be aware of.</p>
<p>[Quick Navigation: <a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a>, <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a>, <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a>, <a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/">Part 4</a>, <a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/">Part 5</a> and Part 6]</p>
<p><span id="more-725"></span></p>
<h2>Code Enhancement 1 &#8211; Debug Breakpoint</h2>
<p>One thing that can be annoying when using this web part is debugging. A small typo in the list of columns to hide and the functionality can break and be difficult to troubleshoot. I have two enhancements that improve this situation. </p>
<p>The first is very simple. If you add a line like this in your JavaScript code</p>
<pre class="csharpcode">debugger;</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>When script debugging is enabled on your browser, a number of 3rd party debug tools such as <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=2f465be0-94fd-4569-b3c4-dffdf19ccd99&amp;displaylang=en">Microsoft Script Debugger</a>, <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfp2k2/html/odc_fpdebugscripts.asp">Microsoft Script Editor</a>, <a href="http://www.gotdotnet.com/team/csharp/learn/whitepapers/How%20to%20debug%20script%20in%20Visual%20Studio%20.Net.doc">Visual Studio.Net</a> and <a href="http://www.mozilla.org/projects/venkman/">Venkman</a> will treat this as a breakpoint and allow you to step through the code and perform client side debugging. This is handy of course, so wouldn&#8217;t it be nice for the web part to have a property that enables a breakpoint?</p>
<p>The code for this is insanely easy. We define a boolean property in our web part that optionally outputs the line &#8216;debugger;&#8217; just before the rest of our code runs. Using the XML Serialisation as described in Part 5, we can expose this property as a checkbox in the web part properties when used in SharePoint.</p>
<p>Below is a code sample of the property and its use.</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">bool</span> _breakpoint;

<span class="rem">// Create a custom category in the property sheet.</span>
[Category(<span class="str">"Custom Properties"</span>)]
[Personalizable(PersonalizationScope.Shared)]
[WebDisplayName(<span class="str">"Enable Breakpoint?"</span>)]
[WebDescription(<span class="str">"Add's breakpoints to Javascript code for script debuggers"</span>)]
[WebBrowsable(<span class="kwrd">true</span>)]
[XmlElement(ElementName = <span class="str">"BreakPoint"</span>)]
<span class="kwrd">public</span> <span class="kwrd">bool</span> BreakPoint {
    get
    {
        <span class="kwrd">return</span> _breakpoint;
    }
    set
    {
        _breakpoint = <span class="kwrd">value</span>;
    }
 }
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>In the render method, where applicable, we then add this line</p>
<pre class="csharpcode"><span class="kwrd">if</span> (_breakpoint)
{
      output.WriteLine(<span class="str">"   debugger;"</span>);
}
</pre>
<p>So after rebuilding and redeploying this project using STSDEV, the web part properties now reflect this new property.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image26.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="220" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb26.png" width="244" border="0"/></a> </p>
<p>Check the &#8220;Enable BreakPoint&#8221; box and click okay. If your browser has script debugging enabled (found in Internet Options/Advanced tab in IE), you will be prompted to launch a debugger then the breakpoint is executed. Below you can see both the IE property page that controls script debugging and the prompt to debug the page when Visual Studio is installed. </p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image27.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="215" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb27.png" width="326" border="0"/></a>&nbsp;<a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image28.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="290" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb28.png" width="269" border="0"/></a> </p>
<p>Choose a new Instance of Visual Studio and you will then be able to see and step through the JavaScript code as shown below</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image29.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="296" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb29.png" width="551" border="0"/></a> </p>
<h2>Code Enhancement 2 &#8211; Debug Log Window</h2>
<p>Sometimes, you will not have the benefit of being able to use a JavaScript debugger and you need a simpler method to display debug information. How about we add a debug log window that can conditionally be invoked when it is enabled in the web part properties?</p>
<p>Fortunately for us, <a href="http://ajaxcookbook.org/javascript-debug-log/">Bret Taylor</a> has done the hard work for us with a complete JavaScript debug log function. </p>
<p>So in JavaScript code, we can for example, add a line like:</p>
<pre class="csharpcode">log(<span class="str">"This is log message "</span>);</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>So once again, we can set this as a boolean property. If the property is set to true, the webpart can write the JavaScript log function to the browser and then call that function at various places in the rest of our code.</p>
<p>Below is a code sample of the property and its use</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">bool</span> _DebugLogWindow;

[Category(<span class="str">"Custom Properties"</span>)]
[DefaultValue(<span class="kwrd">false</span>)]
[Personalizable(PersonalizationScope.Shared)]
[WebDisplayName(<span class="str">"Use Debug Log Window?"</span>)]
[WebDescription(<span class="str">"Select to set value to True."</span>)]
[WebBrowsable(<span class="kwrd">true</span>)]
[XmlElement(ElementName = <span class="str">"DebugLogWindow"</span>)]
<span class="rem">// The accessor for this property.</span>
<span class="kwrd">public</span> <span class="kwrd">bool</span> DebugLogWindow
{
    get
    {
        <span class="kwrd">return</span> _DebugLogWindow;
    }
    set
    {
        _DebugLogWindow = <span class="kwrd">value</span>;
    }
}</pre>
<p>The next section of code outputs the log function itself. I know this looks ugly but thats what you get when using one programming language to write the code of another.</p>
<pre class="csharpcode" style="width: 656px; height: 393px"><span class="kwrd">if</span> (_DebugLogWindow)
{
    output.WriteLine(<span class="str">@"function log(message) {"</span>);
    output.WriteLine(<span class="str">@"if (!log.window_ || log.window_.closed) { "</span>);
    output.WriteLine(<span class="str">@"   var win = window.open("</span><span class="str">""</span><span class="str">", null, "</span><span class="str">"width=400,height=200,"</span><span class="str">" + "</span>);
    output.WriteLine(<span class="str">@"   "</span><span class="str">"scrollbars=yes,resizable=yes,status=no,"</span><span class="str">" + "</span>);
    output.WriteLine(<span class="str">@"   "</span><span class="str">"location=no,menubar=no,toolbar=no"</span><span class="str">"); "</span>);
    output.WriteLine(<span class="str">@"   if (!win) return; "</span>);
    output.WriteLine(<span class="str">@"        var doc = win.document; "</span>);
    output.WriteLine(<span class="str">@"        doc.write("</span><span class="str">"&lt;html&gt;&lt;head&gt;&lt;title&gt;Debug Log&lt;/title&gt;&lt;/head&gt;"</span><span class="str">" +"</span>);
    output.WriteLine(<span class="str">@"        "</span><span class="str">"&lt;body&gt;&lt;/body&gt;&lt;/html&gt;"</span><span class="str">"); "</span>);
    output.WriteLine(<span class="str">@"   doc.close(); "</span>);
    output.WriteLine(<span class="str">@"   log.window_ = win; "</span>);
    output.WriteLine(<span class="str">@"   }"</span>);
    output.WriteLine(<span class="str">@"   var logLine = log.window_.document.createElement("</span><span class="str">"div"</span><span class="str">"); "</span>);
    output.WriteLine(<span class="str">@"   logLine.appendChild(log.window_.document.createTextNode(message)); "</span>);
    output.WriteLine(<span class="str">@"   log.window_.document.body.appendChild(logLine); "</span>);
    output.WriteLine(<span class="str">@"}"</span>);
 }
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>So all we need now is to invoke this function in sections of code where debug output would be useful. For example:</p>
<pre class="csharpcode"><span class="kwrd">if</span> (_DebugLogWindow)
{
     output.WriteLine(<span class="str">"    log(\"We have "</span> + _fieldlist.Length + <span class="str">" fields to hide \" ); "</span>);
}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>So let&#8217;s rebuild and redeploy these changes and see the effect.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image30.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb30.png" width="231" border="0"/></a> </p>
<p>The screen grab below shows the result of enabling this setting. We now have a second browser window spawned that logs to the screen all information passed to the log() function.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image31.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="348" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb31.png" width="603" border="0"/></a></p>
<p>&nbsp;</p>
<h2>Code Enhancement 3 &#8211; Hide Control by ID</h2>
<p>I cannot take the credit for this enhancement. I originally packaged up an early version of the web part for <a href="http://wss.made4the.net/default.aspx">Jeremy Thake</a>, a former colleague of mine to test on his environment before I published part 5 of this series. He in return sent me back another JavaScript function to hide based on HTML element ID&#8217;s.</p>
<p>Way back in Part 1, I described the JavaScript built-in method <a href="http://www.java2s.com/Code/JavaScriptReference/Javascript-Methods/getElementsByTagName.htm">getElementsByTagName</a>. Jeremy is using the function <a href="http://www.java2s.com/Code/JavaScriptReference/Javascript-Methods/getElementById.htm">getElementByID</a>. This function works on the assumption that HTML elements are assigned an optional ID attribute. e.g</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">div</span> <span class="attr">id</span><span class="kwrd">="CleverWorkarounds1"</span>
     <span class="attr">style</span><span class="kwrd">="position:absolute; width:500px; height:150px; visibility: visible"</span><span class="kwrd">&gt;</span>
some DIV tag
<span class="kwrd">&lt;/</span><span class="html">div</span><span class="kwrd">&gt;</span>
</pre>
<p>If you look in SharePoint HTML source, you will see that this is the case.Take for example this particularly feral HTML element for the CLOSE button.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">input</span> <span class="attr">type</span><span class="kwrd">="button"</span> <span class="attr">name</span><span class="kwrd">="ctl00$m$g_100fd177_99ab_4755_a1d3_f064360d4317$ctl00$toolBarTbltop$RightRptControls$ctl02$ctl00$diidIOGoBack"</span>
   <span class="attr">value</span><span class="kwrd">="Close"</span>
   <span class="attr">id</span><span class="kwrd">="ctl00_m_g_100fd177_99ab_4755_a1d3_f064360d4317_ctl00_toolBarTbltop_RightRptControls_ctl02_ctl00_diidIOGoBack"</span>
   <span class="attr">class</span><span class="kwrd">="ms-ButtonHeightWidth"</span> <span class="attr">target</span><span class="kwrd">="_self"</span>
 <span class="kwrd">/&gt;</span>
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>So this button can be referenced by the following ID.:</p>
<pre class="csharpcode" style="width: 656px; height: 45px">document.getElementById(<span class="str">'ctl00_m_g_100fd177_99ab_4755_a1d3_f064360d4317_ctl00_toolBarTbltop_RightRptControls_ctl02_ctl00_diidIOGoBack'</span>).style.display=<span class="str">"none"</span>; </pre>
<p>Below is a code sample of the property and its use</p>
<pre class="csharpcode" style="width: 664px; height: 388px"><span class="kwrd">private</span> <span class="kwrd">string</span> _HideFieldByIdList;

<span class="rem">// Create a custom category in the property sheet.</span>
[Category(<span class="str">"Custom Properties"</span>)]
[Personalizable(PersonalizationScope.Shared)]
[WebDisplayName(<span class="str">"List of HTML element IDs to hide on this page"</span>)]
[WebDescription(<span class="str">"Comma delimited list of HTML element IDs to hide on this page"</span>)]
[WebBrowsable(<span class="kwrd">true</span>)]
[XmlElement(ElementName = <span class="str">"HideFieldByIdList"</span>)]
<span class="kwrd">public</span> <span class="kwrd">string</span> HideFieldByIdList
{
    get
    {
        <span class="kwrd">return</span> _HideFieldByIdList;
    }
    set
    {
        _HideFieldByIdList = <span class="kwrd">value</span>;
    }
}</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>Next up, we have the function written by Jeremy (along with some debug log lines added by me)</p>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<pre class="csharpcode" style="width: 656px; height: 515px"><span class="kwrd">if</span> (HideFieldByIdList != <span class="kwrd">null</span> || HideFieldByIdList != <span class="str">""</span>)
{
     <span class="kwrd">if</span> (_DebugLogWindow)
    {
        output.WriteLine(<span class="str">"    log(\"Calling function hideFieldsById\" ); "</span>);
    }
    output.WriteLine();
    output.WriteLine(<span class="str">"function hideFieldsById() { "</span>);
    _fieldlist = HideFieldByIdList.Split(<span class="str">','</span>);
    <span class="kwrd">if</span> (_fieldlist != <span class="kwrd">null</span>)&nbsp;&nbsp; {
        <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; _fieldlist.Length; i++)
        {
            <span class="kwrd">if</span> (_fieldlist[i] != <span class="str">""</span>)
            {
                <span class="kwrd">if</span> (_DebugLogWindow)
                {
                     output.WriteLine(<span class="str">"    log(\"Looking for ID "</span> + _fieldlist[i] + <span class="str">"\" ); "</span>);
                }
                 output.WriteLine(<span class="str">"document.getElementById('"</span> + _fieldlist[i] + <span class="str">"').style.display=\"none\";"</span>);
             }
         }
    }
    output.WriteLine(<span class="str">" }"</span>);
    output.WriteLine();
}</pre>
<p>So let&#8217;s test this! Redeploy the project and let&#8217;s hide the Close button on DispForm.aspx</p>
<p>Before screen-shot!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image32.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="261" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb32.png" width="509" border="0"/></a> .</p>
<p>Add the ID of the &#8220;Close&#8221; button</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image33.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="337" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb33.png" width="233" border="0"/></a> </p>
<p>After screen-shot! Wohoo!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image34.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="265" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb34.png" width="517" border="0"/></a> </p>
<h2>Quirks and Issues</h2>
<p>We are almost home after 6 posts in this series! No more coding for now as I think we have demonstrated enough of this idea. You can see how this can be used and extended quite easily.</p>
<p>There are a couple of minor points that I think are worth pointing out. One issue I covered back in my <a href="http://www.cleverworkarounds.com/2007/10/27/sharepoint-branding-part-5-%E2%80%93-feature-improvements-and-bugs/">first branding series</a>. If you deactivate this feature, the web part will not be removed from the web part library. </p>
<p>“That is by design. Deactivation of features does not remove data that was created when the feature was activated. if you want to “clean up” the data that was created, you need to create a Feature receiver handler and have the FeatureDeactivating() event handler manually remove the file.”
</p>
<p>and
</p>
<p>“Keep in mind though, data is left in SharePoint BY DESIGN. What would happen if you had deployed a page layout with a Feature and someone removed it while it was in use by thousands of pages? Oops… blamo!”
</p>
<p>So now that we know that the web part will not be deleted, let&#8217;s see what happens when we modify it. Here is the web part as it was installed by the STSDEV solution. </p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image35.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="369" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb35.png" width="483" border="0"/></a> </p>
<p>Now let&#8217;s do a flashback and modify WebPart.XML in our Visual Studio Project. I have modified the Title property to &#8220;CleverWorkArounds Hide Column1 Web Part&#8221;</p>
<pre class="csharpcode" style="width: 656px; height: 235px"><span class="kwrd">&lt;?</span><span class="html">xml</span> <span class="attr">version</span><span class="kwrd">="1.0"</span> <span class="attr">encoding</span><span class="kwrd">="utf-8"</span>?<span class="kwrd">&gt;</span>
<span class="rem">&lt;!--Created by STSDEV at 7/03/2008 11:34:05 PM--&gt;</span>
<span class="kwrd">&lt;</span><span class="html">Elements</span> <span class="attr">xmlns</span><span class="kwrd">="http://schemas.microsoft.com/sharepoint/"</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Module</span> <span class="attr">Name</span><span class="kwrd">="CleverWorkAroundsHideFields"</span> <span class="attr">List</span><span class="kwrd">="113"</span> <span class="attr">Url</span><span class="kwrd">="_catalogs/wp"</span> <span class="attr">Path</span><span class="kwrd">="WebParts"</span> <span class="attr">RootWebOnly</span><span class="kwrd">="True"</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">File</span> <span class="attr">Url</span><span class="kwrd">="CleverWorkAroundsHideFields.webpart"</span> <span class="attr">Type</span><span class="kwrd">="GhostableInLibrary"</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">="Group"</span> <span class="attr">Value</span><span class="kwrd">="CleverWorkArounds"</span> <span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">="Description"</span> <span class="attr">Value</span><span class="kwrd">="Web part to selectively hide columns via JavaScript"</span><span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">="Title"</span> <span class="attr">Value</span><span class="kwrd">="CleverWorkArounds Hide Column1 Web Part"</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">File</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Module</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Elements</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>So let&#8217;s redeploy the solution, and even manually deactivate and reactivate the feature as well. When we re-examine the web part in the gallery, <strong>the change is not reflected</strong>.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image36.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="176" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb36.png" width="548" border="0"/></a> </p>
<p>Another inconsistency (although not a major one), is that the &#8220;Description&#8221; property is ignored completely. If you look at the Webpart.XML screen-shot above, you will notice I have set the Description property to &#8220;<span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">=&#8221;Description&#8221;</span> <span class="attr">Value</span><span class="kwrd">=&#8221;Web part to selectively hide columns via JavaScript</span>&#8220;.</p>
<p>But look at the web part properties above. The description is &#8220;A demo Web Part created by stsdev&#8221;.</p>
<p>I assume this is a bug with STSDEV, but in any event, its pretty minor and I can live with it.</p>
<h2>Conclusion</h2>
<p>Well gawddammit, I am finally done with JavaScript! But to round off this series, let&#8217;s summarise what we have achieved.</p>
<ul>
<li>No programming skills necessary
</li>
<li>No unghosting of Web Part pages
</li>
<li>Easy debug logging
</li>
<li>Leverage audience based content delivery
</li>
<li>Eliminated the requirement for SharePoint Designer
</li>
<li>Packaged up the functionality into an easy to deploy solution</li>
</ul>
<p>I am well pleased, and I hope that you found some useful nuggets of information in this post. </p>
<p>I still hate JavaScript, but at least here we are using it in a sustainable customisation manner. <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Bye for now</p>
<p>Paul</p>
<p><!--adsense--></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/03/12/more-sharepoint-branding-customisation-using-javascript-part-6/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>More SharePoint Branding &#8211; Customisation using Javascript &#8211; Part 5</title>
		<link>http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/</link>
		<comments>http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/#comments</comments>
		<pubDate>Sun, 09 Mar 2008 11:24:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[Governance]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[STSDEV]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Web Parts]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/</guid>
		<description><![CDATA[Hello and welcome to part 5 of another epic CleverWorkArounds blog post. If you think I write a lot on my blog, you should see my documentation and training material! I seem to be rare insofar as I actually like to write documentation and can churn out reasonable quality pretty fast. So if you need [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p>Hello and welcome to part 5 of another epic CleverWorkArounds blog post.</p>
<p>If you think I write a lot on my blog, you should see my documentation and training material! I seem to be rare insofar as I actually like to write documentation and can churn out reasonable quality pretty fast. So if you need your scary SharePoint farm/infrastructure audited and fully documented, you <a href="http://www.cleverworkarounds.com/about/">know who to call</a>! <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Anyhow, here is the current state of play.</p>
<ul>
<li><a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a> of this series looked at how we can use JavaScript to deal with the common request of hiding form elements from the user in lists and document libraries. We looked at a Microsoft documented method, then a better, more flexible method.</li>
<li><a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a> wrapped this JavaScript code into a web part which has been loaded into the SharePoint web part gallery.</li>
<li><a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a> then examined the trials and tribulations of getting this new web part added to certain SharePoint pages (NewForm.aspx, EditForm.aspx and DispForm.aspx), and then with a few simple edits, use this web part to hide form fields as desired. Finally, I demonstrated the power of combining this with SharePoint Audiences targeting functionality to make the hiding/unhiding of form elements personalised to particular groups of users.</li>
<li><a target="_blank" href="http://http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/">Part 4</a> introduced Visual Studio and STSDEV. I created a project to perform the same functionality in part 3, but not requiring any JavaScript knowledge or experience. By the end of part 4 I had a STSDEV project that compiled with no errors.</li>
</ul>
<p>And now we are onto Part 5 where we turn our attention to the packaging and deployment of our web part. As you are about to see, STSDEV makes this a very quick and painless experience. If you aren&#8217;t convinced of the merits of STSDEV and the SharePoint solution framework by the time you finish this article, then I don&#8217;t know what will convince you.</p>
<p>[Quick Navigation: <a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a>, <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a>, <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a>, <a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/">Part 4</a> and <a href="http://http://www.cleverworkarounds.com/2008/03/12/more-sharepoint-branding-customisation-using-javascript-part-6/">Part 6</a>]</p>
<p><span id="more-701"></span></p>
<p>So, for those of you that want to see the complete source code for an easy cut and paste into your own project, I have listed it below.</p>
<pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Web;
<span class="kwrd">using</span> System.Web.UI;
<span class="kwrd">using</span> System.Web.UI.WebControls;
<span class="kwrd">using</span> System.Web.UI.WebControls.WebParts;         

<span class="kwrd">using</span> System.Xml.Serialization;
<span class="kwrd">using</span> System.ComponentModel;         

<span class="kwrd">namespace</span> CleverWorkAroundsHideFields {         

  [XmlRoot(Namespace = <span class="str">"CleverWorkAroundsHideFields"</span>)]
  <span class="kwrd">public</span> <span class="kwrd">class</span> CleverWorkAroundsHideFields : WebPart {         

      <span class="kwrd">private</span> <span class="kwrd">string</span> _HideFieldList;
      <span class="kwrd">private</span> <span class="kwrd">string</span>[] _fieldlist;         

      <span class="rem">// Create a custom category in the property sheet.</span>
      [Category(<span class="str">"Custom Properties"</span>)]
      [Personalizable(PersonalizationScope.Shared)]
      [WebDisplayName(<span class="str">"List of columns to hide on this page"</span>)]
      [WebDescription(<span class="str">"Comma delimited list of columns to hide on this page"</span>)]
      [WebBrowsable(<span class="kwrd">true</span>)]
      [XmlElement(ElementName = <span class="str">"HideFieldList"</span>)]
      <span class="kwrd">public</span> <span class="kwrd">string</span> HideFieldList
      {
          get
          {
              <span class="kwrd">return</span> _HideFieldList;
          }
          set
          {
              _HideFieldList = <span class="kwrd">value</span>;
          }
      }         

      <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Render(HtmlTextWriter output)
      {         

          <span class="rem">// Now lets extract the list of fields from the web part properties</span>
          <span class="kwrd">if</span> (HideFieldList != <span class="kwrd">null</span>)
          {
              _fieldlist = HideFieldList.Split(<span class="str">','</span>);         

              <span class="rem">// javascript inside C# - ugh </span>
              <span class="rem">// I know this looks ugly on account of the escaped quotes. </span>
              <span class="rem">// First section is the findacontrol function</span>         

              output.WriteLine();
              output.WriteLine(<span class="str">@"&lt;script language="</span><span class="str">"javascript"</span><span class="str">" type="</span><span class="str">"text/javascript"</span><span class="str">"&gt;  "</span>);
              output.WriteLine();
              output.WriteLine(<span class="str">@"_spBodyOnLoadFunctionNames.push("</span><span class="str">"hideFields"</span><span class="str">")  "</span>);
              output.WriteLine(<span class="str">@"function findacontrol(FieldName) {  "</span>);
              output.WriteLine(<span class="str">@"var arr = document.getElementsByTagName("</span><span class="str">"!"</span><span class="str">");  //get all comments "</span>);
              output.WriteLine(<span class="str">@"for (var i=0;i &lt; arr.length; i++ ) {   "</span>);
              output.WriteLine(<span class="str">@"   // now match the field name  "</span>);
              output.WriteLine(<span class="str">@"   if (arr[i].innerHTML.indexOf(FieldName) &gt; 0) { "</span>);
              output.WriteLine(<span class="str">@"      return arr[i]; "</span>);
              output.WriteLine(<span class="str">@"   } "</span>);
              output.WriteLine(<span class="str">@"  } "</span>);
              output.WriteLine(<span class="str">@"}"</span>);
              output.WriteLine();
              output.WriteLine();         

              <span class="rem">// Now the hidefields function, which loops for each field to be hidden</span>         

              output.WriteLine(<span class="str">"function hideFields() { "</span>);
              output.WriteLine(<span class="str">"   var control; "</span>);         

              <span class="kwrd">if</span> (_fieldlist != <span class="kwrd">null</span>)
              {
                  <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; _fieldlist.Length; i++)
                  {
                      output.Write(<span class="str">"    control = findacontrol(\""</span>);
                      output.Write(_fieldlist[i]);
                      output.WriteLine(<span class="str">"\" ); "</span>);
                      output.WriteLine(<span class="str">"   control.parentNode.parentNode.style.display=\"none\""</span>);
                  }
              }
              output.WriteLine(<span class="str">" }"</span>);         

              output.WriteLine(<span class="str">"&lt;/script&gt;"</span>);
          } <span class="rem">// if</span>
      } <span class="rem">// method</span>         

   }
}</pre>
<style type="text/css">                  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>Now, let&#8217;s focus back on our STSDEV generated Visual Studio solution and make a couple of changes, to properly package up our code.</p>
<h2>Edit 1: Feature.XML</h2>
<p>You will find Feature.XML under RootFiles\TEMPLATE\Features\CleverWorkAroundsHideFields</p>
<p>In this example, I have modified the Title, Description and ImageUrl attributes of the &lt;Feature&gt; element of Feature.xml to give more meaningful, friendly descriptive text. The default image has been renamed to macgyver.jpg and you will soon see why <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<pre style="width: 656px; height: 310px" class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Feature</span>
  <span class="attr">Id</span><span class="kwrd">="8C39BCDB-9361-4412-950C-5ADE30AFF14E"</span>
<strong>  <span class="attr">Title</span><span class="kwrd">="CleverWorkArounds: JavaScript Hidden Column Manager"</span>
  <span class="attr">Description</span><span class="kwrd">="This SharePoint solution can be used to hide columns from DispForm.apsx, EditFormaspx, NewForm.aspx as well as custom web part pages. (<a href="http://www.cleverworkarounds.com)">http://www.cleverworkarounds.com)"</a></span>
</strong>  <span class="attr">Version</span><span class="kwrd">="1.0.0.0"</span>
  <span class="attr">Scope</span><span class="kwrd">="Site"</span>
  <span class="attr">Hidden</span><span class="kwrd">="false"</span>
<strong>  <span class="attr">ImageUrl</span><span class="kwrd">="CleverWorkAroundsHideFields\macgyver.jpg"</span> <span class="attr">xmlns</span><span class="kwrd">="http://schemas.microsoft.com/sharepoint/"</span><span class="kwrd">&gt;</span>
</strong>  <span class="kwrd">&lt;</span><span class="html">ElementManifests</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">ElementManifest</span>
      <span class="attr">Location</span><span class="kwrd">="WebParts.xml"</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">ElementFile</span>
      <span class="attr">Location</span><span class="kwrd">="WebParts\CleverWorkAroundsHideFields.webpart"</span> <span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">ElementManifests</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Feature</span><span class="kwrd">&gt;</span></pre>
<h2>Edit 2. Custom Icon Image</h2>
<p>I decided that if I am going to create a SharePoint Feature with an icon, I&#8217;d have to use something that captures the very essence of the &#8220;clever workaround&#8221;. When you think about it, can it be anybody but <a href="http://humorsection.blogspot.com/2006/08/funny-picture-macgyver.html">MacGyver</a>?</p>
<p><embed wmode="transparent" height="355" width="425" src="http://www.youtube.com/v/lnScL6o8Egs"></embed></p>
<p>[if you see a broken image above then your IT staff are being anal and blocking YouTube - sorry]</p>
<p>Ahhh- the memories..  *ahem*, focus Paul &#8211; back to the post.</p>
<p>So, I have a small picture of MacGyver called oddly enough, MacGyver.jpg. I have placed this file into the RootFiles\TEMPLATE\IMAGES folder in my STSDEV project as shown below.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image10.png"><img border="0" width="500" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb10.png" alt="image" height="147" style="border-width: 0px" /></a></p>
<p>Now in Visual Studio, I have added this image to the project.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image11.png"><img border="0" width="243" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb11.png" alt="image" height="146" style="border: 0px" /></a> <a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image12.png"><img border="0" width="395" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb12.png" alt="image" height="255" style="border: 0px" /></a></p>
<p>As you can see below, now macgyver.jpg is listed along with the default STSDEV image. You can delete the default image AfricanPith32.gif as we will not be needing it.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image13.png"><img border="0" width="320" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb13.png" alt="image" height="279" style="border-width: 0px" /></a></p>
<h2>Edit 3. WebParts.XML</h2>
<p>You will find WebParts.XML under RootFiles\TEMPLATE\Features\CleverWorkAroundsHideFields</p>
<p>In this example, I have modified the &lt;File&gt; element of WebParts.XML, modified the property element named &#8220;Group&#8221;, as well as added in a Description and Title property also. This XML file uses the &lt;File&gt; directive to put our web part into the web part gallery for any site collection where the feature is activated.</p>
<pre style="width: 656px; height: 199px" class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Elements</span> <span class="attr">xmlns</span><span class="kwrd">="http://schemas.microsoft.com/sharepoint/"</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Module</span> <span class="attr">Name</span><span class="kwrd">="CleverWorkAroundsHideFields"</span> <span class="attr">List</span><span class="kwrd">="113"</span> <span class="attr">Url</span><span class="kwrd">="_catalogs/wp"</span> <span class="attr">Path</span><span class="kwrd">="WebParts"</span> <span class="attr">RootWebOnly</span><span class="kwrd">="True"</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">File</span> <span class="attr">Url</span><span class="kwrd">="CleverWorkAroundsHideFields.webpart"</span> <span class="attr">Type</span><span class="kwrd">="GhostableInLibrary"</span><span class="kwrd">&gt;</span>
      <strong><span class="kwrd">&lt;</span><span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">="Group"</span> <span class="attr">Value</span><span class="kwrd">="CleverWorkArounds"</span> <span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">="Description"</span> <span class="attr">Value</span><span class="kwrd">="Web part to selectively hide columns via JavaScript"</span><span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">="Title"</span> <span class="attr">Value</span><span class="kwrd">="CleverWorkArounds Hide Column Web Part"</span><span class="kwrd">/&gt;</span>
</strong>    <span class="kwrd">&lt;/</span><span class="html">File</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Module</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Elements</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">                  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<h2>Let&#8217;s build it!</h2>
<p>Right! If you have made it this far, then let&#8217;s do a final build using &#8220;DebugBuild&#8221; configuration. If it all compiles, we are ready to test a deployment to our development server.</p>
<p>Now you will get to see why STSDEV is such a damn useful tool. In the drop down window shown below, choose &#8220;DebugDeploy&#8221; as the build option, and then press F6 or build the solution via the &#8220;Build&#8221; menu.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image14.png"><img border="0" width="244" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb14.png" alt="image" height="157" style="border-width: 0px" /></a></p>
<p>Below is the output of the build. Look closely at the annotated output below. The web part has been packaged up into a SharePoint solution, the solution has been added to the SharePoint solution store and then activated for all web applications. (look mum, no hands!)</p>
<p><font size="2" face="Courier New">&#8212;&#8212; Build started: Project: CleverWorkAroundsHideFields, Configuration: DebugDeploy Any CPU &#8212;&#8212;<br />
c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Csc.exe /noconfig /nowarn:1701,1702 /reference:&#8221;C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\Microsoft.SharePoint.dll&#8221; /reference:c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Web.dll /reference:c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /keyfile:KeyFile.snk /out:obj\DebugDeploy\CleverWorkAroundsHideFields.dll </font></p>
<p><font size="2"><strong><em>*** The above output is the command used by Visual Studio to compile the web part DLL.</em></strong></font></p>
<p><font size="2" face="Courier New">Compile complete &#8212; 0 errors, 0 warnings<br />
CleverWorkAroundsHideFields -&gt; C:\VSPROJ\CleverWorkArounds\CleverWorkAroundsHideFields\bin\Debug\CleverWorkAroundsHideFields.dll<br />
Refreshing Deployment Files&#8230;<br />
&#8220;C:\Program Files\Common Files\stsdev.exe&#8221; /refresh CleverWorkAroundsHideFields C:\VSPROJ\CleverWorkArounds\CleverWorkAroundsHideFields\ </font></p>
<p><font size="2" face="ari"><strong><em>*** STSDEV now runs and updates some of the other files in the solution required to deploy this web part (completely hands off for the developer which is great)</em></strong></font></p>
<p><font size="2" face="Courier New">STSDEV &#8211; Simple Tools for SharePoint Developers<br />
Refreshing Solution Package Files<br />
Current Solution Name:<br />
Current Solution Directory:<br />
Refreshing deployment files&#8230;<br />
Rebuilding DeploymentFiles\manifest.xml<br />
Rebuilding DeploymentFiles\SolutionPackage.ddf<br />
Deleting Solution Package File&#8230;<br />
Building Solution Package (Debug Version)<br />
&#8220;C:\Windows\System32\makecab.exe&#8221; /F DeploymentFiles\SolutionPackage.ddf /D CabinetNameTemplate=CleverWorkAroundsHideFields.wsp<br />
Microsoft (R) Cabinet Maker &#8211; Version 5.2.3790.0<br />
Copyright (c) Microsoft Corporation. All rights reserved.. </font></p>
<p><font size="2" face="Courier New">Parsing directives<br />
Parsing directives (DeploymentFiles\SolutionPackage.ddf: 1 lines)<br />
20,812 bytes in 6 files                                         <br />
Executing directives<br />
  0.00% &#8211; manifest.xml (1 of 6)<br />
  0.00% &#8211; CleverWorkAroundsHideFields.dll (2 of 6)<br />
  0.00% &#8211; CleverWorkAroundsHideFields\feature.xml (3 of 6)<br />
  0.00% &#8211; CleverWorkAroundsHideFields\WebParts.xml (4 of 6)<br />
  0.00% &#8211; CleverWorkAroundsHideFields\WebParts\CleverWorkAroundsHideFields.webpart (5 of 6)<br />
  0.00% &#8211; IMAGES\CleverWorkAroundsHideFields\macgyver.jpg (6 of 6)                        <br />
100.00% [flushing current folder]<br />
Total files:              6     <br />
Bytes before:        20,812<br />
Bytes after:          4,955<br />
After/Before:            23.81% compression<br />
Time:                     0.02 seconds ( 0 hr  0 min  0.02 sec)<br />
Throughput:            1354.95 Kb/second<br />
</font></p>
<p><font size="2" face="ari"><strong><em>*** STSDEV now builds the web part and supporting files into a SharePoint solution (WSP) file called CleverWorkAroundsHideFields.wsp</em></strong></font></p>
<p><font size="2" face="Courier New">Installing Solution&#8230;<br />
&#8220;C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\stsadm.exe&#8221; -o addsolution -filename DeploymentFiles\CleverWorkAroundsHideFields.wsp </font></p>
<p><font size="2" face="Courier New">Operation completed successfully. </font></p>
<p><strong><font size="2" face="ari"><em>*** Now we use the SharePoint Admin tool STSADM to add the solution file CleverWorkAroundsHideFields.wsp to the SharePoint solution store. This creates a SharePoint timer job to actually perform this task. </em></font></strong></p>
<p><font size="2" face="Courier New">&#8220;C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\stsadm.exe&#8221; -o execadmsvcjobs </font></p>
<p><font size="2" face="Courier New">Executing .<br />
Operation completed successfully. </font></p>
<p><strong><em><font size="2">*** Now we have forced SharePoint to execute all outstanding timer jobs, thereby forcing the solution to be added to the store</font></em></strong></p>
<p><font size="2" face="Courier New">Deploying Solution&#8230;<br />
&#8220;C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\stsadm.exe&#8221; -o deploysolution -name CleverWorkAroundsHideFields.wsp -immediate -allowgacdeployment -allcontenturls </font></p>
<p><font size="2" face="Courier New">Timer job successfully created. </font></p>
<p><font size="2" face="Courier New">&#8220;C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\stsadm.exe&#8221; -o execadmsvcjobs </font></p>
<p><font size="2" face="Courier New">Executing .<br />
Executing solution-deployment-cleverworkaroundshidefields.wsp-0.<br />
The solution-deployment-cleverworkaroundshidefields.wsp-0 job completed successfully, but could not be properly cleaned up.  This job may execute again on this server.<br />
Operation completed successfully. </font></p>
<p><font size="2"><strong><em>*** These last two steps activated the uploaded solution using STSADM and then once again, executed all outstanding timer jobs. Note that in our example here, the final timer jobs had an error.</em></strong></font></p>
<h2>Verifying Successful Deployment</h2>
<p>We can verify what the above log is telling us by navigating to Solution Management in SharePoint Central Administration. So let&#8217;s take a look! As reported in this log, there was an error. Note the cleverworkaroundshidefields.wsp status in in an &#8220;Error State&#8221;</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image15.png"><img border="0" width="599" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb15.png" alt="image" height="155" style="border-width: 0px" /></a></p>
<h2>Error? Oh no! What to do?</h2>
<p>So for some reason, we have had a deployment error. So let&#8217;s retract this solution from SharePoint and perform an IISReset.</p>
<p>This action can be performed within Visual Studio thanks the the STSDEV functionality. Change the build type to a &#8220;DebugRetract&#8221; and press F6 or perform a build via the &#8220;Build&#8221; menu.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image16.png"><img border="0" width="236" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb16.png" alt="image" height="184" style="border-width: 0px" /></a></p>
<p>This time the log is much simpler, because we are not actually compiling our code this time. Instead, we are running the STSADM commands to retract this problematic solution.</p>
<p><font face="Courier New">&#8212;&#8212; Build started: Project: CleverWorkAroundsHideFields, Configuration: DebugRetract<br />
&#8220;C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\stsadm.exe&#8221; -o retractsolution -name CleverWorkAroundsHideFields.wsp -immediate -allcontenturls </font></p>
<p><font face="Courier New">Timer job successfully created. </font></p>
<p><font face="Courier New">&#8220;C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\stsadm.exe&#8221; -o execadmsvcjobs </font></p>
<p><font face="Courier New">Executing .<br />
Executing solution-deployment-cleverworkaroundshidefields.wsp-0.<br />
Operation completed successfully. </font></p>
<p><font face="Courier New">========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ========== </font></p>
<p>So now I perform an IISReset, and then attempt to redeploy the solution again.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image17.png"><img border="0" width="160" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb17.png" alt="image" height="159" style="border: 0px" /></a></p>
<p>For the sake of readability, I have omitted most of the build log this time.</p>
<p><font face="Courier New">&#8212;&#8212; Build started: Project: CleverWorkAroundsHideFields, Configuration: DebugDeploy</font></p>
<p><font face="Courier New"><strong>[snip lots of log output]</strong></font></p>
<p><font face="Courier New">Executing .<br />
Executing solution-deployment-cleverworkaroundshidefields.wsp-0.<br />
Operation completed successfully. </font></p>
<p><font face="Courier New">Done building project &#8220;CleverWorkAroundsHideFields.csproj&#8221;.<br />
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ========== </font></p>
<p>This time we do not have any warning messages in the Visual Studio build log. So let&#8217;s confirm via SharePoint Central Admin.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image18.png"><img border="0" width="543" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb18.png" alt="image" height="154" style="border-width: 0px" /></a></p>
<p>Great! So now we have successfully deployed the solution, the site collection administrator for this web application can activate the feature</p>
<h2>Governance Interlude</h2>
<p>I think at this time it is very important to reinforce why packaging up code into solutions is such a mandatory governance requirement. In the above example, we had a problem with the deployment of the web part. It may have been an issue with the DLL in the GAC, changes made to web.config files for each web application, or a variety of other reasons. The point is, I was able to <strong>roll back</strong> to a known good state and start over!</p>
<p>I&#8217;ve said it before, but any developer who rolls their eyes at me when I tell them that their work has to be packaged up as a solution, obviously is not serious about governance.</p>
<h2>Activating the Feature</h2>
<p>So, now that our solution has been installed and deployed to each web application, we now have a site collection feature to activate. This feature will copy our web part into the Web Part Gallery for the site collection and thereby make it available for use.</p>
<p>So as a site collection owner, we navigate to &#8220;Site Actions&#8221; and &#8220;Modify All Site Settings&#8221;. Choose the option &#8220;Site Collection Features&#8221;, and you will see the results of our work in all its glory! Wahoo!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image19.png"><img border="0" width="636" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb19.png" alt="image" height="112" style="border: 0px" /></a></p>
<p>So don&#8217;t just sit there! Activate the sucker!</p>
<h2>Testing the new web part</h2>
<p>For this example, I am going to use the same demo site and list that I used in <a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">part 1</a> of this series.</p>
<p>The site is <a href="http://tidemo/tftp">http://tidemo/tftp</a> and the list to try this on is the IT Assets list. I have navigated to the IT Assets list, and opened the entry for the first item in the list (ABCRTR01)</p>
<p>Using the ToolPaneView hack described in <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a>, open DispForm.aspx in page-edit mode as shown below.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image20.png"><img border="0" width="534" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb20.png" alt="image" height="265" style="border-width: 0px" /></a></p>
<p>Click on the Main web part zone and add a new web part. You will see CleverWorkArounds as a web part group, listing our web part. (For reference, Feature.XML is the file where name and description information is set)</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image21.png"><img border="0" width="531" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb21.png" alt="image" height="186" style="border-width: 0px" /></a>&#8216;</p>
<p>Add our web part to the page and then click on &#8220;Modify Shared Web Part&#8221; to being up the properties screen. This is where we get to see if you did all the XML serialisation code from <a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/">Part 4</a> properly!!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image22.png"><img border="0" width="539" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb22.png" alt="image" height="147" style="border-width: 0px" /></a></p>
<p>If you see the screen below, it has all worked a treat! You now have a custom web part property asking you to list the columns to hide. The below-right image shows this web part property filled in with the &#8220;Purchase Date&#8221; and &#8220;IP Address&#8221; columns listed.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image23.png"><img border="0" width="254" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb23.png" alt="image" height="182" style="border: 0px" /></a>   <a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image24.png"><img border="0" width="244" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb24.png" alt="image" height="182" style="border-width: 0px" /></a></p>
<p>Click OK and let&#8217;s see the result! Wohoo! Fields hidden!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image25.png"><img border="0" width="508" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb25.png" alt="image" height="257" style="border: 0px" /></a></p>
<h2>Conclusion</h2>
<p>So, after 5 long winded blog posts, what have we achieved? Going back over the goals they were:</p>
<ul>
<li>Allow hidden fields based on identity/audience</li>
<li>Avoid use of SharePoint Designer</li>
<li>Avoid customisations to the form pages that unghosted the pages from the site definition</li>
<li>Avoid the need for site administrators/designers to have to dabble in javascript code</li>
<li>Packaged up the web part into an easily deployable/retractable solution</li>
</ul>
<p><strong>CleverWorkAround Rating: Awesome!</strong></p>
<p>Phew! Are we done yet? It seems like I have been typing these JavaScript articles for a freakin eternity! Alas no, I&#8217;m *still* not done!</p>
<p>I have an additional enhancement to make to this web part, and I also want to alert to you a couple of issues I had with this whole process.</p>
<p>So a Part 6 is in the works, but for now, I think its time for a well deserved beer! Your shout? <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>regards</p>
<p>Paul</p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>More SharePoint Branding &#8211; Customisation using JavaScript &#8211; Part 4</title>
		<link>http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/</link>
		<comments>http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/#comments</comments>
		<pubDate>Sun, 09 Mar 2008 06:46:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[STSDEV]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Web Parts]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/</guid>
		<description><![CDATA[Hi there. As I write this post, the media are telling me that the stock market is stuffed, the US economy is going to the dogs and banks are writing down billions from sub-prime excess. I dare not check my online broker, road traffic this morning was abysmal, I was late, brought in the wrong [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p><!--adsense--></p>
<p>Hi there. As I write this post, the media are telling me that the stock market is stuffed, the US economy is going to the dogs and banks are writing down billions from sub-prime excess. I dare not check my online broker, road traffic this morning was abysmal, I was late, brought in the wrong laptop and left an important DVD at home.</p>
<p>Could it get any worse? Who knows, but it sounds like the sort of day to re-visit JavaScript and get frustrated with writing a web part for the first time.</p>
<p>So to recap on our journey thus far..</p>
<ul>
<li><a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a> of this series looked at how we can use JavaScript to deal with the common request of hiding form elements from the user in lists and document libraries. It looked at a Microsoft documented method, then a better, more flexible method.</li>
<li><a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a> wrapped this JavaScript code into a web part which has been loaded into the SharePoint web part gallery.</li>
<li><a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a> then examined the trials and tribulations of getting this new web part added to certain SharePoint pages (NewForm.aspx, EditForm.aspx and DispForm.aspx), and then with a few simple edits, use this web part to hide form fields as desired. Finally, I demonstrated the power of combining this with SharePoint Audiences targeting functionality to make the hiding/unhiding of form elements personalised to particular groups of users.</li>
</ul>
<p>All in all a pretty clever workaround so far if I say so myself. <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>My original goals for this JavaScript was to find an effective, easily repeatable way to customise SharePoint form pages by hiding fields or form elements when we need to. Specifically:</p>
<ul>
<li>Allow hidden fields based on identity/audience</li>
<li>Avoid use of SharePoint Designer</li>
<li>Avoid customisations to the form pages that unghosted the pages from the site definition</li>
</ul>
<p>We achieved these goals in part three, but was I satisfied? No. The quest for more clever workarounds always goes on!</p>
<p>[Quick Navigation: <a target="_blank" href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a>, <a target="_blank" href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a>, <a target="_blank" href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a>, <a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/">Part 5</a> and Part 6]</p>
<p><span id="more-668"></span></p>
<p>So the way I am going to structure this post is to pitch it to part-time or junior developers. If you are an experienced software engineer, this article is not going to trouble you.</p>
<p>Coffee rating: <a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img border="0" width="25" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" alt="image" height="25" /></a></p>
<h2>Remaining Issues</h2>
<p>One thing I was unhappy about with the web part in <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">part three</a> was that JavaScript still had to be edited when using the web part on a page. I wanted to take the programming completely out of the equation. Additionally, it was about time I got off my butt and learned to code a web part anyway. I&#8217;d previously blogged about the wonderful STSDEV, and decided I&#8217;d better put my money where my mouth and actually use it before I start mandating that others do.</p>
<p>So the first part of this post is examining STSDEV, and the joyous fun I had with my first ever web part with it, then I will get onto the first part of the coding.</p>
<h2>The Web Part Requirements</h2>
<p>So what are we planning to do here? Basically it is pretty simple. The JavaScript code that hides the columns from a page looks like this.</p>
<p><img src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image67.png" /></p>
<p>If you look closely at the above example, you will see that we have two lines that are repeated for every field we wish to hide.</p>
<pre class="csharpcode">control = findacontrol(“Device Type”);
control.parentNode.parentNode.style.display=“none”;</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>So, how about we make a web part that accepts a custom property that allows the user to list all of the fields to be hidden, and the web part can generate the complete JavaScript code for each of them to be hidden from view. This screen-shot shows the basic idea.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image.png"><img border="0" width="239" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb.png" alt="image" height="170" style="border-width: 0px" /></a></p>
<p>Note that we have listed three columns in the web part properties separated by a comma. Thus the page containing this web part would hide the existence of any of these columns.</p>
<h2>Enter STSDEV (Take 1)</h2>
<p>So first up, I grabbed STSDEV from its <a href="http://www.codeplex.com/stsdev">codeplex home</a>. I installed it and ran the EXE to receive the initial screen.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image1.png"><img border="0" width="512" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb1.png" alt="image" height="248" style="border-width: 0px" /></a> </p>
<p>On my first attempt, I created the solution in my default visual studio projects folder (C:\Documents and Settings\Paul\My Documents\Visual Studio 2005\Projects\CleverWorkarounds)</p>
<p>STSDEV happily accepted this and created my solution, which I opened with Visual Studio 2005 and accepted the obligatory warning as shown. But that&#8217;s cool &#8211; we trust those nice STSDEV guys! <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image2.png"><img border="0" width="423" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb2.png" alt="image" height="299" style="border-width: 0px" /></a> <a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image3.png"><img border="0" width="209" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb3.png" alt="image" height="300" style="border-width: 0px" /></a></p>
<p>I won&#8217;t spend too much time going into the solution created for the web part project because you can watch the <a href="http://www.codeplex.com/stsdev/Release/ProjectReleases.aspx?ReleaseId=10119">videos</a> that explain it much better anyway. But I will draw your attention to the fact that two sample web parts are included in the solution, CustomWebpart1.cs and CustomWebpart2.cs. We will rename and modify these later but first I need you to be aware of one &#8216;gotcha&#8217; that I encountered.</p>
<p>In Visual Studio try and compile this project as it is. Make sure that the build type is set to DebugBuild and press F6 or choose &#8220;Build Solution&#8221; from the &#8220;Build&#8221; menu. Uh-oh, I got a runtime error with STSDEV&#8230; Bummer</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image4.png"><img border="0" width="559" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb4.png" alt="image" height="367" style="border-width: 0px" /></a></p>
<p>This had me going for a while, because at first I had made changes to the solution before I attempted a build. So I spent some time thinking it was my changes that were the root of the issue. All it turned out to be was the spaces in the path to my project.</p>
<p><strong>C:\Documents^ ^and^ ^Settings\Paul\My^ ^Documents\Visual^ ^Studio^ ^2005\Projects\CleverWorkarounds</strong></p>
<h2>Enter STSDEV (Take 2)</h2>
<p>This time, I&#8217;ve created the project with the parent directory parameter being a path with no spaces&#8230;</p>
<p><strong>C:\VSPROJ\CleverWorkarounds</strong></p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image5.png"><img border="0" width="577" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb5.png" alt="image" height="231" style="border-width: 0px" /></a></p>
<p>Follow all the steps as per take 1 and try and compile the solution. Good &#8211; no nasty runtime burps this time.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image6.png"><img border="0" width="453" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb6.png" alt="image" height="215" style="border-width: 0px" /></a></p>
<h2>Customising the Solution</h2>
<p>So we have to now take this generic visual studio solution and make our changes. This consists of deleting stuff that we don&#8217;t need, renaming our class and updating references to the class name. Later we will customise the build/deploy process too. If you have experience with STSDEV or this seems too straightforward for me to blog about, then skip to the next section, otherwise read on for more detail of my specific example.</p>
<p>The first step is to customise our generic web part solution to our needs. We will delete CustomWebPart2.cs and rename CustomWebPart1.cs to CleverWorkaroundsHideFields.cs. When you perform the rename, you will ask if you want all project references to be renamed also. Makes sense doesn&#8217;t it?</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image7.png"><img border="0" width="564" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb7.png" alt="image" height="95" style="border-width: 0px" /></a></p>
<p>This dialog box should not be interpreted as modifying any hardcoded references to the old file name of CustomWebPart1.cs. You will still have to do some search/replace work.</p>
<p>Additionally, there are two .webpart files that go with the two default class files and you have to rename/delete these as well. They can be found in the solution under RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\WebParts.</p>
<p>Delete CustomWebPart2.webpart and rename CustomWebpart1.webpart to CleverWorkAroundsHideFields.webpart.</p>
<p>Below is the result of both changes (.cs files and .webpart files)</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image8.png"><img border="0" width="380" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb8.png" alt="image" height="302" style="border-width: 0px" /></a></p>
<p>Okay, so now this solution comes with xml files, solution files and all the other paraphernalia associated with getting a web part bundled up and installed to a farm. Now we have to delete all references to the deleted web part called CustomWebPart2 and update the references to CustomWebPart1 to CleverWorkAroundsHideFields.</p>
<p>Using the FIND/REPLACE tool, the entire project can be adjusted very quickly</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image9.png"><img border="0" width="216" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb9.png" alt="image" height="244" style="border-width: 0px" /></a></p>
<p>The above operation takes care of the renaming of CustomWebPart1 in one single operation. But with CustomWebPart2 we are deleting references, so it takes a little finer surgery.</p>
<p>Here are the results of the *find* for CustomWebPart2.webpart</p>
<pre class="csharpcode">Find all <span class="str">"CustomWebpart2"</span>, Subfolders, Find Results 1, <span class="str">"Entire Solution"</span>
DeploymentFiles\SolutionPackage.ddf(25):RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\WebParts\CustomWebPart2.webpart
RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\feature.xml(17):      Location=<span class="str">"WebParts\CustomWebPart2.webpart"</span> /&gt;
RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\WebParts.xml(8):    &lt;File Url=<span class="str">"CustomWebPart2.webpart"</span> Type=<span class="str">"GhostableInLibrary"</span>&gt;
Matching lines: 3    Matching files: 3    Total files searched: 9</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>You will find references to CustomWebPart2 in</p>
<ul>
<li>SolutionPackage.ddf under DeploymentFiles</li>
<li>feature.xml under RootFiles\TEMPLATE\FEATUTES\CleverWorkAroundsHideFields</li>
<li>WebParts.xml under RootFiles\TEMPLATE\FEATUTES\CleverWorkAroundsHideFields</li>
</ul>
<p>Using visual studio, open up each of these files and adjust the references. So for example in SolutionPackage.ddf I changed from:</p>
<p><font face="Courier New">;*** add files for CleverWorkAroundsHideFields\WebParts feature<br />
.Set DestinationDir=CleverWorkAroundsHideFields\WebParts<br />
RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\WebParts\CleverWorkAroundsHideFields.webpart<br />
RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\WebParts\CustomWebPart2.webpart</font></p>
<p>to</p>
<p><font face="Courier New">;*** add files for CleverWorkAroundsHideFields\WebParts feature<br />
.Set DestinationDir=CleverWorkAroundsHideFields\WebParts<br />
RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\WebParts\CleverWorkAroundsHideFields.webpart<br />
</font></p>
<p><em>Now if you are thinking to yourself, what is FEATURE.XML and Solutionpackage.DDF anyway? Then I am afraid that you have some homework to do! If you are going to code anything for SharePoint, you need to understand the concepts of </em><a href="http://www.cleverworkarounds.com/2007/10/08/a-simple-example-of-a-sharepoint-%e2%80%9cfeature%e2%80%9d/"><em>features</em></a><em> and how they are used with the </em><a href="http://www.cleverworkarounds.com/2007/11/10/sharepoint-branding-part-6-a-solution-to-all-issues/"><em>solution framework</em></a><em>. Seriously, if you are blindly editing the files using this post as a guide, then you are only going to get yourself into trouble later.</em></p>
<p>For the rest of you, finish off the renames and removals of the default class names and then try and rebuild the solution. If it all builds, you can move onto the next step of actual coding the thing.Once we finish coding, you will see pretty quickly how useful and time saving STSDEV really is.</p>
<h2>Coding the Web Part &#8211; Part 1</h2>
<p>So, now we open up CleverWorkAroundsHideFields.cs and add our code. The first step is to add references to additional libraries that this web part will use.</p>
<pre class="csharpcode"><span class="kwrd">using</span> System.ComponentModel;
<span class="kwrd">using</span> System.Xml.Serialization;</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>What are these and what do they do? Without going into loving detail, these namespaces allow you to use <strong>XML serialisation</strong>. I had not previously coded much ASP.NET stuff, so XML serialisation took me a little getting used to. But the basic idea is this.</p>
<h2>XML Serialisation Interlude</h2>
<p>If you have an object instantiated from a class, with a bunch of properties set to different values, how to you send those properties to another remote object of the same class? What if it is two separate web server or web applications?</p>
<p>XML serialisation allows you to set properties for the object that are then stored behind the scenes as XML (this is the serialisation part). The other end gets the XML (over HTTP) and deserialises it back to the native properties for the destination object. Lo and behold, we have copied the state of one object to another object.</p>
<p>Now think of the code that this saves when the other end simply has to call a deserialise method and all of the properties of the object are auto-magically filled in.</p>
<p>Now in SharePoint, web part properties have to be persisted. When you visit a page, the look and feel of the web part is determined partly by web part properties set by the site designer. Those settings are retrieved from the SharePoint database. So when those properties are first set by the administrator (i.e change the title or appearance of a web part), SharePoint <strong>serialises</strong> all of those properties to XML and that XML is stored into the database. When the page is then later loaded by a user, a web part object is created, and then the XML properties are <strong>deserialised</strong> back to the object properties so it can appear how it is supposed to.</p>
<p>Make sense? <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  I hope so because that&#8217;s all I&#8217;m saying about it! If you are still cofused, try <a href="http://www.devarticles.com/c/a/ASP.NET/XML-Serialization-in-ASP.NET/">this article</a>.</p>
<h2>Coding the Web Part &#8211; Part 2</h2>
<p>So having added the two references to the XML Serialaisation and System.ComponentModel namespace, you should have the following code.</p>
<pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Web;
<span class="kwrd">using</span> System.Web.UI;
<span class="kwrd">using</span> System.Web.UI.WebControls;
<span class="kwrd">using</span> System.Web.UI.WebControls.WebParts;
<span class="kwrd">using</span> System.Xml.Serialization;
<span class="kwrd">using</span> System.ComponentModel;</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>Make sure that there is no reference to a namespace called Microsoft.SharePoint.WebPartPages. There are actually two different web part classes available, one designed for SharePoint 2003 and the more recent one being part of ASP.NET version 2. (System.Web.UI.WebControls.Webparts).</p>
<p><em>MSDN and Microsoft code samples have a lot to answer for here! Most code samples for web parts with custom properties are based on the legacy web part class, and things have changed between old and new, especially when it comes to XML serialised properties. I wasted a lot of time here because of this!</em></p>
<p>The next step is to delete the default code in the web part class. Find the following code and delete it.</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> CreateChildControls() {
  Label lblHello = <span class="kwrd">new</span> Label();
  lblHello.Text = <span class="str">"Hello"</span>;
  Controls.Add(lblHello);
}</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>Serialsed XML parameters are in square brackets around sections of c# code. These are .NET attributes and tell the XML serializer where the various members of this object will appear in the XML and what they will be named. Without these, serialization cannot take place.</p>
<p>So the first serialised parameter is defined in between the namespace and the class itself.</p>
<pre class="csharpcode"><span class="kwrd">namespace</span> CleverWorkAroundsHideFields {
   [XmlRoot(Namespace = <span class="str">"CleverWorkAroundsHideFields"</span>)]
   <span class="kwrd">public</span> <span class="kwrd">class</span> CleverWorkAroundsHideFields : WebPart {
   }
}</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>Now if we serialised the code into XML now it would look like this</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">CleverWorkAroundsHideFields</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">CleverWorkAroundsHideFields</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>Exciting eh? So let&#8217;s now add some web part properties and serialise them as well. First up the properties of this class. If you check the section of this post titled &#8220;Web part Requirements&#8221;, I stated that the web part should accept a custom property that allows the user to list all of the fields to be hidden. So below is the property that will store this list of fields. It is about as simple as a class property can be (just store a string with a get and set method).</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">string</span> _HideFieldList; 

<span class="kwrd">public</span> <span class="kwrd">string</span> HideFieldList
{
   get
   {
      <span class="kwrd">return</span> _HideFieldList;
   }
   set
   {
      _HideFieldList = <span class="kwrd">value</span>;
   }
}</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>Now I need to add the parameters for XML serialsation. The above raw C# code above now changes to:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> CleverWorkAroundsHideFields : WebPart { 

   <span class="kwrd">private</span> <span class="kwrd">string</span> _HideFieldList; 

   <span class="rem">// Create a custom category in the property sheet.</span>
   [Category(<span class="str">"Custom Properties"</span>)]
   [Personalizable(PersonalizationScope.Shared)]
   [WebDisplayName(<span class="str">"List of columns to hide on this page"</span>)]
   [WebDescription(<span class="str">"Comma delimited list of columns to hide on this page"</span>)]
   [WebBrowsable(<span class="kwrd">true</span>)]
   [XmlElement(ElementName = <span class="str">"HideFieldList"</span>)] 

   <span class="kwrd">public</span> <span class="kwrd">string</span> HideFieldList
   {
      get
      {
         <span class="kwrd">return</span> _HideFieldList;
      }
      set
      {
         _HideFieldList = <span class="kwrd">value</span>;
      }
   }
}</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>I haven&#8217;t serialised this into XML, but you can see how all of the properties in square brackets would form an XML document describing the properties. if I did, it would look something akin to:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">CleverWorkAroundsHideFields</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">Category</span><span class="kwrd">&gt;</span>Custom Properties<span class="kwrd">&lt;/</span><span class="html">Category</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">WebDisplayName</span><span class="kwrd">&gt;</span>List of columns to hide on this page<span class="kwrd">&lt;/</span><span class="html">WebDisplayName</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">WebDescription</span><span class="kwrd">&gt;</span>Comma delimited list of columns to hide on this page<span class="kwrd">&lt;/</span><span class="html">WebDescription</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">WebBrowsable</span><span class="kwrd">&gt;</span>True<span class="kwrd">&lt;/</span><span class="html">WebBrowsable</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">XmlElement</span> <span class="attr">ElementName</span><span class="kwrd">="HideFieldList"</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">CleverWorkAroundsHideFields</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>So now SharePoint has this in its database. When this webpart is rendered, the XML similar to above is retrieved and deserialised back to our WebPart class.</p>
<p><em>At this point it is a good idea to build the solution to ensure that you have no syntax errors or namespace issues. If you have trouble getting to this point, its best you not go any further until the project builds correctly.</em></p>
<p>Now where did I get these XML parameter values from? Go to the <a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.webparts.aspx">MSDN documentation</a> for the System.Web.UI.WebControls.WebParts namespace and you will find all of the available properties buried there. (Either that or cheat like me and find out via <a href="http://dkeeling.spaces.live.com/blog/cns!1FF0B17B869C973!158.entry">here</a>)</p>
<h2>Coding the Web Part &#8211; Part 3</h2>
<p>So now let&#8217;s write the code to render the JavaScript output. This is basically C# code to create the JavaScript that will render in the browser. The code is simple enough, we have looked at it in the last posts. But creating the JavaScript inside C# code makes it look worse than it really is.</p>
<p>First up, we need a new array variable called _fieldlist to store the individual fields (remember they come as a comma delimited list so we will split them to their individual names).</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">string</span>[] _fieldlist;</pre>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Render(HtmlTextWriter output)
{   <span class="rem">// Now lets extract the list of fields from the web part properties</span>
   <span class="kwrd">if</span> (HideFieldList != <span class="kwrd">null</span>)
   {
      _fieldlist = HideFieldList.Split(<span class="str">','</span>);
      <span class="rem">// javascript inside C# - ugh    </span>
      <span class="rem">// I know this looks ugly on account of the escaped quotes.    </span>
      <span class="rem">// First section is the findacontrol function</span>
      output.WriteLine();
      output.WriteLine(<span class="str">@"&lt;script language="</span><span class="str">"javascript"</span><span class="str">" type="</span><span class="str">"text/javascript"</span><span class="str">"&gt;  "</span>);
      output.WriteLine();
      output.WriteLine(<span class="str">@"_spBodyOnLoadFunctionNames.push("</span><span class="str">"hideFields"</span><span class="str">")  "</span>);
      output.WriteLine(<span class="str">@"function findacontrol(FieldName) {  "</span>);
      output.WriteLine(<span class="str">@"var arr = document.getElementsByTagName("</span><span class="str">"!"</span><span class="str">");  //get all comments "</span>);
      output.WriteLine(<span class="str">@"for (var i=0;i &lt; arr.length; i++ ) {   "</span>);
      output.WriteLine(<span class="str">@"   // now match the field name  "</span>);
      output.WriteLine(<span class="str">@"   if (arr[i].innerHTML.indexOf(FieldName) &gt; 0) { "</span>);
      output.WriteLine(<span class="str">@"      return arr[i]; "</span>);
      output.WriteLine(<span class="str">@"   } "</span>);
      output.WriteLine(<span class="str">@"  } "</span>);
      output.WriteLine(<span class="str">@"}"</span>);
      output.WriteLine();
      output.WriteLine();
      <span class="rem">// Now the hidefields function, which loops for each field to be hidden</span>
      output.WriteLine(<span class="str">"function hideFields() { "</span>);
      output.WriteLine(<span class="str">"   var control; "</span>);
      <span class="kwrd">if</span> (_fieldlist != <span class="kwrd">null</span>)
      {
         <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; _fieldlist.Length; i++)
         {
            output.Write(<span class="str">"    control = findacontrol(\""</span>);
            output.Write(_fieldlist[i]);
            output.WriteLine(<span class="str">"\" ); "</span>);
            output.WriteLine(<span class="str">"   control.parentNode.parentNode.style.display=\"none\""</span>);
         }
      }
      output.WriteLine(<span class="str">" }"</span>);         output.WriteLine(<span class="str">"&lt;/script&gt;"</span>);
   } <span class="rem">// if</span>
} <span class="rem">// method</span></pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>The only section of code above that is of real interest is in the JavaScript hideFields() function. Here we loop for each field supplied in the list, and construct the code. So for example, if HideFieldList contained &#8220;Column A,Column B&#8221;, the generated JavaScript code would be:</p>
<pre class="csharpcode">control = findacontrol(<span class="str">"Column A"</span>);
control.parentNode.parentNode.style.display=<span class="str">"none"</span>
control = findacontrol(<span class="str">"Column B"</span>);
control.parentNode.parentNode.style.display=<span class="str">"none"</span></pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p><em>Please be careful cutting and pasting this code! Quotes seem to get screwed up sometimes.</em></p>
<h2>Conclusion (let&#8217;s have a break)</h2>
<p>Once again, this post is starting to get a little long. So I&#8217;ll stop now and let you have a breather. In part 5 of this series, we will do an initial build of this solution, which will demonstrate how useful STSDEV is at speedy packaging and deployment. I&#8217;ll show you how to package up a nice, re-usable solution, and be able to test and debug quickly and painlessly.</p>
<p>Until then, bye for now</p>
<p>Paul<br />
<!--adsense--></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>More SharePoint Branding &#8211; Customisation using JavaScript Part 3</title>
		<link>http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/</link>
		<comments>http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/#comments</comments>
		<pubDate>Thu, 28 Feb 2008 12:56:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Web Parts]]></category>
		<category><![CDATA[master pages]]></category>
		<category><![CDATA[page layouts]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/</guid>
		<description><![CDATA[Hey there. Welcome to part 3 of my series on SharePoint customisation using JavaScript and web parts. So here is the lowdown so far. We are trying to find an effective, repeatable way to easily customise SharePoint form pages, so that we can hide fields or form elements when we need to. The goals were [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p><!--adsense--><br />
Hey there. Welcome to part 3 of my series on SharePoint customisation using JavaScript and web parts.</p>
<p>So here is the lowdown so far. We are trying to find an effective, repeatable way to easily customise SharePoint form pages, so that we can hide fields or form elements when we need to. The goals were to:</p>
<ul>
<li>Allow hidden fields based on identity</li>
<li>Avoid use of SharePoint Designer</li>
<li>Avoid customisations to the form pages that unghosted the pages from the site definition</li>
</ul>
<p>So how have we progressed thus far?.</p>
<ul>
<li><a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a> of this series looked at how we can use JavaScript to deal with the common request of hiding form elements from the user in lists and document libraries.</li>
<li><a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a> wrapped this JavaScript code into a web part which has been loaded into the SharePoint web part gallery.</li>
</ul>
<p>So let&#8217;s knock the rest of this over and pick up right from we left off&#8230;</p>
<p>CleverWorkArounds Coffee requirement of this post depends on how much you hate JavaScript.</p>
<p>Metrosexual web developer    <a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img border="0" width="25" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" alt="image" height="25" /></a></p>
<p>Socially inept technical guy    <a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img border="0" width="25" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" alt="image" height="25" /></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img border="0" width="25" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" alt="image" height="25" /></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img border="0" width="25" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" alt="image" height="25" /></a></p>
<p>[Quick Navigation: <a target="_blank" href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a>, <a target="_blank" href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a>, <a target="_blank" href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/">Part 4</a>, Part 5 and Part 6]</p>
<p><span id="more-646"></span></p>
<p><em>Looking for step 1 and 2? Go to the <a target="_blank" href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">previous</a> post</em></p>
<h2>Step 3. Adding the web part to content pages</h2>
<p>So now we hit the supposedly simple step of adding our new web part to our display and edit forms for a list. The image below shows the page that I want to modify. In this example, it is DispForm.aspx</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image59.png"><img border="0" width="644" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb50.png" alt="image" height="345" style="border-width: 0px" /></a></p>
<p>So it should be easy right? Just go to Site Actions menu and choose &#8220;Edit Page&#8221;.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image60.png"><img border="0" width="286" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb51.png" alt="image" height="125" style="border-width: 0px" /></a></p>
<p>Uh&#8230; hang on what&#8217;s going on here then. Where&#8217;s my damn &#8220;Edit Page&#8221; option?</p>
<p>Your first reaction is to probably say something like &#8220;<em>okay so that sucks, how are we supposed drop a web part onto this page</em>?&#8221;. To be honest with you, I&#8217;m still not sure why they did it in MOSS 2007, but when you think it through, I can sort of see the SharePoint team&#8217;s <a href="http://www.bluedoglimited.com/SharePointThoughts/ViewPost.aspx?ID=176">reasoning</a>. These pages are auto generated and each time you add a column to a list or library, the NewForm.aspx, Editform.Aspx and Dispform.aspx are modified. The more you customise these pages, the more you risk breaking something important. Plenty of people have posted on how much of a <a href="http://www.sharepointblogs.com/dwise/archive/2007/11/14/lesson-learned-while-customizing-newform-aspx.aspx">problem</a> this can be.</p>
<p>But by the same token, most of the posts I have read on customising pages like NewForm.aspx and EditForm.aspx involve making changes that requires an unghosted page, that is now different to the original site definition. Thus, why bother removing the ability to add a web part via the SharePoint browser based editor? At least doing it via the browser and web parts does <strong>not</strong> modify the page from the site definition. Seems silly not to allow browser based editing and then force people do make modifications in SharePoint Designer, likely as an unghosted page anyway.</p>
<p>Well, I can speculate all day, but lets get on with getting around this problem.</p>
<h2>Workaround 1: Hacking the menu item code</h2>
<p>The first technique that I first <a href="http://cakriwut.wordpress.com/2007/11/03/how-to-enable-edit-page-in-sharepoints-standard-formaspx/">used</a> to my &#8220;Edit Page&#8221; back involved using SharePoint Designer to customise the page. By default, the code to generate the &#8220;Site Actions&#8221; menu is actually defined on the <strong>master page</strong>, not the current page. However, you can override this behaviour in SharePoint designer by opening the page, clicking on the Site Actions menu and choosing &#8220;Create Custom Content&#8221; as shown below.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image61.png"><img border="0" width="624" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb52.png" alt="image" height="317" style="border-width: 0px" /></a></p>
<p>This will copy the code from the master page to this page, allowing you to customise it. The entire top navigation bar is now modifiable, but we are only interested in the code that controls the Site Actions Menu and specifically the menu that handles the &#8220;Edit Page&#8221; option.</p>
<p>You will find it easily enough in code view.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">SharePoint:MenuItemTemplate</span>
   <span class="attr">runat</span><span class="kwrd">="server"</span>
   <span class="attr">id</span><span class="kwrd">="MenuItem_EditPage"</span>
   <span class="attr">Text</span><span class="kwrd">="&lt;%$Resources:wss,siteactions_editpage%&gt;"</span>
   <span class="attr">Description</span><span class="kwrd">="&lt;%$Resources:wss,siteactions_editpagedescription%&gt;"</span>
   <span class="attr">ImageUrl</span><span class="kwrd">="/_layouts/images/ActionsEditPage.gif"</span>
   <span class="attr">MenuGroupId</span><span class="kwrd">="100"</span>
   <span class="attr">Sequence</span><span class="kwrd">="200"</span>
   <span class="attr">ClientOnClickNavigateUrl</span><span class="kwrd">="javascript:MSOLayout_ChangeLayoutMode(false);"</span>
<span class="kwrd">/&gt;</span></pre>
<style type="text/css">    .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>All you have to do for this hack is to change the ID attribute of the SharePoint:MenuItemTemplate control to a different name. (Line 3 below).</p>
<pre><span class="lnum">   1:  </span><span class="kwrd">&lt;</span><span class="html">SharePoint:MenuItemTemplate</span></pre>
<pre><span class="lnum">   2:  </span>   <span class="attr">runat</span><span class="kwrd">="server"</span></pre>
<pre><span class="lnum">   3:  </span>   <strong><span class="attr">id</span><span class="kwrd">="MenuItem_EditPage1"</span></strong></pre>
<pre><span class="lnum">   4:  </span>   <span class="attr">Text</span><span class="kwrd">="&lt;%$Resources:wss,siteactions_editpage%&gt;"</span></pre>
<pre><span class="lnum">   5:  </span> </pre>
<pre><span class="lnum">   6:  </span><span class="kwrd">/&gt;</span></pre>
<style type="text/css">    .csharpcode, .csharpcode pre  {  font-size: small;  color: black;  font-family: consolas, "Courier New", courier, monospace;  background-color: #ffffff;  /*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt  {  background-color: #f4f4f4;  width: 100%;  margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>Save this page and refresh the page in your browser. You find the &#8220;Edit Page&#8221; menu back again! Now we can add the web part in (as described in the following section entitled &#8220;Final configuration of our web part&#8221;). Once the web part has been added in, we can happily undo/remove this hack.</p>
<p>So, is this a good workaround? I actually don&#8217;t think so. The main problem I have with this method is the customisation of the page from the site definition. If you recall at the start of this post I talked about not wanting to use SharePoint Designer and more importantly, not wanting to modify pages from the site definition wherever possible.</p>
<p><strong>CleverWorkAround Rating: Okay, but not that clever</strong></p>
<h2>Workaround 2: The ToolPaneView hack</h2>
<p>This next workaround is great, because it can be done in the web browser and requires no SharePoint designer. It is exceedingly simple. For any web part page, simply append the following text to the URL:</p>
<p>&amp;ToolPaneView=2</p>
<p>Thus, if my original URL was:</p>
<p>http://tidemo/tftp/Lists/IT%20Assets/DispForm.aspx?ID=2&amp;Source=http%3a%2f%2ftidemo%2ftftp%2fLists%2fIT%2520Assets%2fAllItems.aspx&amp;PageView=Shared</p>
<p>Then my new URL is:</p>
<p>http://tidemo/tftp/Lists/IT%20Assets/DispForm.aspx?ID=2&amp;Source=http%3a%2f%2ftidemo%2ftftp%2fLists%2fIT%2520Assets%2fAllItems.aspx&amp;PageView=Shared<strong>&amp;ToolPaneView=2</strong></p>
<p>Below is a screen capture of the effect. If you look carefully you see two things have happened. The page is now in Edit Mode and the &#8220;Add Web parts&#8221; window is displayed. Since we are in edit mode, we can click any web part zone and add our web part!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image62.png"><img border="0" width="644" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb53.png" alt="image" height="281" style="border-width: 0px" /></a></p>
<p>This time around, there is no SharePoint Designer used and no customisations to the page that require unghosting from the site definition.</p>
<p><strong>CleverWorkAround Rating: My kind of hack! </strong></p>
<h2>Final configuration of our web part</h2>
<p>So, we click to add a new web part to our form page (in this case DispForm.aspx). You see that the web part is listed in its own category below &#8220;CleverWorkArounds&#8221;. This is because when I uploaded the web part to the gallery, I specified the group. (I covered this back in the section &#8220;<a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Step 2:</a> Export the Web Part&#8221; )</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image63.png"><img border="0" width="330" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb54.png" alt="image" height="160" style="border-width: 0px" /></a></p>
<p>Below is a screen capture showing DispForm.aspx page with our custom web part.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image64.png"><img border="0" width="644" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb55.png" alt="image" height="278" style="border-width: 0px" /></a></p>
<p>Now although the JavaScript is loaded, we commented out some code to make the web part re-usable. Now it&#8217;s time to uncomment the code and modify it slightly. Click on the edit drop down menu on the &#8220;CleverWorkArounds Hide Field&#8221; web part and choose &#8220;Modify Shared Web part&#8221;</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image65.png"><img border="0" width="477" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb56.png" alt="image" height="144" style="border-width: 0px" /></a></p>
<p>Choose &#8220;Source Editor&#8221; from the web part properties and find the commented code.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image66.png"><img border="0" width="494" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb57.png" alt="image" height="192" style="border-width: 0px" /></a></p>
<p>Note I have now uncommented the some code from the hideFields function and specified the column to hide. So the code has changed from:</p>
<pre class="csharpcode"><span class="kwrd">function</span> hideFields() {
   <span class="rem">// debugger;</span>
   <span class="kwrd">var</span> control;
   <span class="rem">// Add a line for each control to be hidden</span>
   <span class="rem">//control = findacontrol("Column Name");</span>
   <span class="rem">//control.parentNode.parentNode.style.display="none";</span>
}</pre>
<style type="text/css">    .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<style type="text/css">    .csharpcode, .csharpcode pre  {  font-size: small;  color: black;  font-family: consolas, "Courier New", courier, monospace;  background-color: #ffffff;  /*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt  {  background-color: #f4f4f4;  width: 100%;  margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>to</p>
<pre class="csharpcode"><span class="kwrd">function</span> hideFields() {
   <span class="rem">// debugger;</span>
   <span class="kwrd">var</span> control;
   <span class="rem">// Add a line for each control to be hidden</span>
   control = findacontrol(<span class="str">"Device Type"</span>);
   control.parentNode.parentNode.style.display=<span class="str">"none"</span>;
}</pre>
<p>Click Save and OK and the effect is immediate, because the page refreshes and the JavaScript will be executed even in page edit mode. (Thus testing and debugging is also easy too).</p>
<p>Below is a version of code that hides two fields.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image67.png"><img border="0" width="501" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb58.png" alt="image" height="174" style="border-width: 0px" /></a></p>
<p>Below is the result. Now if you look carefully you can see I have hidden both the &#8220;Purchase Date&#8221; and &#8220;Device Type&#8221; fields and they are accordingly not displayed.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image68.png"><img border="0" width="644" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb59.png" alt="image" height="317" style="border-width: 0px" /></a></p>
<p>WOHOO! Is this clever yet? It has achieved the goal of re-use, as well as eliminating the need for SharePoint Designer, as well as any page customisation that requires unghosting &#8211; all a good thing. But what about personalisation?</p>
<h2>This time its personal!</h2>
<p>Back in part 2 I mentioned that a key requirement is to be able to conditionally hide fields from display. Well, now that this is a web part we can via audiences! Back in the properties of our web part, we have the ability to control when this web part is displayed. In the example below, I have configured this web part to only display when a member of &#8220;TIDEMO VISITORS&#8221; or &#8220;TIDEMO MEMBERS&#8221; is visiting the site.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image69.png"><img border="0" width="188" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb60.png" alt="image" height="343" style="border-width: 0px" /></a></p>
<p>So now when we refresh the page as the site owner, we can see that the JavaScript has not been rendered. &#8220;Purchase Date&#8221; and &#8220;Device Type&#8221; columns are now visible.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image71.png"><img border="0" width="644" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb61.png" alt="image" height="298" style="border-width: 0px" /></a></p>
<p>However if I log on as a site member, &#8220;Terrie&#8221;, the situation is different and the columns are hidden from view. How good is that!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image72.png"><img border="0" width="644" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb62.png" alt="image" height="283" style="border-width: 0px" /></a></p>
<p>So, re-examining our original goals, we have met all of them except the issue of security. As mentioned at the start of part 2, this technique is useful and effective for internal collaboration, but most definitely not recommended for external collaboration.</p>
<p>CleverWorkAround Rating &#8211; Pretty darn clever if you discount security</p>
<h2>Summing Up</h2>
<p>There are two things still bugging me about this whole thing. The first one is that code still has to be edited. Each time you drop this web part onto the form, you need to open its properties and modify the base code to specify the columns to hide. So I am thinking that part 4 of this series will be a first for me. I&#8217;ll code a custom web part that accepts the list of fields to hide as a comma delimited string, supplied via a web part property.</p>
<p>Below is a mockup of the idea</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image73.png"><img border="0" width="207" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb63.png" alt="image" height="202" style="border-width: 0px" /></a></p>
<p>Now I haven&#8217;t actually done this yet, so I might be setting myself up for a big fall, but I figure that I will give STSDEV a go and see what happens.</p>
<p>The other annoyance is the whole reliance on client-side processing. Ideally an ASP.NET server side control could hide fields before they are rendered to the client. I&#8217;ve spoken to some ASP.NET developer friends of mine about that, and it seems doable. I&#8217;ll report about this in part 4 too.</p>
<p>regards</p>
<p>Paul<!--adsense--></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>More SharePoint Branding &#8211; Customisation using JavaScript Part 2</title>
		<link>http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/</link>
		<comments>http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/#comments</comments>
		<pubDate>Thu, 28 Feb 2008 12:11:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[Governance]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Web Parts]]></category>
		<category><![CDATA[master pages]]></category>
		<category><![CDATA[page layouts]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/</guid>
		<description><![CDATA[Hi again. JavaScript sucks! There I said it. Despite me hating it as a programming language, I can&#8217;t deny that in SharePoint, it does have its uses. CleverWorkArounds Coffee requirement of this post depends on how much you hate JavaScript. Metrosexual web developer&#160;&#160;&#160; Socially inept technical guy&#160;&#160;&#160; Luddite IT manager&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;(sorry &#8230; why are you [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p>Hi again.</p>
<p>JavaScript sucks! There I said it. Despite me hating it as a programming language, I can&#8217;t deny that in SharePoint, it does have its uses.</p>
<p>CleverWorkArounds Coffee requirement of this post depends on how much you hate JavaScript.</p>
<table cellspacing="0" cellpadding="2" width="521" border="0">
<tbody>
<tr>
<td valign="top" width="203">Metrosexual web developer&nbsp;&nbsp;&nbsp; </td>
<td valign="top" width="316"><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img height="25" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" width="25" border="0"/></a></td>
</tr>
<tr>
<td valign="top" width="204">Socially inept technical guy&nbsp;&nbsp;&nbsp; </td>
<td valign="top" width="315"><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img height="25" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" width="25" border="0"/></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img height="25" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" width="25" border="0"/></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img height="25" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" width="25" border="0"/></a></td>
</tr>
<tr>
<td valign="top" width="205">Luddite IT manager&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </td>
<td valign="top" width="314"><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img height="25" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" width="25" border="0"/></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img height="25" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" width="25" border="0"/></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img height="25" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" width="25" border="0"/></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img height="25" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" width="25" border="0"/></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img height="25" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" width="25" border="0"/></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img height="25" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" width="25" border="0"/></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img height="25" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" width="25" border="0"/></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img height="25" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" width="25" border="0"/></a><img height="25" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" width="25" border="0"/>&nbsp;<br />(sorry &#8230; why are you here anyway?)</td>
</tr>
</tbody>
</table>
<p>[Quick Navigation: <a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/" target="_blank">Part 1</a>, <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/" target="_blank">Part 3</a>, <a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/" target="_blank">Part 4</a>, Part 5 and Part 6] </p>
<p>To quickly recap the <a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">first post</a> of this series, we looked at how we can use JavaScript to deal with the common request of hiding form elements from the user in lists and document libraries. The technique demonstrated can be used for columns, buttons and whatever else you want. The method once debugged, is fairly easy to implement with SharePoint designer with and some cut and paste.</p>
<p>But there are several problems with the method that prevent it from getting a better CleverWorkaround rating than &#8220;Meh&#8221;. They include:</p>
<ul>
<li>One size fits all, fields are hidden for all visitors irrespective of need.  </li>
<li>You need to modify the page in SharePoint designer via cut and paste of JavaScript code  </li>
<li>You need to modify auto-generated pages  </li>
<li>You need to modify a page from its site definition  </li>
<li>Insecure, relying on client side to hide content/controls is not a secure solution </li>
</ul>
<p><span id="more-617"></span></p>
<p>The first problem is obvious. The whole point of hiding fields is to prevent an audience from seeing them, but as an administrator you very likely want an unrestricted view of the world. So it would be nice to have the JavaScript code be selectively applied to a page. Right now everyone is restricted, no matter who they are.</p>
<p>On the second point, SharePoint designer is obviously *the* tool for serious SharePoint customisation. But ideally if we can apply this JavaScript within the SharePoint publishing feature framework, then SharePoint Designer is not required. It can all be performed via the browser, saving us costs such as SharePoint Designer licenses, user training, governance training and the biggest risk of all &#8211; people going nuts with unnecessary customisations <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>On top of that, we are customising auto-generated aspx pages, namely NewForm.apsx, EditForm.aspx and DisForm.aspx &#8211; probably not such a good idea. (The fact that the &#8220;Edit Page&#8221; menu option for these files should be a hint that Microsoft are discouraging modification).</p>
<p>The fourth problem is a <a href="http://blogs.msdn.com/joelo/archive/2007/05/07/to-unghost-or-not-unghost-that-is-the-question.aspx">tricky</a> one and a large topic in itself. Each time you customise a page, it no longer &#8216;predictable&#8217; from an upgrade perspective, because by the nature of customisation, you are introducing variation. A future SharePoint upgrade or service pack may well make changes to the site definitions and automagically all pages created from them will upgrade fine. But any customised pages are not guaranteed to work.</p>
<p>So what is the result of this? Increased governance costs. Customisations need to be tracked and managed and upgrades are more complex. Thus my perspective on this is that if you can find an easy way to avoid customising pages from the site definition, then do so. Obviously, In a <a href="http://www.cleverworkarounds.com/2007/12/08/learn-to-talk-to-your-cfo-wcm-scenario-part-4/">web content management scenario</a>, significant site definition customisation is a likelihood, but in pure <a href="http://www.cleverworkarounds.com/2007/11/28/learn-to-talk-to-your-cfo-collaboration-scenario-part-3/">collaboration scenarios</a>, you would be surprised with what you can get away with.</p>
<p>The last problem of security is a major concern. Any validation logic relying on client side JavaScript is prone to manipulation outside of your control. JavaScript can be disabled, or it can be fiddled with by debugging proxies such as fiddler. In fact I can tell you a real world example of this sort of manipulation.</p>
<h2></h2>
<h2>Interlude &#8211; JavaScript Security &#8211; A True Story</h2>
<p>I was assigned to do a security audit for an e-commerce site a few years ago that sold products in an online store. Believe it or, not, the pricing information for stock was in a JavaScript file! It was a separate .js file that was called when the page was loaded. I examined the .js file and could see it was auto-generated by their e-commerce system. Each night they dumped their inventory database to this .js file and then published it to the web server! So using a <a href="http://www.parosproxy.org/index.shtml">Paros</a> proxy , I was able to do an on the fly search/replace of the prices in this .js as it was rendered to the browser. From there I was able to submit back to their site, orders for products that were much cheaper than in their database.</p>
<p>Insane? Totally &#8211; but sadly a true story.</p>
<p>Anyhow lets get back to the task at hand.</p>
<h2>Wait just a dog gone second&#8230; is this supported?</h2>
<p>Hacking away at the form pages (NewForm.aspx, EditForm.aspx and DispForm.aspx) certainly wasn&#8217;t supported in SharePoint 2003 according to <a href="http://www.bluedoglimited.com/SharePointThoughts/ViewPost.aspx?ID=176">Maurice</a>. But with 2007 its harder to work this out. I&#8217;ve found nothing official, and Microsoft has a <a href="http://support.microsoft.com/?id=935504">KB article</a> talking about how to modify these pages without breaking stuff. To quote from them:</p>
<p><em>If you want to customize the controls that appear on the NewForm.aspx page, and if you do not want to show the default List Form Web Part, you can hide the List Form Web Part. To do this, follow these steps: </em></p>
<ul>
<li><em>Start SharePoint Designer 2007, and then open the NewForm.aspx page for the list. </em> </li>
<li><em>Right-click the List Form Web Part, and then click Web Part Properties.</em>  </li>
<li><em>Expand Layout, click to select the Hidden check box, and then click OK.</em> </li>
</ul>
<p>Seems like a pretty clear endorsement to me! Anyway, back to business!</p>
<h2>Re-examining the code</h2>
<p>In the last post, I demonstrated the following JavaScript code used to hide some fields from my <a href="http://www.cleverworkarounds.com/2008/01/21/sharepoint-for-cisco-fanboys-part-1/">TFTP demo site</a>.</p>
<pre class="csharpcode">&lt;script language=<span class="str">"JavaScript"</span> type=<span class="str">"text/javascript"</span>&gt;

_spBodyOnLoadFunctionNames.push(<span class="str">"hideFields"</span>);

<span class="kwrd">function</span> findacontrol(FieldName) {
   <span class="kwrd">var</span> arr = document.getElementsByTagName(<span class="str">"!"</span>);<span class="rem">//get all comments</span>
   <span class="kwrd">for</span> (<span class="kwrd">var</span> i=0;i &lt; arr.length; i++ )
   {
      <span class="rem">// now match the field name</span>
      <span class="kwrd">if</span> (arr[i].innerHTML.indexOf(FieldName) &gt; 0) {
         <span class="kwrd">return</span> arr[i];
      }
   }
}

<span class="kwrd">function</span> hideFields() {
   <span class="kwrd">var</span> control = findacontrol(<span class="str">"Device Name"</span>);
   control.parentNode.parentNode.style.display=<span class="str">"none"</span>;
   control = findacontrol(<span class="str">"Comments"</span>);
   control.parentNode.parentNode.style.display=<span class="str">"none"</span>;}
   control = findacontrol(<span class="str">"Options"</span>);
   control.parentNode.parentNode.style.display=<span class="str">"none"</span>;}
}
&lt;/script&gt;
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>So, we have established that having to cut and paste this via SharePoint designer is not really the ideal method if you want to promote cleverness and re-use. We also don&#8217;t want to customise the pages from the site definition, and we want it to work with multiple audiences. Can we satisfy all of these goals?</p>
<p>Yes indeedie <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<h2>Step 1. The Web Part</h2>
<p>We are going to create a web part containing the above JavaScript code. I&#8217;ll do this by creating a new, temporary web part page and dropping a content editor web part onto it. So first up, go to Site Settings and create a new web part page as shown below.</p>
<table cellspacing="0" cellpadding="2" width="644" border="1">
<tbody>
<tr>
<td valign="top" width="300"><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image54.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="112" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb45.png" width="222" border="0"/></a></td>
<td valign="top" width="340">&nbsp;&nbsp; <a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image310.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="374" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image3-thumb.png" width="322" border="0"/></a> </td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>File name and page layout do not matter as we will be deleting this web part page soon. Now edit this newly created page and drag and drop a &#8220;Content Editor Web Part&#8221; to one of the web part zones on the new page (doesn&#8217;t matter which)</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image55.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="194" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb46.png" width="542" border="0"/></a></p>
<p>Now, as instructed on the newly created web part, open the tool pane to the configuration screen below</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image56.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb47.png" width="214" border="0"/></a></p>
<p>Click on &#8220;Source Editor&#8230;&#8221; (make sure you do not use &#8220;Rich Text Editor&#8230; as this will escape the JavaScript code thinking it is text information&#8221;)</p>
<p>Paste the following JavaScript code into the input window. Note that I have sanitised it somewhat from the code example above. I have commented out the code where we need to fill in blanks later. Note that if you have never used it before, the debugger; command is damn handy, especially with Visual Studio installed.</p>
<p><em>Also, watch out for issues with quotes when you paste from here. I have seen my double quotes get screwed up breaking the code. If you uncomment the debugger line and it still never fires, you probably have screwed up quotes.</em></p>
<pre class="csharpcode">&lt;script language=<span class="str">"javascript"</span> type=<span class="str">"text/javascript"</span>&gt;

_spBodyOnLoadFunctionNames.push(<span class="str">"hideFields"</span>);

<span class="kwrd">function</span> findacontrol(FieldName) {
   <span class="kwrd">var</span> arr = document.getElementsByTagName(<span class="str">"!"</span>);<span class="rem">//get all comments</span>
   <span class="kwrd">for</span> (<span class="kwrd">var</span> i=0;i &lt; arr.length; i++ )
   {
      <span class="rem">// now match the field name</span>
      <span class="kwrd">if</span> (arr[i].innerHTML.indexOf(FieldName) &gt; 0) {
         <span class="kwrd">return</span> arr[i];
      }
   }
}

<span class="kwrd">function</span> hideFields() {
   <span class="rem">// uncomment the next line if you are troubleshooting</span>
   <span class="rem">// debugger;</span>
   <span class="kwrd">var</span> control;
   <span class="rem">// Add the two lines below for each control to be hidden</span>
   <span class="rem">//control = findacontrol("&lt;Column Name&gt;");</span>
   <span class="rem">//control.parentNode.parentNode.style.display="none";</span>
}
&lt;/script&gt;</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p></p>
<style type="text/css">.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }<br />
</style>
</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image70.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="322" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image70-thumb.png" width="397" border="0"/></a></p>
<p>Click SAVE and then OK on the web part properties screen. We now have a content editor web part with our JavaScript set and ready to go.</p>
<h2>Step 2: Export the Web Part</h2>
<p>The next step is to create a new web part, based on the customised content editor web part. This is an easy process that I have outlined below.</p>
<p>On the customised content editor web part created from step 1, click the edit drop down menu and choose &#8220;Export&#8221;</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image57.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="217" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb48.png" width="521" border="0"/></a></p>
<p>Save the web part file with a meaningful file name.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image211.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="349" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image21-thumb.png" width="475" border="0"/></a></p>
<p>Once you have exported this web part, you can delete the web part page as we are finished with it.</p>
<p>The next step is to upload this exported web part into the site collection web part gallery. This is performed in site settings at the site collection level. Navigate to the web part gallery and upload the file you just saved.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image58.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="178" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image-thumb49.png" width="195" border="0"/></a>&nbsp;&nbsp; <a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image271.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="173" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image27-thumb.png" width="373" border="0"/></a></p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image301.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="149" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image30-thumb.png" width="583" border="0"/></a></p>
<p>In the next step, we have to set some metadata properties for the new web part. Since the web part gallery is just a document library, it can be assigned columns and content types like any other SharePoint document library. Of particular note here is the <strong>Title</strong>, <strong>Description</strong> and <strong>Group</strong> fields. The Group field is particularly useful, as when this web part is used, it is easy to find.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image361.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="469" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image36-thumb.png" width="554" border="0"/></a></p>
<h2>Conclusion</h2>
<p>Sorry for the abrupt stop here readers, but that&#8217;s it for part 2, I was going to make one large post on this, but it&#8217;s simply gotten too big, so I&#8217;ll finish this off in part 3. But fear not, <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/" target="_blank">part 3</a> is 90% written and should be <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/" target="_blank">published</a> within a day or two.</p>
<p>Bye for now</p>
<p>Paul</p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
