0

Having some trouble adding a "read more" button to an announcements webpart in SP2013 Foundation. This "read more" button is automatically generated by JavaScript after the announcement/news entry is larger than 300 characters, and provides the user with a link to a full view of the text file within SharePoint. Here's the Javascript I'm using as an attempt to make it happen. I pulled it from this SE thread.

<script>

(function () {

    var viewCtx = {};
    viewCtx.Templates = {};

    viewCtx.Templates.Header = "<table>";
    viewCtx.Templates.Item = AnnouncementItem;
    viewCtx.Templates.Footer = "</table>";

    viewCtx.BaseViewID = 1;
    viewCtx.ListTemplateType = 104;

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(viewCtx);

})();

function AnnouncementItem(ctx) {
    var headlineLimit = 300;
    var headline = $(ctx.CurrentItem.Body).text(); 
    if (headline.length > headlineLimit)
    {
        headline = headline.substring(0,headlineLimit);
    }
    return String.format("<tr><td><p><b>{3}</b></p>{1}<a href='{2}/DispForm.aspx?ID={0}'> Read More…</a></td></tr>",
    ctx.CurrentItem.ID,headline,ctx.listUrlDir,ctx.CurrentItem.Title);
}

</script>

Not having much luck at all, it keeps returning me with the errors "ReferenceError: $ is not defined ReferenceError: $ is not defined"

Does anyone have any ideas? Sorry if anything seems off, I'm an extreme beginner when it comes to Javascript.

Thank you in advance.

  • 2
    $(ctx.CurrentItem.Body).text() looks like a jQuery construct to me. Are you loading jQuery? If not, that may be why $ is not defined. – Dylan Cristy Dec 3 '15 at 14:21
0

Indeed $ is jQuery, the extra library you need to load

But..[drumroll] Microsoft has mQuery... so you do not need jQuery

var headline = m$(ctx.CurrentItem.Body)[0].textContent;

Or in native (modern browser) JavaScript:

var headline = document.querySelector(ctx.CurrentItem.Body).textContent;

But... chicken/egg

It won't work because the DOM element you want to get the text from does not exist (because this CSR code creates it)

The text you want is in the items ctx object:

If you call it for the whole Item:

var headline = ctx.CurrentItem.Body; 

The above is tied to the Internal name;

If you call it for (any) one Description Column as shown in the MSDN example that internal name is declared in the ctx object:
and creates more generic/reusable code

var headline = ctx.CurrentItem[ctx.CurrentFieldSchema.Name]; 

FYI: This type of CSR development is a breeze with the free Chrome Browser Cisar Plugin

  • Hey Danny, I implemented your suggestion and now I'm met with an error of "cannot read property 'name' of undefined" "cannot read property 'name' of undefined" Any ideas? Thanks – Alexander Edwards Dec 3 '15 at 14:49
  • I had to test it... It is not common to replace the whole Item and built it yourself.. usually we only overrule one Column and leave the rest of the View intact; See MSDN example of shortening Description. There is (ofcourse) no CurrentFieldSchema in ctx when you call the Item function. So you can use var headline=ctx.CurrentItem.Body; – Danny '365CSI' Engelman Dec 3 '15 at 15:22
  • @AlexEdwards just as an additional note, though, an announcement body is a rich text field, which means there can be HTML formatting. I'm pretty sure the reason the original post you followed used $(ctx.CurrentItem.Body).text() is because that strips out HTML and leaves you with just the real text content. Then you are doing your length check against the real content and not counting any markup characters against the limit. – Dylan Cristy Dec 3 '15 at 15:53
  • And it also just occurred to me that if you don't strip out the markup, and there is markup (especially some closing tags) that is after your 300 character limit, when you truncate the content you are going to remove those tags and break the markup. – Dylan Cristy Dec 3 '15 at 16:01
  • @Danny'365CSI'Engelman Just wondering, the standard JS syntax of ctx.CurrentItem.Body does work but you're right, the returned property contains HTML which makes this solution clunky because of issues with breaking markup depending on the limit set. The .text method is unrecognized (e.g. ctx.CurrentItem.Body) and haven't had any good results looking for an alternative, do you know of one? That is, to get the text w/o the HTML markup. – Christopher Bruce Feb 24 '17 at 21:47

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.