Sunday, January 20, 2013

Adding a Button to SharePoint 2010 Ribbon


 

How to Add Button to Ribbon – Create new SharePoint project and  Add a new item of the type "Empty Element" to the project and Update the xml with the file below.
Elements.xml  (SPRibbonUpdateToProd)

<?xml version="1.0" encoding="utf-8"?>
  <CustomAction Id="DocFinalRibbon" Location="CommandUI.Ribbon">
    <CommandUIExtension>
      <CommandUIDefinitions>
        <CommandUIDefinition Location="Ribbon.Documents.Manage.Controls._children">
          <Button
            Id="WF.Ribbon.Documents.Manage.UpdateToProd"
            Sequence="40"
            Command="WF.Ribbon.Documents.Manage.UpdateToProd.cmdUpdateToProd"
            Image16by16="/_layouts/1033/images/formatmap16x16.png" Image16by16Top="-144" Image16by16Left="0"
            Image32by32="/_layouts/1033/images/formatmap32x32.png" Image32by32Top="-128" Image32by32Left="-256"
            LabelText="Publish to Prod"
            ToolTipTitle="Click button to Publish to Prod"
            ToolTipDescription="Once you click this button, your checked items are pushed to Prod "
            TemplateAlias="o1"/>
        </CommandUIDefinition>
      </CommandUIDefinitions>
      <CommandUIHandlers>
        <CommandUIHandler
          Command="WF.Ribbon.Documents.Manage.UpdateToProd.cmdUpdateToProd"
         CommandAction="javascript:MarkStatusProduction('{SelectedItemId}');"
          EnabledScript="javascript:function singleEnable()
          {
            var items = SP.ListOperation.Selection.getSelectedItems();
            var ci = CountDictionary(items);
            return (ci == 1);
          }
          singleEnable();"/>

      </CommandUIHandlers>
    </CommandUIExtension>
  </CustomAction>
  <Control Id="AdditionalPageHead" ControlSrc="~/_controltemplates/MarkStatusProduction.ascx" Sequence="40"/>
</Elements>







Check to make sure only one item is selected & Enable ribbon only on single select

<CommandUIHandlers>
<
CommandUIHandler Command="SingleSelectButtonCommandAction="javascript:alert('There is only one thing selected!');EnabledScript="javascript:function singleEnable()
{
var items = SP.ListOperation.Selection.getSelectedItems();
var ci = CountDictionary(items);
return (ci == 1);
}
singleEnable();
" />
</
CommandUIHandlers>



Update selected list item with Update Status ( Any Column with some value)

New Project à Add new item (user control) and update with this code.
UserControl (MarkStatusProduction.ascx) and move it to Control templates folder (not in subfolder name of project), no need .ascx.cs file update, as we write the update code here.

<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MarkStatusProduction.ascx.cs" Inherits="SPUserControl.ControlTemplates.SPUserControl.MarkStatusProduction" %>



<SharePoint:ScriptLink ID="ScriptLink1" Name="SP.js" runat="server" LoadAfterUI="true" Localizable="false" />
<SharePoint:FormDigest ID="FormDigest1" runat="server" />

<script language="ecmascript" type="text/ecmascript">
    var ticketsList;
    var web;
    var context;
    var ticketId;
    var ticketItem;
    var ticketStatusField = "Status";
    var ticketDoneStatus = "Done";
    var ticketResolvedStatus = "Production";

    function MarkStatusProduction(itemId) {
        ticketId = itemId;

        context = new SP.ClientContext.get_current();
        web = context.get_web();
        ticketsList = web.get_lists().getByTitle("TME");  //TME is the name of list
        ticketItem = ticketsList.getItemById(ticketId);

        // This will make sure the contents of the list and list item are actually loaded
        context.load(ticketsList);
        context.load(ticketItem);
        context.executeQueryAsync(OnTicketsListsLoaded);
    }

    function OnTicketsListsLoaded() {
        var currentStatus = ticketItem.get_item(ticketStatusField);

        // There's no need to continue this method when the status is already set to Production or Live.
        if (currentStatus == ticketResolvedStatus || currentStatus == ticketDoneStatus) {
            return;
        }

        // Set the ticket status field to the Production
        ticketItem.set_item(ticketStatusField, ticketResolvedStatus);
        ticketItem.update();

        // Submit the query to the server
        context.load(ticketItem);
        context.executeQueryAsync(OnTicketUpdated, OnError);
    }

    function OnTicketUpdated(args) {
        // Nothing really needed here other than refreshing the page to see that the change has been made
        window.location.href = window.location.href;
    }

    function OnError(sender, args) {
        alert(args.get_message());
    }
</script>


  


Deactivating feature: ( For any changes to Ribbon button like image, functionality, delete it features folder, do iisreset and deploy code again for these may be with new feature id)

To update the code, deactivate features for usercontrol (MarkStatusProduction) and SPRibbonButton added to Ribbon. ID’s for features are found in Templates\features. Update ID’s in the command below in command prompt.
Ex:
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN>stsadm.exe -o deactivatefeature -id  "eb6fe60b-fda7-4e40-bc18-ba88f1e9a954" -url http://yourserver/ -force

Thursday, October 18, 2012

SP 2010 Client Object Model with Examples


Brief  discussion about the ECMA script client object model.
Client OM Architecture
Before getting to actual usage we'll take a brief look at the architecture of the Client Object Model to understand how it functions.
Image1.png

As can be seen in the above diagram all versions of the Client OM go through the WCF Web Service namedClient.svc. This Web Service is located, along with all other SharePoint Web Services, in the folder [SharePoint Root]\ISAPI. The Client OM is responsible for packaging any requests into XML and calling the Web Server, however, when this call takes place is controlled by the developer as you will see. The response from the Client.svc Web Service is sent as JSON and the Client OM is responsible for transforming this into appropriate objects for use in the environment the call was made from.

The Client.svc Web Service has one method, ProcessQuery which takes a Stream object, an XML formatted stream as indicated above, and returns a Stream, JSON formatted. The implementation for this method can be found in the assembly Microsoft.SharePoint.Client.ServerRuntime.dll and the private class ClientRquestServiceImpl. Delving into this method, the first thing you find is an authentication check.

The Client OM uses Windows Authentication by default.


ECMAScript Client OM – Is a client object model extension for using JavaScript or JScript. This API is only available for applications hosted inside SharePoint (for example, web part deployed in SharePoint site can use this JavaScript API for accessing SharePoint from browser using JavaScript). You can however use this ECMAScript Client OM in web part pages or application pages (aspx pages) by referencing a javascript file (SP.js).
To use ECMAScript Client OM, add an entry for the below in your web part ascx control (the webparts deisgn interface) or to your content editor webpart’s HTML Source.

<script src=”/_layouts/SP.js” type=”text/ecmascript”></script>

Also, if If your code modifies SharePoint content you need to add a FormDigest control inside your page.The formdigest control can be added in master page and then all content pages will get it automatically.

<SharePoint:FormDigest runat=”server” />


For quick start add a Content editor webpart to your site page and modify its HTML source. Now, add the reference to SP.JS specified above and paste in the below code. Make sure you have ‘myCustomlist’ created in your site.
FYI… To get current client context we use SP.ClientContext.get_current() and to get current web we use ctx.get_web(). See the full example below.


Adding a List item – Now lets look at something advanced than above.

<script type=”text/javascript”>

function AddItem()
{
var context = new SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getByTitle(‘myCustomlist’);
var listItemCreationInfo = new SP.ListItemCreationInformation();
var newItem = list.addItem(listItemCreationInfo);
newItem.set_item(‘Title’, ‘SPUser’);
newItem.update();
context.executeQueryAsync(Function.createDelegate(this, this.success), Function.createDelegate(this, this.failed));
}
function success() {
alert(‘Added!’);
}
function failed(sender, args) {
alert(‘failed. Message:’ + args.get_message());
}

Delete an item - and finally how to delete an item.
function deleteItem(ItemId)
{
var context = new SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getByTitle(‘myCustomlist’);
var itemToDelete = list.getItemById(ItemId);
itemToDelete.deleteObject();
context.executeQueryAsync(Function.createDelegate(this, this.success), Function.createDelegate(this, this.failed));
}
function success() {
alert(‘Deleted!’);
}
function failed(sender, args) {
alert(‘failed. Message:’ + args.get_message());
}</script>
<a href=”#” onclick=”Javascript:AddItem();”>Create Item</a>
<a href=”#” onclick=”Javascript:deleteItem(1);”>Delete Item</a>

Thanks  LearningSharePoint Admin.

Monday, September 3, 2012

SP 2010 - SharePoint Object Model - basic coding ex's (List, Library)


SP 2010 - SharePoint Object Model


Here we are only discussing the Server Object Model. Server Object Model classes are used for Server-side programming and will be executed on the SharePoint Server Farm.
For programming against the SharePoint items, we need to retrieve the properties and the methods to operate on them. The SharePoint Object Model provides various classes to accomplish this. In this article we can discuss the Object Model with the core classes involved with little amount of coding.

Please note that there are 2 Object Models in SharePoint 2010:
  1. Server Object Model
  2. Client Object Model
Here we are discussing only about the Server Object Model. Server Object Model classes are used for server-side programming and will be executed on the SharePoint Server Farm.

Namespace

The Server Object Model classes are residing in the Microsoft.SharePoint assembly. The general classes are available in the Microsoft.SharePoint namespace and the administration classes inside the Microsoft.SharePoint.Administration namespace.

Core Classes

Following are the important classes and their corresponding SharePoint items.
Class
SharePoint Item
SPFarm
Farm
SPServer
Server
SPSite
Site Collection
SPWeb
Web site
SPControl
Control
SPList
List
SPDocumentLibrary
Document Library
SPContentType
Content Type
SPUser
User
SPException
SharePoint Exception
Programming

Now we can start experimenting with some of the above classes. To begin we can create a SharePoint Console Application. Use the New Project > SharePoint > Console Application project item.
ShareObjM1.jpg

Accessing the List Items in a List

For proceeding with this example, create a list derived from the Contacts template and name it as "My Contacts". 

Add some items inside it with the First Name and Last Name set.

Use the following code inside the Console application and execute it.
using (SPSite site = new SPSite("http://appes-pc/my/personal/dotnet")) // Site Collection
    using (SPWeb web = site.OpenWeb()) // Site    {
        SPList list = web.Lists["My Contacts"]; // List        int i = 1;
        foreach (SPListItem item in list.Items)
        {
            Console.WriteLine("Item: " + (i++).ToString());
            Console.WriteLine(item.Name);
            Console.WriteLine(item.Title);
            Console.WriteLine(item.GetFormattedValue("First Name"));
            Console.WriteLine(item.GetFormattedValue("Last Name"));
            Console.WriteLine(string.Empty);
        }
    }
}
Console.ReadKey(false);

If you receive any build errors regarding a namespace, change the Project Properties > Target to .Net Framework 3.5.
ShareObjM2.jpg

Now try building the application and it should work fine. You will see the following output.
ShareObjM3.jpg

Please note the use of Title and Name properties and the GetFormattedValue() method.

Accessing the items in a Library

Now we can proceed with accessing the document library items programmatically. For proceeding you need to create a document library inheriting from the Document Library template and name it "My Docs". Upload one or two documents into it. We are proceeding to get the file name and length in this example.

Enter the following code in the console application.
using (SPSite site = new SPSite("http://appes-pc/my/personal/dotnet")) // Site Collection{
    using (SPWeb web = site.OpenWeb())                    // Site    {
        SPDocumentLibrary library = web.Lists["My Docs"as SPDocumentLibrary// Library        int i = 1;
        foreach (SPListItem item in library.Items)
        {
            Console.WriteLine("Item: " + (i++).ToString());
            Console.WriteLine(item.File.Name);
            Console.WriteLine(item.File.Length);
            Console.WriteLine(string.Empty);
        }
    }
}


Executing the application, you will see the following results.

ShareObjM4.jpg

SPControl

The SPControl class acts as the base class while developing server controls. It reseides in the namespace Microsoft.SharePoint.WebControls.

SPControl provides static methods that returns reference to the current site, web, web application, module. The methods are:
SPControl.GetContextSite()SPControl.GetContextWeb()SPControl.GetContextWebApplication()SPControl.GetContextModule()

SPException

The SPException class can be used to handle an exception in a try catch block. It represents the exceptions thrown by the server object model.
try{
    // Code here}
catch (SPException ex)
{
    // Handle Exception}


SPUser

The SPUser class can be used to access user information for a SharePoint site. Enter the following code to get the number of users and their names.
using (SPSite site = new SPSite("http://appes-pc/my/personal/dotnet"))
{
    using (SPWeb web = site.OpenWeb())
    {
        foreach (SPUser user in web.AllUsers)
            Console.WriteLine("User: " + user.Name);
    }
}


On running the code you will see the results based on your machine users.

ShareObjM5.jpg

Note

You can add a new list item or library item using the Items.Add() method. For updating and deleting use the item.Update() and item.Delete() methods respectively. More code coverage on these areas will be provided later.

References

http://msdn.microsoft.com/en-us/library/ms473633.aspx 
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webcontrols.spcontrol.aspx 
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spuser.aspx 



Summary

In this article we have explored the SharePoint Object Model and some basic coding examples with List and Library.

Sandboxed Solution Vs Farm Solution


Sandboxed Solution Vs Farm Solution


Foreword
:
Whenever you create a solution for a SharePoint you must have to specify the trust level for the solution. There  are two trust levels defined in the SP2010 i.e.
  1. Sandboxed Solution (or User Solution)
  2. Farm Solution
Figure: Trust Level options
Sandboxed Solutions:
  • Are more restrictive solutions i.e. provide limited functionality
  • A solution that runs in  secure sandbox i.e. in a separate process then wpw3.exe.
  • Are secure by default and are protected by CAS policies i.e. deploying sandboxed solution does not affect other solutions
  • Easy monitoring
  • Are deployed to Site Collection level
  • One limitation is that, they can’t access the File system
  • SPUCHostService.exe, also known as the Sandboxed Code Service, runs on each server on the farm that you are going to allow to work in the sandbox
  • SPUCWorkerprocess.exe process is the sandbox worker process, redeploying Sandboxed solution does not required to restart application pool
  • Can be validated using the sandboxed solution validation by the farm administrator
Farm Solutions:
  • Have no restrictions i.e. provide unrestricted functionality
  • A solution that runs in a wpw3.exe (process)
  • Are less secure in nature, can be protected by implementing custom CAS ploicies
  • Difficult monitoring
  • Can be deployed to any object hierarchy
  • No limitations in accessing File system
  • When deployed, they could run any kind of code and they could make any kinds of changes to the servers.