Sort and Filter SharePoint List Data with Angular JS

Angular JS is a Javascript that extends HTML with new attributes and allows you to create declarative templates and do data-binding. If you want to learn more about Angular go here.  I have heard a lot about Angular and wanted to try it out so here is how I got it working on a SharePoint 2010 site.

Fist I included all my dependencies on the page

<script src="/SiteAssets/jquery-1.12.0.min.js"></script>
<script src="/SiteAssets/angular.min.js"></script>

First I created a new app and defined some variables

 
<script type="text/javascript">
// make a new app and give it a new 
angular.module('spApp',[])

.controller("contactController", function($scope){    
    GetListItems($scope, "ContactList");   // calling this function to get items from my list and add them to my scope
  $scope.sortType     = ''; // set the default sort type
  $scope.sortReverse  = true;  // set the default sort order
  $scope.searchFish   = '';     // set the default search/filter term
    
});  

function GetListItems($scope, listName){    //this function gets all the items from the list
    $.ajax({    
        url: "/_vti_bin/listdata.svc/"+listName+"?select=FullName",    // this is specific to SP2010 the URL is different for 2013 
        method: "GET",    
        async: false,    
        headers: { "Accept": "application/json;odata=verbose" },    
        success: function(data){    
            $scope.items = data.d.results;    // assigning the data from the list to the scope so I can use it
           // console.log(data.d.results);
        },    
        error: function(sender,args){    
            console.log(args.get_message());    
        }    
    });    
} 
</script>  

Next we need to get some data to work with.  In this example I am using a contacts list.  I used some of the code from this article to get it working but I had to tweak it to work with SharePoint 2010.

Ok so now that we have the items from the list we need to display them on the page, for this I built a simple table and added some code to allow for sorts and filters. I have included comments in the code to help it make sense. This article explains in more detail how the sort and filter works.



<div ng-app="spApp" ng-controller="contactsController" >
 //the app name and controller name here should match what you defined in the js code

        <input type="text" class="form-control" placeholder="Search" ng-model="searchContact" id="rosterSrchBx">  //search box angular uses the value entered in this box to filter the table


<table class="rosterTbl">
    
<thead>

<tr>
         
<td>
          <a href="#" ng-click="sortType = 'FullName'; sortReverse = !sortReverse"> //sort order code
            Name 
            <span ng-show="sortType == 'FullName' && !sortReverse" class="fa fa-caret-down"><img src="/_layouts/images/ARWDOWN.GIF"/></span>
            <span ng-show="sortType == 'FullName' && sortReverse" class="fa fa-caret-up"><img src="/_layouts/images/ARWUp.GIF"/></span>
          </a>
        </td>


<td>
          Phone Number
        </td>


<td>
          Cubicle
        </td>


<td>
          Email
        </td>

     </tr>

  </thead>


<tbody>    
    
<tr ng-repeat="item in items | orderBy:sortType:sortReverse | filter:searchContact" > //this is basically a repeater that spits out all the items in the list        
        
<td class="ms-vb">
           {{ item.FullName }} // this is how you display a column from the list, you have to use the internal name of the column
        </td>


<td class="ms-vb">
                   <img src="/_layouts/images/gbwcawpt.gif" align="absmiddle"/> 
                   {{ item.Phone }}
             </td>


<td class="ms-vb">
                   {{ item.Cubicle }}
             </td>


<td class="ms-vb"> 
                  <a href="mailto:{{ item.Email }}">
                   {{ item.UFOUOEmail }}
                  </a>
             </td>

            </tr>

       </tbody>

    </table>

</div>


To make it look a bit better I also added some CSS

.rosterTbl {
   padding:7px;
}
.rosterTbl td {
   padding:9px;
}
.rosterTbl thead td{
    background-color:#bfe8ff; 
    border:1px solid #90c6e5;
}
.rosterTbl tbody tr:hover {
   background-color:#edf8ff;
}
.rosterTbl tbody td {
   border-bottom:1px solid #eee;
}
#rosterSrchBx{
   padding:7px; 
   padding-left:25px; 
   font-size:1.7em; 
   margin:5px 0px; 
   background:url('/_layouts/images/magnify.gif') no-repeat 3px; 
   border:1px solid #ccc; 
}

Read More

SP Services SPGetCurrentUser Error

function getCurrentUserInfo() {
var thisUsersValues = $().SPServices.SPGetCurrentUser({
fieldNames: ["ID", "Name", "Picture", "Email"],
debug: false
});
var name = thisUsersValues["Name"];
var userPic = thisUsersValues["Picture"];
}

But I was getting this error in Internet Exporer, everything worked fine in Chrome:

SCRIPT438: Object doesn’t support property or method ‘replace’

File: jquery.SPServices-2014.01.js, Line: 2414, Column: 17

In Chrome I looked at the values being returned for the user and I noticed that the ID value always came back empty. In the application I was working on I did not really need to use the users ID because the username/email are enough to find the users profile.  So I removed ID from the list of field names and everything started working again. If I needed to get other information about the user it is possible to just call this spservices function using the username from the code above.

 

Hope this helps someone.

Read More

SharePoint Featured Content Slider

SharePoint Featured Content Slider for 2010

SharePoint Featured Content Slider

So I rewrote this web part to work a little better in SharePoint 2010. I made a few minor changes and improvements. If you can think of other improvements put them in the comments. Here is the older version.

Whats new

  • Added an order field to the List template to allow more control of the display order. In the list template this field is setup to require unique values.
  • Re-wrote the CSS to include some new CSS3 enhancements. If you are using a newer browser the slider will look better.
  • Tested across muliple browsers. See screenshots below.

Read More

Hiding the user presence icon

When you are using a data view web part to display information including a person field SharePoint always shows the status icon beside thier name.

status icon
status icon

In some cases this is exactly what you want and can be very useful. But sometimes you just want to show a name and nothing else. With most fields you can just change the formatting options to change the display. If you choose to format the value as text SharePoint spits out this long html string.

<nobr><span><A HREF="/sites/site/_layouts/userdisp.aspx?ID=2">Cavins, David R</A><img border="0" height="1" width="3" src="/_layouts/images/blank.gif"/><a href='javascript:' onclick='IMNImageOnClick();return false;' class='ms-imnlink'><img name='imnmark' title='' border='0' height='12' width='12' src='/_layouts/images/blank.gif' alt='No presence information' sip='email@email.com' id='imn_8,type=sip'/></a></span></nobr>

Format as

Each of the other formatting options also provides un-desirable results.
Using some basic CSS we can get rid of the status icon and format the text so it does not look like a hyperlink. First wrap the field value in an element with a class. I used a span with a class of “person”

<span class=”person”>
<xsl:value-of select="@Author" />
</span>

Then just add this css to the page.

.person nobr span a {
text-decoration:none;
color:black;
cursor:default;
}

If you want to take it a step further you can use jQuery to remove the ‘href’ attribute. Using jQuery we can target the container with the link in it and then change the href value.

$('span.person a').removeAttr('href');

Read More

Filter Lists by Date Range

On a recent project one of the requirements was that users be able to filter a list by a date range.  To this I tried using two date filter webparts connected to a data view webpart.  A detailed description of how to set this up can be found here.  This solution worked well enough but there was a page refresh after the user entered each date, so the user enters the first date (page refresh) user enters second date (page refresh again) and finally they get the results.  This annoyed me, I wanted to remove the extra page loads so I tried several things and this is what I finally came up with.

Setup

Using a content editor webpart build the form elements needed to collect the dates, two inputs and a search button.  Give each input a unique ID. Here is the code I used.

<script language="JavaScript">
function submitForm()
{
var startDate = document.getElementById('startDate').value;
var endDate = document.getElementById('endDate').value;
window.parent.location="default.aspx?T1=" + startDate + '&T2=' + endDate;
}
</script>
<p><div id="dateDiv" style="display:none;" class="filterBox">
<h4>Date Search</h4>
        Between
<input name="startDate" type="text" id="startDate" value="" size="15" class="dateformat-Y-ds-m-ds-d" value="">
and
<input name="endDate" type="text" id="endDate" value="" size="15" class="dateformat-Y-ds-m-ds-d" value="">
 YYYY-MM-DD
<input type="submit" name="Submit" value="Go"  onClick="submitForm();this.disabled=true;">
</div>

The class names are used to activate the date picker script but can be whatever you want. I used this date picker script from Frequecy Decoder

The submitForm() function simply takes the values from the inputs and adds them as query string variables at the end of the URL. We can now use these values to filter the list.

Filtering the Data View Web part

To filter the content of the DVWP based on the date we have to setup some parameters for the start and end dates.   Under ‘Common Data View Tasks’ just choose ‘Parameters’ for both the start and end date set the source as ‘Query String’. The query string variable will be whatever you defined in the JavaScript so in this case they are T1 and T2. Set the default value for the start date to some date impossibly far in the past and for the end date set it to something like the year 3000. This will ensure that the list will show all records if no values are passed for the start and end dates.

parameters

Then all you have to do is setup your filter based on the parameters from the query string.

filter

You’re done.

Things to remember

The date has to be passed in YYYY-MM-DD format in order to work.

If the detault values for your start and end date parameters are not set high / low enough all records will not display when not date range is entered.

Read More

Dynamic Drive’s Featured Content Slider in Sharepoint

There is an updated version of this solution for SharePoint 2010 found here

I have used Dynamic Drive’s Featured Content Slider on a couple of recent projects and wanted to see if I could get it working in SharePoint. There were several key requirements:

  1. User can easily add items
  2. Users  can choose a style for each item
  3. Expired Items must not show
  4. Each item will have a Title, Body and a customizable “read more” link.

Here’s how I did it.

Dynamic Drive's Featured Content Slider in Sharepoint
Featued content slider

 

The list

First I created a custom list to store the slider items.  These are the columns I used:

  • Title – Single Line of text
  • Body – Multiple Lines of text
  • Link URL – HyperLink
  • Expiration – Date and Time (expired items will not be shown)
  • Image – Picture
  • Style – Choice  (we will use this column to allow users to choose the style of each item)

On the page I used a DataView WebPart to display the Title, Body, Image and Link URL columns.   Using Sharepoint Designer I setup filtering on the expiration date.  To do this in design view right click on the data view webpart and bring up the “Common Data View Tasks ” box and choose Filter.  In the window I set the conditional statement so that items would only be shown if the expiration date was greater than today. (more…)

Read More