5

I have created a JavaScript function to take a url from a list item and turn it into an image.

This function works great on a list that doesn't have group by setup.

With this script the images will show up after I click the link the second time:

$(document).ready(function($) { 
    //Create the images on page load
    createImages();

    //check if the url hash changes and run createImages if it does
    window.onhashchange = createImages;

    var regExp = /ExpCollGroup(.*)\)/
    $('.ms-commentexpand-iconouter').closest('a').each( function() {
        var scr = regExp.exec($(this).attr('onclick'));
        $(this).attr('onclick', scr[0] + '; ' + 'createImages();'); 
    });
});

Here is the SharePoint function that is being called to load the groups data:

ExpCollGroup('58-2_', 'img_58-2_',event, false)

It looks like the group by doesn't load the data until you click on the link to show the data in that group. So with the script above the createImages function gets called but there is no data. If I click on it a 2nd, 3rd, etc... time the script works because the data has been loaded.

How can I run the createImages() function after the function to show the data has been loaded?

  • 1
    I was able to find a work-around that isn't ideal but does the job. When setting up the "group by" under the "By default, show groupings:" section select "expanded". This will load all the rows in each grouping when the page is first loaded. This allows my script to find the items. – Neil Hoff Oct 16 '13 at 16:08
3

I have been having a similar issue and found a blog post that can assist you. Have a look at it.

UPDATE:

The trick is to use the jQuery .delegate() function instead of the .click() or .attr('onclick') function. Above linked blog post states that the .delegate() function will work with all dynamically added elements to the page, whereas the .bind() function will only work once, when its ran. Please go to the jQuery site to read more on how to use the .delegate() function.

  • 4
    Hi Pagail, Welcome to SPSE! While your answer does seem to point to the right direction, could you please post important parts from the link in your answer? This way, users coming to this site will not have to navigate to another site to get the relevant info. Also if in the future the link becomes dead, the important bits will remain in your answer. Thanks! Hope you enjoy participating in the forums. – Vardhaman Deshpande Nov 6 '13 at 13:55
  • Responding to @VardhamanDeshpande The trick is to use the jQuery .delegate() function instead of the .click() / .attr('onclick'). The blog post shared on my link states that the .delegate() function will work with all dynamically added elements to the page, whereas the .bind() function will only work on when its ran. Please go to the jQuery site to read more on how to use the .delegate() function. – Pagial Feb 13 '18 at 8:56
4

I had a similar problem and found a solution that doesn't require pre-expanding the groups. I've adapted it to fix your problem.

After digging through the sharepoint javascript files, here's the approach I used:

function FixTheThings()
{
    createImages();

    //Hook into SharePoint event to fix all links in group-by tables.
    var oldExpand = ProcessImn;

    ProcessImn = function(){
        var results = oldExpand.apply(this, arguments);

        createImages();

        return results;
    }
}

function createImages()
{
    //your logic here
}

//this is the SharePoint preferred alternative of $(document).ready
_spBodyOnLoadFunctionNames.push("FixTheThings");

The ProcessImn function gets called directly after the items have been rendered by SharePoint. It would have been more ideal to override the functions ExpGroupReceiveData or ExpGroupRenderData instead, but my installation of SharePoint wasn't happy with that, and my code never executed properly.

2

I actually spent a bit of time on this particular issue. _spBodyOnLoadFunctionNames.push will work but it needs to be added to the ExpCollGroup which is the onclick function of the group by in the List View.

Unfortunately, you can't just run javascript on page load because the ajax for the List View group by is making a callback to the server which will run only after you click the expand (+) icon on the grouping. This prevents a setTimeout from working.

The following code is what I used. Please note that this code will iterate through all links on the page and add a target="_blank" to any links that have been appended with #openinnewwindow (i.e. http://www.google.com/#openinnewwindow).

<script language="JavaScript">
function rewriteLinks() {
 var anchors = document.getElementsByTagName("a");
 for (var x=0; x<anchors.length; x++) {
      if (anchors[x].outerHTML.indexOf('#openinnewwindow') > 0) 
  {
      //Testing
      //alert(x); 
      anchors[x].setAttribute('target','_blank');
      }
 }
}
$(document).ready(function() {
 var defaultExpCollGroupMethod = ExpCollGroup; 
 ExpCollGroup = function() {  
       defaultExpCollGroupMethod.apply(this, arguments);
       setTimeout(rewriteLinks,2000);
 };
 rewriteLinks();
});
</script>

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.