Sharepoint Insight by Namwar Rizvi

Sharepoint Tips, Tricks and inside knowledge from real world experience by Namwar Rizvi

Posts Tagged ‘Code’

How to generate a valid SharePoint FileName

Posted by namwar on June 17, 2010


SharePoint imposes several restrictions for the filenames. To get the details of all these restrictions, please check this support article from Microsoft. I have created a utility function to convert a given string to a valid SharePoint filename. This function is valid for SharePoint 2003, 2007 and 2010. Here you go

public string ConvertToValidSharePointFileName(string originalFileName)
        {
            char[] InvalidFilenameCharacters = new[] {'\\', '/', ':', '*', '?', '"', '<', '>', '|', '#', '{', '}', '%', '~','&' };
            string[] InvalidFileNameStrings = new[] { ".files", "_files", 
                "-Dateien", "_fichiers", "_bestanden","_file", 
                "_archivos", "-filer", "_tiedostot", "_pliki", 
                "_soubory","_elemei", "_ficheiros", "_arquivos", 
                "_dosyalar", "_datoteke","_fitxers", "_failid", 
                "_fails", "_bylos", "_fajlovi", "_fitxategiak"};
            
            string validSharePointFileName = originalFileName;

            //Remove Invalid characters
            validSharePointFileName = validSharePointFileName.Remove(InvalidFilenameCharacters);
            
            //Remove consecutive periods(..)
            while (validSharePointFileName.Contains(".."))
            {
                validSharePointFileName = validSharePointFileName.Replace("..", ".");
            }

            //Remove reserved words from end
            foreach (string s in InvalidFileNameStrings)
            {
                if (validSharePointFileName.EndsWith(s))
                {
                    if (validSharePointFileName.Length > s.Length)
                    {
                        validSharePointFileName = validSharePointFileName.Substring(0, validSharePointFileName.Length - s.Length);
                    }
                }
            }

            //Remove period (.) at end
            if (validSharePointFileName.EndsWith("."))
            {
                validSharePointFileName = validSharePointFileName.Remove(validSharePointFileName.Length - 1, 1);
            }

            //Remove period (.) at end
            if (validSharePointFileName.StartsWith("."))
            {
                validSharePointFileName = validSharePointFileName.Remove(0, 1);
            }

            return validSharePointFileName;
        }

Posted in C#, Solutions, SP2010, Tips | Tagged: , , , , | Leave a Comment »

How to create a general purpose Search Results ticker in SharePoint by jQuery

Posted by namwar on May 22, 2010


Business Problem

Display SharePoint search results as a scrolling ticker.

Solution:

SharePoint has two very powerful web parts Search Core Results WebPart and Content Editor WebPart . By combining these two web parts along with some jQuery and jCarousel Lite plug-in we can achieve desired results very quickly. The technique described here is very generic and can be used in CQWP and other web parts too.

What we are doing is quite simple. We use jCarousel plugin for jQuery to scroll the elements of HTML unordered list i.e. <ul>. To achieve this we need an HTML code similar to following

<div class="wrapper">
   <ul id="listticker">
       <li>Item 1</li>
       <li>Item 2</li>
       <li>Item 3</li>
   </ul>
 </div>

We generate this code by updating the XSL of Search Core Results Web part.

Step 1 : Setup required javascript libraries:

  • jQuery: No need to download, we will use it from Google CDN.
  • jCarousel Lite: Please download it from here and store it either under _layouts folder or in a document library at your sharepoint web.

Step 2 : Add Content Editor Web Part (CEWP):

Add CEWP on your target page. Edit the CEWP and paste following code by clicking on Source Editor:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

//Replace the value of src attribute with the path of your jcarousellite.js file
<script type="text/javascript" src="http://moss-server/SearchCenter/Resources/jcarousellite/jcarousellite.js"></script>

<script type="text/javascript">
$(function() {
	$(".wrapper").jCarouselLite({
		vertical: true,
		hoverPause:true,
		visible: 1,
		auto:3000,
		speed:1000
	});
});
</script>

Step 3 : Add Search Core Results Web Part :

Add Search Core Results web part. Configure the web part as you wish. For example, I used it to display all documents by using  Fixed Keyword Query functionality as follows:

  • Fixed Keyword Query = IsDocument:1
  • Cross-Web Part query ID = Query 2

Step 4 : Update XSL of Search Core Results Web Part :

Click XSL Editor and paste following XSL

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:param name="ResultsBy" />
<xsl:param name="ViewByUrl" />
<xsl:param name="ViewByValue" />
<xsl:param name="IsNoKeyword" />
<xsl:param name="IsFixedQuery" />
<xsl:param name="ShowActionLinks" />
<xsl:param name="MoreResultsText" />
<xsl:param name="MoreResultsLink" />
<xsl:param name="CollapsingStatusLink" />
<xsl:param name="CollapseDuplicatesText" />
<xsl:param name="AlertMeLink" />
<xsl:param name="AlertMeText" />
<xsl:param name="SrchRSSText" />
<xsl:param name="SrchRSSLink" />
<xsl:param name="ShowMessage" />
<xsl:param name="IsThisListScope" />
<xsl:param name="DisplayDiscoveredDefinition" select="True" />
<xsl:param name="NoFixedQuery" />
<xsl:param name="NoKeyword" />
<xsl:param name="NoResults" />
<xsl:param name="NoResults1" />
<xsl:param name="NoResults2" />
<xsl:param name="NoResults3" />
<xsl:param name="NoResults4" />
<xsl:param name="DefinitionIntro" />

<!-- When there is keywory to issue the search -->
<xsl:template name="dvt_1.noKeyword">
  <span class="srch-description">
  <xsl:choose>
  <xsl:when test="$IsFixedQuery">
      <xsl:value-of select="$NoFixedQuery" />
  </xsl:when>
   <xsl:otherwise>
      <xsl:value-of select="$NoKeyword" />
   </xsl:otherwise>
  </xsl:choose>
  </span>
</xsl:template>

<!-- When empty result set is returned from search -->
<xsl:template name="dvt_1.empty">
 <div class="srch-sort">
  <xsl:if test="$AlertMeLink and $ShowActionLinks">
    <span class="srch-alertme" > <a href ="{$AlertMeLink}" id="CSR_AM1" title="{$AlertMeText}"><img style="vertical-align: middle;" src="/_layouts/images/bell.gif" alt="" border="0"/><xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text><xsl:value-of select="$AlertMeText" /></a>
    </span>
  </xsl:if>

  <xsl:if test="string-length($SrchRSSLink) &gt; 0 and $ShowActionLinks">
   <xsl:if test="$AlertMeLink">
    |
   </xsl:if>
   <a type="application/rss+xml" href ="{$SrchRSSLink}" title="{$SrchRSSText}" id="SRCHRSSL"><img style="vertical-align: middle;" border="0" src="/_layouts/images/rss.gif" alt=""/><xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text><xsl:value-of select="$SrchRSSText"/></a>
  </xsl:if>
 </div>
 <br/> <br/>

  <span class="srch-description" id="CSR_NO_RESULTS">
   <xsl:value-of select="$NoResults" />

    <ol>
    <li><xsl:value-of select="$NoResults1" /></li>
    <li><xsl:value-of select="$NoResults2" /></li>
    <li><xsl:value-of select="$NoResults3" /></li>
    <li><xsl:value-of select="$NoResults4" /></li>
    </ol>
  </span>
</xsl:template>

<!-- Main body template. Sets the Results view (Relevance or date) options -->
<xsl:template name="dvt_1.body">

  <div class="srch-results">
  <xsl:if test="$ShowActionLinks">
  <div class="srch-sort"> <xsl:value-of select="$ResultsBy" />
   <xsl:if test="$ViewByUrl">
     |
    <a href ="{$ViewByUrl}" id="CSR_RV" title="{$ViewByValue}">
     <xsl:value-of select="$ViewByValue" />
    </a>
   </xsl:if>
   <xsl:if test="$AlertMeLink">
     |
    <span class="srch-alertme" > <a href ="{$AlertMeLink}" id="CSR_AM2" title="{$AlertMeText}"><img style="vertical-align: middle;" src="/_layouts/images/bell.gif" alt="" border="0"/><xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text><xsl:value-of select="$AlertMeText" /></a>
    </span>
   </xsl:if>
   <xsl:if test="string-length($SrchRSSLink) &gt; 0">
     |
     <a type="application/rss+xml" href ="{$SrchRSSLink}" title="{$SrchRSSText}" id="SRCHRSSL"><img style="vertical-align: middle;" border="0" src="/_layouts/images/rss.gif" alt=""/><xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text><xsl:value-of select="$SrchRSSText"/></a>
   </xsl:if>
  </div>
  <br /><br />
  </xsl:if>

	<div class="wrapper">
			<ul id="listticker">
				<xsl:apply-templates />
			</ul>

	</div>

  </div>

  <xsl:call-template name="DisplayMoreResultsAnchor" />

</xsl:template><!-- This template is called for each result -->
<xsl:template match="Result">
  <xsl:variable name="id" select="id"/>
  <xsl:variable name="url" select="url"/>
	<li>
  <span class="srch-Icon">
   <a href="{$url}" id="{concat('CSR_IMG_',$id)}" title="{$url}">
   <img align="absmiddle" src="{imageurl}" border="0" alt="{imageurl/@imageurldescription}" />
   </a>
  </span>
  <span class="srch-Title">
   <a href="{$url}" id="{concat('CSR_',$id)}" title="{$url}">
    <xsl:choose>
     <xsl:when test="hithighlightedproperties/HHTitle[. != '']">
         <xsl:call-template name="HitHighlighting">
          <xsl:with-param name="hh" select="hithighlightedproperties/HHTitle" />
         </xsl:call-template>
     </xsl:when>
     <xsl:otherwise><xsl:value-of select="title"/></xsl:otherwise>
    </xsl:choose>
   </a>
    <br/>
   </span>

   <xsl:choose>
     <xsl:when test="$IsThisListScope = 'True' and contentclass[. = 'STS_ListItem_PictureLibrary'] and picturethumbnailurl[. != '']">
       <div style="padding-top: 2px; padding-bottom: 2px;">
        <a href="{$url}" id="{concat('CSR_P',$id)}" title="{title}">
          <img src="{picturethumbnailurl}" alt="" />
        </a>
       </div>
     </xsl:when>
   </xsl:choose>
   <div class="srch-Description">
    <xsl:choose>
    <xsl:when test="hithighlightedsummary[. != '']">
       <xsl:call-template name="HitHighlighting">
          <xsl:with-param name="hh" select="hithighlightedsummary" />
       </xsl:call-template>
    </xsl:when>
     <xsl:when test="description[. != '']">
        <xsl:value-of select="description"/>
     </xsl:when>
    </xsl:choose>
    </div >
    <p class="srch-Metadata">

    <span class="srch-URL">
     <a href="{$url}" id="{concat('CSR_U_',$id)}" title="{$url}" dir="ltr">
      <xsl:choose>
        <xsl:when test="hithighlightedproperties/HHUrl[. != '']">
           <xsl:call-template name="HitHighlighting">
              <xsl:with-param name="hh" select="hithighlightedproperties/HHUrl" />
           </xsl:call-template>
        </xsl:when>
       <xsl:otherwise><xsl:value-of select="url"/></xsl:otherwise>
      </xsl:choose>
     </a>
    </span>
     <xsl:call-template name="DisplaySize">
      <xsl:with-param name="size" select="size" />
     </xsl:call-template>
     <xsl:call-template name="DisplayString">
      <xsl:with-param name="str" select="author" />
     </xsl:call-template>
     <xsl:call-template name="DisplayString">
      <xsl:with-param name="str" select="write" />
     </xsl:call-template>
     <xsl:call-template name="DisplayCollapsingStatusLink">
        <xsl:with-param name="status" select="collapsingstatus"/>
        <xsl:with-param name="urlEncoded" select="urlEncoded"/>
        <xsl:with-param name="id" select="concat('CSR_CS_',$id)"/>
     </xsl:call-template>
    </p>
	</li>
</xsl:template>

<xsl:template name="HitHighlighting">
 <xsl:param name="hh" />
 <xsl:apply-templates select="$hh"/>
</xsl:template>

<xsl:template match="ddd">
  …
</xsl:template>
<xsl:template match="c0">
    <b><xsl:value-of select="."/></b>
</xsl:template>
<xsl:template match="c1">
    <b><xsl:value-of select="."/></b>
</xsl:template>
<xsl:template match="c2">
    <b><xsl:value-of select="."/></b>
</xsl:template>
<xsl:template match="c3">
    <b><xsl:value-of select="."/></b>
</xsl:template>
<xsl:template match="c4">
    <b><xsl:value-of select="."/></b>
</xsl:template>
<xsl:template match="c5">
    <b><xsl:value-of select="."/></b>
</xsl:template>
<xsl:template match="c6">
    <b><xsl:value-of select="."/></b>
</xsl:template>
<xsl:template match="c7">
    <b><xsl:value-of select="."/></b>
</xsl:template>
<xsl:template match="c8">
    <b><xsl:value-of select="."/></b>
</xsl:template>
<xsl:template match="c9">
    <b><xsl:value-of select="."/></b>
</xsl:template>

<!-- The size attribute for each result is prepared here -->
<xsl:template name="DisplaySize">
  <xsl:param name="size" />
  <xsl:if test='string-length($size) &gt; 0'>
   <xsl:if test="number($size) &gt; 0">
   -
    <xsl:choose>
     <xsl:when test="round($size div 1024) &lt; 1"><xsl:value-of select="$size" /> Bytes</xsl:when>
     <xsl:when test="round($size div (1024 *1024)) &lt; 1"><xsl:value-of select="round($size div 1024)" />KB</xsl:when>
     <xsl:otherwise><xsl:value-of select="round($size div (1024 * 1024))"/>MB</xsl:otherwise>
    </xsl:choose>
   </xsl:if>
  </xsl:if>
</xsl:template>

<!-- A generic template to display string with non 0 string length (used for author and lastmodified time -->
<xsl:template name="DisplayString">
  <xsl:param name="str" />
  <xsl:if test='string-length($str) &gt; 0'>
   -
   <xsl:value-of select="$str" />
  </xsl:if>
</xsl:template>

<!-- document collapsing link setup -->
<xsl:template name="DisplayCollapsingStatusLink">
    <xsl:param name="status"/>
    <xsl:param name="urlEncoded"/>
    <xsl:param name="id"/>
    <xsl:if test="$CollapsingStatusLink">
      <xsl:choose>
          <xsl:when test="$status=1">
              <br/>
              <xsl:variable name="CollapsingStatusHref" select="concat(substring-before($CollapsingStatusLink, '$$COLLAPSE_PARAM$$'), 'duplicates:&quot;', $urlEncoded, '&quot;', substring-after($CollapsingStatusLink, '$$COLLAPSE_PARAM$$'))"/>
              <span class="srch-dup">
              [<a href="{$CollapsingStatusHref}" id="$id" title="{$CollapseDuplicatesText}">
              <xsl:value-of select="$CollapseDuplicatesText"/>
              </a>]
              </span>
          </xsl:when>
      </xsl:choose>
    </xsl:if>
</xsl:template><!-- The "view more results" for fixed query -->
<xsl:template name="DisplayMoreResultsAnchor">
  <xsl:if test="$MoreResultsLink">
   <a href="{$MoreResultsLink}" id="CSR_MRL">
    <xsl:value-of select="$MoreResultsText"/>
    </a>
   </xsl:if>
</xsl:template>

<xsl:template match="All_Results/DiscoveredDefinitions">
  <xsl:variable name="FoundIn" select="DDFoundIn" />
  <xsl:variable name="DDSearchTerm" select="DDSearchTerm" />
  <xsl:if test="$DisplayDiscoveredDefinition = 'True' and string-length($DDSearchTerm) &gt; 0">
    <script language="javascript">
      function ToggleDefinitionSelection()
      {
        var selection = document.getElementById("definitionSelection");
        if (selection.style.display == "none")
        {
          selection.style.display = "inline";
        }
        else
        {
          selection.style.display = "none";
        }
      }
    </script>
    <div>
      <a href="#" onclick="ToggleDefinitionSelection(); return false;">
        <xsl:value-of select="$DefinitionIntro" /><b><xsl:value-of select="$DDSearchTerm"/></b></a>
      <div id="definitionSelection" class="srch-Description" style="display:none;">
        <xsl:for-each select="DDefinitions/DDefinition">
          <br/>
          <xsl:variable name="DDUrl" select="DDUrl" />
          <xsl:value-of select="DDStart"/>
          <b>
            <xsl:value-of select="DDBold"/>
          </b>
          <xsl:value-of select="DDEnd"/>
          <br/>
          <xsl:value-of select="$FoundIn"/>
          <a href="{$DDUrl}">
          <xsl:value-of select="DDTitle"/>
          </a>
        </xsl:for-each>
      </div>
    </div>
  </xsl:if>
</xsl:template>

<!-- XSL transformation starts here -->
<xsl:template match="/">
  <xsl:if test="$AlertMeLink">
   <input type="hidden" name="P_Query" />
   <input type="hidden" name="P_LastNotificationTime" />
  </xsl:if>
  <xsl:choose>
   <xsl:when test="$IsNoKeyword = 'True'" >
    <xsl:call-template name="dvt_1.noKeyword" />
   </xsl:when>
   <xsl:when test="$ShowMessage = 'True'">
     <xsl:call-template name="dvt_1.empty" />
   </xsl:when>
   <xsl:otherwise>
    <xsl:call-template name="dvt_1.body"/>
   </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- End of Stylesheet -->
</xsl:stylesheet>

Step 5 : Enjoy! :
Click OK and exit from edit mode. Your ticker is ready, Enjoy.

Posted in Information, JavaScript, jQuery, Search, Solutions | Tagged: , , , , , , , , , | Leave a Comment »

Custom Edit Form for SharePoint Lists

Posted by namwar on October 21, 2009


If you want to set a custom edit form to your Sharepoint List then please make sure you follow these Golden Rules as correctly suggested by Hugo in a SharePoint news group.

  1. NEVER delete or rename the default pages…
    when you want to create a new EditForm.aspx it’s best to copy it to
    another file and then edit the original one (without renaming it and
    without reassigning the supporting files)…
  2. DON’T ever delete the webparts that exist.
    It’s better to hide them and create new ones “side-by-side”.

These rules are real time savers and I will highly encourage every reader to follow them.

Posted in Customization, Errors, Tips | Tagged: , , , | 1 Comment »

How to use Case statement in RenderPattern of a Custom Field Type

Posted by namwar on October 14, 2009


While designing a custom field type, you may sometime need to render different HTML based on the value of field. For example, if you want to display Red,Amber, Green traffic light images to highlight High,Medium, Low value then you need to dynamically switch image url based  on the value of the field.

In CAML, you have Case structure to implement this switching logic. It works very much like the C# switch-case statement. Following is an example of RenderPattern of a custom field which display different images based on the value of the field.

<RenderPattern Name="DisplayPattern">
      <Switch>
        <Expr>
          <Column />
        </Expr>
        <Case Value="1" >
          <HTML><![CDATA[<img alt="Red" src="/_layouts/IMAGES/ewr210m.gif" />]]></HTML>
         </Case>
        <Case Value="2" >
          <HTML><![CDATA[<img alt="Amber" src="/_layouts/IMAGES/ewr211m.gif"]]></HTML>
        </Case>
        <Case Value="3" >
          <HTML><![CDATA[<img alt="Green" src="/_layouts/IMAGES/ewr209m.gif"]]></HTML>
        </Case>
        <Default>
            <HTML><![CDATA[<span>No Value</span>]]></HTML>
        </Default>
      </Switch>
    </RenderPattern>

Posted in Tips | Tagged: , , , | Leave a Comment »

How to add custom CSS in your WebPart

Posted by namwar on June 14, 2009


If you want to add custom CSS file for your webpart, here is the code:

  1. protected override void CreateChildControls()
  2. {
  3. base.CreateChildControls();
  4. CssLink cssLink = new CssLink();
  5. cssLink.DefaultUrl = “/_layouts/Test.css”;
  6. this.Page.Header.Controls.Add(cssLink);
  7. }

Posted in C#, Solutions, Tips | Tagged: , , | Leave a Comment »

Update List Item without changing Modified By and Modified fields

Posted by namwar on September 30, 2008


If you update a field of a SPListItem obeject from code by using the following code snippet

item[“Title”]=”Updated Title”;

item.Update();

then you will notice that Modified By  and Modified field will be updated also. Sometimes, you just want to update fields without changing Modified By and Modified fields, you can do so by using 

item.SystemUpdate();

instead of item.Update();

SystemUpdate() method just updates the intended field values.

Posted in Object Model | Tagged: , , | Leave a Comment »