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