Wednesday, December 15, 2010

Moved to new location...sudhirke.wordpress.com

Hi,

I have shifted my blog onto new address...

http://sudhirke.wordpress.com/

Thanks for all your support...

Sudhir Kesharwani

Friday, August 6, 2010

jQuery : Enhancing List View web part rendering


Contents
jQuery : Enhancing List View web part rendering    1


Overview



The more I work on jQuery + SharePoint the more I get attracted to it.  There is limitless possibility when we use jQuery in SharePoint.  My latest research includes enhancing the way ListView web part gets rendered.


Once you get hold of the jQuery selector you feel like everything is possible and is very much in your hands. You just have to find a unique way of getting the required DOM element and then it obeys all your orders like a Gin (I am sure I am not exaggerating).


I hope this helps someone in need.


Requirements

The requirement was to display following table in a web part.


Topic
Presenter
Link to Presentation
Link to Video
Some topicSome presenter[ICON to download ppt][Icon to download video]


I first thought of reading the data using our dear friend SharePoint web services and then rendering it on my own way.  But then I thought I should be able to do it in some OOB way.  But the issue was that I had to show two icons that are linked to content
-       Icon to download presentation.
-       Icon to download the video.


Solution



I uploaded all the presentations onto the document library.  The default document library did not have the columns to display the additional metadata about the presentation.  So I created the columns that described the presentation.
-       Topic (Single line of text)
-       Presenter (Single line of text)
-       Video (Hyperlink that will contain the URL to video)


Figure 1


I uploaded the videos in the same folder and updated the metadata of presentation to contain link to the video file.


The benefit that I get out of this is the "Type" column renders the icon and it is linked to the original document.  And I had added the other metadata using columns, this is 70% complete, I still have the task to display the icon that is linked to video. 


When I add the list view web part I could see following view.



Figure 2


Note: Video column was getting rendered as the plain hyperlink.


jQuery – the lightweight magic



Since I am a big fan of jQuery and I knew there must be a way to select everything on the page.  I did some analysis on how this is rendered.  I found that its all Table and TD tags.  So the list view table is rendered as
<TABLE ---- summary="<<Web Part Title>>">


Something worth noting is that the table contains a property called summary and the value contains the web part title.  Now the next job is to find how the link is getting rendered further down the line I found something interesting.


<TR><TD Class="ms-vb2"><A HREF="URL of Video">Text to Display</A></TD></TR>


So it was a TD that contained class "ms-vb2" and contained a child node as <a>.


Once I identified the way it renders the link it was just a matter of replacing the text of <a> with <img> of my choice. 


By this time all the jQuery folks have an idea of how to do that.  Still I thought of copying the magical part of the script.


Note: My apologies for copying this as image, but for some reason I was not able to publish this document when it contained jQuery code. (Google and Blogger started boggling me J)



Figure 3


Just replace web part title with the summary of your list view table.  And here is the final output.



Figure 4


Now you see that I have the desired icon to download video and it looks really good.  And all that I needed was 4 lines of jQuery and understand how SharePoint renders the contents.




RegardsSudhir Kesharwani  MCTS - MOSS 2007 | MCTS - WSS 3.0 | MCPD-EA | MCSD.NET 

Wednesday, June 9, 2010

Using LinQ to query xml

-          Create a xml file with following structure.
<?xml version="1.0" encoding="utf-8" ?>

<Errors>

  <Error voucherId="1" message="Issues while saving data"/>

  <Error voucherId="1" message="Transaction Blocked"/>

  <Error voucherId="1" message="Account is Closed"/>

  <Error voucherId="3" message="This voucher has minumum balance."/>

  <Error voucherId="3" message="Some errors occured while saving the voucher."/>

</Errors>



-          Make sure your code file has following references
using System.Linq;

using System.Xml.Linq;


-          Open Visual Studio 2008 and create a new console application.  Write following code on the program.cs file.
        /// <summary>

        /// Class to represent an error message.  You can have similar class to represent your data

        /// </summary>

        public class Error

        {

            public string VoucherId { get; set; }

            public string ErrorMessage { get; set; }

        }



        static void Main(string[] args)

        {

            //Load XML document on to XDocument object

            XDocument xdoc = XDocument.Load("../../ErrorMessages.xml");



            //Query the XML document and read all the "Error" element.  Prepare a list of Error class from the returned data

            List<Error> errorCollection = (from errors in xdoc.Descendants("Error")

                                           where errors.Attribute("voucherId").Value=="1"

                                          select new Error

                                          {

                                              VoucherId = errors.Attribute("voucherId").Value,

                                              ErrorMessage = errors.Attribute("message").Value

                                          }

                                          ).ToList<Error>();



            //Loop through the returned collection and output the result.

            foreach (Error e in errorCollection)

            {

                Console.WriteLine("Voucher Id: " + e.VoucherId);

                Console.WriteLine("Error Message: " + e.ErrorMessage);

            }

            Console.ReadKey();

        }

    }

-         Execute this console application and it will print the selected nodes from xml


Regards,
Sudhir Kesharwani
Mob: +91 98225 11209

Updating URL field using Lists.asmx

Updating URL field using SharePoint Lists Web Service (Lists.asmx)



One thing that I always complain about SharePoint 2007 web service is lack of documentation and samples.  This is the most neglected areas of SharePoint 2007.  I hope this have been improved in SharePoint 2010 especially since Microsoft has added a lot of new web services.

I had been working on a jQuery based SharePoint solution to display a modal popup to all the visitors. Apart from displaying the jQuery pop up dialogue on page load, I also had to record the history about visitor.

I had to update the list items using Lists.asmx UpdateListItems() method. 

My custom list had following fields:-

Field Name
Type
Description
Title
Text
This field is used to record the login name of logged in user
URL
URL
This field is used to store the link of a text file hosted on server.

After struggling for some time I found that updating the URL field requires some additional attention, since the SharePoint URL field value consists of two parts <URL>, <Description>. Even when working with Object Modal we have to use SPUrlFieldValue.

Please make sure to follow these guidelines while updating the URL field through web services.

-          Please notice that URL needs to include “http://” e.g. http://www.google.com/, generally we write http://www.google.com/ and think that SharePoint should be intelligent enough to append http, but this is not the case.

-          The other thing is that we need to make sure to include a space between the comma (,) and description.  So our URL field value needs to have <URL including http://>,<SPACE><Description>, e.g. http://www.google.com/, Google.

Please pay extra attention while updating/Reading the URL field (through Web Service or thorough object modal).

Here is how the element should look in your soap envelope.

<Field Name=”URL”>http:\\www.google.com, Google</Field>


Here is my soap envelop for calling the UpdateListItems() method. I have omitted the other parts of calling the web service for clarity. (You get lots of examples through Google)
                // The SOAP Envelope
var soapEnv =
"<?xml version=\"1.0\" encoding=\"utf-8\"?> \
                <soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \
                xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" \
                xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> \
                <soap:Body> \
                <UpdateListItems xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\"> \
                <listName>Audit</listName> \
 <updates> \
<Batch OnError=\"Continue\"> \

                                                                                <Method ID=\"1\" Cmd=\"New\"> \

                                                                                                <Field Name=\"Title\">Some Text</Field> \

<Field Name=\"URL\">http://www.google.com, Google</Field> \

                                                                                </Method> \

</Batch>

                </updates> \
                </UpdateListItems> \
                  </soap:Body> \
                </soap:Envelope>";


Hope this helps someone in need J

Regards,
Sudhir Kesharwani 
MCTS - MOSS 2007 | MCTS - WSS 3.0 | MCPD-EA | MCSD.NET 

Saturday, May 15, 2010

Fwd: Hard Work Redefined

Some of the great words from the real motivator Manish Gupta from Chrysalis....just wanted to spread the word to larger audience. Some people think smart work is a substitute for hard work...

Regards,
Sudhir Kesharwani
sudhir.kesharwani@gmail.com
---------- Forwarded message ----------
From: MG's Desk! <desk.mg@chrysalis.net.in>
Date: Sat, May 15, 2010 at 5:56 PM
Subject: Hard Work Redefined

Dear Chrysalian,

Working Hard is considered as one of the most important pathways to achieving success. Since centuries sages, masters, wise men, elders, consultants have been advocating, endorsing and supporting the above statement. I too am in alignment with these folks. (Should I miss out on an opportunity of being linked to the wise ones? ) 

New age generation wants to stick on to Smart Work but I believe even Smart Work involves some "Work".( and many a time ends up with lots of Hard Work) There is no substitute for Hard work. 

I want you to read the above statement one more time and focus on the fact of Hard work leading to success, which implies that if our understanding of Hard work is not what it should be then chances are high that we may not be anywhere near our desired goal. Lets understand Hard work from a different perspective. Lets understand the difference between hard Work and working hard for success.

When in office an executive works as per his schedule and finishes what he had planned to do , this is called hard work, but when the same executive over and above his daily tough schedule goes for an evening course for technical up gradation – this is called working hard for success . At home when a home maker after a tough morning grind of the daily chores takes out time to learn sitar which she so dearly wanted since childhood- that's called working hard for success. A father on coming home tired and exhausted after a long days haul plays with his children with the same vibrancy and freshness which he had at the start of a new day, then it is called working hard for success. A cycle rickshaw puller works real hard for more than 12 hours a day, but he'll be working hard for success when you spot him talking to a co-operative bank for the loan of his second rickshaw. An Entrepreneur when working hard to set his business in motion also thinks and acts on succession planning then it is said he's working hard for success. ( I wonder how Dhirubhai Ambani missed out on that one) 

The concept of working hard for success is the same whether you are a student, a businessman, a sports person or a spouse. Other than our regular work (where we have really worked hard) what are we doing extra to maximise our output is called working hard for success.

Its almost midnight and I feel I have been working hard for success for the day..

Love you lots and wish you a "Hard Working" Life …

MG

Friday, May 14, 2010

jQuery - Announcement carousel for SharePoint

The Annoucements Carousel
Your web part should look like following image (announcements.jpg). You will see all the announcements scrolling one by one, Announcement items are linked to the actual announcement page. When you hover the mouse pointer over a news item, the scrolling will stop automatically.




Note: All the required files can be downloaded from
https://docs.google.com/leaf?id=0B1XvO-SvpjhGYWEyYzNhYTYtZTQ5MS00MGRkLTk2ZmYtYTkwZmNlZDAxNmE2&hl=en
Code is pasted in the email body for reference.


Overview

Recently I have been working on jQuery Carousel plug in and SharePoint. Accidently/fortunately I was able to develop an announcement carousel solution. I thought of posting this to the broader audience. I find this really useful as we can show all the announcements in the smaller area.

Prerequisites

Make sure you have an announcements list in your SharePoint site with some sample announcements.

Step 1 – Required JavaScript and CSS file.

Following files are required for this carousel functionality.
-          jQuery library – jQuery 1.4.1 library,  you can download it from the jQuery site.  I love to rename it to jQuery-latest.min.js.  I have used jQuery-1.4.2.min.js
-          jCarousel script –I have updated the original jCarousel script for hoverPause functionality as per the comments given in the plug in page.  Make sure to use the same.
-          News-Ticker-Source.js – this file contains the actual source code to query the announcements links and making it carousel. Make sure to replace {Site Url} with your site url.
-          News-ticker.css - Contains style sheet for the announcements list.

The folder structure that I followed in my site is as following, highlighted the folders in the hierarchy.
-          Shared Documents

o   BIN

§  JQLIB – this folder contains all the JavaScript files
·         jQuery-latest.js
·         jcarousellite_1.0.1.hoverPause.js
·         news-ticker-source.js
§  CSS -  this folder contains folder for the style sheet and required images
·         News-ticker : Folder for the style sheet.
o   Images: folder for images
§  News1.jpg
§  Mic1.jpg
o   News-ticker.css : CSS filefor styling.


Note: I have given this folder structure since my code has all the references based on this folder structure, however you can have your own folder structure; make sure to update the references in the HTML script and news-ticker-source.js files.


Step 2 – The JavaScript Code

All the required files are attached with this email. Still thought of putting the code of news-ticker-source.js on to this post.

$(document).ready(function()

{

                //Call the method to read data from annoucements list and display it as carousel.

                GetAnnoucementData();

});



/*

This function reads the data from annoucement list and passes the control to processResults method

This makes and ajax call to lists.asmx web service.

Make sure to replace {Site URL} with your SharePoint site url.

*/

function GetAnnoucementData()

{



//Prepare the SOAP envelop for calling GetListItems method from lists.asmx web service

var soapEnv = "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> \

   <soapenv:Body> \

    <GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \

     <listName>Announcements</listName> \

     <viewFields> \

      <ViewFields> \

                                 <FieldRef Name='ows_ID' /> \

                                 <FieldRef Name='LinkTitleNoMenu' /> \

                                 <FieldRef Name='Body' /> \

                                 <FieldRef Name='Expires' /> \

                                 <FieldRef Name='Author' /> \

      </ViewFields> \

     </viewFields> \

    </GetListItems> \

   </soapenv:Body> \

  </soapenv:Envelope>";



/*Post the request envelop to web service thorugh ajax request and pass the results to processResults method*/                                      

        $.ajax({

            url: "{SITE URL}/_vti_bin/lists.asmx",

            type: "POST",

            dataType: "xml",

            data: soapEnv,

            complete: processResult,

            contentType: "text/xml; charset=\"utf-8\""

        });   

}



/* This method parses the resultant xml and prepares the display.

Please replace {Site Url} with your sharepont site url.

*/

function processResult(xData, status)

{

                                //Select the root element.

        var newnews =$("#newsItems");



        var rows;

                               

                                //Check if query returns no rows

        if (xData.responseXML.getElementsByTagName("z:row").length==0)

        {

                                                //Prepare the display for 0 rows.

                                                var url = "{SITE URL}/Lists/Announcements/";

                                                var head = "<li><div class='thumbnail'> <img src='{SITE URL}/Shared%20Documents/BIN/css/news-ticker/images/news1.jpg'></div>";

            var body = "<div class='info'>No news items<a href=" + url + "> Read all</a> <span class='cat'> no items found</span></div>";

                                                var tail = "<div class='clear'></div></li>";

                                                var liHtml = head + body + tail;

                                               

                                                //Append the HTML element to newNews element

            newnews.append(liHtml);

        }

        else

        {

                                                //Read all the rows from responseXml

                                                rows = xData.responseXML.getElementsByTagName("z:row");



                                                jQuery(rows).each(function()

                                                {

                                                //Read the information from returned rows

            var url = "{SITE URL}/Lists/Announcements/DispForm.aspx?ID=" + $(this).attr("ows_ID");

                                                var title = $(this).attr("Title");

                                                var news = $(this).attr("ows_Body");

                                                var author = $(this).attr("ows_Author");

                                                author = author.split('#')[1];



                                                //Prepare the div element

                                                var head = "<li><div class='thumbnail'><img src='{SITE URL}/Shared%20Documents/BIN/css/news-ticker/images/news1.jpg'></div>";

            var body = "<div class='info'><a href=" + url + ">" +  $(this).attr("ows_Title")+ "</a> <span class='cat'>by " + author + "</span></div>";

                                                var tail = "<div class='clear'></div></li>";

                                                var liHtml = head + body + tail;



                                                //Append the resultant element onto newNews element

            newnews.append(liHtml);

                                                });

        }

                               

                                //Append entire newNews element to root Div

                                newnews.appendTo(".newsticker-jcarousellite");

                               

                                //Prepare the Carousel of all the returned items

                                $(".newsticker-jcarousellite").jCarouselLite({

                                vertical: true,

                                hoverPause: true,

                                visible: 4,

                                auto:500,

                                speed:1000

                                });



    }



Step 3 – The HTML Script

Add a content editor web part on your home page and add following HTML Script in the source editor. (Make sure to update the references of script and css files, replace {SITE URL} with your site url).

<link rel="stylesheet" href="{SITE URL}/Shared%20Documents/BIN/css/news-ticker/news-ticker.css" type="text/css" media="screen" />

<script src="{SITE URL}/Shared%20Documents/BIN/jqlib/jquery-latest.min.js" type="text/javascript"></script>

<script src="{SITE URL}/Shared%20Documents/BIN/jqlib/jcarousellite_1.0.1.hoverPause.js" type="text/javascript"></script>

<script src ="{SITE URL}/Shared%20Documents/BIN/jqlib/news-ticker-source.js" type="text/javascript"></script>



<div id="newsticker-demo">   

     <div class="newsticker-jcarousellite">

                                <ul id="newsItems">

        </ul>

    </div>

</div>

<div id='status'></div>


References

-          http://sorgalla.com/jcarousel/


Regards, Sudhir Kesharwani  MCTS - MOSS 2007 | MCTS - WSS 3.0 | MCPD-EA | MCSD.NET 

Thursday, January 7, 2010

Creating default Security Groups for new site collection

Everyday in SharePoint makes you learn something new...this is very true

Al though it is a very small issue and most of us might be knowing this but still thought of sharing with community. In my current assignment we are provisioning SharePoint sites using Workflows and Workflow activities.

I have a list that is used to record a request for new site collection,  i have also developed a custom Visual Studio workflow that contains one custom workflow activity to create a new site collection. My list contains a field that accepts Site Template based on which the new site collection gets created.

Till now everything looks good, but when i create a site based on Team Site through code my new site collection looked different then when it is created using central admin.

It just had one security group where as when we create site using same site template using central admin we can see three groups

1. Site Members

2. Site Owners

3. Site Viewers

After googling around i came to know that apart from provisioning site, SharePoint central admin makes some method calls to provision default security group.

SPSite.CreateDefaultAssociatedGroup(string PrimaryOwnerLogin, string SecondaryOwnerLogin, string GropuPrefix)

This method call will make default security groups (Members, Owners, Visitors) for your new site collection with all the required permissions. 

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.createdefaultassociatedgroups.aspx

This method is called automatically by SharePoint central admin.

Regards,

Sudhir Kesharwani