0

For my sharepoint list, I have several views, which all reflect the same basic list, but with different filters.

I am wanting to render the header section of this page, and to suffix each view header name with the counts of items that are covered by the view.

(e.g. All items [20] In progress [10] Complete [10])

My plan was to use a CSR Prerender, call SPServices to get the statistics, then plug these values back into the form using a Header render, as per the code below

RegisterModuleInit(".../jquery-1.11.3.js", RegisterPreRender); // CSR-override for MDS enabled site
 RegisterPreRender();


(function RegisterPreRender() {
var ctx = {};
ctx.Templates = {};
ctx.Templates.Header = renderCustomHeader;
ctx.OnPreRender = preRenderHandler;
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(ctx);

})();


function renderCustomHeader(renderCtx) { 
alert('in header');
var headerHtml = RenderTableHeader(renderCtx);
var headerHtml = headerHtml.replace(">All Items<", ">All Items ["+allnum+"]<");
var headerHtml = headerHtml.replace(">In Progress<", ">In Progress ["+prognum+"]<");
var headerHtml = headerHtml.replace(">Complete<", ">Complete ["+compnum+"]<");
return headerHtml;
};

function preRenderHandler(renderCtx) { 

alert('in view counts');
$().SPServices({
    operation: "GetListItems",
    async: false,
    listName: "Project Status",
    CAMLQuery: "<Query></Query>",
    CAMLViewFields: "<ViewFields>  <FieldRef Name='Status' /> </ViewFields>",
    completefunc: function (xData, Status) {
      $(xData.responseXML).SPFilterNode("z:row").each(function() {

       var liHtml = $(this).attr("ows_Status");

-- do extra processing to tally according to status

       alert(liHtml); 

      });
    }
  });
alert('finished');

};

My understanding is that SPservices also requires jquery, so how do I use RegisterModuleInit to register both jquery as well as the SPservices script?

Is SPservices the best approach to use for this situation? Is RegisterModuleInit the best way to load the scripts?

Notes: - The above code is being attached via the JSLINK option on the webpart.
= SP2013 is being used.

Thanks!

  • But renderCtx allready has all the List Items. Why do you need to call for them again with SPServices? – Danny '365CSI' Engelman Sep 7 '15 at 7:46
  • I did try this. However, the view that was used had a grouped by function. So when I went through the rows, only the rows that were visible in that view were being returned. Also, when the other views were selected, I needed to get counts for the number of rows that were available for those other views. Lastly, the field that I was using to determine the counts wasn't displayed on any view. – southskies Sep 8 '15 at 2:05
  • When I stated "only the rows that were visible in that view were being returned", I meant that if the group had not been expanded, then the rows of that unexpanded group were not returned. Expanded groups did provide all the rows, but the field being used to generate the counts was not displayed in any view. – southskies Sep 8 '15 at 3:02
0

I worked out the solution. I added a CEWP and put the definitions for the JS in there.

0

First of all dump the alert() rows and use console() to trace in the Developers Console, that will save you some time. Using the F12 Tools Console to View Errors and Status

In your code you make a second call to get the Status for all ListItems.

This is not needed as you allready have all items in preRenderHandler in

renderCtx.ListData.Rows

The only problem you might have is Status is not displayed as a Column in the View, so not available in the context.

A workaround is to stick it onto some other column you do have in the view using a Calculated Column 'MyColumn':

 =[Status] & "##" & [Due Date]

And then in the CSR code extract both with something like:

renderCtx.ListData.Rows.forEach(function(row){
   var status=row.MyColumn.split('##')[0];
   var duedate=row.MyColumn.split('##')[1];
   -- do extra processing to tally according to status
});

The Non-CSR solution

Without any coding you can get a Status tally by setting the View to Group By Status, and Total Count the Status

And CSR again

On the above GroupBy/Total Count View you get the COUNT.group tally without any extra loops:

Note: screenshots taken from different lists, so they show different columnnames

Console is your friend

so use

 console && console.info('context ListData', ctx.ListData);

a lot in all your CSR code to see what you allready get for free

0

I see that you have found a solution to your real problem (loading multiple JS library dependencies) by using a CEWP, but I think you have mis-understood what RegisterModuleInit is for and how it should be used.

RegisterModuleInit is used to tell the MDS engine to always execute a particular JavaScript function. The two parameters you pass to it are the path of a JavaScript file, and the name of a function within that file that should be executed.

In the example you have given:

RegisterModuleInit(".../jquery-1.11.3.js", RegisterPreRender);

the MDS engine will be looking for your function RegisterPreRender in the jQuery library, where of course it won't find it.

I think what you wanted to do in this situation is something like the following. Let's say that all of your code is in a file named MyCustomHeaderRendering.js. You want the contents of that file to look like this:

function RegisterPreRender() {
    var ctx = {};
    ctx.Templates = {};
    ctx.Templates.Header = renderCustomHeader;
    ctx.OnPreRender = preRenderHandler;
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(ctx);
};

function renderCustomHeader(renderCtx) {

    // your code here

};

function preRenderHandler(renderCtx) {

    // your code here

};

RegisterModuleInit("/path/to/MyCustomHeaderRendering.js", RegisterPreRender);
RegisterPreRender();

Notice also that since you have named the function that registers the overrides, and you call it explicitly, you do not have to wrap it to be self-executing.

Now, to load your dependencies, you add them to the JSLink property. You can specify multiple files in the JSLink property using a pipe separator. So your JSLink entry would look like this:

~site/path/to/jquery-1.11.3.js|~site/path/to/SPServices.js|~site/path/to/MyCustomHeaderRendering.js

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.