I wanted to create a slider that contains images and items from an announcements in my SharePoint 2010 home page. I started writing my own slider, but realized I was just re-creating the wheel. I ended up finding Nivo Slider. It seemed well supported and clean, so I went with that as my jQuery slider. Let’s dive into the code:
First, here is the HTML code I put on the home page. I just added a CEWP and linked it to a text file in a document library. This is the contents of the text file:
<div class="slider-wrapper theme-default"> <div id="slider" class="nivoSlider"> <img src="/PhotoLibrary/cityscape1.jpg" title="#htmlcaption" /> <img src="/PhotoLibrary/cityscape2.jpg" title="#htmlcaption" /> <img src="/PhotoLibrary/cityscape3.jpg" title="#htmlcaption" /> <img src="/PhotoLibrary/cityscape4.jpg" title="#htmlcaption" /> </div> <div id="htmlcaption" class="nivo-html-caption"> <span data-bind="html: sliderCurrentTitle" style="font-weight:bold;text-decoration:underline;"></span> <span data-bind="html: sliderCurrentSummary" ></span> </div> </div>
This interesting parts are lines 9 & 10. I set these two spans to Knockout observable arrays. When the slide changes, I am going to update the contents of these values
And here is the JavaScript document.ready code. Explanation of the code is below the block.
$(document).ready(function () { $('#slider').nivoSlider({ effect: 'sliceDownRight', pauseTime: 4000, beforeChange: function () { VM.sliderNextItem() } }); ko.applyBindings(VM); VM.sliderRetrieveAnnouncments(); var VM = new viewModel(); })
Lines 2-8: are the settings for the Nivo Slider.
Line 6: This is the most important part of this part of the code. This calls the function for get the next announcement when the slide changes.
Line 10: This line calls the function that initially loads all the announcements into a JavaScript object.
Here is the code to my Knockout View Model (explanations below):
function viewModel() { var self = this; self.sliderAnnouncement = function (title, summary) { this.title = title; this.summary = summary; } self.sliderAllAnnouncments = ko.observableArray(); self.sliderCurrentTitle = ko.observable(); self.sliderCurrentSummary = ko.observable() self.sliderCurrentItemIndex = 0 self.sliderNextItem = function () { self.sliderCurrentTitle(self.sliderAllAnnouncments()[self.sliderCurrentItemIndex].title) self.sliderCurrentSummary(self.sliderAllAnnouncments()[self.sliderCurrentItemIndex].summary) self.sliderCurrentItemIndex++ if (self.sliderCurrentItemIndex > self.sliderAllAnnouncments().length - 1) { self.sliderCurrentItemIndex = 0 } } self.sliderRetrieveAnnouncments = function () { var clientContext = SP.ClientContext.get_current(); var oList = clientContext.get_web().get_lists().getByTitle('Announcements'); var camlQuery = new SP.CamlQuery(); camlQuery.set_viewXml("<View><Query><Where><And><IsNotNull><FieldRef Name='Title' /></IsNotNull><Gt><FieldRef Name='Expires' /><Value Type='DateTime'><Today/></Value></Gt></And></Where><OrderBy><FieldRef Name='Created' Ascending='False' /></OrderBy></Query></View>"); var collListItem = oList.getItems(camlQuery); clientContext.load(collListItem); clientContext.executeQueryAsync( Function.createDelegate(this, function () { var listItemInfo = ''; var listItemEnumerator = collListItem.getEnumerator(); while (listItemEnumerator.moveNext()) { var oListItem = listItemEnumerator.get_current(); listItemInfo += '\n' + oListItem.get_item('Title') + '\n' + oListItem.get_item('Summary'); self.sliderAllAnnouncments.push(new self.sliderAnnouncement(oListItem.get_item('Title'), oListItem.get_item('Summary'))); } self.sliderNextItem() }), Function.createDelegate(this, function () { alert('There was an error - sliderRetrieveAnnouncments') })); } }
Lines 3-6 this is the announcement object that I will use to hold the info of a single announcement
Lines 7-9: this is the observable items that are displayed on the slider that contain the announcement’s title and summary
Line 10: this is the index of the current announcement that is being displayed. All I am doing is incrementing it with the NextItem function
Lines 11-18: This is fired when the slide changes (a builtin hook of the Nivo slider). Once it has changed the item, it increments for the next slide.
Lines 19-40: This is the CSOM query to retrieve all the items from the announcement list that have not expired.
Line 23: This is CAML query to get the items that have not expired.
Line 26: This line makes the query.
Lines 30-36: This code loops through the successful returned items.
Line 35: This line puts each of the items into observable array that is used to house all the announcements.
I hope this is helpful to some one. I have been pretty happy with the outcome.
Update: I saw this slider in action at SharePoint conference: http://corporatenewsapp.codeplex.com/
Looked pretty sweet. May have to try to backport to SharePoint 2010.
Hi, Jeff,
Wow! This is pure awesomeness! The best write-up that I have been looking forward to regarding Knockout, CSOM/REST and Sharepoint.
Thank you for taking the time to share with us.
Keep it coming.
Peng
Thanks for taking the time to comment. A nice comment is a great way to start the weekend!
Cheers.
Thanks mate, cannot wait to “play” around with this.
I have custom announcement list with title,description column and i want to devlope rotating content query web part based on this list so plz send me XSLT and Jquery