Open SharePoint 2010 Dialog Box from Content By Query Web Part

July 25, 2010

 

Content By Query web part uses xml style sheets for UI and therefore allow us to customized its look and feel by modifying these style sheets. The style sheet which is applied to the items displayed in Content Query Web Part is “Item Style” and you can find it in the folder called “XSL Style Sheets” in the out of the box style library in your site collection.

image

Here is how you can add your own style to ItemStyle.xsl:

1. Download ItemStyle.xsl and open it using Visual Studio.

2. You’ll see multiple "<xsl:template” nodes each of which indicates a Item style.

3. You can create your own style by either copying & pasting existing style and customizing it or create your own style by scratch.

4. I have created my style by copying and customizing style called “Bullets” and following is how my customized style looks like:

<xsl:template name=MyBullets match=Row[@Style=’MyBullets’] mode=itemstyle>
        <
xsl:variable name=SafeLinkUrl>
            <
xsl:call-template name=OuterTemplate.GetSafeLink>
                <
xsl:with-param name=UrlColumnName select=‘LinkUrl’/>
            </
xsl:call-template>
        </
xsl:variable>
        <
xsl:variable name=DisplayTitle>
            <
xsl:call-template name=OuterTemplate.GetTitle>
                <
xsl:with-param name=Title select=@Title/>
                <
xsl:with-param name=UrlColumnName select=‘LinkUrl’/>
            </
xsl:call-template>
        </
xsl:variable>
        <
div class=item link-item bullet>
            <
xsl:call-template name=OuterTemplate.CallPresenceStatusIconTemplate/>
            <
a href=# title={@LinkToolTip}>
                    <
xsl:attribute name=onclick>
                        javascript:

                        function DialogCallback(dialogResult, returnValue)
                        {
                            SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
                        }

                        function onQuerySucceded()
                        {
                        
                        var currentSiteUrl = this.site.get_url() + ‘/_layouts/MyPage.aspx?Source=<xsl:value-of select=@LinkUrl/>&amp;ItemId=<xsl:value-of select=@ID/>‘;

                        var options =
                        {
                        url: currentSiteUrl,
                        title: ‘My Dialog’,
                        allowMaximize: false,
                        showClose: true,
                        width: 600,
                        height: 300,
                        dialogReturnValueCallback: DialogCallback
                        };

                        SP.UI.ModalDialog.showModalDialog(options);
                        }

                        function onQueryFailed()
                        {
                        alert(‘Failed’);
                        }

                        var ctx = SP.ClientContext.get_current();
                        this.site = ctx.get_site();

                        ctx.load(this.site);

                        ctx.executeQueryAsync
                        (
                        Function.createDelegate(this, onQuerySucceded),
                        Function.createDelegate(this, onQueryFailed)
                        );

                    </xsl:attribute>
                <
xsl:value-of select=$DisplayTitle/>
            </
a>
        </
div>
    </
xsl:template>

I modified the hyperlink action and called the JavaScript to open a SharePoint dialog box. You can find lots of posts on how to open a SharePoint 2010 Dialog box and hence i am not including explanation for that here. Also, i have placed the JavaScript directly in xsl file but you can create a separate JS file and can call the JS method in the xsl file.

Notice that i have passed two query string parameters to my dialog page and used @LinkUrl and @ID for Item URL and Item ID respectively. You can do the experiments with your custom columns as well.

5. Upload the ItemStyle.xsl back in Style Library.

6. Now edit the Content By Query Web part and expand the "Presentation" group under content query tool part.

7. Here you will find the newly added style as “My Bullets”.

8. Select the style and you click ok. Now when you’ll click on the link of item in the web part it will open the your dialog page and will pass Item URL and Item Id as query string parameters to it.

Advertisements

Execute SharePoint Power shell commands from C# code

July 25, 2010

A friend of mine asked me yesterday how can we run a SharePoint power shell command like backup a site collection from a C# windows application and i decided to give it a try and here are the steps on how can we do it.

1. Add a reference to “System.Management.Automation” assembly in your project. I could not locate the assembly and a bit goggling suggested that add the following xml to your csproj file by editing it directly.

<Reference Include="System.Management.Automation" />

2. Add a using statement for following namespace:

using System.Management.Automation

3. Call following method on your button click event. This method executes “backup-spsite” command to backup a site collection. Modify the method by changing your site collection URL and backup file path and you are good to go.

  private void ExecutePowerShell()
        {
            PowerShell OPowerShell = null;
            Runspace OSPRunSpace = null;

            try
            {
                RunspaceConfiguration OSPRSConfiguration = RunspaceConfiguration.Create();
                PSSnapInException OExSnapIn = null;

                //Add a snap in for SharePoint. This will include all the power shell commands for SharePoint
                PSSnapInInfo OSnapInInfo = OSPRSConfiguration.AddPSSnapIn(“Microsoft.SharePoint.PowerShell”, out OExSnapIn);

                OSPRunSpace = RunspaceFactory.CreateRunspace(OSPRSConfiguration);

                OPowerShell = PowerShell.Create();

                OPowerShell.Runspace = OSPRunSpace;

                Command Cmd1 = new Command(“backup-spsite”);
                Cmd1.Parameters.Add(“identity”, “Your Site Coll URL”);
                Cmd1.Parameters.Add(“path”, “Back up file path”);

                OPowerShell.Commands.AddCommand(Cmd1);

                OSPRunSpace.Open();

                OPowerShell.Invoke();

                OSPRunSpace.Close();
            }
            catch (Exception Ex)
            {
                //Handle exception
            }
            finally
            {
                if (OSPRunSpace != null)
                {
                    OSPRunSpace.Dispose();
                    OSPRunSpace = null;
                }

                if (OPowerShell != null)
                {
                    OPowerShell.Dispose();
                    OPowerShell = null;
                }
            }
        }

Power shell is a wide subject and there are many things which you can do like executing the commands on remote machine, writing your own commands etc. I’ll write down about these in my future posts.

Lock Down Feature for WSS

December 31, 2009

When we setup the anonymous access for the SharePoint site, all anonymous user gets the limited access to the site. Because of the limited access to the site, users are able to view the list form pages like AllItems.aspx, DispForms.aspx etc.

MOSS provides a feature called ViewFormPagesLockDown which allow us to secure these form pages from anonymous users. The following table details the default permissions of the limited access permission level and the reduced permissions when lockdown mode is turned on.

Permission

Limited access — default

Limited access — lockdown mode

List permissions: View Application Pages

Site permissions: Browse User Information

Site permissions: Use Remote Interfaces

Site permissions: Use Client Integration Features

Site permissions: Open

Unfortunately this feature comes along with MOSS only and is not the part of WSS. So how can we achieve the similar functionality in WSS?

What about creating our own Lock Down feature?

Yes, I developed the custom Lock down feature to achieve this. Following is the code i used to suppress the permissions of Limited Access permission level.

private void UpdateLimitedAccess(bool LockDown, string StrSiteCollURL)
       {
           SPSecurity.RunWithElevatedPrivileges(delegate()
           {
               SPSite Site = new SPSite(StrSiteCollURL);
               Site.AllowUnsafeUpdates = true;
               SPWeb RootWeb = Site.RootWeb;
               RootWeb.AllowUnsafeUpdates = true;
               SPRoleDefinition ByType = RootWeb.RoleDefinitions.GetByType(SPRoleType.Guest);
               if (!LockDown)
               {
                   ByType.BasePermissions |= SPBasePermissions.EmptyMask | SPBasePermissions.ViewFormPages;
                   ByType.BasePermissions |= SPBasePermissions.UseRemoteAPIs;
               }
               else
               {
                   ByType.BasePermissions &= ~(SPBasePermissions.EmptyMask | SPBasePermissions.ViewFormPages);
                   ByType.BasePermissions &= ~SPBasePermissions.UseRemoteAPIs;
               }
               ByType.Update();
           });
       }

Call this method in your feature activation event passing true as parameter value and in feature deactivation event passing false as parameter value.

SharePoint List – Add/Update/Delete Item from Silverlight 3.0 App using lists.asmx

August 26, 2009

In this post, I’ll explain how can we use lists.asmx to Insert/Update/Delete items in a SharePoint list from Silverlight 3.0 app. In my next post I’ll show how can we get the data from SharePoint list and display it in grid in Silverlight 3.0 App.

Below are the steps to create a form using Silverlight 3.0 to insert item in the list:

Create a input form using following XAML:

<UserControl x:Class="SilverLightDemo.ListInsertion"

             xmlns:Primitives= "

             clr-namespace:

                System.Windows.Controls.Primitives;

             assembly=System.Windows.Controls"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d" Width="470" Height="250">


    <Grid x:Name="GridMain" Background="#40E1F0"  Width="450" Height="230" >


        <Grid.RowDefinitions>

            <RowDefinition Height="30"></RowDefinition>

            <RowDefinition Height="200"></RowDefinition>

        </Grid.RowDefinitions>


        <Grid.ColumnDefinitions>

            <ColumnDefinition></ColumnDefinition>

        </Grid.ColumnDefinitions>


        <Border Grid.Row="0" Grid.Column="0" CornerRadius="10" Background="#409DF0" Margin="0,0,0,0">

            <TextBlock Text="Insert record..." Foreground="White" Margin="10,3,0,0"></TextBlock>

        </Border>


        <Grid x:Name="GridInner" Grid.Row="1">


            <Grid.RowDefinitions>

                <RowDefinition></RowDefinition>

                <RowDefinition></RowDefinition>

                <RowDefinition></RowDefinition>

                <RowDefinition></RowDefinition>

            </Grid.RowDefinitions>


            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="100"></ColumnDefinition>

                <ColumnDefinition Width="300"></ColumnDefinition>

            </Grid.ColumnDefinitions>


            <TextBlock Grid.Row="0" Grid.Column="0" Text="Employee Name" Height="25" Foreground="#FF14517B" Margin="10,3,0,0"></TextBlock>

            <TextBox Grid.Row="0" Grid.Column="1" x:Name="TxtEmployeeName" Height="25" Margin="10,3,0,0"></TextBox>

            <TextBlock Grid.Row="1" Grid.Column="0" Text="Designation" Height="25" Foreground="#FF14517B" Margin="10,3,0,0"></TextBlock>

            <TextBox Grid.Row="1" Grid.Column="1" x:Name="TxtDesignation" Height="25" Margin="10,3,0,0"></TextBox>

            <TextBlock Grid.Row="2" Grid.Column="0" Text="Project" Height="25" Foreground="#FF14517B" Margin="10,3,0,0"></TextBlock>

            <TextBox Grid.Row="2" Grid.Column="1" x:Name="TxtProject" Height="25" Margin="10,3,0,0"></TextBox>

            <StackPanel Grid.Row="3" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Left">

                <Button Content="Insert" Height="25" Width="60" Margin="10,3,0,0" Click="InsertButton_Click"></Button>

                <Button Grid.Row="3" Grid.Column="1" Content="Clear" Height="25" Width="60" Margin="10,3,0,0" Click="ClearButton_Click"  ></Button>

            </StackPanel>

        </Grid>


    </Grid>

</UserControl>

Form will look like as picture below:

image

Add a service reference to Lists.asmx located at

http://myserver/_vti_bin/lists.asmx

Add following methods to code file:

private void AddDataToList()

       {

           string [] ArrFieldNames = {"Title","Designation","Project"};

           string [] ArrFieldValues = {TxtEmployeeName.Text.Trim(),TxtDesignation.Text.Trim(),TxtProject.Text.Trim()};

           string StrListName = "SilverLightDemoList";


           ListService.ListsSoapClient ListServiceProxy = new ListService.ListsSoapClient();


           ListServiceProxy.UpdateListItemsCompleted += new EventHandler<SilverLightDemo.ListService.UpdateListItemsCompletedEventArgs>(ListServiceProxy_UpdateListItemsCompleted);


           XElement XElementBacth = GetQueryForListItem(ArrFieldNames, ArrFieldValues, "New");


           ListServiceProxy.UpdateListItemsAsync(StrListName, XElementBacth);

           ListServiceProxy.CloseAsync();

       }

/// <summary>

        /// Returns Xelement containg the Data to be added to the List.

        /// </summary>

        /// <param name="ArrFieldNames">Array containg the name of the fields</param>

        /// <param name="ArrFieldValues">Array containing the values for the field</param>

        /// <param name="operationType">Insert/Update</param>

        /// <returns></returns>

        private XElement GetQueryForListItem(string[] ArrFieldNames, string[] ArrFieldValues, string StrOperationType)

        {

            XElement XElementMethod = new XElement(("Method"), new XAttribute("ID", "1"), new XAttribute("Cmd", StrOperationType));


            for (int i = 0; i < ArrFieldNames.Length; i++)

            {

                XElementMethod.Add(new XElement("Field", ArrFieldValues[i], new XAttribute("Name", ArrFieldNames[i])));

            }


            XElement XElementBatch = new XElement(("Batch"), new XAttribute("OnError", "Return"));

            XElementBatch.Add(XElementMethod);


            return XElementBatch;

        }

Call AddDataToList method from Insert Button click event. In AddDataToList method, i have used UpdateListItemsAsync method to update the list. Add an event handler for this asynchronous method. This event handler will get executed when UpdateListItemsAsync method finishes its job. You can use this event handler to notify the user or for some other stuff post insertion.

Below is the code for UpdateListItemsCompleted event handler:

void ListServiceProxy_UpdateListItemsCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)

       {

           MessageBox.Show("Item Added");

       }

Also, Silverlight does not support XmlDocument/XmlElement classes hence i have used XElement class under System.Xml.Linq namespace.

Lastly, add a ClientAccessPolicy.xml file to the application directory of your SharePoint site. Below is the xml for basic ClientAccessPolicy.xml file:

<?xml version="1.0" encoding="utf-8"?>

<access-policy>

    <cross-domain-access>

        <policy>

            <allow-from http-request-headers="*" >

                <domain uri="*"/>

            </allow-from>

            <grant-to>

                <resource path="/" include-subpaths="true"/>

            </grant-to>

        </policy>

    </cross-domain-access>

</access-policy>

For more information on ClientAccessPolicy.xml file, check out the following link:

http://msdn.microsoft.com/en-us/library/cc197955(VS.95).aspx

Run your Silvelight App and enter data in the input form. Click Insert and an item will get created in your list.

To update/delete the list item, we require the id of that particular item. Hence do not forget to add a text box for the Id field in the input form. Following is the code to update and delete the existing list item:

private void UpdateDataInList()

       {

           string[] ArrFieldNames = { "ID","Title", "Designation", "Project" };

           string[] ArrFieldValues = {TxtId.Text.Trim(), TxtEmployeeName.Text.Trim(), TxtDesignation.Text.Trim(), TxtProject.Text.Trim() };

           string StrListName = "SilverLightDemoList";


           ListService.ListsSoapClient ListServiceProxy = new ListService.ListsSoapClient();


           ListServiceProxy.UpdateListItemsCompleted += new EventHandler<SilverLightDemo.ListService.UpdateListItemsCompletedEventArgs>(ListServiceProxy_UpdateListItemsCompleted);


           XElement XElementBacth = GetQueryForListItem(ArrFieldNames, ArrFieldValues, "Update");


           ListServiceProxy.UpdateListItemsAsync(StrListName, XElementBacth);

           ListServiceProxy.CloseAsync();

       }

private void DeleteDataFromList()

       {

           string[] ArrFieldNames = { "ID"};

           string[] ArrFieldValues = {TxtId.Text.Trim()};

           string StrListName = "SilverLightDemoList";


           ListService.ListsSoapClient ListServiceProxy = new ListService.ListsSoapClient();


           ListServiceProxy.UpdateListItemsCompleted += new EventHandler<SilverLightDemo.ListService.UpdateListItemsCompletedEventArgs>(ListServiceProxy_UpdateListItemsCompleted);


           XElement XElementBacth = GetQueryForListItem(ArrFieldNames, ArrFieldValues, "Delete");


           ListServiceProxy.UpdateListItemsAsync(StrListName, XElementBacth);

           ListServiceProxy.CloseAsync();

       }

Create a user friendly URL for your SharePoint site

August 9, 2009

Often we need to create a user friendly URL for our SharePoint site like http://demo.sharepoint.com.

Following are the major activities needed to be performed to achieve this:

  1. Create a DNS entry
  2. Add an Alternate access mapping
  3. Set the host header in IIS web application


Create a DNS entry

Add a record for demo.sharepoint.com in the DNS server. Your IT administrator should be able to do it for you.

However, a DNS Server is not necessary. The hosts file can also be used, but that means the hosts file must be edited on each client.

Host file path:  “%WinDir%\system32\drivers\etc”


Add an Alternate access mapping:

  1. Open Central Administration site.
  2. Click on Operations tab.
  3. Under “Global Configuration” section, click on “Alternate access mappings”.
  4. 1

  5. Click on “Show All” menu in the right and then click on “Change Alternate Access Mapping Collection”.
  6. 2

  7. Select the web application for which you wish to create a user friendly URL. In my case the name of the Web App is DemoApp.
  8. 3

  9. Click on “Edit Public URLs”.
  10. 4

  11. In the “Public URLs” section, in “Default” text box, enter the fully qualified URL for the web application. In my case it is http://demo.sharepoint.com. In the “Intranet” text box enter the original URL of the web application.
  12. 5

  13. Click  save.


Set the host header in IIS web application

Note: This activity is to be performed on all the front end servers.

  1. Open IIS.
  2. Right click on the web application and select properties. In my case, the Web App name is DemoApp.
  3. 6

  4. Click on “Advanced…”.
  5. 7

  6. Click on Add”.
  7. 8

  8. Fill the  TCP port and Host Header Value as shown below and click OK.
  9. 9

  10. Your screen should like as shown in the screenshot below.
  11. 10

    Note: If you have your site at port 80 in that case you need not add a new identity. Instead you can edit the existing entry and specify the host header value for it. A screenshot of that is below:


    11

  12. Click Ok and apply.
  13. Restart IIS.

You should be able to access your site now using the URL http://demo.sharepoint.com.

12