Monday, February 22, 2010

Add “Edit Item” link or remove “View Properties” link on SharePoint Discussion board Flat/Threaded views

One of my clients had a requirement to add "Edit Item" link on SharePoint Discussion Board Flat/Threaded View like this…

I had searched a lot on the Google to find an answer, but wasn't able to find one. Finally I had decided to dig through SharePoint file system and find how it works.

As we all know all the lists in SharePoint are features so I went in to this location "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\FEATURES\DiscussionsList\Discuss" to open the schema.xml file for Discussion boards. I went through all the code but was not able to exactly find where this "View Properties" link is getting generated. After spending lot of time swimming through the code finally I got a code block which generates "View Properties" link. The code which generates "View Properties" is the field with the name "StatusBar" as shown below.


Now in the "StatusBar" you have something called "DisplayPattern" which contains the code for displaying "View Properties". So I have decided to add "Edit Item" link before "View Properties" link.

Below is the code to add "Edit Item" link before "
View Properties"

I you want to remove "View Properties" link then simply comment the code highlighted in blue.

Note: Making Changes to the Schema file of Discussion Board will affect all the lists of type Discussion Board across the SharePoint farm. So I suggest to create a Custom Discussion Board list definition and implement in that.

You can also add "Edit Item" link like below, without modifying the SharePoint Custom Discussion Board list definition using jQuery Like this…

<script type="text/javascript" src="../../Shared Documents/jquery-1.4.2.js"></script>
<script type="text/javascript">
$(document).ready(function(){
//debugger;
//To display edit link after reply
$("a:contains('Reply')").each(function(index) {
//debugger;
var dispFormID = $(this).closest('td').siblings().find("a:contains('View Properties')")[0].search;
dispFormID = dispFormID.substring(0,(dispFormID.indexOf('&', 0)+1));
var itemID = dispFormID.substring((dispFormID.indexOf('=', 0)+1),(dispFormID.length)-1);
var parentID = "&amp;DiscussionParentID="+itemID;
var editformWithID = "EditForm.aspx"+dispFormID;
var editLink = $(this).closest('td')[0].outerHTML;
editLink = replaceAll(editLink,"reply.gif", "edititem.gif");
editLink = replaceAll(editLink,"Reply", "Edit");
editLink = ReplaceAll(editLink,"&amp;ContentTypeId=0x0107", "");
editLink = ReplaceAll(editLink,"NewForm.aspx?", editformWithID);
editLink = ReplaceAll(editLink,parentID, "");
editLink = "<td class=ms-separator><img src='/_layouts/images/blank.gif' alt=''></td>"+editLink;
$(this).closest('td').parent().append($(editLink));
});
});

function replaceAll(txt, replace, with_this)
{
return txt.replace(new RegExp(replace, 'g'),with_this);
}

function ReplaceAll(Source,stringToFind,stringToReplace)
{
var temp = Source;
var index = temp.indexOf(stringToFind);
while(index != -1){
temp = temp.replace(stringToFind,stringToReplace);
index = temp.indexOf(stringToFind);
}
return temp;
}
</script>

Saturday, February 13, 2010

How to Install SharePoint/MOSS 2007 Development Environment on Windows 7

I was surprised to see a hack from Bamboo Nation on installing MOSS 2007 development environment on Windows 7/Vista. Microsoft officially doesn't support SharePoint installation on Windows 7/Vista. Thanks to Bamboo Nation for finding the hack. It makes lot easier for users to practice on their laptops with medium configurations without the need to have high end configurations. Of course with the new release of SharePoint 2010 Microsoft had opened up SharePoint 2010 installation on Windows 7/Vista. Yet to see how easy that is going to be.

I don't want to detail the procedure of installation, which is found here

http://community.bamboosolutions.com/blogs/bambooteamblog/archive/2009/05/07/installing-wss-3-0-moss-sp2-on-windows-7-rc.aspx

http://community.bamboosolutions.com/blogs/bambooteamblog/archive/2008/05/21/how-to-install-windows-sharepoint-services-3-0-sp1-on-vista-x64-x86.aspx

But want to write about a problem that I came across during the installation.

Once you download and install the Bamboo Nation Installation helper you will have to run SetupLauncher.exe. Setup launcher takes SharePoint.exe or OfficeServer.exe as input and extracts the files in to the following directory C:\Users\Your Login\AppData\temp\Xtracted and launches the SharePoint Installation. Problem is here, what if we have a CD and want to use the files from the CD and not download any trial version from Microsoft's site?

Here is the trick, Copy the files from the CD on to this location C:\Users\Your Login\AppData\temp\Xtracted and then point SetupLauncher.exe to the setup.exe file on the CD. It will give a help popup and fail to extract, but launch the SharePoint setup installation. This is how SetupLauncher.exe works.

Note: If you dont see "Create or extend web application" under application management in central admin run your IE as administrator then you will see it.

Thursday, October 22, 2009

Remove auto focus on SharePoint web form

We normally get auto focus if there is a textbox on the SharePoint web form. That works fine if the textbox is on the top of the web form, but if there is some content on the top and there is a textbox on the bottom of the page then it is a problem i.e since there will be auto focus on the textbox, when the page loads it will directly move the page to bottom to get the autofocus on the textbox. This happens because SharePoint automatically calls a JavaScript function named WebForm_AutoFocus(focusId) to get the auto focus on the textbox. This JavaScript function is present in the Core.js file. If you don’t want the textbox to get auto focus on the page load then simply override this function in your page, i.e simply call this function this way in your page…

function WebForm_AutoFocus(focusId)
{
//when the page loads, focus is automatically set to commets textbox, to remove the auto focus override this function.
//Override the AutoFocus function
}

Monday, September 14, 2009

SharePoint List Operations (Insert, Update and Delete) through JavaScript

I was thinking if there was a good way to access a SharePoint List through JavaScript. You might be wondering why there will be a need to do Insert, Update and Delete operations through JavaScript. Here is a scenario…

Assume that’s you don’t want a column in a SharePoint list to contain duplicate items or there are related lists with primary and secondary relationships, then if you want to update an item in the second list based on the primary list updation then, performing this operations through JavaScript is very comfortable and easy.

This has become possible with the help of SharePoint and Office Live JavaScript API. This API internally calls SharePoint Web Services to perform List Operations. You can find these details here…

http://darrenjohnstone.net/2008/07/22/examples-for-the-sharepoint-and-office-live-javascript-api/

http://darrenjohnstone.net/2008/07/22/a-cross-browser-javascript-api-for-the-sharepoint-and-office-live-web-services/

Wednesday, July 15, 2009

Client side validation for rich text field in SharePoint

I have faced lot of problem in validating a rich text box in SharePoint through JavaScript. Problem is that it does not recognize the text present in the rich text box.

Here is the solution for validating the rich text box.

function validateComments()
{
//debugger;
var Comment = getTagFromIdentifierAndTitle('textarea','TextField','Comment');
var docEditor=RTE_GetEditorDocument(Comment.id);
if (null==docEditor)
return;
strHtml=docEditor.body.innerHTML;
//alert(strHtml);
if(strHtml !="" && strHtml !="
")
{
return true;
}
else
{
alert('Please enter your comment in the box above');
return false;
}
return true;
}

Wednesday, June 17, 2009

Read more>> option for rich text field in SharePoint

One of the most common requirements in customized SharePoint sites is that if there are announcements that are getting displayed then we may want to some lines of text and then show Read more>> option. This is how we implement it.

<xsl:choose>
<xsl:when test="string-length@Body) &gt; 500">
<xsl:variable name="BodyText" select="substring@Body,1,500)"></xsl:variable> <xsl:variable name="BodyContent"> <xsl:call-template name="substring-before-last"> <xsl:with-param name="input" select="$BodyText" /> <xsl:with-param name="substr" select="string' ')" /> </xsl:call-template> </xsl:variable> <xsl:value-of disable-output-escaping="yes" select="concat$BodyContent,' ')" /> <xsl:if test="not@Body = '')"> <xsl:if test="string-length@Body) &gt; 500"> <a href="ViewHeadlines.aspx?ID={@ID}" style="white-space:nowrap" >Read more&gt;&gt;</a> </xsl:if> </xsl:if> </xsl:when> <xsl:otherwise> <xsl:value-of disable-output-escaping="yes" select="@Body" /> </xsl:otherwise> </xsl:choose>

Function:

<xsl:template name="substring-before-last"> <xsl:param name="input" /> <xsl:param name="substr" /> <xsl:if test="$substr and contains$input, $substr)"> <xsl:variable name="temp" select="substring-after$input, $substr)" /> <xsl:value-of disable-output-escaping="yes" select="substring-before$input, $substr)" /> <xsl:if test="contains$temp, $substr)"> <xsl:value-of select="$substr" /> <xsl:call-template name="substring-before-last"> <xsl:with-param name="input" select="$temp" /> <xsl:with-param name="substr" select="$substr" /> </xsl:call-template> </xsl:if> </xsl:if></xsl:template>

This is how the logic works…..
It first checks if the length of the rich text field if greater than 500 characters. If it is greater than 500 characters then it will take the first 500 characters. There is a possibility that the end of 500 characters might be in the middle of a word, so I am again calling a recursive function “substring-before-last” in XSLT which finds the last space in the text and cuts the text to the end of last space. After the end of last space I am appending the Read more>> option.

Problems:

If the rich text contains html elements like anchor tag even those are counted as characters.

Breaking the rich text at 500 characters might result in the middle of the anchor tag or a span or bold(HTML elements), In this case content authors should take care.

If you are copying the text from Word or PDF or any other source, then the styles are carried forwarded and this might result in SharePoint Designer acting cranky like text becoming double automatically etc…. here is an example of this http://blog.thekid.me.uk/archive/2007/02/18/problems-with-sharepoint-designer.aspx

Another way of implementing the same requirement is here
http://mdasblog.wordpress.com/2009/01/20/displaying-the-first-n-words-of-a-long-text-column-with-xsl/

but the problem with this one is that it strips of all HTML formatting.

Playing flash and media files in SharePoint

On our site we had posts(executive messages) getting displayed every week. As a part of this we were storing the title, description, image link(path – this is the link to executive image of who has given the executive message) and video file link(path - we normally upload the video files to the media library and we get the link to video file) in the SharePoint announcements list. Media can be in flash or .wmv format. Requirement is like this.
• There can be video, image and text. In this case when the page loads first image should be displayed then when the user clicks on the image then the image should disappear and video should start playing.
• There can be video and text.
• There can be image and text.
• There can be only text.
• If the text length is more then specified characters then it should get cut of after some specified characters and provide the option of Read more>>

Here is how I have customized XSLT with DataView web part and implemented it.
<script type="text/javascript">

function PlayVideo(photoId, videoId, playerId)
{
document.getElementById(photoId).style.display = "none";
document.getElementById(videoId).style.display = "block";
document.getElementById(playerId).play();
}

function PlayFlashVideo(photoId, videoId, playerId)
{
document.getElementById(photoId).style.display = "none";
document.getElementById(videoId).style.display = "block";
}
</script>











And the output would be like this.