1,804 articles and 15,407 comments as of Monday, December 27th, 2010

Tuesday, January 13, 2009

JQuery for Everyone: Expand/Collapse All Groups

Erwin gave me another great idea from Stump the Panel.

We have a document library with a view using a grouped by.
We would like to make it possible to collapse all expanded records with one click.

As much as I try to avoid jQuery becomming a hammer and seeing everything as a nail, this is one of those prime examples of a simple but elegant solution to close a gap in the List View Web Part functionality.

(UPDATED!).

UPDATE: 1/15/2009 – Larry pointed out that nested groups still tried to trigger even if they were not visible which caused some looping. I added the :visible filter to the selectors for the code snippet which seems to work much better for nested groups.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
function collapseGroups() {
	$("img[src='/_layouts/images/minus.gif']:visible").parent().click();
}
function expandGroups() {
	$("img[src='/_layouts/images/plus.gif']:visible").parent().click();
}
$(function() {
	var expandAll = "<a href='#' onClick="
		+'"'+"this.href='javascript:expandGroups()'"
		+'"><img title="expand all groups" style="border:none;" alt="expand all" src="/_layouts/images/collapseplus.gif"></a>';
	var collapseAll = "<a href='#' onClick="+'"'
		+"this.href='javascript:collapseGroups()'"
		+'"><img title="collapse all groups" style="border:none;" alt="collapse all" src="/_layouts/images/collapseminus.gif"></a>';
	$("td.ms-toolbar[width='99%']").append(expandAll).append(collapseAll);
});
</script>

Update (7/28/2009):
This version tested with jQuery 1.3.2 and IE8:

<script type="text/javascript">
if(typeof jQuery=='undefined'){
	var jQPath = 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/';
	document.write('<script src="',jQPath,'jquery.min.js" type="text/javascript"><\/script>');
}
</script>
<script type="text/javascript">
/*
 * Copyright (c) 2009 Paul Grenier (endusersharepoint.com)
 * Licensed under the MIT (MIT-LICENSE.txt)
 */
$(function(){
	jQuery.groups = {
		collapse : function() {
			$("img[src*='minus.gif']:visible").parent().click();
		},
		expand : function() {
			$("img[src*='plus.gif']:visible").parent().click();
		}
	};
	var expandAll = "<a href='#' onClick="
		+'"'+"this.href='javascript:$.groups.expand()'"
		+'"><img title="expand all groups" style="border:none;" alt="expand all" src="/_layouts/images/collapseplus.gif"></a>',
	collapseAll = "<a href='#' onClick="+'"'
		+"this.href='javascript:$.groups.collapse()'"
		+'"><img title="collapse all groups" style="border:none;" alt="collapse all" src="/_layouts/images/collapseminus.gif"></a>';
	$("table.ms-menutoolbar td.ms-toolbar[width='99%']").append(expandAll).append(collapseAll);
});
</script>
View all entries in this series: PaulGrenier-JQuery for Everyone»
Entries in this series:
  1. JQuery for Everyone: Accordion Left Nav
  2. JQuery for Everyone: Print (Any) Web Part
  3. JQuery for Everyone: HTML Calculated Column
  4. JQuery for Everyone: Dressing-up Links Pt1
  5. JQuery for Everyone: Dressing-up Links Pt2
  6. JQuery for Everyone: Dressing-up Links Pt3
  7. JQuery for Everyone: Cleaning Windows Pt1
  8. JQuery for Everyone: Cleaning Windows Pt2
  9. JQuery for Everyone: Fixing the Gantt View
  10. JQuery for Everyone: Dynamically Sizing Excel Web Parts
  11. JQuery for Everyone: Manually Resizing Web Parts
  12. JQuery for Everyone: Total Calculated Columns
  13. JQuery for Everyone: Total of Time Differences
  14. JQuery for Everyone: Fixing Configured Web Part Height
  15. JQuery for Everyone: Expand/Collapse All Groups
  16. JQuery for Everyone: Preview Pane for Multiple Lists
  17. JQuery for Everyone: Preview Pane for Calendar View
  18. JQuery for Everyone: Degrading Dynamic Script Loader
  19. JQuery for Everyone: Force Checkout
  20. JQuery for Everyone: Replacing [Today]
  21. JQuery for Everyone: Whether They Want It Or Not
  22. JQuery for Everyone: Linking the Attachment Icon
  23. JQuery for Everyone: Aspect-Oriented Programming with jQuery
  24. JQuery for Everyone: AOP in Action - loadTip Gone Wild
  25. JQuery for Everyone: Wiki Outbound Links
  26. JQuery for Everyone: Collapse Text in List View
  27. JQuery for Everyone: AOP in Action - Clone List Header
  28. JQuery for Everyone: $.grep and calcHTML Revisited
  29. JQuery for Everyone: Evolution of the Preview
  30. JQuery for Everyone: Create a Client-Side Object Model
  31. JQuery for Everyone: Print (Any) Web Part(s) Plugin
  32. JQuery for Everyone: Minimal AOP and Elegant Modularity
  33. JQuery for Everyone: Cookies and Plugins
  34. JQuery for Everyone: Live Events vs. AOP
  35. JQuery for Everyone: Live Preview Pane
  36. JQuery for Everyone: Pre-populate Form Fields
  37. JQuery for Everyone: Get XML List Data with OWSSVR.DLL (RPC)
  38. Use Firebug in IE
  39. JQuery for Everyone: Extending OWS API for Calculated Columns
  40. JQuery for Everyone: Accordion Left-nav with Cookies Speed Test
  41. JQuery for Everyone: Email a List of People with OWS
  42. JQuery for Everyone: Faster than Document.Ready
  43. jQuery for Everyone: Collapse or Prepopulate Form Fields
  44. jQuery for Everyone: Hourly Summary Web Part
  45. jQuery for Everyone: "Read More..." On a Blog Site
  46. jQuery for Everyone: Slick Speed Test
  47. jQuery for Everyone: The SharePoint Game Changer
  48. JQuery For Everyone: Live LoadTip
 

Please Join the Discussion

56 Responses to “JQuery for Everyone: Expand/Collapse All Groups”
  1. Paul – Beautiful solution. How did you get it to sit on the list menubar? — Mark

  2. AutoSponge says:

    I revisited the code from the Gantt chart fix. td.ms-toolbar[width='99%'] only appears in one place in a List View, the space between the last action button and the View selector. Then I used append() to insert the HTML.

  3. Mike B. says:

    This is actually a solution I’ve been looking for for a long time, thanks!

  4. For some more nails for you to hammer, how about expanding on my POC here:
    http://mo.notono.us/2009/01/moss-add-incoming-links-to-wiki-page.html

    As the url and title state: this copies the Incoming Links for a wiki page onto the wiki page itself. But it needs perfecting, so that’s where you come in… ;-)

  5. AutoSponge says:

    @Oskar,

    That’s awesome! I don’t use the Wiki template on my site(s) but that’s a great idea.

    If you’re fishing for ideas: this could get loaded into a hidden div that flies out when you hover on “Incoming Links”. That way if the load takes a second no one will see it.

  6. larry says:

    This is really great and I do not want to take away from that. I implemented this on a list with about 150 items. They are grouped 2 levels, 12 top and 3 secondary. For some reason when I initially click the expand, it opens one item at a time. From start to finish is about 2 minutes before all items are open. If I click collapse before it is complete it will only close what was already opened, but then it seems to be disabled. Have I missed something with the installation?

    Thanks

  7. AutoSponge says:

    @Larry,

    I appreciate your comments. You used a lot more data than my test case so I’ll need some time to check this out. I’m fairly certain the 2nd level groups will not expand with the first “expand all” can you confirm that?

    When groups expand, the page makes a POST request to the list for additional data. Asking so many groups to expand at once could be a strain on the browser or the server. I’ll know more later.

    Thanks again,
    ~Paul

  8. larry says:

    The second level expanded. Works great, but it appears as if it is looping through each item, then it opens.

  9. AutoSponge says:

    @Larry,

    I have a hunch. Try adding the :visible filter to the end of the two selectors so they look like this:

    $(”img[src='/_layouts/images/minus.gif']:visible”).parent().click();

  10. larry says:

    BINGO! Much faster, the delay isn’t any more than what you get if you clicked to expand or collapse. You know sometimes you get the loading… until the content displays. This one on first click in about 5-7 seconds all 150 items are viewable. Collapse is instant. The second expand, instant.

    Great job thanks!

  11. AutoSponge says:

    Thanks again Larry, I updated the code snippet.

  12. Erwin says:

    Thanks for the solution Paul, it works like a charm. Just one question … could it be that upgrading to jQuery 1.3 brakes the solution?

  13. AutoSponge says:

    @Erwin,

    I have an article coming out next week that references 1.3 and I will continue to publish new solutions with it but I can’t make promises about anything published before now until I test.

    I read the changelog and nothing jumped out at me.

    ~Paul

  14. AutoSponge says:

    @Erwin,

    Actually, I did notice something strange with the attribute selectors in my new script. If you’re having this script break in 1.3, try this selector:

    $(”img[src$='minus.gif']:visible”)
    AND
    $(”img[src$='plus.gif']:visible”)

  15. Erwin says:

    @Paul

    I completely understand you can’t guaranty every piece of code you write here will work with every new version of jQuery being released.

    But … with the new selectors you gave everything works as before the upgrade of jQuery to 1.3.

    Thank you very much.

    Erwin

  16. Erwin says:

    For those interested I changed the selector in the “append” line from :

    $(”td.ms-toolbar[width='99%']“).append(expandAll).append(collapseAll);

    into:

    $(”table.ms-menutoolbar td.ms-toolbar[width='99%']“).append(expandAll).append(collapseAll);

    The “Expand/Collapse All Groups” images where showing up in my view properties pages too …

    Erwin

  17. Rich says:

    This is a great little trick you have hear. i would like to do some testing on some of my list. Can someone point me in the right direction for implementing this code into my list.

  18. AutoSponge says:

    @Rich,

    Check out the screencast I made for another post in this series:
    http://www.endusersharepoint.com/?p=1223

    The only difference will be which code you paste into the Content Editor Web Part.

    ~Paul

  19. SevenOfNine says:

    Had the same problem as somebody else until I changed the selector to:

    $(”td.ms-gb img[src*='/_layouts/images/plus.gif']:visible”)

    Also, I didn’t want the separate + and – images show up on the menu toolbar (which can be hidden on ListView Web Parts), hence I changed it to add a single image to the view header like this:

    var imgTitle = “Expand/Collapse all”;
    $(”tr.ms-viewheadertr td.ms-vh-group img”).parent().attr(”title”, imgTitle);
    $(”tr.ms-viewheadertr td.ms-vh-group img”).attr(”alt”, imgTitle);
    $(”tr.ms-viewheadertr td.ms-vh-group img”).attr(”src”,”/_layouts/images/plus.gif”);
    $(”tr.ms-viewheadertr td.ms-vh-group img”).parent().click(
    function()
    {
    var expanded = $(”td.ms-gb img[src*='/_layouts/images/plus.gif']:visible”);
    var collapsed = $(”td.ms-gb img[src*='/_layouts/images/minus.gif']:visible”);
    if (expanded.length > 0)
    {
    $(”td.ms-gb img[src*='/_layouts/images/plus.gif']:visible”).parent().click();
    }
    if (collapsed.length > 0)
    {
    $(”td.ms-gb img[src*='/_layouts/images/minus.gif']:visible”).parent().click();
    }
    });

    Plus adding some style to my custom CSS file (which certainly could be added via JQuery too):

    .ms-viewheadertr td.ms-vh-group img
    {
    height: 16px;
    margin-left: 1px;
    margin-top: 2px;
    width: 16px;
    }

    Now I do have a nice (I’m using a custom icon, tho) image in the left column of each grouped view header, no matter if a Web Part or list view which expands/collapses all groups on a single click.

    HTH

  20. Kermt says:

    I love this, but. I have the toobar hidden on my document library. Could you please provide code that would do the same idea without needing the toolbar to be available? I can make use of this right away. Thanks so much.

  21. Nick says:

    under firfox, the display is weired.

  22. Nick – Define “weird”. — Mark

  23. Rao says:

    Hi,

    There is no wards to prise you. Simply Superb.

    Thanks,
    Rao.

  24. Olga says:

    Awesome solution! Easy to apply, serves its purpose. Simply brilliant!

  25. Peter says:

    I’m not a developer … just a lowly end-user doing my company’s SharePoint site development and maintenance via the browser.

    Can this expand/collapse features be implem,ented through the browser? Or do I need to use something like SharePoint Designer?

  26. Jenny says:

    This code works great with JQuery-1.2.6-min but when I tried to use it with JQuery-1.3.2-min, it didn’t work. It was just not doing anything when clicking on the plus/minus icon to expand or collapse all groups. Any suggestions?

  27. AutoSponge says:

    @Jenny,

    The problem is the :visible filter, it is broken for IE in the newest version of jQuery. I rewrote this to avoid using :visible, but it’s not published yet. I’ll try to get to that soon.

  28. AutoSponge says:

    @Peter,

    As Jenny stated, this is something you can do in your environment (even in your default.master) without any special tools or server access.

    Jan’s site as well as my series on using JavaScript in SharePoint have some good resources.

  29. Nancy says:

    Echoing Kermt’s comment- can this be made to work on web parts with the toolbar hidden?

  30. AutoSponge says:

    @Nancy,

    Where do you want to put the +/- icons?

  31. Ad says:

    Very interesting, looking forward to the update with JQuery-1.3.2-min.

  32. AutoSponge says:

    @Ad,

    see above.

  33. Greg says:

    I am following up on @Nancy.

    It would be cool if we could add these buttons to the Summary Toolbar rather than Full Toolbar. AutoSponge, would this be possible?

  34. srikanth says:

    Hi, I tried with JQuery-1.3.2-min and IE 6 and it isn’t working. Let me know if anything is wrong!!!

  35. srikanth says:

    its working well….i typed in something wrong..its awesome…thanks alot!!!

  36. tuki says:

    I am following up with Greg…Is it possible to use the summary toolbar. It will be really very good if there is some solution for that…Thanks,,,

  37. Nancy says:

    And I have one more question- I have a page with 10 data view web parts which appear grouped by default. These web aprts must have the title bar hidden.

    I want a button to place at the top of the page in a CEWP that will allow “expand all’-”collapse all” for all ten web parts at once. Can this be leveraged for something like that?

  38. AutoSponge says:

    @Nancy,

    The original code should do that. I wrote another version that only functions for the web part the “buttons” appear on.

    If the toolbar is hidden, try changing $(”table.ms-menutoolbar td.ms-toolbar[width='99%']“) to $(”.ms-titlearea”).

    This will put the icons above the content area and below the top-nav.

  39. Nancy says:

    Just to clarify- I am talking a about a web part page that has a bunch of DVWPs on it, not a list view or library view.

    And what is requested is “one control to rule them all,” ideally a button (or two buttons?) to sit at the top of the page and force expand/collapse of all grouped items in all ten DVWPs- “Collapse all Groups,” “Expand all Groups.”

    This code will do that?

  40. AutoSponge says:

    @Nancy,

    It should, but I think the DVWP expand/collapse fails in FireFox which is why I had to rewrite it for my site. So I can’t test that situation. But all this script does is find the .gif on the page and click its parent. DVWP uses the same .gif.

  41. Nancy says:

    This did work- I was expecting them to appear lower down. They are appearing above the .gif image I have on the page header. Thanks!

  42. SAS says:

    This is great and just what I need. I am relatively new to all this SP stuff so this may be easy to do. I am trying to get the ms-seperator lines before th ‘+’ and after the ‘-’. so the bar looks like | + – |. As soon as I add the seperator it gets all whacked out. Any suggestions?

  43. Tom says:

    The code works absolutely great when I place it in a CEWP or save it to a .js file and reference it. When I move the .js file to a different site collection and then use the Content Link to reference it, the whole thing breaks with a message of

    “Cannot retrieve the URL specified in the Content Link property. For more assistance, contact your site administrator.”

    I am trying to use Mark’s methodology of creating one main center for all code and script and reference everything back to it. Any ideas why this is breaking the code?

  44. AutoSponge says:

    @Tom,

    I’m fairly certain that this would be a problem with the file having a permissions issue when accessed with the id used to consume the script. Whatever id is used on the viewing page, needs to also have access to the secondary collection (or the collection has anon access turned on).

  45. Tom says:

    I have been told that this is due to the CEWP not able to use the content link across site collections unless you have the proper port specified in the url link. Unfortunately, I cannot seem to get the correct information from the admins to make this work. I am going to have to find another way.

  46. Chris says:

    Love this script. It works great when I place it on a view that I have grouped. I’m actually using a copy of what SevenOfNine has in his posting above.

    My question is that I would also like to implement something like this in a dataview that I have. Not sure how to do this. I took the code that was working great on the allitems.aspx page that I have it on and copied it to my default.aspx page where the dataview is but it does not work anymore now?

    Any ideas? Thanks

  47. Prashant Renge says:

    It can easily converted in expandable menu ! good script carry on.

  48. Erin Glenn says:

    I want to use this functionality on a web part web page with a DVWP (no toolbar turned on). Is this possible? My DVWP has two levels of groupings and pulls from a SP list. (Using a DVWP to remove the grouping field name.)

  49. salvo says:

    We are using this piece of code with a big document library and it works fine. However it’s very fast with Google Chrome but very slow with IE7. Any idea? Tips?
    Thanks.

Trackbacks

Check out what others are saying about this post...
  1. [...] by ken zheng on January 14, 2009 Just follow the idea of JQuery for Everyone: Expand/Collapse All Groups. I have deployed on a few SharePoint Pages by control id. Just use IE Dev Tool to get control id [...]

  2. [...] jQuery script is written (http://www.endusersharepoint.com/?p=1167) by Paul Grenier of EndUserSharePoint.com (http://endusersharepoint.com) as a response to a [...]

  3. [...] JQuery for Everyone: Expand/Collapse All Groups [...]




Notify me of comments to this article:


Speak and you will be heard.

We check comments hourly.
If you want a pic to show with your comment, go get a gravatar!