3

I have customized the view for my SharePoint 2013 List using a JSLink file but have not been able to get the buttons I added to the page to respond properly. They cannot find any DOM elements when the events fire.

The custom formatting includes a header portion which has a few buttons a user can click to filter the list items displayed on the page. I have it set so that when they click a button I can get an alert which tells me which button they clicked but when I try to find a DOM element it fails.

It appears that even though the page has finished loading with all of the DOM displayed, the javascript event which fires onclick cannot see the DOM element I'm looking for. I've seen examples of how to get a jQuery UI Accordion to work but that fires the event as a part of the PostRender event.

Once I can get access to the DOM elements I will then be hiding the items which are not needed on the screen based on which button they clicked. This is very similar to using multiple "Views" of a List but I'm trying to simplify the navigation between Views for the user. I would need it to show a list of at least 7 views for them to choose from.

I'm hoping for any suggestions on how to get my JSLink code to be able to access the DOM of the current page? It feels like there must be something simple I'm missing.

Here is the JSLink code I'm using:

(function () {
    var overrideCtx = {};
    overrideCtx.Templates = {};
    overrideCtx.Templates.Header = customHeader;
    overrideCtx.Templates.Item = customItem;
    overrideCtx.Templates.Footer = "</div>";
    overrideCtx.BaseViewID = 1;

    //overrideCtx.OnPreRender = preRenderHandler;
    //overrideCtx.OnPostRender = postRenderHandler;
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);})();

function customHeader() {
    var $ = document; // shortcut
    var cssId = 'LaunchPadCSS';  // you could encode the css path itself to generate id..
    if (!$.getElementById(cssId))
    {
        var head  = $.getElementsByTagName('head')[0];
        var link  = $.createElement('link');
        link.id   = cssId;
        link.rel  = 'stylesheet';
        link.type = 'text/css';
        link.href = '/CommonCSS/LaunchPad.css';
        link.media = 'all';
        head.appendChild(link);
    }

    var _header = "<tr>" +
            "<table><tr><td colspan=4> Legend: " +
                "<span id='featured' class='legend lbutton featured' onclick='displayGroup(this.id);'>Frequently Used</span>" +
                "<span id='investigations' class='legend lbutton investigations' onclick='displayGroup(this.id);'>Investigations</span>" +
                "<span id='reference' class='legend lbutton reference' onclick='displayGroup(this.id);'>Reference</span>" +
            "</td>" +
        "</tr></table><div class='buttonframe'>";

    return _header;};

function customItem(ctx) {
    var item = {};
    item.Id = ctx.CurrentItem["Id"];
    item.Title = ctx.CurrentItem["Title"];
    item.Group = ctx.CurrentItem["Group"];
    item.Id = ctx.CurrentItem["ID"];
    JSLaunchPad.WebParts.Links.Items.push(item);

    return buildButton(ctx);
};

function buildButton(ctx) {
    var _Button = "<li id='Button" + ctx.CurrentItemIdx + "' class='lbutton " + ctx.CurrentItem.CSSClass + "' value='" + ctx.CurrentItem.Group + "'>" + 
                    "<a href='" + ctx.CurrentItem.SystemURL + "' target='_blank'>  " +
                    "<span class='systemname'>" + ctx.CurrentItem.Title + "</span> " +
                    "<div class='systemlogobackground'>&nbsp;</div> " +
                    "<img class='systemlogo' src='" + getRollupImageURL(ctx) + "' alt='' /> </a>" + 
                    "<a class='infobutton' href='" + ctx.CurrentItem.InfoURL + "'>i</a> " +
                    "</li>";

    return _Button;

};

function getRollupImageURL(ctx) {
    //var rollupImage = ctx.CurrentItem.PublishingRollupImage;
    var rollupImage = ctx.CurrentItem.LogoURL;
    return rollupImage;
};

function displayGroup(group) {
    alert(group);

    var links = document.getElementById("buttonframe");

    if (links != null) {
    var listItems = links.getElementsByTagName("li");

    alert('found ' + listItems.length + ' items');
    };
    // var arrayLinks = [];

    // for (var i=0; i < listItems.length; i++) {
        // var listItem = listItems[i];
        // var valItem = lisItem.value;

        // if(valItem.indexOf(group) > -1) {
            // alert(group + ' in ' + valItem + ' for ' + listItem.ID);
        // }

    // }
};
2

I think it is the PostRender that will help you. Try attaching the click event w/ jQuery after they have rendered:

overrideContext.OnPostRender = postRenderHandler;

function postRenderHandler(ctx) {
  $('#featured').click(function(){
      var links = document.getElementById("buttonframe");
      if (links != null) {
      var listItems = links.getElementsByTagName("li");
  });

}
  • I tried this to see how it would work and it appears to fire the function that is within the .click() on page load and it is not adding it to the DOM as an event. Each time I refresh the page the code in the .click() executes, not when the span is clicked. – Josh Mikow May 7 '14 at 14:34
  • I tested and it works for me. But I stripped it down to just overrideContext.Header = "<span id='featured'>Text</span> overrideContext.OnPostRender = postRenderHandler; function postRenderHandler(ctx) { $('#featured').click(function(){ var links = document.getElementById("feat1ured"); }); It may be something in your header() function?? Is the 'featured' span being rendered? – Michael Colbs May 7 '14 at 15:30

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.