0

I have a list where contributors in the organization can submit their resolutions as a results of their troubleshooting process. I want to display the top 10 contributors with the total count of contribution submissions next to their names in a web part:

Example: Top 10 Contributors: 1. createdbyname1 (12) 2. createdbyname2 (10) 3. createdbyname3 (8) etc.

Thank you in advance!

  • These entries are submissions to a list, each as a new item? – KGlasier Aug 23 at 15:37
  • Yes. The entries are submissions to a list and each items are new items. I attempted to use the "Created By" field but wasn't able to get it to just the way I needed it. – Ikaika Aug 23 at 16:40
  • Can you get a screenshot (maybe made with Paint, visio, or photoshop) or flesh out what exactly you're looking for? Because the description you have right now makes it sound like grouping by 'Created by' was the way to go. – KGlasier Aug 23 at 16:57
  • When I group by "Created By", it does show the user's name and the counter next to it, but it leaves the group expansion arrow which allows you to expand the group which I don't want. I want display just the user's name and counter like name-of-contribtor (7). – Ikaika Aug 23 at 17:22
  • Outside of doing an CSOM query, I'm not sure how to go around doing that. If you're comfortable with using JS, I can give a template to make the query, but you'd have to figure out how specifically you want it formatted. – KGlasier Aug 23 at 17:47
0

I'm not sure how to do what you're asking for outside of a CSOM query. Normally I'd just say you could group the list by "Created By" but in the comments you mentioned you didn't want the dropdown of content afterward.

I use a script in my SharePoint 2016 environment that queries all items from a given list/library, view (optional), and site(optional) and you can use JS to manipulate the data however you want. I'll leave that template below. We have it, along with some other functions, referenced in the masterpage so it's available site-collection wide.

To execute a query you need to use a callback to modify the returned data. But here's an example of how we currently use it:

// Give the url for the list you're wanting to query
var libraryURL = 'http://mySiteCollection/sites/mySite/path/to/list';
// Give the name of the view, otherwise just queries the whole list
var listView = 'All Items View';
// If where you're running the script isn't the same site as the library, provide that site's location.
var siteLocation = 'http://mySiteCollection/sites/mySite';

sharepointHomebrew.queries.queryList(libraryURL, listView, siteLocation);
sharepointHomebrew.queries.retrieveItems(function(myItems) {

    for (var i = 0; i < myItems.length; i++) {
        var currentItem = myItems[i].get_fieldValues();
        console.log(currentItem);
    }


});

You need to send a function of some sort in with some sort of parameter. In the example above, it'll itterate over all the items in the given list and print its metadata in the Console (F12 screen). You can select the fields you want and display them however you want... Or count the number of people who posted within some timeframe, etc. This will require a little bit of knowledge on JS, but it shouldn't be too daunting now that the hard part of querying is done.

Here's the template we use.

/**
 * Collection of reusable SharePoint functions that have been peppered throughout the site.
 *
 * This collection of functions includes things like genereic queries to lists or libraries, new
 * prototype methods, and other useful things.
 *
 * @file   This file defines the sharepointHomeBrew namespace
 * @author Kris Glasier.
 * @since  0.2.7
 */
var sharepointHomeBrew = sharepointHomeBrew || {};

sharepointHomeBrew.queries = function () {
   /**
    * Creates a simple way to query SharePoint lists and libraries. Returns all items in
    * the specified library, and associated view if supplied.
    *
    * @namespace sharepointHomeBrew.queries
    * @memberof  sharepointHomeBrew
    *
    * @since 0.0.1
    *
    * @property {object[]} desiredItems   Holds a list of items to return from the library.
    * @property {String}   libURL         Contains user specified URL to a library.
    * @property {String}   viewName       Holds the title of a view in the library.
    * @property {object}   ctx            Holds the ClientContext object.
    * @property {String}   webURL         To redirect the query to another site in which the
    *                                     target library is hosted.
    */

   var desiredItems = null;
   var viewName = null;
   var listType = null;
   var libURL = null;
   var webURL = null;
   var ctx = null;

   var init = function (RelativeURL, LibraryViewName, LibraryWebURL) {
      /**
       * To prime and execute the query.
       *
       * @since  0.0.1
       * @access ????????????????????????????????????????????????????
       *
       * @type     {function}
       * @property {String} RelativeURL     URL to a library. Can be relative or absolute.
       * @property {String} LibraryViewName Title field of a view within the above library.
       * @property {String} LibraryWebURL   URL to the web in which a library is located. Only
       *                                    required if it's not on current web.
       */
      libURL = RelativeURL;
      viewName = LibraryViewName;
      webURL = LibraryWebURL;
      execute()
   }
   var execute = function () {
      /**
       * Begins the query. Waits for sp.js is loaded and SP.ClientContext is available.
       *
       * @since  0.0.1
       * @access private
       *
       * @type     {function}
       */
      if (viewName)
         SP.SOD.executeFunc('sp.js', 'SP.ClientContext', getViewXml);
      else
         SP.SOD.executeFunc('sp.js', 'SP.ClientContext', getAllItemsInView);
   }
   var getViewXml = function () {
      /**
       * Gets the XML view from the SharePoint List Vew specified.
       *
       * @since  0.0.1
       * @access private
       *
       * @type     {function}
       */
      ctx = getContext();

      var view = ctx.get_web().getList(libURL).get_views().getByTitle(viewName);
      ctx.load(view);

      ctx.executeQueryAsync(
         function () {
            getAllItemsInView(view);
         },
         failedQuery
      );
   }
   var getAllItemsInView = function (viewSchema) {
      /**
       * Start the query to get all items in view.
       *
       * @since  0.0.1
       * @access private
       *
       * @type     {function}
       * @property {object} viewSchema ListView schema from supplied list name.
       */
      ctx = getContext();
      viewBase = viewSchema || libURL

      var ContentQuery = buildQuery(viewBase);
      var items = ctx.get_web().getList(libURL).getItems(ContentQuery)

      ctx.load(items);

      ctx.executeQueryAsync(
         function () {
            success(items);
         },
         failedQuery
      );
   }
   var getContext = function () {
      /**
       * Collects the SP.ClientContext based off of the webURL provided.
       *
       * @since  0.0.1
       * @access private
       *
       * @type     {function}
       */
      var context = null;
      if (webURL)
         context = new SP.ClientContext(webURL);
      else
         context = SP.ClientContext.get_current();

      return context;
   }
   var buildQuery = function (loc) {
      /**
       * Builds the XML Query.If no view was given then just select all, recusivelly.
       *
       * @since  0.0.1
       * @access private
       *
       * @type     {function}
       * @property {String} RelativeURL     URL to a library. Can be relative or absolute.
       * @property {String} LibraryViewName Title field of a view within the above library.
       * @property {String} LibraryWebURL   URL to the web in which a library is located. Only
       *                                    required if it's not on current web.
       */
      var re;
      var relLoc;
      var inputQuery;
      var queryBase = '<View Scope="RecursiveAll"><Query>{0}</Query></View>'

      /* We need to extract the XML from the defined view. But if there isn't any defined views
       * we have to create our own XML query. */
      if (typeof (loc.get_viewQuery) !== "undefined") {
         relLoc = loc.get_viewQuery()
      }
      else {
         re = new RegExp("^(" + window.location.protocol + "//)?" + window.location.host)
         relLoc = decodeURIComponent(loc.replace(re, ""))
         relLoc = '<Where><Eq><FieldRef Name="FileDirRef" /><Value Type="Text">{0}</Value></Eq></Where>'.format(relLoc);
      }
      var query = new SP.CamlQuery()
      query.set_viewXml(queryBase.format(relLoc));
      return query;
   }
   var success = function (enumerable) {
      /**
       * Itterate through list and pull all SP ListItems into one variable.
       *
       * @since  0.0.1
       * @access private
       *
       * @type     {function}
       * @property {object} enumerable Linked List of items returned by the async query.
       */
      var oListEnum = enumerable.getEnumerator();
      desiredItems = [];
      /* The items are stuck inside an enumerable object/linked list. We're itterating through
       * to pull all the objects into a more useable form in an external source. */
      while (oListEnum.moveNext()) {
         desiredItems.push(oListEnum.get_current());
      }
   }
   var failedQuery = function (sender, args) {
      /**
       * Failed Query. Output error.
       *
       * @since  0.0.1
       * @access private
       *
       * @type     {function}
       * @property {object} sender No clue.
       * @property {object} args   No clue.
       */
      console.log(
         'Request failed. ' + args.get_message() + '\n' +
         args.get_stackTrace() + '\n' +
         'Please contact an administrator'
      );
   }
   var retrieveItems = function (callback) {
      /**
       * Execute the Callback variable supplied with the given items. Have to wait until
       * async operation is completed.
       *
       * @since  0.0.1
       * @access ????????????????????????????????????????????????????
       *
       * @type     {function}
       * @property {function} callback Function given by user to utilize items.
       */
      if (callback && desiredItems) {
         callback(desiredItems)
         desiredItems = null;
      }
      else {
         setTimeout(function () {
            retrieveItems(callback)
         }, 10)
      }
   }


   return {
      queryList: init,
      retrieveItems: retrieveItems
   };
}();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.