views:

826

answers:

2

I have a SharePoint list column of type 'Single line of text'. Out of the box SharePoint only provides the ability to display a 'Count' total for this column type. I would like to be able to perform a custom aggregation on the data (specifically to sum numeric data held as text to overcome this deficiency).

I have found examples for doing something similar for calculated columns using XSLT and Javascript but I believe that both of these approaches fail where the data is paginated (only aggregating the subset of the list content displayed on screen).

I want to retain the functionality of the ListViewWebPart (rendering, sorting, filtering, view definition, action menus etc.) but add this functionality. How can I do this?

A: 

The only things you can do with totals are:

Average; Count; Max; Min; Sum; Standard Deviation; Variance

Not sure how to calculate anything else.

JD-Daz
A: 

I've not had a chance to fully test it but this is the best I could come up with:

Create a WebPart which contains two controls:

  1. A ViewToolBar with the context of the list/view to be displayed
  2. A Literal containing the rendered HTML of the view to be displayed

This will then render as the original list/view.

On rendering the WebPart, get the items from the view, specifying the RowLimit as the maximum value so that all items in are retrieved (not just the first page).

Iterate over the items, calculating the total in a suitable data type to retain precision.

Render the total as a hidden value in the HTML and overwrite the rendered Count total with Javascript such as by the method described here.

A rough sketch of the code:

public sealed class TextAggregatingWebPart : WebPart {
  protected override void CreateChildControls() {
    base.CreateChildControls();

    var web = SPContext.Current.Web;
    var list = web.Lists[SourceList];
    var view = list.Views[ViewOfSourceList];

    var toolbar = new ViewToolBar();
    var context = SPContext.GetContext(
    Context, view.ID, list.ID, SPContext.Current.Web);
    toolbar.RenderContext = context;
    Controls.Add(toolbar);

    var viewHtml = new Literal {Text = view.RenderAsHtml()};
    Controls.Add(viewHtml);
  }

  protected override void Render(HtmlTextWriter writer) {
    EnsureChildControls();
    base.Render(writer);

    var web = SPContext.Current.Web;
    var list = web.Lists[SourceList];
    var view = list.Views[ViewOfSourceList];

    var items = list.GetItems(new SPQuery(view) {RowLimit = uint.MaxValue});
    foreach (SPItem item in items) {
      // Calculate total
    }

    // Render total and Javascript to replace Count
  }
}

Note that this doesn't solve the problem with the Modify View screen only showing Count as a total for text columns. Also there is a possibility that changes to the list between the initial rendering by the view and the retrieval of the items for aggregation could produce discrepancies between the total and the displayed items.

Matthew Murdoch