tag:blogger.com,1999:blog-79769526628775289832024-02-07T16:41:09.206-05:00SharePoint Can Be FrustratingShawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.comBlogger40125tag:blogger.com,1999:blog-7976952662877528983.post-38361903634338331012015-12-17T12:09:00.003-05:002015-12-17T12:09:40.228-05:00<h3>
People Picker MVC Sample</h3>
<br />
OfficeDev PnP has a great <a href="https://github.com/OfficeDev/PnP/tree/master/Components/Core.PeoplePicker" target="_blank">sample</a> for using the people picker in a provider hosted add-in. The only problem is that the sample uses web forms. In this post I'll demonstrate using the people picker in an MVC application.<br />
<h4>
Create a new App for SharePoint</h4>
Make it Provider hosted<br />
Choose MVC Web Application<br />
Choose Windows Azure Access Control Service<br />
<h4>
Add a dummy module to the SharePoint project</h4>
Right click the SharePoint project and add a dummy module. This will allow you to easily get a SharePoint context.<br />
<h4>
Edit _Layout.cshtml </h4>
Add MicrosoftAjax.js and a Styles section. Remove the menu and footer. <br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvLHcfGdeqrp9w2LMpsIYWpz0puqBPWSUK2VYy-IGujhHdixNWJzyVmUoV1csTRhRpNrxP42u_FpEq7XoyIf-DWvt7qk3ZWVVv2X5vuDrMxUUUOxxpv2wPtF2hyphenhyphenRnHWnp2JB6I-9O7rfs/s1600/layoutschtml.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvLHcfGdeqrp9w2LMpsIYWpz0puqBPWSUK2VYy-IGujhHdixNWJzyVmUoV1csTRhRpNrxP42u_FpEq7XoyIf-DWvt7qk3ZWVVv2X5vuDrMxUUUOxxpv2wPtF2hyphenhyphenRnHWnp2JB6I-9O7rfs/s1600/layoutschtml.png" /></a><br />
<h4>
Copy files from the PnP Project Scripts folder into the MVC Scripts folder</h4>
app.js<br />
peoplepickercontrol.js<br />
peoplepickercontrol_resources.en.js<br />
<h4>
Copy files from the PnP Project Styles folder into the MVC Content folder</h4>
peoplepickercontrol.css<br />
<h4>
Edit the app.js file</h4>
Add functions for the chrome control, renderSPChrome and chromeLoaded.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5DuTtbQZJ0qDjsFzvbSD9zUfQsXdMAj75ggB3S5f3aHCqBxIDljHgvYoycmFpqj4BA4BuEUgRW1E3cv9bcDAxQmlBTWavPskJsuCFc0vFHX9P2QdLL4D2uiw2h-EbBcjQPBEfXGiY2gM/s1600/chromejs.png" imageanchor="1"><img border="0" height="336" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5DuTtbQZJ0qDjsFzvbSD9zUfQsXdMAj75ggB3S5f3aHCqBxIDljHgvYoycmFpqj4BA4BuEUgRW1E3cv9bcDAxQmlBTWavPskJsuCFc0vFHX9P2QdLL4D2uiw2h-EbBcjQPBEfXGiY2gM/s640/chromejs.png" width="640" /></a><br />
<h4>
Add a people picker to index.cshtml</h4>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV2hhZMjtAN1QoAkzvmBQR85-nt4jWjRa1IjaSb6lveWxR-yh7lLkyIHdNm5BZqmO0Fz9pxL1IykNaUaqxvgGNAo66bbtffaR3YnuzWiNz67EK03UhEoDHbBpLTnSwcGSDe7tySIwWjBA/s1600/indexcshtml.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV2hhZMjtAN1QoAkzvmBQR85-nt4jWjRa1IjaSb6lveWxR-yh7lLkyIHdNm5BZqmO0Fz9pxL1IykNaUaqxvgGNAo66bbtffaR3YnuzWiNz67EK03UhEoDHbBpLTnSwcGSDe7tySIwWjBA/s1600/indexcshtml.png" /></a><br />
<br />
Lets walk through this.<br />
<br />
Line 1 add the CSS for the control.<br />
<br />
Line 5 this is for loading the SharePoint chrome control. If this is not what you want you will need to include the SharePoint core.css file into your project or at least those bits needed for the people picker.<br />
<br />
Lines 9 - 19 this is the html needed for the people picker. The ids are important. They are used by the JavaScript to build the control.<br />
<br />
Line 29 add the people picker JavaScript files to the page<br />
<br />
<br />
That's it. If you've followed along the people picker should be up and running in your MVC application. Full source code can be found here <a href="https://github.com/spkrby/MVCPeoplePicker.git">https://github.com/spkrby/MVCPeoplePicker.git</a><br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0nHPSziFAIXvE-BubmXnhxolQQJyBLZaim2m6kN4_KQmtkcKSzo8bAJZAbq2z0u0Uwo6c4fLUJ36Z9oQe66jF8PYpLHuIOv0pocVF6yFU3_SbNh-uXP8EvpDMwwKPEiLVTnDK5PZOjxI/s1600/mvcpp.png" imageanchor="1"><img border="0" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0nHPSziFAIXvE-BubmXnhxolQQJyBLZaim2m6kN4_KQmtkcKSzo8bAJZAbq2z0u0Uwo6c4fLUJ36Z9oQe66jF8PYpLHuIOv0pocVF6yFU3_SbNh-uXP8EvpDMwwKPEiLVTnDK5PZOjxI/s640/mvcpp.png" width="640" /></a><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com1tag:blogger.com,1999:blog-7976952662877528983.post-41232022319752943322015-04-01T14:29:00.000-04:002015-04-01T14:32:55.444-04:00Use Powershell with SharePoint Online<h4>
Install Powershell on your machine</h4>
http://www.microsoft.com/en-us/download/details.aspx?id=40855<br />
<br />
<h4>
Install SharePoint Online Management Shell</h4>
http://www.microsoft.com/en-us/download/details.aspx?id=35588<br />
<h4>
Connect to SharePoint</h4>
<pre id="codesnippet"></pre>
<pre id="codesnippet">Connect-SPOService -Url https://???????-admin.sharepoint.com -C
redential ?????@?????.onmicrosoft.com
</pre>
<br />
I can't connect, I get the following error: "Current site is not a tenant administration site."<br />
Fix: You must connect to the administration site. You're administration site will be something like this https://achme-admin.sharepoint.com <br />
<br />
<br />Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-70930032275442997612015-03-29T13:23:00.001-04:002015-04-02T09:13:39.903-04:00Deploy JavaScript to SharePoint Online with a Console App <br />
One of the new challenges facing SharePoint professionals is adding JavaScript files to SharePoint online. The most direct and simple approach that I have found is to use the UserCustomAction class to add a ScriptLink. To make the deployment a snap, use the SharePointOnlineCredentials class within a console application. The SharePointOnlineCredentials class allows you to access the site using your credentials. You will need full control permission to run this solution. <br />
<br />
WARNING, improper use use of a UserCusomAction to add a ScriptLink WILL break your site/site collection in a very disturbing fashion. SharePoint will gladly serve you an absolutely blank page with no error. Therefore, it is recommended to test this solution prior to a production deployment. <br />
<br />
<h3>
Create a new Console App</h3>
<br />
<h4>
Add references to SharePoint </h4>
Microsoft.SharePoint.Client<br />
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll<br />
<br />
Microsoft.SharePoint.Client.Runtime<br />
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll<br />
<br />
<h4>
Use SharePointOnlineCredentials</h4>
First, collect the url, logon and user password from the console. Create a new client context and set the credentials of the context to a new SharePointOnlineCredentials class.<br />
<br />
<pre class="brush:csharp">static void Main(string[] args)
{
Console.WriteLine("Enter SharePoint online url:");
string url = Console.ReadLine();
Console.WriteLine("Enter SharePoint online Login : ");
string logon = Console.ReadLine();
Console.WriteLine("Enter your password.");
SecureString password = GetPasswordFromConsoleInput();
using (var context = new ClientContext(url))
{
context.Credentials = new SharePointOnlineCredentials(logon, password);
}
Console.WriteLine("Press Enter to End");
Console.ReadLine();
}
private static SecureString GetPasswordFromConsoleInput()
{
ConsoleKeyInfo info;
//Get the user's password as a SecureString
SecureString securePassword = new SecureString();
do
{
info = Console.ReadKey(true);
if (info.Key != ConsoleKey.Enter)
{
securePassword.AppendChar(info.KeyChar);
}
}
while (info.Key != ConsoleKey.Enter);
return securePassword;
}
</pre>
<h4>
Use the Utility Functions</h4>
The downloadable code has a few functions built to list, add and remove ScriptLinks. I would start by just listing them out. The functions are executed directly after SharePointOnlineCredentials. <br />
<h4>
</h4>
<pre class="brush:csharp">/// <summary>
/// adds a scriptlink to the site
/// </summary>
/// <param name="ctx"></param>
/// <param name="file"></param>
/// <param name="seq"></param>
private static void AddScriptLink(ClientContext ctx, string file, int seq)
{
// Register Custom Action
var customAction = ctx.Site.UserCustomActions.Add();
customAction.Location = "ScriptLink";
customAction.ScriptSrc = file;
customAction.Sequence = seq;
customAction.Update();
ctx.ExecuteQuery();
Console.WriteLine("ScriptLink Added : {0}", file);
}
/// <summary>
/// remove all customactions from the site
/// </summary>
/// <param name="ctx"></param>
private static void ClearAllScriptLinks(ClientContext ctx)
{
var customActions = ctx.Site.UserCustomActions;
ctx.Load(customActions);
ctx.ExecuteQuery();
customActions.Clear();
ctx.ExecuteQuery();
Console.WriteLine("All SriptLinks removed");
}
/// <summary>
/// list the scriptlinks on the site
/// </summary>
/// <param name="ctx"></param>
private static void ListScriptLinks(ClientContext ctx)
{
var customActions = ctx.Site.UserCustomActions;
ctx.Load(customActions);
ctx.ExecuteQuery();
foreach(UserCustomAction ua in customActions)
{
if (string.Compare(ua.Location, "ScriptLink", true) == 0)
{
Console.WriteLine("Script Source : {0}, Sequence : {1}", ua.ScriptSrc, ua.Sequence);
}
}
if(customActions.Count == 0)
{
Console.WriteLine("No ScriptLinks found for {0}", ctx.Url);
}
}
/// <summary>
/// remove a scriptlink matching script source
/// </summary>
/// <param name="ctx"></param>
private static void RemoveScriptLink(ClientContext ctx, string scriptsource)
{
var customActions = ctx.Site.UserCustomActions;
ctx.Load(customActions);
ctx.ExecuteQuery();
foreach (UserCustomAction ua in customActions)
{
if (string.Compare(ua.ScriptSrc, scriptsource, true) == 0)
{
Console.WriteLine("Removing Script Src : {0}, Sequence : {1}", ua.ScriptSrc, ua.Sequence);
ua.DeleteObject();
}
}
if(ctx.HasPendingRequest)
{
ctx.ExecuteQuery();
}
}
</pre>
<h4>
Download Source Code</h4>
https://github.com/spkrby/SriptLinkUtil<br />
<h4>
References</h4>
<br />
http://blogs.msdn.com/b/kaevans/archive/2014/02/23/call-o365-using-csom-with-a-console-application.aspx<br />
http://blog.mastykarz.nl/deploying-custom-actions-app-model/<br />
http://www.ashokraja.me/post/Refer-Scripts-and-CSS-Style-Sheet-in-SharePoint-2013-Visual-Web-Part-and-Master-Page.aspx<br />
<br />
<br />
<br />
<br />Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-38243997099901781032011-02-27T20:49:00.000-05:002011-02-27T20:49:51.867-05:00Create Site Collections from Custom Site TemplatesIn SharePoint 2010 creating templates from sites is as simple as a few clicks. Using that template to create new site collections is a bit more involved. The standard approach goes something like this; download the newly created template, in central administration create a new site collection without specifying a template, navigate to the new site collection, when prompted for the site template upload your custom template. The problem with this approach it's too repetitive if you're going to create a lot of sites and site collections.<br />
<br />
What I wanted to do was to select the template to create new sites and site collection just like the builtin ones. To do this you need to understand what's going on when you create a site template from the SharePoint interface. It's a solution file so we can rename it to a .cab file and take a look inside. Along with the manifest.xml file, there are folders for; ListInstances, Modules, PropertyBags, and WebTemplate. The webtemplate folder is the giveaway, what has been created for us is a definition for a webtemplate. The webtemplate folder contains a feature with a scope of "Site" that needs to be changed to a scope of "Farm". <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRu9sZZTtgJrXuiOzptr4humWlWY7zOjIHcvFNQzbdCZN2CyKr8Yr-6sbcu5GaSxNzG-7l-ppt9ABBlHjI3xm2__ArQBP5Ld6HPlXxF9AYihxQVL4mxY5kY4jCETMqpw1p6-_LV8kPK6c/s1600/temp2.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRu9sZZTtgJrXuiOzptr4humWlWY7zOjIHcvFNQzbdCZN2CyKr8Yr-6sbcu5GaSxNzG-7l-ppt9ABBlHjI3xm2__ArQBP5Ld6HPlXxF9AYihxQVL4mxY5kY4jCETMqpw1p6-_LV8kPK6c/s1600/temp2.gif" /></a></div>That's it, this webtemplate can now be used to create site collections from central administration, after installation of coarse.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK4gVhAJ73JltMpTF9g8mhqIPTHcb98GyqPdSw5-IJ1LAJbpj5oVGO6XBA_ueUGjcvenVEDhPoI661u2pHksD4zplBiBMRe_K-jFxbW9USfmkGLd0T5VuDomzoFaSt2ruLTizomjScv-g/s1600/temp3.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK4gVhAJ73JltMpTF9g8mhqIPTHcb98GyqPdSw5-IJ1LAJbpj5oVGO6XBA_ueUGjcvenVEDhPoI661u2pHksD4zplBiBMRe_K-jFxbW9USfmkGLd0T5VuDomzoFaSt2ruLTizomjScv-g/s320/temp3.gif" width="320" /></a></div><br />
<br />
The steps; create the template, download the template, rename the template to .cab, extract the .cab file to a folder, modify the feature xml, convert folder back to .cab, rename to .wsp, add and deploy the solution. To convert the folder back to a cab file I used TUGZip.Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-30942954437496087792011-02-24T23:17:00.001-05:002015-03-30T12:48:34.971-04:00Disable ASP:Button onclick<div style="color: black; font-family: inherit;">
A common requirement is to disable a button after it's been clicked. It can be accomplished by modifying two properties of the asp:button control. First, set the UseSubmitButton to "false". Second, modify the OnClientClick property to include "this.disabled=true;". These two settings will work in most cases. A problem will crop up if client side data validation is being used. The button will remain disabled and the user will not be able to click the button again. If you're using .Net validation controls you will need to check Page_ClientValidate() and then disable the button. </div>
<br />
<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;">
<script type='text/javascript'><br />
function disableBtn(control) {<br />
if (typeof Page_ClientValidate == 'function') {<br />
if (Page_ClientValidate()) { control.disabled = true; }<br />
}<br />
else<br />
{ control.disabled = true; }<br />
}<br />
</script><br />
<br />
<asp:Button runat="server" ID="btnSubmit" OnClientClick="disableBtn(this);" UseSubmitBehavior="false" OnClick="btnSubmit_Click" Text="Submit" /></div>
<br />
<br />
<br />Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-65284266784371604292010-12-28T12:12:00.000-05:002010-12-28T12:12:51.831-05:00SharePoint People Picker Limit SelectionBy default, the people picker will let a user select anyone visible to the picker. This is not always an ideal situation. Luckily, there are a couple of ways to easily limit what the user can select from.<br />
<br />
First, if you need to limit selection to site collection users, you can use an stsadm command<br />
<br />
<blockquote><pre>stsadm -o setproperty –url http://sitecollectionURL
–pn peoplepicker-onlysearchwithinsitecollection –pv yes</pre></blockquote><br />
<a href="http://technet.microsoft.com/en-us/library/cc261988%28office.12%29.aspx"></a><br />
There are a couple of other options to limit selection that involve setup in active directory. They can be found here; Keep it Simple!<br />
<a href="http://technet.microsoft.com/en-us/library/cc263318%28office.12%29.aspx">Peoplepicker: Stsadm properties</a><br />
<br />
<br />
Second, customize the people editor control with the SharePointGroup property. I've found this solution very helpful in customizing input screens as it gives really fine grained control over an individual field. The field below will only allow selection from "SomeGroup".<br />
<br />
<span style="font-size: small;"><span style="color: blue; font-family: Consolas;"><span style="color: blue; font-family: Consolas;"><span style="color: blue; font-family: Consolas;"><</span></span></span><span style="color: maroon; font-family: Consolas;"><span style="color: maroon; font-family: Consolas;"><span style="color: maroon; font-family: Consolas;">SharePoint</span></span></span><span style="color: blue; font-family: Consolas;"><span style="color: blue; font-family: Consolas;"><span style="color: blue; font-family: Consolas;">:</span></span></span><span style="color: maroon; font-family: Consolas;"><span style="color: maroon; font-family: Consolas;"><span style="color: maroon; font-family: Consolas;">PeopleEditor</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> </span></span><span style="color: red; font-family: Consolas;"><span style="color: red; font-family: Consolas;"><span style="color: red; font-family: Consolas;">ID</span></span></span><span style="color: blue; font-family: Consolas;"><span style="color: blue; font-family: Consolas;"><span style="color: blue; font-family: Consolas;">="plpEdit"</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> </span></span><span style="color: red; font-family: Consolas;"><span style="color: red; font-family: Consolas;"><span style="color: red; font-family: Consolas;">runat</span></span></span><span style="color: blue; font-family: Consolas;"><span style="color: blue; font-family: Consolas;"><span style="color: blue; font-family: Consolas;">="server"</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> </span></span><span style="color: red; font-family: Consolas;"><span style="color: red; font-family: Consolas;"><span style="color: red; font-family: Consolas;">SharePointGroup</span></span></span><span style="color: blue; font-family: Consolas;"><span style="color: blue; font-family: Consolas;"><span style="color: blue; font-family: Consolas;">="SomeGroup"</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> </span></span><span style="color: blue; font-family: Consolas;"><span style="color: blue; font-family: Consolas;"><span style="color: blue; font-family: Consolas;">/></span></span></span></span>Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-35070106565395851442010-12-26T17:25:00.000-05:002010-12-26T17:25:45.513-05:00SharePoint People Picker Multiple DomainsThe people picker is an important part of a SharePoint farm. Making sure that the correct users are available for selection is key. Issues almost always show up in farms where multiple domains need to be available for selection. The fix is a couple of stsadm commands, these commands work in SharePoint 2007 and 2010. <br />
<br />
By default, the application pool identity is used to search active directory. If the account does not have the correct permissions, you will need to encrypt the password for the account that will be used to search that domain. This account needs to be noted for password changes!<br />
<br />
Set the encryption key (run on each WFE)<br />
<blockquote style="font-family: "Courier New",Courier,monospace;"><pre>stsadm -o setapppassword -password *********</pre></blockquote>Set the domains that should be searched (run on one WFE per web application)<br />
<blockquote style="font-family: "Courier New",Courier,monospace;"><pre>stsadm -o setproperty -pn peoplepicker-searchadforests
-pv domain:domain1;domain:domain2,domain2\account,password
-url http://webapp</pre></blockquote>A more detailed discussion can be found here:<br />
<a href="http://blogs.msdn.com/b/joelo/archive/2007/03/08/cross-forest-multi-forest-configuration-additional-info.aspx">http://blogs.msdn.com/b/joelo/archive/2007/03/08/cross-forest-multi-forest-configuration-additional-info.aspx</a>Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-83768696605316436912010-12-26T16:12:00.002-05:002010-12-27T19:02:16.426-05:00Visual Studio 2010 Code SnippetsCode snippets are a great way to speed up development time. In this post I'll go through a simple way to create your own code snippets. I'll be creating a snippet to log to the 14\LOGS files.<br />
<br />
Open a Visual Studio project and add a new xml file. Make sure to save it with a .snippet extension.<br />
<br />
Right click in the new xml file, select Insert Snippet and double click on snippet. The xml below will be inserted for you.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3XMmqUkPdMpXhCdw_F1lz7RoHB4K2BjC7PCXR1mSeBPnn_O-rL-TW6kkhSK-arye2Svzto2Y3WNx1pa2jNRbBHbG0y2e7gK3NLO6Znu0dxTkIDv1gKVPnf52TXZNLPR8Z5LOhPJPEtyc/s1600/sn2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3XMmqUkPdMpXhCdw_F1lz7RoHB4K2BjC7PCXR1mSeBPnn_O-rL-TW6kkhSK-arye2Svzto2Y3WNx1pa2jNRbBHbG0y2e7gK3NLO6Znu0dxTkIDv1gKVPnf52TXZNLPR8Z5LOhPJPEtyc/s640/sn2.jpg" width="640" /></a></div><br />
<br />
Fill in the values you would like for these tag. The most important is the shortcut - its what will start intellisence for you.<br />
<Title>SharePoint Logging</Title><br />
<Author>Me</Author><br />
<Shortcut>SPLog</Shortcut><br />
<Description></Description><br />
<br />
Choose what type of snippet you want either SurroundsWith or Expansion, I'm using expansion here.<br />
<SnippetTypes><br />
<SnippetType>SurroundsWith</SnippetType><br />
<SnippetType>Expansion</SnippetType><br />
</SnippetTypes><br />
<br />
Now enter what you would like to replace in instances of the snippet. Here the component name to be logged changes. If there are more replacements needed, add more Literal tags.<br />
<Declarations><br />
<Literal><br />
<ID><span style="background-color: yellow;">Component</span></ID><br />
<Default>CustomComponent</Default><br />
</Literal><br />
</Declarations> <br />
<br />
Change the code language to CSharp.<br />
<Code Language="CSharp"><br />
<br />
Enter the code to be inserted in CDATA[ YOUR CODE GOES HERE ] <br />
<![CDATA[<br />
SPDiagnosticsService.Local.WriteTrace(0, <br />
new SPDiagnosticsCategory(<span style="background-color: yellow;">"$Component$"</span>, TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);<br />
]]><br />
<br />
<br />
Save the snippet to the default location "C:\Users\Administrator\Documents\Visual Studio 2010\Code Snippets\Visual C#\My Code Snippets" and your ready to try your new snippet.<br />
<br />
Completed snippet file<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"><br />
<Header><br />
<Title>SharePoint Logging</Title><br />
<Author>Me</Author><br />
<Shortcut>SPLog</Shortcut><br />
<Description></Description><br />
<SnippetTypes><br />
<br />
<SnippetType>Expansion</SnippetType><br />
</SnippetTypes><br />
</Header><br />
<Snippet><br />
<Declarations><br />
<Literal><br />
<ID>Component</ID><br />
<Default>CustomComponent</Default><br />
</Literal><br />
</Declarations><br />
<Code Language="CSharp"><br />
<![CDATA[<br />
SPDiagnosticsService.Local.WriteTrace(0,<br />
new SPDiagnosticsCategory("$Component$", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);<br />
]]><br />
</Code><br />
</Snippet><br />
</CodeSnippet></div>Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-52273466686450961492010-12-26T16:11:00.000-05:002010-12-26T16:11:19.204-05:00Logging in Sharepoint 2010Logging in SharePoint 2010 is a pretty straight forward affair. The code block below will write to 14\LOGS <br />
<br />
using Microsoft.SharePoint.Administration;<br />
<br />
SPDiagnosticsService.Local.WriteTrace(0, <br />
new SPDiagnosticsCategory("CustomComponent", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);<br />
<br />
If you want to create your own custom logging component, the following two blogs will assist you.<br />
<br />
<a href="http://blog.mastykarz.nl/logging-uls-sharepoint-2010/">http://blog.mastykarz.nl/logging-uls-sharepoint-2010/</a><br />
<a href="http://www.sharepointproconnections.com/article/sharepoint-development/SharePoint-Logging-What-s-New-in-SharePoint-2010.aspx">http://www.sharepointproconnections.com/article/sharepoint-development/SharePoint-Logging-What-s-New-in-SharePoint-2010.aspx</a>Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-25768404259648779622010-10-03T12:48:00.000-04:002010-10-03T12:48:34.115-04:00ASP.NET Align Labels with TextThe simple task of aligning labels and text can become not so easy when you move away from using tables. In this example I'm wrapping the lables and textboxes in div and using a bit of CSS to produce the result below. The important bits are highlighted.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzJ3R7nc4o7fmwr1TKqwHdtktIgP9T8fxr0aLEeOTv1Ss7DMkO8YY8xJaSfR6NH1dR5jlPH0peK6PwnDOFrIM5mrek5Yxj4dyPX4LSSLqvP6W8R7gk9ES2UQ5n0mkNGFnvbfsmwVBVQn0/s1600/align1.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="282" px="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzJ3R7nc4o7fmwr1TKqwHdtktIgP9T8fxr0aLEeOTv1Ss7DMkO8YY8xJaSfR6NH1dR5jlPH0peK6PwnDOFrIM5mrek5Yxj4dyPX4LSSLqvP6W8R7gk9ES2UQ5n0mkNGFnvbfsmwVBVQn0/s320/align1.jpg" width="320" /></a></div><br />
<span style="color: #a31515;"><span style="color: #a31515;">div</span></span>{<br />
<span style="color: red;"><span style="color: red;"> <span style="background-color: yellow;">clear</span></span></span><span style="background-color: yellow;">:<span style="color: blue;"><span style="color: blue;">left</span></span>; </span><br />
<span style="color: red;"><span style="color: red;"><span style="background-color: white; color: black;"> </span>margin</span></span>: <span style="color: blue;"><span style="color: blue;">5px</span></span> <span style="color: blue;"><span style="color: blue;">0</span></span> <span style="color: blue;"><span style="color: blue;">0</span></span>; <span style="color: red;"><span style="color: red;">padding</span></span>: <span style="color: blue;"><span style="color: blue;">1px</span></span> <span style="color: blue;"><span style="color: blue;">3px</span></span>; <br />
<span style="color: red;"><span style="color: red;">width</span></span>: <span style="color: blue;"><span style="color: blue;">400px</span></span>;<br />
}<br />
<span style="color: #a31515;"><span style="color: #a31515;">.input</span></span>{<br />
<span style="color: red;"><span style="color: red;"> <span style="background-color: yellow;">display</span></span></span><span style="background-color: yellow;">:<span style="color: blue;"><span style="color: blue;">block</span></span>; <span style="color: red;"><span style="color: red;">float</span></span>: <span style="color: blue;"><span style="color: blue;">left</span></span>; </span><span style="color: red;"><span style="color: red;"> </span></span><br />
<span style="color: red;"><span style="color: red;"> margin</span></span>: <span style="color: blue;"><span style="color: blue;">0</span></span> <span style="color: blue;"><span style="color: blue;">0</span></span> <span style="color: blue;"><span style="color: blue;">5px</span></span>; <span style="color: red;"><span style="color: red;">padding</span></span>: <span style="color: blue;"><span style="color: blue;">3px</span></span> <span style="color: blue;"><span style="color: blue;">5px</span></span>; <br />
<span style="color: red;"><span style="color: red;">text-align</span></span>:<span style="color: blue;"><span style="color: blue;">right</span></span>;<span style="color: red;"><span style="color: red;">width</span></span>: <span style="color: blue;"><span style="color: blue;">130px</span></span>;<br />
}<br />
<br />
<br />
<br />
<br />
<span style="color: blue;"><span style="color: blue;"><</span></span><span style="color: #a31515;"><span style="color: #a31515;">div</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">Label</span></span> <span style="color: red;"><span style="color: red;">AssociatedControlID</span></span><span style="color: blue;"><span style="color: blue;">="txtOne"</span></span> <span style="background-color: yellow;"><span style="color: red;"><span style="color: red;">CssClass</span></span><span style="color: blue;"><span style="color: blue;">="input"</span></span></span> <span style="color: red;"><span style="color: red;">ID</span></span><span style="color: blue;"><span style="color: blue;">="label1"</span></span> <span style="color: red;"><span style="color: red;">runat</span></span><span style="color: blue;"><span style="color: blue;">="server"</span></span> <span style="color: red;"><span style="color: red;"> </span></span><br />
<span style="color: red;"><span style="color: red;"> Text</span></span><span style="color: blue;"><span style="color: blue;">="Text One:"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">Label</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">TextBox</span></span> <span style="color: red;"><span style="color: red;">ID</span></span><span style="color: blue;"><span style="color: blue;">="txtOne"</span></span> <span style="color: red;"><span style="color: red;">runat</span></span><span style="color: blue;"><span style="color: blue;">="server"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">TextBox</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"><span style="color: blue;"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">div</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"><span style="color: blue;"><</span></span><span style="color: #a31515;"><span style="color: #a31515;">div</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">Label</span></span> <span style="color: red;"><span style="color: red;">AssociatedControlID</span></span><span style="color: blue;"><span style="color: blue;">="txtTwo"</span></span><span style="color: red;"><span style="color: red;"> CssClass</span></span><span style="color: blue;"><span style="color: blue;">="input"</span></span> <span style="color: red;"><span style="color: red;">ID</span></span><span style="color: blue;"><span style="color: blue;">="label2"</span></span> <span style="color: red;"><span style="color: red;">runat</span></span><span style="color: blue;"><span style="color: blue;">="server"</span></span><br />
<span style="color: red;"><span style="color: red;"> Text</span></span><span style="color: blue;"><span style="color: blue;">="Text Two:"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">Label</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">TextBox</span></span> <span style="color: red;"><span style="color: red;">ID</span></span><span style="color: blue;"><span style="color: blue;">="txtTwo"</span></span> <span style="color: red;"><span style="color: red;">runat</span></span><span style="color: blue;"><span style="color: blue;">="server"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">TextBox</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"><span style="color: blue;"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">div</span></span><span style="color: blue;"><span style="color: blue;">></span></span> <br />
<span style="color: blue;"><span style="color: blue;"><</span></span><span style="color: #a31515;"><span style="color: #a31515;">div</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">Label</span></span> <span style="color: red;"><span style="color: red;">AssociatedControlID</span></span><span style="color: blue;"><span style="color: blue;">="ddlOne"</span></span> <span style="color: red;"><span style="color: red;">CssClass</span></span><span style="color: blue;"><span style="color: blue;">="input"</span></span> <span style="color: red;"><span style="color: red;">ID</span></span><span style="color: blue;"><span style="color: blue;">="label3"</span></span> <span style="color: red;"><span style="color: red;">runat</span></span><span style="color: blue;"><span style="color: blue;">="server"</span></span><span style="color: red;"><span style="color: red;"> </span></span><br />
<span style="color: red;"><span style="color: red;"> Text</span></span><span style="color: blue;"><span style="color: blue;">="DropDown:"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">Label</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">DropDownList</span></span> <span style="color: red;"><span style="color: red;">ID</span></span><span style="color: blue;"><span style="color: blue;">="ddlOne"</span></span> <span style="color: red;"><span style="color: red;">runat</span></span><span style="color: blue;"><span style="color: blue;">="server"></span></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">ListItem</span></span><span style="color: blue;"><span style="color: blue;">></span></span>Choice1<span style="color: blue;"><span style="color: blue;"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">ListItem</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">ListItem</span></span><span style="color: blue;"><span style="color: blue;">></span></span>Choice2<span style="color: blue;"><span style="color: blue;"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">ListItem</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"> </</span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">DropDownList</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"><span style="color: blue;"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">div</span></span><span style="color: blue;"><span style="color: blue;">></span></span> <br />
<span style="color: blue;"><span style="color: blue;"><</span></span><span style="color: #a31515;"><span style="color: #a31515;">div</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">Label</span></span> <span style="color: red;"><span style="color: red;">AssociatedControlID</span></span><span style="color: blue;"><span style="color: blue;">="txtThree"</span></span> <span style="color: red;"><span style="color: red;">CssClass</span></span><span style="color: blue;"><span style="color: blue;">="input"</span></span> <span style="color: red;"><span style="color: red;">ID</span></span><span style="color: blue;"><span style="color: blue;">="label4"</span></span> <span style="color: red;"><span style="color: red;">runat</span></span><span style="color: blue;"><span style="color: blue;">="server"</span></span> <span style="color: red;"><span style="color: red;"> </span></span><br />
<span style="color: red;"><span style="color: red;"> Text</span></span><span style="color: blue;"><span style="color: blue;">="Text Three:"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">Label</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">TextBox</span></span> <span style="color: red;"><span style="color: red;">ID</span></span><span style="color: blue;"><span style="color: blue;">="txtThree"</span></span> <span style="color: red;"><span style="color: red;">runat</span></span><span style="color: blue;"><span style="color: blue;">="server"</span></span> <span style="color: red;"><span style="color: red;">Rows</span></span><span style="color: blue;"><span style="color: blue;">="5"</span></span> <span style="color: red;"><span style="color: red;">TextMode</span></span><span style="color: blue;"><span style="color: blue;">="MultiLine"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">TextBox</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"><span style="color: blue;"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">div</span></span><span style="color: blue;"><span style="color: blue;">></span></span> <br />
<span style="color: blue;"><span style="color: blue;"><</span></span><span style="color: #a31515;"><span style="color: #a31515;">div</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">Label</span></span> <span style="color: red;"><span style="color: red;">AssociatedControlID</span></span><span style="color: blue;"><span style="color: blue;">="txtFour"</span></span> <span style="color: red;"><span style="color: red;">CssClass</span></span><span style="color: blue;"><span style="color: blue;">="input"</span></span> <span style="color: red;"><span style="color: red;">ID</span></span><span style="color: blue;"><span style="color: blue;">="label5"</span></span> <span style="color: red;"><span style="color: red;">runat</span></span><span style="color: blue;"><span style="color: blue;">="server"</span></span><br />
<span style="color: red;"><span style="color: red;"> Text</span></span><span style="color: blue;"><span style="color: blue;">="Text Four:"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">Label</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">TextBox</span></span> <span style="color: red;"><span style="color: red;">ID</span></span><span style="color: blue;"><span style="color: blue;">="txtFour"</span></span> <span style="color: red;"><span style="color: red;">runat</span></span><span style="color: blue;"><span style="color: blue;">="server"</span></span> <span style="color: red;"><span style="color: red;">Rows</span></span><span style="color: blue;"><span style="color: blue;">="5"</span></span> <span style="color: red;"><span style="color: red;">TextMode</span></span><span style="color: blue;"><span style="color: blue;">="MultiLine"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">asp</span></span><span style="color: blue;"><span style="color: blue;">:</span></span><span style="color: #a31515;"><span style="color: #a31515;">TextBox</span></span><span style="color: blue;"><span style="color: blue;">></span></span><br />
<span style="color: blue;"><span style="color: blue;"></</span></span><span style="color: #a31515;"><span style="color: #a31515;">div</span></span><span style="color: blue;"><span style="color: blue;">></span></span>Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-62975291697800650882010-07-31T21:54:00.000-04:002010-07-31T21:54:31.438-04:00Enable IntelliSense for SharePoint Client Object Model in Visual Studio 2010Microsoft released some guidance on <a href="http://msdn.microsoft.com/en-us/library/ff798328.aspx">enabling intellisense for the SharePoint client object model</a> and was disappointed, it only gave partial intellisense. After a bit of investigating, I found that there are a number of debug.js files in the layouts folder. Adding the SP.Core.debug.js file gave me the result I was looking for. <br />
<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><script type="text/javascript" src="/_layouts/MicrosoftAjax.js" ></script><br />
<script type="text/javascript" src="/_layouts/SP.debug.js" /><br />
<script type="text/javascript" src="/_layouts/SP.Core.debug.js" /></div><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_g_Rym2mP9A59VAlL_1CeB3BGGjfoUeKe2XMjot4aG7YSE6CTuoSjZqElluHL44PiGvLoBpE66qExTefnTo3tbFsgvvgoGAqeGXCKEfbcrpTpbWE3GVuju6Yy-tC1r_PzWXNniGHvx_k/s1600/vs2010.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="451" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_g_Rym2mP9A59VAlL_1CeB3BGGjfoUeKe2XMjot4aG7YSE6CTuoSjZqElluHL44PiGvLoBpE66qExTefnTo3tbFsgvvgoGAqeGXCKEfbcrpTpbWE3GVuju6Yy-tC1r_PzWXNniGHvx_k/s640/vs2010.jpg" width="640" /></a></div>Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-90642230053105924582010-07-25T21:34:00.002-04:002010-07-25T21:36:16.011-04:00Table of Contents Web PartThe table of contents web part isn't showing all the sites. Go to site settings, navigation and increase the number of sites to display.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjajwgV4G4UyFJ9rzHKKo1q5mlsuiEPsKOJVb4in4yT6nHyBC_x01m_rwJirXb9XprpPgJXrk2rQyprZLA-CK_GF5PHgCWdwHWAfyRKF7kqC5fK74qDx4UBxZ9np0vLc3K2-ZA4eyNibU8/s1600/nav1.jpg" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="216" hw="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjajwgV4G4UyFJ9rzHKKo1q5mlsuiEPsKOJVb4in4yT6nHyBC_x01m_rwJirXb9XprpPgJXrk2rQyprZLA-CK_GF5PHgCWdwHWAfyRKF7kqC5fK74qDx4UBxZ9np0vLc3K2-ZA4eyNibU8/s400/nav1.jpg" width="400" /></a></div>Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-58584744202573098842010-07-22T21:29:00.001-04:002010-07-23T06:16:07.808-04:00Windows 2008R2 boot VHDI was in need of a faster SharePoint 2010 development environment and saw some posts on booting from a vhd and decided to give it a try. I'm running Windows 7 ultimate on my laptop and will install Windows 2008 R2 on the vhd. The first thing I tried was converting my virtualbox hard drive. Big waste of time, the conversion from vdi to vhd just didn't work. So, it was time to create a new vhd and install everything all over again. In this post I'll go thorough the steps to create a new vhd and install Windows 2008R2 on to it.<br />
<br />
Change the bios settings on your machine so the dvd will boot before the hard drive. <br />
<br />
Boot your machine from the install dvd. Oh, you don't have an install dvd, you have an iso file don't you? So you need to create an install dvd from the iso file. It's not so bad. Use a utility like <a href="http://www.imgburn.com/">ImgBurn</a> to unpack the image file to disk, you'll see all the setup files when your done. <br />
<br />
Boot your machine from the install dvd. Select your language and click next.<br />
<br />
<br />
Go to the command prompt - enter shift+F10 <br />
x:\sources > diskpart<br />
diskpart > create vdisk file=c:\win2008r2.vhd maximum=40000 type=expandable<br />
diskpart > select vdisk file=c:\win2008r2.vhd<br />
diskpart > attach vdisk<br />
diskpart > exit<br />
x:\sources > exit <br />
<br />
Install the operating system - you will be able to select your new vhd later.<br />
<br />
Select the disk you just created, there will be more than one to choose from. Choose carefully. Ignore the warning that you can't use the disk.<br />
<br />
Continue with the installation. <br />
<br />
When the installation is finished, remove the dvd from the drive and restart your machine. You will be able to choose between Windows 7 and Windows 2008R2.Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-16908718533567742162010-06-26T23:36:00.001-04:002010-06-26T23:38:02.942-04:00Migrating to SharePoint 2010Recently I've been migrating farms from SharePoint 2007 to 2010 using the attach database method. In this post I'm going to outline the steps I've used to perform the upgrade. I'm assuming SharePoint 2010 has been set up and that the visual compatibility mode will be used. <br />
<br />
<b>Clean Up Your Current Environment </b><br />
Remove unused site collections, features, etc. Run "stsadm -o preupgradecheck" to identify potential problems. <br />
<br />
<b>Find the Customizations</b><br />
Your disaster recovery plan will really come in handy here. If you don't have a disaster recovery plan, this will be a good start for one. Go to central administration and note your settings. They will need to be used to configure your new farm. Find the custom code and files that have been deployed to your farm. If solutions have been used to deploy customizations, they can be used to deploy to the new farm. Make copies of the web.config files, many of the custom settings have been made by hand. Think safe controls, http modules, application settings, connection strings. Run a comparison between your 12 hive and an oob 12 hive to find any differences. Check IIS for any folders or applications that have been added.<br />
<br />
<b>Copy your Content Databases</b><br />
The databases can be detached and copied or backups can be taken. Copy the .mdf files to the new SQL Server. <br />
<br />
<b>Install Customizations to the new 2010 Farm</b><br />
Install your solutions and features, move files into the 14 hive, edit the web.config files... Create new Web Applications for the ones you’re moving. Delete the configuration databases that are created. <br />
<br />
<b>Attach the Content Databases to the new SQL Server </b><br />
<br />
<br />
<b>Test Content Database against the Web Applications</b><br />
Run Powershell command: Test-SPContentDatabase -Name "contentdbname" -WebApplication "http://webapplicationurl" This will give you the guids of missing features and let you know if there are any errors that would stop the upgrade. <br />
<br />
<b>Attach the Content Database to the farm</b><br />
Run Powershell command: Mount-SPContentDatabase -Name "contentdbname" -WebApplication "http://webapplicationurl"<br />
<br />
<b>Test the upgraded farm</b>Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-2140726296636132412010-05-12T21:36:00.001-04:002010-05-12T21:37:54.819-04:00Copy DLL from GACFrom time to time you will need to copy a dll from the GAC or assembly. The easiest way I've found to copy the file is to open a command prompt and enter the following command. <br />
<br />
SUBST M: C:\Windows\Assembly<br />
<br />
This will create a new drive M: that you can use to copy the file. Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-73160945486793092402010-05-10T20:01:00.003-04:002010-05-10T20:33:06.818-04:00Content Query Web Part - Common EnhancementsThe content query web part affectionately known as CQWP is one of the go to oob SharePoint components. It's really great at rollups on content types within a site collection. The CQWP is built with xslt so this post will focus on modifications to "ItemStyle.xsl" or your own custom item style file. Be careful of white spaces and line returns when formatting the XSLT. A couple of tools that will help a great deal with the CAML and fields are U2U CAML query Builder, SharePoint Manager and SharePoint designer. <br />
<br />
<h3>Use additional fields</h3><div style="padding-left: 15pt;">First, export the webpart and open it in notepad. Edit the CommonViewFields property. The fields are formatted like this "internal name","type"; After adding the fields, save the file and import it back into the site. Test and make sure the web part still works. If not check names, types, white space and new lines.</div><div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><pre id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"><code><span class="pln"> <property name="CommonViewFields" type="string"></span><span class="atn"></span></code><code><span class="tag"></span></code><code><span class="tag">Sorted1,Text;Status,Text;CDate,Date;
</property></span></code>
</pre></div><br />
<h3>Formatting Dates</h3><div style="padding-left: 15pt;">Add the highlighted line to the xsl:stylesheet tag.</div><div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><xsl:stylesheet <br />
version="1.0" <br />
exclude-result-prefixes="x d xsl msxsl cmswrt"<br />
xmlns:x="http://www.w3.org/2001/XMLSchema" <br />
xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" <br />
xmlns:cmswrt="http://schemas.microsoft.com/WebParts/v3/Publishing/runtime"<br />
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"<br />
<span style="background-color: yellow;"> xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"</span>><br />
<br />
</div><div style="padding-left: 15pt;">You can then format the date like this.</div><div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><xsl:value-of select="ddwrt:FormatDate(string(@CDate) ,1033 ,1)"/></div><br />
<h3>Headers and Footers</h3><div style="padding-left: 15pt;">There are a number of posts out there on this subject but this is what has worked for me and has been the least painful to develop. First create variables for the header and footer and then use them at the top and bottom of the template.</div><div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"> <xsl:variable name="HEADER"><br />
<span style="background-color: yellow;"><xsl:if test="count(preceding-sibling::*)=0"></span><br />
<![CDATA[<table border="0" cellspacing="0" width="100%"><br />
<tr><br />
<th>Header1</th><br />
<th>Header2</th><br />
<th>Header3</th> </tr>]]><br />
</xsl:if><br />
</xsl:variable><br />
<br />
<xsl:variable name="FOOTER"><br />
<span style="background-color: yellow;"><xsl:if test="count(following-sibling::*)=0"></span><br />
<![CDATA[ </table> ]]><br />
</xsl:if><br />
</xsl:variable></div> You can then use them like this.<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><pre id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"><xsl:value-of select="$HEADER" disable-output-escaping="yes"/></pre><pre id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"></pre><pre id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"><xsl:value-of select="$FOOTER" disable-output-escaping="yes"/> </pre></div><br />
<h3>Only Show the Most Recent Entry</h3><div style="padding-left: 15pt;">This is common requirement when rolling up status reports. This technique requires that the list items be in the correct order. To ensure that the list items are in the correct order the web part itself needs to be modified. To do this export the webpart and open it in notepad. Edit the QueryOverride property with the correct CAML statements. Save the changes and import the web part. (Any valid CAML can be placed in the QueryOverride tag.)</div><div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><pre id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"><code><span class="pln"> <property name="QueryOverride" type="string"><![CDATA[</span><span class="tag"><OrderBy><FieldRef</span><span class="pln"> </span><span class="atn">Name</span><span class="pun">=</span><span class="atv">"Sorted1"</span><span class="pln">
</span><span class="atn"> Ascending</span><span class="pun">=</span><span class="atv">"True"</span><span class="tag">/></span></code><code><span class="tag"><FieldRef</span><span class="pln"> </span><span class="atn">Name</span><span class="pun">=</span><span class="atv">"CDate"</span><span class="pln"> </span><span class="atn">Ascending</span><span class="pun">=</span><span class="atv">"False"</span><span class="tag">/></span></code><code><span class="tag"></OrderBy>]]></property></span></code>
</pre></div><div style="padding-left: 15pt;">Now that the data is in the correct order, only show the first record. First create a variable that contains the value of the unique field. Then use the variable to get a count of records before the current record that contains the unique value.</div><div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"> <xsl:variable name="UniqueField" select="normalize-space(@Sorted1)" /><br />
<xsl:variable name="CountUniqueField" <br />
select="count(preceding-sibling::*[@*['Sorted1']=$UniqueField])" /> </div>Wrap your detail html with the following if statement.<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><pre id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"><xsl:if test="$CountUniqueField &lt; 1">
<!-- Your xslt & html here ---></pre><pre id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"></xsl:if>
</pre></div><br />
<h3>Format as KPI/Stop Light/Green Yellow Red</h3><div style="padding-left: 15pt;">Here the status field is compared to green/yellow/red and the src attribute of the <img> tag is set appropriately.</div><div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"> <img><br />
<xsl:attribute name="src"><br />
<xsl:if test="normalize-space(@status) = 'Green'">/images/green.gif</xsl:if><br />
<xsl:if test="normalize-space(@status) = 'Yellow'">/images/yellow.gif</xsl:if><br />
<xsl:if test="normalize-space(@status) = 'Red'">/images/red.gif</xsl:if><br />
</xsl:attribute><br />
</img></div><br />
<br />
It looks like this all put together<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 500px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><pre id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"><span style="color: blue;"></span>
</pre> <xsl:template name="CustomItemStyle" match="Row[@Style='CustomItemStyle']"<br />
mode="itemstyle"><br />
<br />
<xsl:variable name="SafeLinkUrl"><br />
<xsl:call-template name="OuterTemplate.GetSafeLink"><br />
<xsl:with-param name="UrlColumnName" select="'LinkUrl'" /> <br />
</xsl:call-template><br />
</xsl:variable><br />
<xsl:variable name="DisplayTitle"><br />
<xsl:call-template name="OuterTemplate.GetTitle"><br />
<xsl:with-param name="Title" select="normalize-space(@Title)" /> <br />
<xsl:with-param name="UrlColumnName" select="'LinkUrl'" /> <br />
</xsl:call-template><br />
</xsl:variable><br />
<xsl:variable name="LinkTarget">_blank</xsl:variable> <br />
<xsl:variable name="UniqueField" select="normalize-space(@Sorted1)" /><br />
<xsl:variable name="CountUniqueField" <br />
select="count(preceding-sibling::*[@*['Sorted1']=$UniqueField])" /><br />
<br />
<xsl:variable name="HEADER"><br />
<span style="background-color: white;"> </span><span style="background-color: white;"><xsl:if test="count(preceding-sibling::*)=0"></span><br />
<![CDATA[<table border="0" cellspacing="0" width="100%"><br />
<tr><br />
<th>Link To Item</th><br />
<th>Status</th><br />
<th>Date</th> <br />
</tr><br />
]]><br />
</xsl:if><br />
</xsl:variable><br />
<br />
<xsl:variable name="FOOTER"><br />
<span style="background-color: white;"><xsl:if test="count(following-sibling::*)=0"></span><br />
<![CDATA[ </table> ]]><br />
</xsl:if><br />
</xsl:variable><br />
<br />
<xsl:value-of select="$HEADER" disable-output-escaping="yes"/> <br />
<br />
<xsl:if test="$CountUniqueField &lt; 1"><br />
<tr><br />
<td class="ms-vb"><br />
<xsl:call-template name="OuterTemplate.CallPresenceStatusIconTemplate"/> <br />
<a href="{$SafeLinkUrl}" target="{$LinkTarget}" title="{@LinkToolTip}" <br />
style="font-size:12px;font-weight:bold;"><br />
<xsl:value-of select="$DisplayTitle" /> <br />
</a><br />
</td><br />
<br />
<td class="ms-vb"><br />
<img><br />
<xsl:attribute name="src"><br />
<xsl:if test="normalize-space(@status) = 'Green'"><br />
/images/green.gif</xsl:if><br />
<xsl:if test="normalize-space(@status) = 'Yellow'"><br />
/images/yellow.gif</xsl:if><br />
<xsl:if test="normalize-space(@status) = 'Red'"><br />
/images/red.gif</xsl:if><br />
</xsl:attribute><br />
</img><br />
</td><br />
<br />
<td class="ms-vb"><br />
<xsl:value-of select="ddwrt:FormatDate(string(@CDate) ,1033 ,1)"/><br />
</td><br />
<br />
</tr><br />
<br />
</xsl:if><br />
<br />
<xsl:value-of select="$FOOTER" disable-output-escaping="yes"/><br />
<br />
</xsl:template></div>Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-62981425834610547202010-04-22T20:20:00.001-04:002010-04-23T08:10:42.224-04:00Using SPList as Datasource for jQuery UI AutocompleteA client recently wanted an auto complete field populated with a SharePoint list. Luckily, the jQuery UI library recently added an auto complete widget to their offering. So with the widget and SharePoint's ability to expose SPList data as xml we have a robust solution at our fingertips. <br />
<br />
First, lets look at SharePoint's underutililized feature of exposing lists as xml through the url. That's right, use the right url and your list comes back as xml. Here's the format <br />
<br />
"#WEBURL#/_vti_bin/owssvr.dll?Cmd=Display&List={#LISTGUID#}&Query=Title%20Name&XMLDATA=TRUE"<br />
<br />
Replace #WEBURL# with url of your site.<br />
Replace #LISTGUID# with your list's guid.<br />
The "Query=Title%20Name" limits the fields coming back to "Title" and "Name". These are the internal field names, one more reason not to use spaces in your field names.<br />
<br />
These are really only the basics of what you can do with this techinque, the rest can be found here. <a href="http://msdn.microsoft.com/en-us/library/ms478653.aspx">URL Protocol</a><br />
<br />
Next, you will need jQuery version 1.4.2 and jQuery UI version 1.8.0. You can either download these from their sites or use the <a href="http://code.google.com/apis/ajaxlibs/documentation/#jquery">Google cdn.</a> Take a look here about adding the <a href="http://sharethefrustration.blogspot.com/2009/10/sharepont-cross-site-list-views-with.html">jQuery library</a> and code into SharePoint if you need to. Use the code below and you have an input box with auto complete feed by a list. Pretty cool. <br />
<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: "Courier New", courier, monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;"> <script type="text/javascript"> <br />
(function(){ <br />
var xmlSource = "#WEBURL#/_vti_bin/owssvr.dll?Cmd=Display&<br />
List={#LISTGUID}&Query=Title%20Name&XMLDATA=TRUE"; <br />
<br />
$.ajax({<br />
url: xmlSource,<br />
dataType: "xml",<br />
success: function(xmlResponse) {<br />
var data = $("z\\:row", xmlResponse).map(function() {<br />
return {<br />
title: $(this).attr("ows_Title"),<br />
name: $(this).attr("ows_Name")<br />
};<br />
}).get();<br />
$("#auto").autocomplete({<br />
source: data,<br />
minLength: 1,<br />
select: function(event, ui) {<br />
var title = ui.item.title;<br />
var name = ui.item.name;<br />
//TO DO what to do with the values that have been selected<br />
}<br />
});<br />
}<br />
})//end .ajax<br />
<br />
}) //end function<br />
</script><br />
<br />
<input id="auto" type="text" /><br />
<br />
</div><br />
This solution could be wrapped in a <a href="http://sharethefrustration.blogspot.com/2010/01/sharepoint-maskededit-field-control.html">custom field control</a>. If you were to do this you may be able to do away with lookup fields and provide auto complete everywhere in your site.Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com1tag:blogger.com,1999:blog-7976952662877528983.post-65344830605081926882010-03-17T12:33:00.000-04:002010-03-17T12:33:24.922-04:00Too Many Users Remoted into MachineThere's a really easy way around the too many users remoted into the server. Just remember that you may be bumping someone else from the machine. An added bonus most of the time imo.<br />
<br />
C:\>mstsc -v:MachinenameOrIP /F -adminShawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-69123604680008716112010-03-03T20:50:00.003-05:002010-03-03T20:56:54.507-05:00SharePoint TreeView Site NavigationThis is a really simple and powerful solution for site navigation within a site collection. It consists of a TreeView control, a PortalSiteMapProvider and a SiteMapDataSource. It sounds like there's a lot going on and there is, but SharePoint is taking care of most of the work for us.<br />
<br />
<div style="text-align: left;"><a href="http://sites.google.com/site/sharepointcanbefrustrating/treeviewsitenav/TreeViewSiteNav.zip?attredirects=0&d=1">Download the code</a></div><br />
<div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXYSgOe9LF1PC7QXnjaqzFEeBsbwL1hvvFvO9xKHfZiwFqVWsaPD8lMnZdduBiu8cowH8F-wvRz3fevvw6XJ0me4nNoMJJV0U_sjMeGKXYWIK9Ore6q30z_JmdnC_RthDTYMPLXlxIL-Q/s1600-h/nav1.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXYSgOe9LF1PC7QXnjaqzFEeBsbwL1hvvFvO9xKHfZiwFqVWsaPD8lMnZdduBiu8cowH8F-wvRz3fevvw6XJ0me4nNoMJJV0U_sjMeGKXYWIK9Ore6q30z_JmdnC_RthDTYMPLXlxIL-Q/s320/nav1.jpg" /></a></div>The TreeView control gives a familiar look most users will quickly recognize. It can be easily styled with css or skins.<br />
<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglJA4CwUqJ3d1ulbcGHpsucccR1t85_K9SCLK-QuqYTM-kXGNsw9q7XDA7oKJskIjBkn-l6v30ohfw5UqwQWSqoyg6KNN137yCG6uuuoRTR86xSjyOr4peJGlhMRRtKyVUbWxSA0KvOHk/s1600-h/nav2.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglJA4CwUqJ3d1ulbcGHpsucccR1t85_K9SCLK-QuqYTM-kXGNsw9q7XDA7oKJskIjBkn-l6v30ohfw5UqwQWSqoyg6KNN137yCG6uuuoRTR86xSjyOr4peJGlhMRRtKyVUbWxSA0KvOHk/s320/nav2.jpg" /></a> Here is the editor of the webpart. The TreeView section has been added for a few customizations. The Site Map Provider is provided by SharePoint. Additional providers can be found in the web.config file. Number of levels to Show sets the number of levels to expand. Only Display Subsites if checked will only display the current site and it's subsites.</div><br />
<div style="clear: both; text-align: left;">The code below creates and customizes the sitemapprovider.</div><div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"> //setup the sitemapprovider<br />
protected override void OnInit(EventArgs e)<br />
{<br />
base.OnInit(e);<br />
<br />
SiteMapProvider siteMapProvider = SiteMap.Providers[_siteMapProvider];<br />
if (siteMapProvider == null)<br />
{ return; }<br />
<br />
InitPortalSiteMapProvider(siteMapProvider);<br />
}<br />
<br />
//set some defaults for the customized data provider<br />
//this is intended to only show sites and not pages<br />
private void InitPortalSiteMapProvider(SiteMapProvider siteMapProvider)<br />
{<br />
if (siteMapProvider is PortalSiteMapProvider)<br />
{<br />
_provider = siteMapProvider as PortalSiteMapProvider;<br />
_provider.DynamicChildLimit = 0;<br />
_provider.EncodeOutput = true;<br />
_provider.IncludePages = PortalSiteMapProvider.IncludeOption.Never;<br />
_provider.IncludeSubSites = PortalSiteMapProvider.IncludeOption.Always; <br />
_provider.IncludeHeadings = false;<br />
_provider.IncludeAuthoredLinks = false;<br />
}<br />
}</div><br />
Here's the CreateChildControls method where everything is put together. <br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"> protected override void CreateChildControls()<br />
{<br />
Controls.Clear();<br />
//create the datasource <br />
_datasource = new SiteMapDataSource();<br />
//associate the datasource with the customized provider<br />
_datasource.Provider = _provider;<br />
//if true only show self and subsites<br />
_datasource.StartFromCurrentNode = startAtCurrentWeb;<br />
<br />
treeView = new TreeView();<br />
treeView.ExpandDepth = levels;<br />
//set the datasource of the treeview and bind it<br />
treeView.DataSource = _datasource;<br />
<br />
treeView.DataBind();<br />
<br />
Controls.Add(treeView);<br />
}</div>Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com1tag:blogger.com,1999:blog-7976952662877528983.post-47738304557198612542010-02-22T22:34:00.004-05:002010-02-24T11:52:30.342-05:00PowerShell ISE Server 2008 R2<div style="width: 85%;">By default PowerShell ISE is not available in Server 2008 R2. It's a feature that you will need to add. Go to Server Manager -> Features -> Add Features<br />
<br />
PowerShell uses the "profile" concept somewhat similar to Unix. Profiles can be really useful in setting up your PowerShell session defaults. There are a number of built in profiles I was expecting to be available and was surprised when I had to create one.<br />
<br />
<a href="http://technet.microsoft.com/en-us/library/dd819434.aspx">How to use Profiles in Windows PowerShell ISE</a><br />
<a href="http://technet.microsoft.com/en-us/library/dd819492.aspx">How to Create Profiles in Windows PowerShell ISE</a><br />
<br />
Create a new Profile<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqWjCcvzVeTg4SHkykxVQDXgJv-NRDJIe0JsxDqPaNHWif8MqlbuxC4dOXx3MHNunzzbv7JgjFgRt_gi6J9cQKIc6hO8yXLpOhXLaoBarS-F3xQlGlWJC0ZFjB08cMbdo2f1qZ5Zwn_JY/s1600-h/ps1.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" ct="true" height="284" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqWjCcvzVeTg4SHkykxVQDXgJv-NRDJIe0JsxDqPaNHWif8MqlbuxC4dOXx3MHNunzzbv7JgjFgRt_gi6J9cQKIc6hO8yXLpOhXLaoBarS-F3xQlGlWJC0ZFjB08cMbdo2f1qZ5Zwn_JY/s640/ps1.jpg" width="640" /></a></div><div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: "Courier New",courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><pre id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: "Courier New",courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;">if (!(test-path $profile.CurrentUserAllHosts))
{new-item -type file -path $profile.CurrentUserAllHosts -force}</pre></div><br />
Add the SharePoint Snapin and run all my commands without annoyance. Execute the psEdit command and add the Add-PSSnapin and Set-Executionpolicy commands in the tabbed window at the top. You'll have to save the changes.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja9cl3wGOjGbtV9BruHY_Rden2olnB8gWF8ASeW99gyRguZuHZ-TyH2-HwFIv8QaFnL62RVeE4H75Ur0zKNVhvCT_RDGTx6GsAEHsL88QLv_GBaAiC1l0SJ0dpHomJZjSdPEsGKifhCUQ/s1600-h/ps2.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" ct="true" height="283" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja9cl3wGOjGbtV9BruHY_Rden2olnB8gWF8ASeW99gyRguZuHZ-TyH2-HwFIv8QaFnL62RVeE4H75Ur0zKNVhvCT_RDGTx6GsAEHsL88QLv_GBaAiC1l0SJ0dpHomJZjSdPEsGKifhCUQ/s640/ps2.jpg" width="640" /></a></div><div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: "Courier New",courier,monospace; font-size: 8pt; height: 40px; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.49%;"><pre id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: "Courier New",courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;">psEdit $profile.CurrentUserAllHosts</pre></div><div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: "Courier New",courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><pre id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: "Courier New",courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;">Add-PSSnapin Microsoft.SharePoint.Powershell
Set-ExecutionPolicy Bypass</pre></div></div>Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-62140621100837963612010-02-16T19:58:00.003-05:002010-02-24T11:53:45.413-05:00SPGridView WebPart with Multiple Filter and Sort ColumnsThe SPGridView is one of the most useful SharePoint controls. For viewing data it's tough to beat. It provides a very nice interface for sorting, filtering, paging and grouping. It gives custom data sources the look and feel of SharePoint list views, providing a consistent look and feel across your site<br />
<br />
Unfortunately, it can be quite a handful and good examples of using the features in combination are hard to come by. This example doesn't combine all of the features, notably grouping has not been included. Wouldn't want to spoil all of your fun.<br />
<br />
This webpart contains an ObjectDataSource that feeds an SPGridView. The sort and filter properties are maintained in viewstate. The ObjectDataSource does most of the work with a little bit of help with sorting. For the sorting to work, the SortParameterName needs to be set to the value of the persisted sort property. This will then be passed into the SelectMethod of the ObjectDataSource where we will need to implement a custom sort. This solution has been built with WSPBuilder and Visual Studio 2008.<br />
<br />
A couple of screen shots of the finished webpart, looks familiar ? <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU-b0Xm264qZWgDkGkjYdg4mCKijtzCRrUYcijUXXckGLyck-60BRtd6Gg5hi0T8VBz5oZw5hm_Gc0jq_vGZTBHsURA4w1SaXu9gwBwzuVUHvl0tVN7L9nhxVLUyXa78fcMra53IAWGkw/s1600-h/grid1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="44" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU-b0Xm264qZWgDkGkjYdg4mCKijtzCRrUYcijUXXckGLyck-60BRtd6Gg5hi0T8VBz5oZw5hm_Gc0jq_vGZTBHsURA4w1SaXu9gwBwzuVUHvl0tVN7L9nhxVLUyXa78fcMra53IAWGkw/s640/grid1.jpg" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8XntiomgpoIxKrmhiCQbttXxNevTWFlNXlnGj9m8vQPSLgmbHIDeSpV7pZfTg12UUvEJh_ycriiF73tpFNJlpVUuS32KfSa1tSXYdYrIEhBnbOW59inX9z5yiamDe-ZCOMsVSUQWex_0/s1600-h/grid3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="90" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8XntiomgpoIxKrmhiCQbttXxNevTWFlNXlnGj9m8vQPSLgmbHIDeSpV7pZfTg12UUvEJh_ycriiF73tpFNJlpVUuS32KfSa1tSXYdYrIEhBnbOW59inX9z5yiamDe-ZCOMsVSUQWex_0/s640/grid3.jpg" width="640" /></a> </div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxRnaoM7lWbQnG47BnMqXAqyUoAqaW7-_QcC9E5WgmCdASjgEa6MSEwQ8ygFngH2C23S_xhxrD5OjZGtxRavHkxrnMdznWMp-86n_Vklur8A2ze9-cjNoieU5Ln6OJ9xaLjOgTyFYrRas/s1600-h/grid2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxRnaoM7lWbQnG47BnMqXAqyUoAqaW7-_QcC9E5WgmCdASjgEa6MSEwQ8ygFngH2C23S_xhxrD5OjZGtxRavHkxrnMdznWMp-86n_Vklur8A2ze9-cjNoieU5Ln6OJ9xaLjOgTyFYrRas/s320/grid2.jpg" /></a></div><div class="separator" style="clear: both; text-align: center;"> <a href="http://sites.google.com/site/sharepointcanbefrustrating/spgridviewmultisortfilter/SPGridViewMultiSortFilter.zip?attredirects=0&d=1">Download the code here</a></div><div class="separator" style="clear: both; text-align: center;"></div><br />
Here are the filter and sort properties being saved to and retrieved from viewstate. The format of the strings is important. It seems that filters work best with this format ((col1 = 'val1') AND (col2 = 'val2')). The sort works best in the format of "col1 DESC, col2 ASC". <br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"> string FilterExpression<br />
{<br />
get<br />
{<br />
if (ViewState["FilterExpression"] == null)<br />
{ ViewState["FilterExpression"] = ""; }<br />
<br />
return (string)ViewState["FilterExpression"];<br />
}<br />
set<br />
{<br />
string thisFilterExpression = "(" + value.ToString() + ")";<br />
List<string> fullFilterExpression = new List<string>();<br />
<br />
if (ViewState["FilterExpression"] != null)<br />
{<br />
string[] fullFilterExp = ViewState["FilterExpression"].ToString().Split(_ssep, StringSplitOptions.RemoveEmptyEntries);<br />
fullFilterExpression.AddRange(fullFilterExp);<br />
<br />
//add the filter if not present<br />
int index = fullFilterExpression.FindIndex(s => s.Contains(thisFilterExpression));<br />
if (index == -1)<br />
{ fullFilterExpression.Add(thisFilterExpression); }<br />
}<br />
else<br />
{<br />
fullFilterExpression.Add(thisFilterExpression);<br />
}<br />
//loop through the list<T> and serialize to string<br />
string filterExp = string.Empty;<br />
fullFilterExpression.ForEach(s => filterExp += s + " AND ");<br />
filterExp = filterExp.Remove(filterExp.LastIndexOf(" AND "));<br />
if (!filterExp.EndsWith("))") && filterExp.Contains("AND"))<br />
{ filterExp = "(" + filterExp + ")"; }<br />
ViewState["FilterExpression"] = filterExp; <br />
}<br />
}<br />
<br />
<br />
string SortExpression<br />
{<br />
get<br />
{<br />
if (ViewState["SortExpression"] == null)<br />
{ ViewState["SortExpression"] = ""; }<br />
<br />
return (string)ViewState["SortExpression"];<br />
}<br />
set<br />
{<br />
string[] thisSE = value.ToString().Split(' ');<br />
string thisSortExpression = thisSE[0];<br />
List<string> fullSortExpression = new List<string>();<br />
<br />
if (ViewState["SortExpression"] != null)<br />
{<br />
string[] fullSortExp = ViewState["SortExpression"].ToString().Split(_sep);<br />
fullSortExpression.AddRange(fullSortExp);<br />
<br />
//does the sort expression already exist?<br />
int index = fullSortExpression.FindIndex(s => s.Contains(thisSortExpression));<br />
if (index >= 0)<br />
{<br />
string s = string.Empty;<br />
if (value.ToString().Contains("DESC"))<br />
{ s = value.ToString(); }<br />
else<br />
{<br />
s = fullSortExpression[index];<br />
if (s.Contains("ASC"))<br />
{ s = s.Replace("ASC", "DESC"); }<br />
else<br />
{ s = s.Replace("DESC", "ASC"); }<br />
}<br />
//reset the sort direction<br />
fullSortExpression[index] = s;<br />
}<br />
else<br />
{<br />
if (value.ToString().Contains("DESC"))<br />
{ fullSortExpression.Add(value.ToString()); }<br />
else<br />
{ fullSortExpression.Add(thisSortExpression + " ASC"); }<br />
}<br />
}<br />
else<br />
{<br />
if (value.ToString().Contains("DESC"))<br />
{ fullSortExpression.Add(value.ToString()); }<br />
else<br />
{ fullSortExpression.Add(thisSortExpression + " ASC"); }<br />
}<br />
//loop through the list<T> and serialize to string<br />
string sortExp = string.Empty;<br />
fullSortExpression.ForEach(s => sortExp += s);<br />
sortExp = sortExp.Replace(" ASC", " ASC,");<br />
sortExp = sortExp.Replace(" DESC", " DESC,");<br />
ViewState["SortExpression"] = sortExp.Remove(sortExp.LastIndexOf(',')); <br />
}<br />
}</div><br />
This is the CreateChildControls where the ObjectDataSource and SPGridView controls are instantiated and properties are set.<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><br />
protected override void CreateChildControls()<br />
{<br />
base.CreateChildControls();<br />
<br />
try<br />
{<br />
//build the datasource<br />
gridDS = new ObjectDataSource();<br />
gridDS.ID = "gridDS";<br />
<span style="background-color: yellow;">gridDS.SelectMethod = "SelectData";</span><br />
gridDS.TypeName = this.GetType().AssemblyQualifiedName;<br />
gridDS.EnableViewState = false;<br />
<br />
//pass the SortExpression to the select method<br />
<span style="background-color: yellow;">gridDS.SortParameterName = "SortExpression";</span><br />
<br />
//this resets the dropdown options for other columns after a filter is selected<br />
gridDS.FilterExpression = FilterExpression;<br />
//add the data source<br />
Controls.Add(gridDS);<br />
<br />
//build the gridview<br />
gridView = new SPGridView();<br />
gridView.AutoGenerateColumns = false;<br />
gridView.EnableViewState = false;<br />
gridView.ID = "gridView";<br />
<br />
//sorting<br />
gridView.AllowSorting = true;<br />
<br />
//filtering <br />
gridView.AllowFiltering = true;<br />
gridView.FilterDataFields = ",FirstName,LastName,Department,Country,Salary";<br />
gridView.FilteredDataSourcePropertyName = "FilterExpression";<br />
gridView.FilteredDataSourcePropertyFormat = "{1} = '{0}'";<br />
<br />
//set header icons for sorting an filtering<br />
gridView.RowDataBound += new GridViewRowEventHandler(gridView_RowDataBound);<br />
<br />
//sorting<br />
gridView.Sorting += new GridViewSortEventHandler(gridView_Sorting);<br />
<br />
//paging<br />
gridView.AllowPaging = true;<br />
gridView.PageSize = 5;<br />
<br />
//create gridView columns<br />
BuildColumns();<br />
<br />
//set the id and add the control<br />
gridView.DataSourceID = gridDS.ID;<br />
Controls.Add(gridView);<br />
<br />
SPGridViewPager pager = new SPGridViewPager();<br />
pager.GridViewId = gridView.ID;<br />
Controls.Add(pager);<br />
<br />
}<br />
catch (Exception ex)<br />
{<br />
//To Do Log it<br />
}<br />
}</div><br />
Here is the SelectMethod of the ObjectDataSource. Note the signature, a DataTable is being returned, necessary for filtering. The SortParameterName, SortExpression, is passed to enable custom sorting. The custom sort is necessary due to a bug? with the sort ascending / descending menu options.<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><br />
public DataTable SelectData(string SortExpression)<br />
{<br />
DataTable dataSource = new DataTable();<br />
<br />
dataSource.Columns.Add("ID");<br />
dataSource.Columns.Add("LastName");<br />
dataSource.Columns.Add("FirstName");<br />
dataSource.Columns.Add("Department");<br />
dataSource.Columns.Add("Country");<br />
dataSource.Columns.Add("Salary", typeof(double));<br />
<br />
dataSource.Rows.Add(1, "Smith", "Laura", "Sales", "IreLand", 150000);<br />
dataSource.Rows.Add(2, "Jones", "Ed", "Marketing", "IreLand", 75000);<br />
dataSource.Rows.Add(3, "Jefferson", "Bill", "Security", "Britian", 87000);<br />
dataSource.Rows.Add(4, "Washington", "George", "PMO", "France", 110000);<br />
dataSource.Rows.Add(5, "Bush", "Laura", "Accounting", "USA", 44000);<br />
dataSource.Rows.Add(6, "Clinton", "Hillory", "Human Resources", "USA", 121000);<br />
dataSource.Rows.Add(7, "Ford", "Jack", "IT", "France", 150000);<br />
dataSource.Rows.Add(8, "Hailey", "Tom", "Networking", "Canada", 72000);<br />
dataSource.Rows.Add(9, "Raul", "Mike", "Accounting", "Canada", 97000);<br />
dataSource.Rows.Add(10, "Shyu", "Danny", "Sales", "Britian", 89000);<br />
dataSource.Rows.Add(11, "Hanny", "Susan", "Sales", "USA", 275000);<br />
<br />
//clean up the sort expression if needed - the sort descending <br />
//menu item causes the double in some cases <br />
if (SortExpression.ToLowerInvariant().EndsWith("desc desc"))<br />
SortExpression = SortExpression.Substring(0, SortExpression.Length - 5);<br />
<br />
//need to handle the actual sorting of the data<br />
if (!string.IsNullOrEmpty(SortExpression))<br />
{<br />
DataView view = new DataView(dataSource);<br />
view.Sort = SortExpression;<br />
DataTable newTable = view.ToTable();<br />
dataSource.Clear();<br />
dataSource = newTable;<br />
}<br />
<br />
return dataSource; <br />
}</div><br />
The gridView_RowDataBound event is used to add the sort and filter images to the header.<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"> private void gridView_RowDataBound(object sender, GridViewRowEventArgs e)<br />
{<br />
if (sender == null || e.Row.RowType != DataControlRowType.Header)<br />
{ return; }<br />
<br />
SPGridView grid = sender as SPGridView;<br />
<br />
// Show icon on filtered and sorted columns <br />
for (int i = 0; i < grid.Columns.Count; i++)<br />
{<br />
DataControlField field = grid.Columns[i];<br />
<br />
if (FilterExpression.Contains(field.SortExpression) && <br />
!string.IsNullOrEmpty(FilterExpression))<br />
{<br />
PlaceHolder panel = HeaderImages(field, "/_layouts/images/filter.gif");<br />
e.Row.Cells[i].Controls[0].Controls.Add(panel);<br />
}<br />
else if(SortExpression.Contains(field.SortExpression)) <br />
{<br />
string url = sortImage(field);<br />
PlaceHolder panel = HeaderImages(field, url);<br />
e.Row.Cells[i].Controls[0].Controls.Add(panel);<br />
} <br />
}<br />
}<br />
<br />
<br />
private string sortImage(DataControlField field)<br />
{<br />
string url = string.Empty;<br />
string[] fullSortExp = SortExpression.Split(_sep);<br />
List<string> fullSortExpression = new List<string>();<br />
fullSortExpression.AddRange(fullSortExp);<br />
<br />
//does the sort expression already exist?<br />
int index = fullSortExpression.FindIndex(s => s.Contains(field.SortExpression));<br />
if (index >= 0)<br />
{<br />
string s = fullSortExpression[index];<br />
if (s.Contains("ASC"))<br />
{ url = "_layouts/images/sortup.gif"; }<br />
else<br />
{ url = "_layouts/images/sortdown.gif"; }<br />
}<br />
return url;<br />
}<br />
<br />
<br />
private PlaceHolder HeaderImages(DataControlField field, string imageUrl)<br />
{<br />
Image filterIcon = new Image();<br />
filterIcon.ImageUrl = imageUrl;<br />
filterIcon.Style[HtmlTextWriterStyle.MarginLeft] = "2px";<br />
<br />
Literal headerText = new Literal();<br />
headerText.Text = field.HeaderText;<br />
<br />
PlaceHolder panel = new PlaceHolder();<br />
panel.Controls.Add(headerText);<br />
<br />
//add the sort icon if needed<br />
if (FilterExpression.Contains(field.SortExpression) &&<br />
SortExpression.Contains(field.SortExpression)) <br />
{<br />
string url = sortImage(field);<br />
Image sortIcon = new Image();<br />
sortIcon.ImageUrl = url;<br />
sortIcon.Style[HtmlTextWriterStyle.MarginLeft] = "1px";<br />
panel.Controls.Add(sortIcon);<br />
//change the left margin to 1<br />
filterIcon.Style[HtmlTextWriterStyle.MarginLeft] = "1px";<br />
}<br />
<br />
panel.Controls.Add(filterIcon);<br />
return panel;<br />
}</div><br />
<br />
This is the sorting method of the SPGridView. The event handler is registered in CreateChildren and is where the sortexpression property is built. The filter needs to be reset here or it will be lost. <br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"> void gridView_Sorting(object sender, GridViewSortEventArgs e)<br />
{<br />
string sDir = e.SortDirection.ToString();<br />
sDir = sDir == "Descending" ? " DESC" : "";<br />
<br />
SortExpression = e.SortExpression + sDir;<br />
e.SortExpression = SortExpression;<br />
<br />
//if the filter is not reset it will be cleared<br />
if (!string.IsNullOrEmpty(FilterExpression))<br />
{ gridDS.FilterExpression = FilterExpression; }<br />
<br />
}<br />
<br />
<br />
void buildFilterView(string filterExp)<br />
{<br />
string lastExp = filterExp;<br />
if (lastExp.Contains("AND"))<br />
{<br />
if (lastExp.Length < lastExp.LastIndexOf("AND") + 4)<br />
{ lastExp = lastExp.Substring(lastExp.LastIndexOf("AND") + 4); }<br />
else<br />
{ lastExp = string.Empty; }<br />
}<br />
<br />
//update the filter<br />
if (!string.IsNullOrEmpty(lastExp))<br />
{ FilterExpression = lastExp; }<br />
<br />
//reset object dataset filter<br />
if (!string.IsNullOrEmpty(FilterExpression))<br />
{ gridDS.FilterExpression = FilterExpression; }<br />
}</div>Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com15tag:blogger.com,1999:blog-7976952662877528983.post-37086728393032002882010-02-05T23:45:00.001-05:002010-02-24T11:54:40.912-05:00Custom Site Collection CreationSite collections are the fundamental building blocks of SharePoint applications. They provide security boundaries and the smallest built-in unit for backup and disaster recovery. Most of the time, the central administration interface is fine for creating site collections. Problems arise when you need to frequently create site collections or allow users to create site collections. More than likely you're going to need a custom solution.<br />
<br />
Recently, a client requested just such a custom solution for creating site collections. Not wanting to start from scratch, I found a very good solution from Gary Lapointe <a href="http://stsadm.blogspot.com/2009/07/custom-sharepoint-2007-site-collection.html">here</a>. The solution consists of two main components an application page, for user input, and a web service to create the site collection. It's really very well done and customizable depending on your needs. Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-62134081211052259892010-01-26T21:59:00.003-05:002010-02-24T11:55:32.320-05:00SharePoint MaskedEdit Field ControlA control that I used over and over in the good old days of VB6 was the masked edit control. I recently came across a jQuery plugin for a masked edit control and wanted to implement it as a custom SharePoint field. <a href="http://sites.google.com/site/sharepointcanbefrustrating/maskededitfield/MaskedEditField.zip?attredirects=0&d=1">Download the code here</a><br />
<br />
What you will need. <br />
<a href="http://jquery.com/">jQuery</a><br />
<a href="http://digitalbush.com/projects/masked-input-plugin/">jQuery Masked Edit Plugin</a><br />
<a href="http://www.codeplex.com/wspbuilder">WSPBuilder</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiQHlQJiRIWnF-Nyaxp_iOIDKJbAe8o2cbyINkzeJssjtRg2SiGSu4pj1VLQLhXfJgUmn90PZv78GqtEhnj0yKr4qyyyME-7aKhK4smIlIqeLEsYGYheGwCMnCUD8WBQvDanOy8wR0V6g/s1600-h/cf1.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiQHlQJiRIWnF-Nyaxp_iOIDKJbAe8o2cbyINkzeJssjtRg2SiGSu4pj1VLQLhXfJgUmn90PZv78GqtEhnj0yKr4qyyyME-7aKhK4smIlIqeLEsYGYheGwCMnCUD8WBQvDanOy8wR0V6g/s320/cf1.jpg" /></a></div>This is masked edit field as seen when adding it to a list. I've defined a small number of masks, you can add more! This interface is built with the next two code blocks. The first code block is the user control that contains the HTML and the server controls. The second code block is the code behind for the user control. <br />
<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><%@ Control Language="C#" Inherits="MaskedEditField.jQueryMaskedEditFieldEditor, MaskedEditField, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ab6ae01ba130938e" compilationMode="Always" %><br />
<%@ Register TagPrefix="wssuc" TagName="InputFormControl" src="~/_controltemplates/InputFormControl.ascx" %><br />
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <br />
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %><br />
<%@ Import Namespace="Microsoft.SharePoint" %><br />
<br />
<wssuc:InputFormControl runat="server" LabelText="Input Masks Explained"><br />
<Template_Control><br />
<div>A mask is defined by a format made up of mask literals and mask definitions. <br />
Any character not in the definitions list below is considered a mask literal. <br />
Mask literals will be automatically entered for the user as they type and will<br />
not be able to be removed by the user.<br />
<ul><br />
<li>a - Represents an alpha character (A-Z,a-z)</li><br />
<li>9 - Represents a numeric character (0-9)</li><br />
<li>* - Represents an alphanumeric character (A-Z,a-z,0-9)</li><br />
</ul> <br />
</div><br />
</Template_Control><br />
</wssuc:InputFormControl><br />
<br />
<wssuc:InputFormControl runat="server" LabelText="Input Masks"><br />
<Template_Control><br />
<table><br />
<tr><br />
<td><asp:RadioButton Text="Phone Number" GroupName="MaskedEdit" ID="rPhone" runat="server"></asp:RadioButton></td><br />
<td><asp:TextBox Enabled="false" ID="txtPhone" runat="server">(999) 999-9999</asp:TextBox></td><br />
</tr><br />
<tr><br />
<td><asp:RadioButton Text="SSN" GroupName="MaskedEdit" ID="rSSN" runat="server"></asp:RadioButton></td><br />
<td><asp:TextBox Enabled="false" ID="txtSSN" runat="server">999-99-9999</asp:TextBox></td><br />
</tr><br />
<tr><br />
<td><asp:RadioButton Text="Zip Code + 4" GroupName="MaskedEdit" ID="rZip4" runat="server"></asp:RadioButton></td><br />
<td><asp:TextBox Enabled="false" ID="txtZip4" runat="server">99999-9999</asp:TextBox></td><br />
</tr><br />
<tr><br />
<td><asp:RadioButton Text="Zip Code" GroupName="MaskedEdit" ID="rZip" runat="server"></asp:RadioButton></td><br />
<td><asp:TextBox Enabled="false" ID="txtZip" runat="server">99999</asp:TextBox></td><br />
</tr><br />
<tr><br />
<td><asp:RadioButton Text="Custom" GroupName="MaskedEdit" ID="rCustom" runat="server"></asp:RadioButton></td><br />
<td><asp:TextBox Enabled="true" ID="txtCustom" runat="server"></asp:TextBox></td><br />
</tr><br />
</table><br />
</Template_Control><br />
</wssuc:InputFormControl><br />
<br />
<br />
</div><br />
User Control Code Behind<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;">using System;<br />
using System.Collections.Generic;<br />
using System.Text;<br />
using System.Web.UI;<br />
using System.Web.UI.WebControls;<br />
using Microsoft.SharePoint;<br />
using Microsoft.SharePoint.WebControls;<br />
<br />
namespace MaskedEditField<br />
{<br />
public class jQueryMaskedEditFieldEditor : UserControl, IFieldEditor<br />
{<br />
// Fields<br />
protected RadioButton rPhone;<br />
protected RadioButton rSSN;<br />
protected RadioButton rZip;<br />
protected RadioButton rZip4;<br />
protected RadioButton rCustom;<br />
protected TextBox txtPhone;<br />
protected TextBox txtSSN;<br />
protected TextBox txtZip;<br />
protected TextBox txtZip4;<br />
protected TextBox txtCustom;<br />
private jQueryMaskedEdit fldjQueryMaskedEdit;<br />
<br />
public void InitializeWithField(SPField field)<br />
{<br />
this.fldjQueryMaskedEdit = field as jQueryMaskedEdit;<br />
<br />
if (this.Page.IsPostBack)<br />
{<br />
return;<br />
}<br />
<br />
//when modifying a field check the correct radio button <br />
if (field != null)<br />
{<br />
string prop = fldjQueryMaskedEdit.MyCustomProperty;<br />
<br />
if (prop.Equals(txtPhone.Text))<br />
{ rPhone.Checked = true; }<br />
else<br />
if (prop.Equals(txtSSN.Text))<br />
{ rSSN.Checked = true; }<br />
else<br />
if (prop.Equals(txtZip.Text))<br />
{ rZip.Checked = true; }<br />
else<br />
if (prop.Equals(txtZip4.Text))<br />
{ rZip4.Checked = true; }<br />
else<br />
{<br />
rCustom.Checked = true;<br />
txtCustom.Text = prop;<br />
}<br />
}<br />
}<br />
<br />
//save the value for the mask from the ascx to the field property<br />
//this is the value the plugin will use to format the masked input<br />
public void OnSaveChange(SPField field, bool bNewField)<br />
{<br />
jQueryMaskedEdit jme = (jQueryMaskedEdit)field;<br />
<br />
jme.IsNew = bNewField;<br />
<br />
if (rPhone.Checked)<br />
{ jme.MyCustomProperty = txtPhone.Text; }<br />
else<br />
if (rSSN.Checked)<br />
{ jme.MyCustomProperty = txtSSN.Text; }<br />
else<br />
if (rZip.Checked)<br />
{ jme.MyCustomProperty = txtZip.Text; }<br />
else<br />
if (rZip4.Checked)<br />
{ jme.MyCustomProperty = txtZip4.Text; }<br />
else<br />
{ jme.MyCustomProperty = txtCustom.Text.Trim(); }<br />
}<br />
<br />
<br />
// Properties<br />
public bool DisplayAsNewSection<br />
{<br />
get<br />
{<br />
return false;<br />
}<br />
}<br />
}<br />
}</div><br />
This is the field class. Here I' inheriting form the SPFieldText since it most closely matches what we're trying to produce. This class provides the plumbing for the field. It saves the settings from the user control above, saves the values that users type in, validates the input, provides default display rendering. Luckily, most of this functionality is built into the SPFieldText class or provided by the Visual Studio project.<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;">using System;<br />
using System.Collections.Generic;<br />
using System.Text;<br />
using Microsoft.SharePoint;<br />
using Microsoft.SharePoint.WebControls;<br />
using System.Web.UI;<br />
using System.Web.UI.WebControls;<br />
<br />
<br />
namespace MaskedEditField<br />
{<br />
public class jQueryMaskedEdit : SPFieldText<br />
{<br />
private static string[] CustomPropertyNames = new string[] { "MyCustomProperty" };<br />
<br />
public jQueryMaskedEdit(SPFieldCollection fields, string fieldName)<br />
: base(fields, fieldName)<br />
{<br />
InitProperties();<br />
}<br />
<br />
public jQueryMaskedEdit(SPFieldCollection fields, string typeName, string displayName)<br />
: base(fields, typeName, displayName)<br />
{<br />
InitProperties();<br />
}<br />
<br />
#region Property storage and bug workarounds - do not edit<br />
<br />
/// <summary><br />
/// Indicates that the field is being created rather than edited. This is necessary to <br />
/// work around some bugs in field creation.<br />
/// </summary><br />
public bool IsNew<br />
{<br />
get { return _IsNew; }<br />
set { _IsNew = value; }<br />
}<br />
private bool _IsNew = false;<br />
<br />
/// <summary><br />
/// Backing fields for custom properties. Using a dictionary to make it easier to abstract<br />
/// details of working around SharePoint bugs.<br />
/// </summary><br />
private Dictionary<string, string> CustomProperties = new Dictionary<string, string>();<br />
<br />
/// <summary><br />
/// Static store to transfer custom properties between instances. This is needed to allow<br />
/// correct saving of custom properties when a field is created - the custom property <br />
/// implementation is not used by any out of box SharePoint features so is really buggy.<br />
/// </summary><br />
private static Dictionary<string, string> CustomPropertiesForNewFields = new Dictionary<string, string>();<br />
<br />
/// <summary><br />
/// Initialise backing fields from base property store<br />
/// </summary><br />
private void InitProperties()<br />
{<br />
foreach (string propertyName in CustomPropertyNames)<br />
{<br />
CustomProperties[propertyName] = base.GetCustomProperty(propertyName) + "";<br />
}<br />
}<br />
<br />
/// <summary><br />
/// Take properties from either the backing fields or the static store and <br />
/// put them in the base property store<br />
/// </summary><br />
private void SaveProperties()<br />
{<br />
foreach (string propertyName in CustomPropertyNames)<br />
{<br />
base.SetCustomProperty(propertyName, GetCustomProperty(propertyName));<br />
}<br />
}<br />
<br />
/// <summary><br />
/// Get an identifier for the field being added/edited that will be unique even if<br />
/// another user is editing a property of the same name.<br />
/// </summary><br />
/// <param name="propertyName"></param><br />
/// <returns></returns><br />
private string GetCacheKey(string propertyName)<br />
{<br />
return SPContext.Current.GetHashCode() + "_" + (ParentList == null ? "SITE" : ParentList.ID.ToString()) + "_" + propertyName;<br />
}<br />
<br />
/// <summary><br />
/// Replace the buggy base implementation of SetCustomProperty<br />
/// </summary><br />
/// <param name="propertyName"></param><br />
/// <param name="propertyValue"></param><br />
new public void SetCustomProperty(string propertyName, object propertyValue)<br />
{<br />
if (IsNew)<br />
{<br />
// field is being added - need to put property in cache<br />
CustomPropertiesForNewFields[GetCacheKey(propertyName)] = propertyValue + "";<br />
}<br />
<br />
CustomProperties[propertyName] = propertyValue + "";<br />
}<br />
<br />
/// <summary><br />
/// Replace the buggy base implementation of GetCustomProperty<br />
/// </summary><br />
/// <param name="propertyName"></param><br />
/// <param name="propertyValue"></param><br />
new public object GetCustomProperty(string propertyName)<br />
{<br />
if (!IsNew && CustomPropertiesForNewFields.ContainsKey(GetCacheKey(propertyName)))<br />
{<br />
string s = CustomPropertiesForNewFields[GetCacheKey(propertyName)];<br />
CustomPropertiesForNewFields.Remove(GetCacheKey(propertyName));<br />
CustomProperties[propertyName] = s;<br />
return s;<br />
}<br />
else<br />
{<br />
return CustomProperties[propertyName];<br />
}<br />
}<br />
<br />
/// <summary><br />
/// Called when a field is created. Without this, update is not called and custom properties<br />
/// are not saved.<br />
/// </summary><br />
/// <param name="op"></param><br />
public override void OnAdded(SPAddFieldOptions op)<br />
{<br />
base.OnAdded(op);<br />
Update();<br />
}<br />
<br />
#endregion<br />
<br />
<br />
public override BaseFieldControl FieldRenderingControl<br />
{<br />
get<br />
{<br />
BaseFieldControl fieldControl = new jQueryMaskedEditControl(this);<br />
fieldControl.FieldName = InternalName;<br />
return fieldControl;<br />
}<br />
}<br />
<br />
<br />
public override void Update()<br />
{<br />
SaveProperties();<br />
base.Update();<br />
}<br />
<br />
<br />
public override string GetValidatedString(object value)<br />
{<br />
if ((this.Required == true) && (value == null))<br />
{ throw new SPFieldValidationException("This is a required field."); }<br />
<br />
return base.GetValidatedString(value);<br />
}<br />
<br />
<br />
public override object GetFieldValue(string value)<br />
{<br />
if (String.IsNullOrEmpty(value))<br />
return null;<br />
<br />
return value;<br />
}<br />
<br />
public string MyCustomProperty<br />
{<br />
get { return this.GetCustomProperty("MyCustomProperty") + ""; }<br />
set { this.SetCustomProperty("MyCustomProperty", value); }<br />
}<br />
}<br />
<br />
}<br />
<br />
</div><br />
<br />
This is the class that renders the control users interact with in the new and edit forms. It closely resembles a webpart. Here is where the JavaScript is written to the page.<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;">using System;<br />
using System.Collections.Generic;<br />
using System.Text;<br />
using Microsoft.SharePoint;<br />
using Microsoft.SharePoint.WebControls;<br />
using System.Web.UI;<br />
using System.Web.UI.HtmlControls;<br />
using System.Web.UI.WebControls;<br />
<br />
<br />
namespace MaskedEditField<br />
{<br />
public class jQueryMaskedEditControl : BaseFieldControl<br />
{<br />
private jQueryMaskedEdit field;<br />
private TextBox txtBox;<br />
private string txtVal;<br />
<br />
// Used for the linked script file<br />
private const string MaskedInputJS = "jquery.maskedinput-1.2.2.min.js";<br />
private const string MaskedInputScriptKey = "jQueryMaskedInputKey";<br />
private const string IncludeScriptFormat =<br />
@"<script type=""{0}"" src=""{1}""></script>";<br />
<br />
<br />
public jQueryMaskedEditControl(jQueryMaskedEdit parentField)<br />
{<br />
this.field = parentField;<br />
this.txtBox = new TextBox();<br />
}<br />
<br />
//get/set value for custom field <br />
public override object Value<br />
{<br />
get<br />
{<br />
return txtBox.Text;<br />
}<br />
set<br />
{<br />
txtBox.Text = string.Empty;<br />
string txtVal = value as String;<br />
if (txtVal != null)<br />
{<br />
txtBox.Text = txtVal;<br />
}<br />
}<br />
}<br />
<br />
<br />
protected override void CreateChildControls()<br />
{<br />
if (this.Field == null<br />
|| this.ControlMode == SPControlMode.Display<br />
|| this.ControlMode == SPControlMode.Invalid)<br />
return;<br />
<br />
base.CreateChildControls();<br />
<br />
txtBox = new TextBox();<br />
this.Controls.Add(txtBox);<br />
}<br />
<br />
//Update field value with user input & check field validation<br />
public override void UpdateFieldValueInItem()<br />
{<br />
this.EnsureChildControls();<br />
try<br />
{ <br />
this.Value = this.txtBox.Text;<br />
this.ItemFieldValue = this.Value;<br />
}<br />
<br />
catch (Exception ex)<br />
{<br />
this.IsValid = false;<br />
this.ErrorMessage = "* " + ex.Message;<br />
}<br />
}<br />
<br />
<br />
protected override void OnPreRender(EventArgs e)<br />
{<br />
base.OnPreRender(e);<br />
<br />
if (this.ControlMode == SPControlMode.Edit ||<br />
this.ControlMode == SPControlMode.New)<br />
{ RegisterCommonScript(); }<br />
}<br />
<br />
<br />
//Function which will register the linked file script and the embedded script<br />
protected void RegisterCommonScript()<br />
{<br />
string location = null;<br />
<br />
//include the mask plugin on the page<br />
if (!Page.ClientScript.IsClientScriptBlockRegistered(MaskedInputScriptKey))<br />
{<br />
location = @"/_layouts/";<br />
string includeScript =<br />
String.Format(IncludeScriptFormat, "text/javascript", location + MaskedInputJS);<br />
Page.ClientScript.RegisterClientScriptBlock(typeof(jQueryMaskedEditControl), MaskedInputScriptKey, includeScript);<br />
}<br />
<br />
if (!Page.ClientScript.IsClientScriptBlockRegistered(txtBox.ClientID))<br />
{<br />
//this is where the mask plugin is hooked into our field, its all happening on the clients machine<br />
string function =<br />
"<script type=\"text/javascript\">jQuery(function($){$(\"input[id*=" + txtBox.ClientID +<br />
"]\").mask(\"" + field.MyCustomProperty + "\"); });</script>";<br />
Page.ClientScript.RegisterClientScriptBlock(typeof(jQueryMaskedEditControl), txtBox.ClientID, function);<br />
}<br />
}<br />
<br />
}<br />
}<br />
<br />
</div><br />
XML used to define the field.<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 5px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"><?xml version="1.0" encoding="utf-8" ?><br />
<FieldTypes><br />
<FieldType><br />
<Field Name="TypeName">jQueryMaskedEdit</Field><br />
<Field Name="ParentType">Text</Field><br />
<Field Name="TypeDisplayName">jQueryMaskedEdit</Field><br />
<Field Name="TypeShortDescription">jQuery Masked Edit</Field><br />
<Field Name="UserCreatable">TRUE</Field><br />
<Field Name="Sortable">TRUE</Field><br />
<Field Name="AllowBaseTypeRendering">TRUE</Field><br />
<Field Name="Filterable">TRUE</Field><br />
<Field Name="FieldTypeClass">MaskedEditField.jQueryMaskedEdit, MaskedEditField, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ab6ae01ba130938e</Field><br />
<Field Name="FieldEditorUserControl">/_controltemplates/jQueryMaskedEditFieldEditor.ascx</Field><br />
<PropertySchema><br />
<Fields><br />
<Field Hidden="TRUE" Name="MyCustomProperty"<br />
DisplayName="My Custom Property"<br />
Type="Text"><br />
</Field><br />
</Fields><br />
<Fields></Fields><br />
</PropertySchema><br />
<RenderPattern Name="DisplayPattern"><br />
<Column /><br />
</RenderPattern><br />
</FieldType><br />
</FieldTypes><br />
<br />
</div><br />
Display View<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKfdk9meQzBsAPpzvRT5RTa-glT_KRfVnsssr2Xb1hKFGY8bNX3NlXNvcW0hC_WWvIlhbojAKIB2oXjhvOXQ0CkTQRIlcMVSrRpkElup4Tl128acwgq7w5My_zCyFf1BGzHegf3Fd1h6M/s1600-h/cf2.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="64" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKfdk9meQzBsAPpzvRT5RTa-glT_KRfVnsssr2Xb1hKFGY8bNX3NlXNvcW0hC_WWvIlhbojAKIB2oXjhvOXQ0CkTQRIlcMVSrRpkElup4Tl128acwgq7w5My_zCyFf1BGzHegf3Fd1h6M/s640/cf2.jpg" width="640" /></a></div><br />
<br />
<br />
<br />
<br />
Edit View<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEit3TeU469GwD5uU7pNKdRFXQEpIw5ejIGl0P9t_XWaJEpS8LD50h00KctQ23eusJWK8PB8RzzlLaIgrArfOrz67TbNvu2oF_4GS_VPchcW41GB2JImb7nIUhlrXY4TuPj1cVMoPPh_bUI/s1600-h/cf3.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEit3TeU469GwD5uU7pNKdRFXQEpIw5ejIGl0P9t_XWaJEpS8LD50h00KctQ23eusJWK8PB8RzzlLaIgrArfOrz67TbNvu2oF_4GS_VPchcW41GB2JImb7nIUhlrXY4TuPj1cVMoPPh_bUI/s640/cf3.jpg" width="640" /></a></div>Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com2tag:blogger.com,1999:blog-7976952662877528983.post-21940743273572785692010-01-23T08:33:00.000-05:002010-01-23T08:33:06.301-05:00Turn Verbose Error Messaging In SharePoint OnAn annoying and easily fixed issue you will see on development machines is the really unhelpful message "<span id="ctl00_PlaceHolderMain_LabelMessage">An unexpected error has occurred." Open your web.config file, found by default here C:\inetpub\wwwroot\wss\VirtualDirectories\80, and make two changes. The brave will not backup the web.config file first ! </span> <br />
<br />
<customErrors <span style="background-color: yellow;">mode="Off"</span> /><br />
<br />
<SafeMode MaxControls="200" <span style="background-color: yellow;">CallStack="true"</span> DirectFileDependencies="10" TotalFileDependencies="50" AllowPageLevelTrace="false">Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0tag:blogger.com,1999:blog-7976952662877528983.post-6011031343315673322010-01-17T21:05:00.003-05:002010-02-24T12:02:48.213-05:00VirtualBox Resize Hard DriveI've recently upgraded my development and virtual machines to 64bit to start working with SharePoint 2010. Much to my surprise, VirtualPC from Microsoft doesn't support 64bit guest operating systems. VirtualBox from Sun does and I've been really pleased with it so far. <br />
<br />
On to the topic at hand. I created a new virtual hard drive and didn't give it enough space. Did quite a bit of Googling before finding an easy way to fix the mess I made for myself. This process really isn't resizing, it's copying and replacing.<br />
<br />
1. Create a new virtual hard drive. (See step 3c below - click new)<br />
2. Copy the contents of the old virtual hard drive to the new virtual hard drive.<br />
a. Open up a command window.<br />
b. Change the directory to the VirtualBox directory. The default is<br />
"C:\Program Files\Sun\VirtualBox"<br />
c. Execute this command <span style="background-color: yellow;">VBoxManage clonehd --existing "path\old.vdi" "path\new.vdi"</span><br />
3. Add the new hard drive to the virtual machine. <br />
a. Select Storage <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrgMTQAk8YgVK_V6Teq3NiP5Sp5eZ5cX5CjCrKo2uxMgQ2nbfenKhxp3nCGzK7fxJQI-FciPnzuYuYVIt6fvlvngLAy7k8ttgYwmnSVJCw3ciiF3636Noid2l9LP_C6CRALOXv8zmV4sA/s1600-h/vb1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrgMTQAk8YgVK_V6Teq3NiP5Sp5eZ5cX5CjCrKo2uxMgQ2nbfenKhxp3nCGzK7fxJQI-FciPnzuYuYVIt6fvlvngLAy7k8ttgYwmnSVJCw3ciiF3636Noid2l9LP_C6CRALOXv8zmV4sA/s320/vb1.jpg" /></a></div> b. Click the folder icon to the right of "Hard Drive:"<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjah5Qyn6SuFg1z4FBDzpa3GG9UHbyeNTwO7Flm9vKeA58QZCjuJJ4q-n6O-JBRmKNnoGgeWaXisj1ss9seZ7Yq2wFnQzMy7V3O03bUHiq4CMZUANjjq4DgZpmKY5JvVyd8fBSMg19m7ac/s1600-h/vb2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjah5Qyn6SuFg1z4FBDzpa3GG9UHbyeNTwO7Flm9vKeA58QZCjuJJ4q-n6O-JBRmKNnoGgeWaXisj1ss9seZ7Yq2wFnQzMy7V3O03bUHiq4CMZUANjjq4DgZpmKY5JvVyd8fBSMg19m7ac/s320/vb2.jpg" /></a></div> c. Add your new hard drive<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdWqpF7VH6_wKxI3yq15MmOaKwJuMgCoTrs5PKMoyEP73u2mSbixK9LPEjVAfUFSlIMxO6vs4TVIrZYVpZYV8BXeo2yMxU55aUiNIWJPsERdD-JOkIDVBIWhfveQCVO6cp5NSr2ZacerI/s1600-h/vb3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdWqpF7VH6_wKxI3yq15MmOaKwJuMgCoTrs5PKMoyEP73u2mSbixK9LPEjVAfUFSlIMxO6vs4TVIrZYVpZYV8BXeo2yMxU55aUiNIWJPsERdD-JOkIDVBIWhfveQCVO6cp5NSr2ZacerI/s320/vb3.jpg" /></a></div>3. Release/Remove old hard drive on the same screen you added your new hard drive.<br />
4. Make sure the new drive is set as the Primary Master (See step 3b).<br />
5. Start Up your VM.<br />
<br />
The additional space will not be recognized by default. Windows 7 and Server 2008 come with disk management software that will let you extend the original partition into the new partition. If you're guest operating system is not one of the above there are a number of free software products available. Look for partition software on download.com.Shawn Kirbyhttp://www.blogger.com/profile/14785048873648547272noreply@blogger.com0