jQuery for Everyone: Hourly Summary Web Part
On our Stump the Panel forum, bmix offered this problem:
We’re trying to figure out if there’s any way to show a total of how many people are scheduled for a particular hour of the day.
Well, after refining the problem statement, I put my owsapi to good use. The code below can be placed into a CEWP. You will need jQuery 1.3.1 as well as my owsapi code. Alter the paths to the scripts as needed in the first few lines of the code.
Of course, the CSS styling can be improved on, but this screenshot will give you the basic idea.

The web part will hide the Hourly Summary HTML on any calendar view other than Day-view. On Day view, it pulls the date you are viewing and fetches the data using the owsapi and some dynamic filtering.
UPDATE: Note, if you’re using IE8, I’ve seen problems where the browser cache keeps an old version of the ows xml. You have to clear the cache or change your browser settings for a new file to be retrieved each time the page loads.
Click “Read more…” to see the code. I will also post this web part on the codeplex project examples.
<script type="text/javascript"> if(typeof jQuery=="undefined"){ document.write("<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js' type='text/javascript'><\/script>"); } </script> <script type="text/javascript"> document.write("<script src='/javascripts/ows.js' type='text/javascript'><\/script>"); </script> <script type="text/javascript"> $(function(){ var clean = function(str){ return str.replace(sp," "); }; var getKv = function(){ var params = window.location.search.substring(1).split("&"), kv = {},sp=/%20|\+/g; $.each(params,function(i,e){ var p=e.split("="); kv[p[0]]=decodeURIComponent(p[1]); }); return kv; }; var owsObj = function(){ var obj = $("[id*='ExportToDatabase']").attr("onmenuclick").split(','); return obj; }; var owsCalList = function(){ var obj = owsObj(); var list = obj[1].replace(/'/g,''); return list; }; var owsCalView = function(){ var obj = owsObj(); var view = obj[2].replace(/'/g,''); return view; }; var _today = function(todayStr){ var x; if (!todayStr){ x = new Date(); }else{ x = new Date(todayStr); } var m = x.getMonth()+1, y = x.getFullYear(),d = x.getDate(); if (m<10){m="0"+m;} if (d<10){d="0"+d;} var today = y+'-'+m+'-'+d+' '; return today; }; var getHours = function(todayStr){ var hours={}; var today = _today(todayStr); for (i=0;i<24;i++){ var z = "",zz=""; if (i<10){z="0";} if (i<9){zz="0";} hours[i]=ows.getValues('Calendar','Start Time',['Start Time','<=',today+z+i+":00:00",'End Time','>=',today+zz+(i+1)+":00:00"]); } return hours; }; var kv = getKv(); var todayStr = kv.CalendarDate; if (kv.CalendarPeriod=='day'){ owsapi({ctx:"Calendar",list:owsCalList(),view:owsCalView()}, function(o){ var hours = getHours(todayStr); var td = $("#insertHours tr:first td"); $.each(hours,function(i,e){ $(td[i]).text(e.length); }); }); }else{ $("#insertHours").hide(); } }); </script> <style type="text/css"> #insertHours, #insertHours td { border-color: #000; border-style:solid; border-width:1px; text-align:center; padding:5px; } </style> <div> <table id="insertHours"> <tr> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td></td> </tr> <tr> <td>12:00<br>AM</td> <td>1:00</td> <td>2:00</td> <td>3:00</td> <td>4:00</td> <td>5:00</td> <td>6:00</td> <td>7:00<br>AM</td> <td>8:00</td> <td>9:00</td> <td>10:00</td> <td>11:00</td> <td>12:00<br>PM</td> <td>1:00</td> <td>2:00</td> <td>3:00</td> <td>4:00</td> <td>5:00</td> <td>6:00</td> <td>7:00<br>PM</td> <td>8:00</td> <td>9:00</td> <td>10:00</td> <td>11:00<br>PM</td> </tr> </table> </div>
- JQuery for Everyone: Accordion Left Nav
- JQuery for Everyone: Print (Any) Web Part
- JQuery for Everyone: HTML Calculated Column
- JQuery for Everyone: Dressing-up Links Pt1
- JQuery for Everyone: Dressing-up Links Pt2
- JQuery for Everyone: Dressing-up Links Pt3
- JQuery for Everyone: Cleaning Windows Pt1
- JQuery for Everyone: Cleaning Windows Pt2
- JQuery for Everyone: Fixing the Gantt View
- JQuery for Everyone: Dynamically Sizing Excel Web Parts
- JQuery for Everyone: Manually Resizing Web Parts
- JQuery for Everyone: Total Calculated Columns
- JQuery for Everyone: Total of Time Differences
- JQuery for Everyone: Fixing Configured Web Part Height
- JQuery for Everyone: Expand/Collapse All Groups
- JQuery for Everyone: Preview Pane for Multiple Lists
- JQuery for Everyone: Preview Pane for Calendar View
- JQuery for Everyone: Degrading Dynamic Script Loader
- JQuery for Everyone: Force Checkout
- JQuery for Everyone: Replacing [Today]
- JQuery for Everyone: Whether They Want It Or Not
- JQuery for Everyone: Linking the Attachment Icon
- JQuery for Everyone: Aspect-Oriented Programming with jQuery
- JQuery for Everyone: AOP in Action - loadTip Gone Wild
- JQuery for Everyone: Wiki Outbound Links
- JQuery for Everyone: Collapse Text in List View
- JQuery for Everyone: AOP in Action - Clone List Header
- JQuery for Everyone: $.grep and calcHTML Revisited
- JQuery for Everyone: Evolution of the Preview
- JQuery for Everyone: Create a Client-Side Object Model
- JQuery for Everyone: Print (Any) Web Part(s) Plugin
- JQuery for Everyone: Minimal AOP and Elegant Modularity
- JQuery for Everyone: Cookies and Plugins
- JQuery for Everyone: Live Events vs. AOP
- JQuery for Everyone: Live Preview Pane
- JQuery for Everyone: Pre-populate Form Fields
- JQuery for Everyone: Get XML List Data with OWSSVR.DLL (RPC)
- Use Firebug in IE
- JQuery for Everyone: Extending OWS API for Calculated Columns
- JQuery for Everyone: Accordion Left-nav with Cookies Speed Test
- JQuery for Everyone: Email a List of People with OWS
- JQuery for Everyone: Faster than Document.Ready
- jQuery for Everyone: Collapse or Prepopulate Form Fields
- jQuery for Everyone: Hourly Summary Web Part
- jQuery for Everyone: "Read More..." On a Blog Site
- jQuery for Everyone: Slick Speed Test
- jQuery for Everyone: The SharePoint Game Changer
- JQuery For Everyone: Live LoadTip
Will this work with recurring events? I’d say no, as the “Start time” field in recurring events is not the actual start time.
@Christophe,
Actually, it does seem to support recurring events to a point (as long as it repeats the same time every day).
Bmix did not seem to need recurring event support. And you probably well know, expanding recurring events is a major pain in the rear.
If it’s a problem for bmix, I should be able to update the filter to ignore data with a recurrence node.
UPDATE:
I just tested that. By changing the getHours line to filter Recurrence, it ignores those troublesome events.