Wednesday, December 28, 2011

Programmatically search a SharePoint list for a specific items

If you'd like to programmatically search a SharePoint list for specific list items that contain a certain value in one of the lists' fields, the following sample code will allow you to obtain any list items that precisely match the specified criteria:
    string searchValue = "ECM Project";
    using (SPSite site = new SPSite(siteGuid))
    {
        using (SPWeb web = site.OpenWeb())
        {
            SPList projectList = web.Lists["Project List"];
            SPQuery query = new SPQuery();
            query.Query = string.Format("<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>{0}</Value></Eq></Where>", searchValue);
            SPListItemCollection listItems = projectList.GetItems(query);
            web.AllowUnsafeUpdates = true;
            foreach (SPListItem listItem in listItems)
            {
                listItem["Title"] = "Enterprise Content Management Project";
                listItem.Update();
            }
            web.AllowUnsafeUpdates = false;
        }
    }
In this example, I'm performing a search on a custom SharePoint list called "Project List" for any list items that have "ECM Project" for the Title field. Once I find those list items, I replace the Title field with a value of "Enterprise Content Managment Project".

How to temporarily disable the Shift+R shortcut that brings up the IE Toolbar Ruler window

If you're constantly being plagued by the IE Toolbar Ruler window popping up every time you hit Shift+R, I found that you can temporarily disable it by hitting Ctrl+R. Unfortunately, this is only a temporary solution; however, it works long enough to be an effective means for dealing with this nagging issue.

Thursday, December 22, 2011

Programmatically add a user-friendly name in place of a hyperlink in a SPListItem Link field

There may come a time in which you would like to specify concise, user-friendly text instead of the hyperlink itself within a hyperlink field/column contained in a SharePoint list.  To do this, you simply add a comma followed by a space within your hyperlink field between the URL and text you wish to display and SharePoint will display the text after the comma as opposed to the hyperlink (i.e. "http://www.google.com/, Click here to go to Google").  Naturally, if the user clicks on the link, he/she will be redirected to the url specified in your hyperlink field.  In this example, I'm inserting a new SPListItem into a custom SPList and updating the hyperlink field, called Link, to display "Sherman's Blog" as opposed to the url, http://shermanstechnicalblog.blogspot.com/.  Here is sample code that demonstrates this technique:

            string blogTitle = "Sherman's Blog";
            string blogUrl = "http://shermanstechnicalblog.blogspot.com/";
            using (SPSite rootSite = new SPSite(rootSiteUrl))
            {
                using (SPWeb rootWeb = rootSite.OpenWeb())
                {
                    SPList blogList = rootWeb.Lists["Blog Directory"];
                    SPListItem item = blogList.Items.Add();
                    item["Title"] = "My Blog";
                    item["Link"] = string.Format("{0}, {1}", blogTitle, blogUrl);
                    item.Update();
                }
            }

Wednesday, December 21, 2011

WSPBuilder configuration settings that will allow the created ddf and manifest.xml files to be retained

If you're using Carsten Keutmann'sWSPBuilder to build your deployment packages and wish to retain the ddf and manifest.xml files that it creates, you can do so by adding or, if they already exist, updating the respective <appSettings> nodes in the WSPBuilder.exe.config file as follows:

Tuesday, December 20, 2011

Replace the logo on your SharePoint site via a Feature

The following C# class is the code you can associate with a feature that will replace the standard logo of your SharePoint site with a custom logo once that feature is activated.  When the feature is deactivated, it will reset the logo back to the default SharePoint logo.  Naturally, you'll want to update the reference to the logo with the proper location in which your custom logo is stored under the 12 (SharePoint 2007) or 14 (SharePoint 2010) hive.  In this particalur instance, I've got mine located under "_layouts/IMAGES/CustomLogoFolder/Custom_logo.png" (which translates to 14/TEMPLATE/IMAGES/CustomLogoFolder/Custom_logo.png on a SharePoint 2010 farm).

    public class UpdateLogoFeatureReceiver : SPFeatureReceiver
    {
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            base.FeatureActivated(properties);
            SPWeb currentWeb;
            using (currentWeb = properties.Feature.Parent as SPWeb)
            {
                try
                {
                    currentWeb.AllowUnsafeUpdates = true;
                    StringBuilder sbServerRelativeUrl = new StringBuilder(currentWeb.ServerRelativeUrl);
                    if (!currentWeb.ServerRelativeUrl.EndsWith(@"/"))
                    {
                        sbServerRelativeUrl.Append(@"/");
                    }
                    StringBuilder sbSiteLogoUrl = new StringBuilder(sbServerRelativeUrl.ToString());
                    sbSiteLogoUrl.Append(@"_layouts/IMAGES/CustomLogoFolder/Custom_logo.png");
                    currentWeb.SiteLogoUrl = sbSiteLogoUrl.ToString();
                    currentWeb.Update();
                }
                catch (Exception ex)
                {
                    WriteToEventLog(ex.Message, EventLogEntryType.Error);
                }
                finally
                {
                    currentWeb.AllowUnsafeUpdates = false;
                }
            }
        }
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            base.FeatureDeactivating(properties);
            SPWeb currentWeb;
            using (currentWeb = properties.Feature.Parent as SPWeb)
            {
                try
                {
                    currentWeb.AllowUnsafeUpdates = true;
                    StringBuilder sbServerRelativeUrl = new StringBuilder(currentWeb.ServerRelativeUrl);
                    if (!currentWeb.ServerRelativeUrl.EndsWith(@"/"))
                    {
                        sbServerRelativeUrl.Append(@"/");
                    }
                    StringBuilder sbSiteLogoUrl = new StringBuilder(sbServerRelativeUrl.ToString());
                    sbSiteLogoUrl.Append(@"_layouts/IMAGES/siteicon.png");
                    currentWeb.SiteLogoUrl = sbSiteLogoUrl.ToString();
                    currentWeb.Update();
                }
                catch (Exception ex)
                {
                    WriteToEventLog(ex.Message, EventLogEntryType.Error);
                }
                finally
                {
                    currentWeb.AllowUnsafeUpdates = false;
                }
            }
        }
    }

Monday, December 19, 2011

Deploying/retracting a SharePoint 2010 solution that installs a GAC-deployed feature via Powershell

This might be useful information if you're attempting to deploy a .wsp file that installs a GAC-deployed feature on a SharePoint 2010 farm:
Accessing Powershell:
  1. Click Start -> Microsoft SharePoint 2010 Products -> SharePoint 2010 Management Shell
Deploying the solution:
  1. Add-spsolution -literalpath \\filepath\wspfilename.wsp
  2. Install-spsolution -identity wspfilename.wsp -webapplication http://webapplicationname -gacdeploy
  3. Enable-spfeature featuredirectoryname -Url http://webapplicationname
Retracting the solution:

  1. Disable-spfeature featurefoldername -Url http://webapplicationname
  2. Uninstall-spsolution -identity wspfilename.wsp -webapplication http://webapplicationname
  3. Remove-spsolution -identity wspfilename.wsp

Remove all leading and lagging empty spaces from items in an array

I was looking for a way to efficiently remove all leading and lagging empty spaces from items in an array in as few lines of code as possible.  In this particular instance, the goal was to read items into an array from the web.config file and then use the Trim() method to remove all leading and lagging empty spaces from each item.  Here is the code that will do this activity in just two lines for a particular, comma-delimited AppSetting node called ChargeCodesToUse in my web.config file:

string[] chargeCodesToUse = ConfigurationManager.AppSettings["ChargeCodesToUse"].ToString().Split(',');
Array.ForEach(chargeCodesToUse, chargeCodes => chargeCodesToUse[Array.IndexOf(chargeCodesToUse, chargeCodes)] = chargeCodes.Trim());

Wednesday, November 23, 2011

How to create a simple Wildcard People Search Box Web Part for SharePoint 2010

If your users are complaining about so-called "invalid" results being returned whenever they perform a people search on part of a given person's name (i.e. expecting my name to be at the top of the list of returned results if "Sher" is typed in the search textbox), they most likely don't know that you can add a wildcard character, *, to the search parameter (i.e. "Sher*") to get the results they might expect.  One possible solution to this problem is to use the following steps to create a custom HTML/Javascript version of the People Search Box web part that automatically appends a wildcard character, *, to the end of their search parameter:

    1. Open your web browser and navigate to the page that contains the current People Search Box web part
    2. Select Site Actions -> Edit Page
    3. Click on your web part's menu and select Edit Web Part
    4. Expand Display Properties and click on the XSL Editor... button
    5. In the Text Editor window, copy the existing XSL to a temporary location since you'll probably need it again.  Here is a possible option for you:
      1. Hit Ctrl+a to highlight all of the content
      2. Hit Ctrl+c to save the content
      3. Open Notepad
      4. Hit Ctrl+v to past the content to Notepad
    6. Return to the Text Editor window, hit Ctrl+a, and hit Delete
    7. Copy and paste the HTML and Javascript code below into the Text Editor window:
    8. Click Save
    9. Click OK
    10. Publish the page
NOTE:  You may need to modify the getSearchUrl method if your search center url is a bit different than the one I specified here.

If the new web part works as expected, you can then hide the original People Search Box web part and you're done!  With that being said, here is the code you will need to copy for Step #7...

<div>
    <table border="0" ID="WildcardPeopleSearchTable" width="500px">
        <tr >
            <td class="ms-sbcell" align="left" style="width: 450px" >
                <input id="txtSearchParameter" name="txtSearchParameter" type="text" onkeypress="pressEnter()" onFocus="this.select();" class="ms-sbplain peopleInput" style="width: 100%"/>
            </td>
            <td class="ms-sbgo ms-sbcell">
                <img id="btnSearch" alt="Search" onmouseover="mouseOverImage();" onmouseout="mouseOutImage();" src="/_layouts/images/gosearch30.png" onkeydown="if (event && event.keyCode==13) search();" onclick="search()" style="border-width:0px;" />
            </td>
        </tr>
    </table>
</div>
<script language="javascript" type="text/javascript">
    document.getElementById("txtSearchParameter").focus();
    function mouseOverImage() 
    {
        document.getElementById("btnSearch").src = "/_layouts/images/gosearchhover30.png";
    }
    function mouseOutImage() 
    {
        document.getElementById("btnSearch").src = "/_layouts/images/gosearch30.png";
    }
    function pressEnter() 
    {
        if (window.navigate) 
        {
            if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
                search();
            }
        }
    }
    function search() 
    {
        var resultsUrl = getSearchUrl();
        var space
        var searchParameter = document.getElementById("txtSearchParameter").value;
        resultsUrl = resultsUrl + "?k="
        if (searchParameter != "") 
        {
            resultsUrl = resultsUrl + searchParameter + "*";
        }
        window.location.replace(resultsUrl)
    }
    function getSearchUrl() 
    {
        var searchUrl;
        searchUrl = window.location.protocol + '//' + window.location.hostname + '/search/Pages/peopleresults.aspx';
        return searchUrl;
    }
</script>

Tuesday, November 22, 2011

Hide the left navigation panel of a SharePoint page

If you're looking for a quick way to hide the left navigation panel of a single SharePoint page, a possible solution is to follow the steps I document in my Quick method for testing CSS style changes on a SharePoint site post and replace the HTML in Step #12 with the following code:

For SharePoint 2007:

<style>
.ms-navframe { display:none; }
</style>

For SharePoint 2010:

<style>
#s4-leftpanel { display:none; }
.s4-ca { BACKGROUND: none transparent scroll repeat 0% 0%; MARGIN-LEFT: 5px; }
</style>

This will hide the left navigation panel on the page in which the Content Editor web part is installed.  If you wish to hide the panel for the entire site, you can add this CSS rule to a custom CSS file and apply it yo your site.

Saturday, November 19, 2011

Quick method for testing CSS style changes on a SharePoint site

I've got a good trick for rapidly evaluating CSS style changes on a SharePoint site without having to go through all the steps required for uploading a custom style sheet.  This works great if you simply wish to tweak the style rules to determine how changes will impact the look of a given page.  The method involves using a standard Content Editor web part to host a CSS style element and will operate in the same fashion as if you were applying a custom stylesheet against the particular page you're viewing.  The following steps are applicable to SharePoint 2010, but the same technique can be used on SharePoint 2007 with minor variation to the steps:
  1. Open your web browser to the page of your SharePoint site which you'd like to view your CSS style changes 
  2. Click on Site Actions -> Edit Page
  3. Locate the Bottom Zone and click Add a Web Part
  4. Under Categories, select Media and Content
  5. Under Web Parts, select Content Editor
  6. Click the Add button
  7. Locate the newly added web part and click on the dropdown arrow in the upper right hand corner
  8. Select the Edit Web Part option
  9. Under Layout, place a check in the Hidden checkbox
  10. In the Content Editor web part, click on the link that reads Click here to add new content link
  11. In the Format Text ribbon, click on the HTML button and select Edit HTML Source
  12. In the HTML Source dialog, enter the following HTML:
    <style> 
    Insert CSS rule changes here...
    </style>
  13. Click OK
  14. Click OK
You will now be able to view how the CSS style updates will impact your page without having to jump through the hoops of uploading a custom stylesheet.  Once you've finalized all of your style changes, you can then add them to a custom CSS file, apply the custom CSS to your site, and then delete this Content Editor web part.

    Tuesday, November 15, 2011

    Purpose of this site

    I've got a couple of reasons for creating this blog that I'll highlight as follows:

    First...

    I can't even begin to tell you how many times I've written some code or made some tweak to one of our environments that I've had to revisit/reuse a few months down the road. One purpose of this blog is that it'll allow me to store various random helpful nuggets of information for later use. If it helps you solve a problem or give you some good ideas...even better!

    Second...

    I have interests in many different technologies and a major part of my job is trying to identify the strengths and weaknesses of various platforms for solving different types of problems. My thought is that this blog could provide a good platform for relaying those experiences. Perhaps it might help validate a technology decision you've made, steer you in the right direction, or help you avoid pitfalls...who knows!

    Last, but no least...

    I've got a ton of developer tips and tricks stored in my brain that I think would be beneficial to share with the general development community. Some of these nuggets of wisdom will be obvious to those well-versed in the given platform, but could prove invaluable to those who are still learning the nuances of it.

    Anyway, those are my initial reasons for creating this site, but I do plan to take creative liberties with it and we'll see where it goes from here!