Sunday, February 21, 2016

SharePoint 2013 - Event Handler Manager

If you are developing event receivers in SharePoint, things can get a little bit messy, because, sometimes you might find yourself in a situation where you have multiple events firing on your SharePoint lists and you don't know why. And SharePoint platform doesn't give you any tool for monitoring events in your farm

Sometimes you accidentally deploy multiple event receivers and you aren't aware of that, but there is no way you can know how many event receivers per one list you have.

But, luckily, there are many free tools for monitoring and even creating new event receivers for SharePoint lists. One of them is "SharePoint 2013 Event Manager", a simple windows application which enables to monitor all event receivers in you farm, create new events or delete existing events:

Download tool from CodePlex:
SHAREPOINT 2013 EVENT MANAGER

Friday, February 19, 2016

SP 2013 Provider Hosted Apps - How to access items on subsite items of HostWeb

Recently I came across a problem when working with provider hosted apps. If you are trying to access items (fetching lists, or list items) in Host Web (using CSOM), then you need to set the appropriate permissions in AppManifest of the app.
With the permission "Web" you can access items on Host web, but if you want to access items on a subsite of the Host Web, then you will get "Access denied" error.

SOLUTION:
In the AppManifest you need to change permission from "Web" to "SiteCollection". This should allow you to access lists and other items on that all subsites in Host Web.




Monday, June 22, 2015

SharePoint 2013 - Get list items with javascript

In one of my older posts (here), I demonstrated how to fetch items of a SharePoint list with javascript using SPServices. In SharePoint 2013, we are no longer using SPServices. Now we have two different approaches; JSOM (JavaScript Object Model) and REST (OData) services. 

Now, I will not describe in details how each of them works, I will just show you the code for getting list items in each technology. If you want to know more details about these technologies and differences between then, check this post on Andrew Connell's blog:
http://www.andrewconnell.com/blog/sharepoint-2013-csom-vs.-rest-...-my-preference-and-why

Example code for both REST and JSOM:

REST:



function GetListItemsFromSPList() {
    var siteUrl = _spPageContextInfo.webAbsoluteUrl;

    $.ajax({
        url: siteUrl + "/_api/web/lists/getbytitle('My List Title')/items",
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        success: function (data) {
            // Returning the results
            var listItems = data.d.results;
            listItems.forEach(function (entry) { 
               // Do something with list item which is in 'entry' object              
            });
        },
        error: function (data) {
            alert("Error: " + data)
        }
    });
}
 


Explanation: First, we are getting the URL of our site in through object that resides in every SP page (_spPageContextInfo). Then, we making ajax call to REST APIto get list item of a SP list (you need to put your list's name instead 'My List Title'). If call was successful, then list items will be returned in object 'data.d.results' and we can access them in forEach loop.


JSOM:



function GetListItemsFromSPList(listId) {   
    // here we are fetching current context, but you can also use explicit call (where 'site'  is URL of your site):  var clientContext = new SP.ClientContext(site);
    var context = new SP.ClientContext.get_current();
    var web = context.get_web();
    var list = web.get_lists().getById(listId);
    var query = SP.CamlQuery.createAllItemsQuery();
    var allItems = list.getItems(query);
    context.load(allItems, 'Include(Title, Id)');
    context.executeQueryAsync(Function.createDelegate(this, function () { onQuerySuccess(allItems); }),
        Function.createDelegate(this, this.onQueryFailed));
}

function onQuerySuccess(allItems) {
    var ListEnumerator = allItems.getEnumerator();
    while (ListEnumerator.moveNext()) {
        var currentItem = ListEnumerator.get_current();
        // do something with your list item

    }
}
function onQueryFailed(sender, args) {
    alert('Error: ' + args.get_message() + '\n' + args.get_stackTrace());
}
 


Explanation: In method 'GetListItemsFromSPList' we are getting the current context, getting the SP list by its id (it is also possible to get list by title) and we are making query to get all items from that list ('SP.CamlQuery.createAllItemsQuery()'). After that, we need to explicitly include which fields of our list items we are going to use. For example, I included 'Title' and 'Id' field (context.load(allItems, 'Include(Title, Id)')). After that, we are making async call to SP list (context.executeQueryAsync). If query was successful, than method 'onQuerySuccess' will be called. In this method, we can now iterate through our list items and do want we want with them. If query was not successful, method 'onQueryFailed' will be called.

Tuesday, June 9, 2015

SP2013 - Programmatically filter workflow task list for tasks assigned to current user or his group

If you are using SharePoint workflows (default or custom), you are probably using tasks and Workflow Task List. In the default view of that list, every user can approve every task in the list. This could be a big problem, because, if users have option to do something wrong, they will probably do it. Usually, the requirement is that users are allowed to see only their own tasks.

If you want to do this programmatically, it is easy to make caml query that would filter tasks for a logged in user, but what if task is assigned to a SP group and current user is a member of that group? Fortunately, this is a simple task too.

For this example, I created SharePoint console application in Visual Studio. This example fetches your Workflow Task List, gets the default view of that list and sets the filter on the list items. It filters tasks that are assigned to current user and tasks assigned SP groups that user is a member of. This is the code:




namespace SharePointConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SPSite site = new SPSite("http://dev/mySite"))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPList list = web.Lists["WorkflowTaskList"];

                    for (int i = 0; i < list.Views.Count; i++)
                    {
                        SPView view = list.Views[i];
                        if (view.DefaultView)
                        {
                            web.AllowUnsafeUpdates = true;
                            view.Query = @"<Where>
                                           <Or>
                                             <Eq>
                                               <FieldRef Name='AssignedTo'/>
                                               <Value Type='Integer'><UserID/></Value>
                                             </Eq>
                                             <Membership Type='CurrentUserGroups'>
                                             <FieldRef Name='AssignedTo'/></Membership>
                                           </Or>
                                         </Where>";
                            view.Update();
                            web.AllowUnsafeUpdates = false;
                        }
                    }
                }
            }
        }
    }
}




Source:
https://msdn.microsoft.com/en-us/library/office/aa544234.aspx?f=255&MSPPError=-2147217396