Customizing ActivityFeed markup

ActivityFeed control uses KnockoutJS framework for client side presentation logic and view rendering.
The control has been designed to allow easy modification of view templates. Below is a snippet ilustrating how various parts of ActivityFeed control markup can be customized. All the templates can use KnockouJS
data binding syntax.

<ow:ActivityFeed runat="server">
         <textarea data-bind="value: newPostText" />
         <button data-bind="command: postUpdate">Post</button>

         <ow:UpdatesPlaceholder runat="server" />

         <button data-bind="command: loadNextPage">Next page</button>

         <ow:UpdateContentPlaceholder runat="server" />

         <ow:CommentsPlaceholder runat="server" />


          <ow:UpdateContentTemplate runat="server" ContentType="post">


Template is rendered as a root element of ActivityFeed control. It is bound to ActivityFeedViewModel object.

Default template contains markup to publish new update, refresh updates, search updates and a container for updates list.

<%--Post status updates--%>
<fieldset class="update" 
  data-bind="jQuery: 'fakeInput', css: { disabled: !postUpdate.isInProgress() }">
  <legend class="hidden-visualy">What are you doing?</legend>
  <textarea cols="61" rows="2"
    data-bind="valueExt: newPostText, enable: !postUpdate.isInProgress(), valueUpdate: 'afterkeydown'">
  <button class="right" data-bind="command: postUpdate">Update</button>

<%--Refresh updates--%>
<div class="refresh-updates">
  <button data-bind="click: refreshUpdates">Refresh updates</button>

<%--Search updates--%>
<fieldset class="update search">
  <label for="txtSearch">Search:</label>
  <input id="txtSearch" type="text" class="watermark" 
    data-bind="value: searchTerm, valueUpdate: 'afterkeydown'" 
    title="Write a message...">

<%--Updates placeholder--%>
<af:UpdatesPlaceHolder cssclass="post-list" runat="server"/>

ActivityFeedViewModel is a javascript based object responsible for passing and retrieving data to view.

ActivityFeedViewModel properties:
  • updates - observable array of loaded updates
  • newPostText - text to be posted as a user entered post
  • searchTerm - text to be used for full text filtering of the feed
  • hasMoreUpdates - bool indicating if there is more updates to be loaded (due to page size limit)

ActivityFeedViewModel commands:
  • postUpdate - publish status update
  • loadNextPage - load next package of updates based on pageSize
  • refreshUpdates - refresh list of updates; first page is loaded
  • hasMoreUpdates - used to check if there is more updates on server
  • searchUpdates - filter updates based on searchTerm

UpdatesPlaceholdercontrol - indicates where the list of updates will be rendered. It renders them inside <ul> element.


is used to render each of the updates in UpdatesPlaceholder.

UpdateContentPlaceholder - this is where the update content will be rendered. The template will be selected from UpdateContentTemplates by matching content type.


Renders a list of comments for a given update.

<af:CommentsPlaceHolder runat="server" />


Renders comment item.

          <img alt="Placeholder image from" 
            data-bind="attr: { 'src': publisher().profile.photoUrl, 
              'alt': publisher() }" 
            width="30px" height="30px" />  
      <div class="content-wrapper">
      <p><a href="javascript:void(0);" title="palceholder" 
       data-bind='text: publisher()'></a></p> 
      <p data-bind="text: text"></p>
    <div class="utils">
        <!-- ko if: removeComment.isAllowed -->
        <li><a href="javascript:void(0);" title="placeholder" 
          data-bind="command: removeComment, commandConfirm: function () 
                { return confirm('Remove comment?'); }">Delete</a></li>
        <!-- /ko -->
        <li data-bind="attr: { 'title': publishedOn() }">
          <p><time datetime="2012-05-23T12:12+02:00" 
      data-bind="text: moment(publishedOn()).fromNow()"></time></p></li>

Update contents templates

Each update content type requires UpdateContentTemplate defined in ActivityFeed control. There is default implementation for 'post' content type.

<af:UpdateContentTemplate runat="server" ID="postTemplate" ContentType="post">
  <div class="content-wrapper postContent">
      <a href="javascript:void(0);" title="palceholder" 
          data-bind="text: publisher()"></a>
    <p data-bind="text: content().text"></p>

To define new update content type template, add new UpdateContentTemplate control as a child of UpdateContentTemplates. UpdateContentTemplate requires ContentType property.

<af:ActivityFeed runat="server" FeedType="Global">
    <af:UpdateContentTemplate runat="server" ContentType="contentTypeA">
    <af:UpdateContentTemplate runat="server" ContentType="contentTypeShareB">
    <af:UpdateContentTemplate runat="server" ContentType="contentTypeShareC">
During rendering ActivityFeed will select update content template based on contentType property of update. When ActivityFeedViewModel will not find content template, then 'Template /Content Type/ not found' text will appear.

Last edited Jul 18, 2012 at 9:59 PM by grzwie, version 26


No comments yet.