1,403 articles and 9,466 comments as of Friday, February 26th, 2010

Tuesday, December 23, 2008

JQuery for Everyone: Fixing the Gantt View

This question came in from Stump The Panel:

Does anyone know how to freeze the Title column in Project Task list Gantt chart view?

Since I want to get better using jQuery, and tweaking the UI will be easier than fixing the web part, I went after it.

Instead of freezing the Title column, I decided to drop the x-axis scrollbar and add labels to the ends of each activity.

Since the header rows also disappear when you scroll down on the inner scrollbar, I froze the date header by moving it out of the chart area.

But I couldn’t stop there.  I don’t always need the Task List View below my chart and sometimes I need to see more of the chart at once. I decided to add some buttons to the toolbar that control the List View display and Gantt View height.

Check out the results of these tweaks in this screencast:

<a onclick="javascript:pageTracker._trackPageview('/outgoing/video.msn.com/?mkt=en-US&#038;playlist=videoByUuids:uuids:48e76d58-1871-408d-8f15-da8aa60c56f7&#038;showPlaylist=true&#038;from=msnvideo');" href="http://video.msn.com/?mkt=en-US&#038;playlist=videoByUuids:uuids:48e76d58-1871-408d-8f15-da8aa60c56f7&#038;showPlaylist=true&#038;from=msnvideo" target="_new" title="SharePoint Gantt Fix">Video: SharePoint Gantt Fix</a>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
	//capture variables
	var div=$("div[class^='ms-ganttDiv']:eq(0)");
	var tlv=$("table.ms-listviewtable:eq(0)");
	var w = $("#GanttTable").width();
	var a = "img[src='/_layouts/images/EndNormal.gif']"
	var b = "img[src='/_layouts/images/MileStone.gif']"
	//build new html from header rows
	var html="<table class='ms-ganttInnerTable' cellspacing='0' cellpadding='0' style='table-layout:fixed' width='"+w+"'>"+
			"<col width='222px'></col>"+
			"<tbody><tr>"+
			$("#GanttTable tr:eq(0)").html()+
			"</tr><tr class='ms-ganttDetailTimeUnitRow'>"+
			$("#GanttTable tr:eq(1)").html()+
			"</tr></tbody></table>";
	//build toggle buttons
	var bt1="<input id='tlv0' class='ms-ButtonHeightWidth' type='button' target='_self' value='Toggle List' name='togglelv'/>";
	var bt2="<input id='div100' class='ms-ButtonHeightWidth' type='button' target='_self' value='Full Gantt' name='div100'/>";
	var bt3="<input id='div272' class='ms-ButtonHeightWidth' type='button' target='_self' value='Min Gantt' name='div100'/>";
	//DOM manipulation
	$("#GanttTable").prepend("<col width='222px'></col>");
	$("table.ms-menutoolbar:eq(0)").after(html); 								//insert html
	$("td.ms-toolbar[width='99%']").append(bt1).append(bt2).append(bt3);//add buttons
	$("#tlv0").click(function() {$(tlv).toggle()});						//add toggle fn
	$("#div100").click(function() {
		$(div).height("100%");
		$(div).css({"overflow-y": "visible", position: "relative"});
	}); 																//add 100% fn
	$("#div272").click(function() {
		$(div).height("272");
		$(div).css({"overflow-y": "auto"});
	}); 																//add 272 fn
	$("#GanttTable tr:lt(2)").replaceWith("<th></th>"); 				//replace original rows
	$(a+", "+b).each(function(i,e) {  									//add labels
		var title = $(e).parent().siblings("th").text();
		$(e).parent().next().html("<div style='position:relative;z-index:99;white-space: nowrap'>"+title+"</div>");
	});
	//css fixes
	$("#GanttTable").css({"table-layout":"fixed","word-wrap":"normal",width:w});
	$("table.ms-listviewtable > tbody > tr[class='']").css("background-color","#fff");
	$(div).css({"overflow-y": "auto", "overflow-x": "hidden"});
});
</script>
<style type="text/css">
body {background-color:#83B0EC}
.ms-main {height:97%}
.ms-globalTitleArea {background-color:#fff}
.ms-bodyareapagemargin {border-top:1px solid #83B0EC}
.ms-bodyareaframe {background:none transparent}
.ms-ganttInnerTable {background-color:#fff}
.ms-bodyareacell {background-color:#83B0EC}
</style>

Paul Grenier

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

84 Responses to “JQuery for Everyone: Fixing the Gantt View”
  1. Looks excellent!

    Thanks for all the great ideas. :)

  2. Stump says:

    Paul,

    Xmas came early for me.

    This works splendidly. Thanks for working on this and finding an excellent solution.

    Stump

  3. Paul – I have to agree with Stump on this one… Christmas came early. The Gantt view has such obvious short comings, your work around makes it actually usable. — Mark

  4. Robin says:

    Paul,
    Great articles! Do you have any plans to use jQuery to help modify the width of list columns?

  5. JillyBean says:

    I want audio! :-P

  6. Zeev Shilor says:

    Paul,

    I successfully implemented your solution and would like to thank you for this posting.

  7. AutoSponge says:

    @Robin,

    I’ll add that to the idea hat :)

    ~Paul

  8. Paul – I agree with Robin. Managing the width of columns is almost always the first request as people try to manage the interface of a list or library. Count me in… Mark

  9. Stump says:

    Paul,

    I just implemented this for a few project sites and noticed that the task name only appends when the task is not complete. Was that intended? Is there a way to show it regardgless of whether the task is complete or not?

    Thanks

    Stump

  10. AutoSponge says:

    @Stump,

    I can’t replicate that in IE or FF. In my site, all Task statuses appear the same.

    In the script, var a and b(milestone) are images that make up the activity “bar.” On the line with the comment “add labels” I tell jQuery to find a+”, “+b, then loop through adding the Title.

    Check your Gantt charts. If you have a different ending .gif for your completed Tasks, you can modify the code with a third variable (c) and a selector like: a+”, “+b+” ,”+c.

  11. Grace says:

    I will certainly try that.

    Thanks

    Stump.

  12. Dean says:

    Any ideas on how to change the date format columns from week/day to month/week?

  13. AutoSponge says:

    @Dean,

    Just so I’m certain what you mean–are you suggesting a more “macro” view of the data so it displays activities lasting weeks instead of months?

    ~Paul

  14. Dean says:

    Paul, what I’m suggesting is being able to change the Time Scale like we can in MS Project. I’d like to be able to change the top units to months or quarters or years and the bottom units to weeks or months. If tasks are long, it is good to be able to see their entire duration on one screen without having to scroll way to the right.

    Dean

  15. Chris says:

    Paul,

    Thanks for all you effort getting this jquery code out there – it is much appreciated! Once question, though – this works for the list view page. What would need to change to get this fix to work on the project task list that is added to a site page?

    Thanks in advance.

  16. AutoSponge says:

    @Chris,

    First, the width would need to be changed. In IE especially, the Web Part’s div will not extend to 100% of the content area.

    Second, without the toolbar, there is no place to put the Title bar, so you’d need to create an element there to hold it.

    I changed the background color in my script. That doesn’t look as hot when the web part is smaller than the content area, so you might need to do some CSS changes.

  17. Cami Woolam says:

    I love the update Gantt chart – but is there a way to restrict the width, and add a scroll bar at the bottom? Some of my projects go on for years, and the default screen width just isn’t wide enough.

  18. AutoSponge says:

    @Cami

    I’m not sure I understand. This change makes the web part as large as it needs to be to display the entire Gantt chart. The scroll bar appears at the bottom of the browser.

  19. Scrapperchick says:

    This is so very close. I don’t like how the full view expands the whole page, I would like the scroll bar for horizontal scrolling back at the bottom of the gannt view where it was before. It must be too late for me to not be able to figure this out on my own.

  20. AutoSponge says:

    @Scrapperchick,

    To get the week/day header to stay put, I placed it in the toolbar.

    If put the inner scrollbar back in the Gantt view, the week/day header in the toolbar gets crunched to the Gantt width.

    It probably could be done but there’s a lot more fancy scripting involved to sync the toolbar and Gantt’s scrolling.

    Since I try to keep my published solutions “short,” that wasn’t an option for this article.

    But thanks for the ideas, keep them coming!

    ~Paul

  21. jriesen says:

    I would like to reiterate Scrapperchick on January 21st, 2009 8:19 pm comment about the horizontal scrollbar being much more useful at the bottom of the gantt chart. If I had to choose if the week/day header staying put or the scrollbar at the bottom of the gantt chart, I would choose the the scrollbar. Let me know if you plan to add it to a future release of the script. Thanks!

  22. derek says:

    Great Script. However, the labels aren’t appearing next to images on chart. Odd. Any ideas? I am using custom css and master pages. The gifs point to the right ones as listed in the code as well. Thanks in advance and thank you for you contribution!!

  23. derek says:

    Found my solution. Odd really. I had to put the entire URL to gifs in place of Directory URL. Regardless, it works like a champ!!!! Thanks!!!

  24. martin says:

    thanks for the solution, had thought about implementing it myself too. one note: when using SSL/HTTPS you can replace the beginning of the javascript loading url with “https://ajax.googleapis.com/..” to avoid browser warning that some parts of the page are insecure.

  25. AutoSponge says:

    @martin

    I tried that when I first started messing with jQuery and it didn’t work. Now it does! That’s great.

  26. Wanda says:

    I’m having a problem getting this enhanced Gantt to work properly with Christophe’s slider. I find the Gantt more useful if I can change the date scale, which is what Christope’s slider does.

    I can get them on the same page, but I lose the laod tips, and the slider behavior is peculiar. And perfomance seems to be impacted.

    Have you tried this? Suggestions?

  27. cloudno9 says:

    Great script, I was looking for this and here i found it.

    Have you had a chance to review what “Dean on January 8th, 2009 10:55 am” was suggesting?

    I wanted to do something similiar, infact exactly the same. I appreciate your help in this regard.

    thanks

  28. AutoSponge says:

    @Wanda

    I have not tried that, I’ll take a look and see if the two scripts are compatible.

    @cloudno9

    I think this is related to Wanda’s comments. I’ll look into it.

  29. cloudno9 says:

    thx for response. christpophe slider still maintain the same date scale. all it does it removes Weeks/days and change it with months.
    I wanted to do similar what dean said “I’d like to be able to change the top units to months or quarters or years and the bottom units to weeks or months. If tasks are long, it is good to be able to see their entire duration on one screen without having to scroll way to the right.”

    Thanks

  30. Carolyn says:

    Hi Paul,

    This is fantastic!

    Do you have a similar trick for freezing column headings on sharepoint lists?

  31. AutoSponge says:

    @Carolyn

    Good idea.

  32. Charlotte says:

    Hi paul

    Very nice post! I like it so much tat I have this question: Is there a way to make the the “Full Gant” and the “Toggle List” the default view? So that these functions are already activated when you visit the page and you wont have to click on it each time you go to the page.

    Charlotte

  33. AutoSponge says:

    @Charlotte

    Try replacing the last two lines of the JavaScript portion with this:

    $("#tlv0").click();
    $("#div100").click();
    });
    
  34. Wanda says:

    Re my Feb 18th question on integrating this code with Christophe’s slider. Any luck? Or any alterntive for changing the view from days to weeks, or months or quarters?

  35. Niche says:

    How would you fix the Title column, so when you scroll to the right, it stays put?

  36. Niche says:

    Like others have said, having the scroll bar at the bottom of the Gantt would be an ideal solution, along with the fixed date headers.

  37. Charlotte says:

    @AutoSponge, works perfectly!

  38. Alex says:

    Hi Paul, any ideas on how to implement what Dean was asking for in comment 15? Your jquery works like a charm, with the option to change the timeline it would be perfected.

  39. MSILinda says:

    Yes, I have a similar need in that I need to change it out even further

    from Month/Day
    to Quarters/Months

    Any ideas?

  40. Jay says:

    Very nice, thanks for sharing.

    Has anyone looked at how to group the “Title” field? I have all the titles listed but would like them to display in the same grouping I have in the list view.

    I’m not near a good enough scripter/programmer to figure it out on myown.

    Thanks!

  41. MSILinda says:

    I have the same need to Grouping By Title in the header area, and haven’t been successful doing it yet.

  42. Eric says:

    This is really awesome! I’m having a problem making this work with my branding – I have a fixed width design, and the Gantt chart really shouldn’t be wider than about 751px. When I use this code, the html changes cause the Gantt chart to push the browser window way out there. Is there a way to avoid this?

    I’ve tried manipulating this code, and the only thing I can think of is that this part:

    var w = $(”#GanttTable”).width();

    That w is setting the width rather high (in my environment, this var returns >1600). When I take out the code that’s manipulating the DOM html fragment, the date header (I think this might be handled by the ms-ganttDetailTimeUnitRow class) disappears.

    Any ideas?

  43. AutoSponge says:

    @Eric,

    $(”#GanttTable”).css({”table-layout”:”fixed”,”word-wrap”:”normal”,width:w});

    That link actually changes the width of the chart. However, if you leave the default, it will break the “sticky header.” Also, the default only appears page-width in IE, FireFox lets the chart grow.

  44. Eric says:

    I figured out a fix for my problem. After examining the CSS and tweaking that in-browser a bit, I realized that the width can be explicitly set by grabbing the width of the TABLE element whose class is “ms-ganttOuterTable” and applying that to the parent div. So, my fix is to grab the calculated width of this table on render, and apply that to the DIV whose class is “ms-ganttDiv” that you’re setting as the var “div”:

    In the “//capture variables” section, add:

    var outerTableWidth = $(”table[class^='ms-ganttOuterTable']:eq(0)”).width();

    And at the bottom in the “//DOM manipulation”, add:
    $(div).width(outerTableWidth);

    That fixes it for me, anyway – hopefully that helps someone else out there!

  45. Eric says:

    Actually, I take that back – it fixes the width issue, but now the buttons don’t appear anymore, and neither do the dates. Something is conflicting with the “//css fixes” section – back to the drawing board .

  46. Mat says:

    Thanks for the excellent post. I am attempting to take this a step further and add the Assigned To field from the List view to the text after the bar on the Gantt. So far no luck, but if I figure it out I’ll post it up!

  47. Walter says:

    Humm… the Full Gantt and Min Gantt buttons aren’t working on my site… but the Toggle List does…

  48. Mat says:

    Got it. Well, a dirty bodge, but it seems to work if anyone is interested. I am sure there must be a more elegant solution than this, but hey ho.

    // define array
    var usrTxt = [];
    // scan through thepage for elements of ms-vb-user class. Bung each one into an array for use later on.
    $(”.ms-vb-user”).each(function() { usrTxt.push($(this).text()) });
    // Juggle these about a bit, as it always seems to screw the order up
    usrTxt.push(usrTxt.shift());

    —-
    And then just add this + usrTxt[count] + to the line that puts the title after the Gantt line – remembering that it is an array so you’ll need to maintain a count.

    PS. Walter – I had the same problem as you – for “some” reason when I copy & pasted the example here to my site it changed some values – specifically the names of the 272 and 100 functions, so take a look to make sure that what you thought you copied is actually what you got!

  49. Alicia says:

    I implemented the original suggestion, and it moves the scroll bar to the bottom of the page instead of of right below the Gantt, which causes me to not be able to view the entire project list without scrolling. Anyway to only add the titles to the Gannt points, but keep everything else as is? I don’t need the button either. Thanks!

  50. Flux says:

    Thanks for usefull post. it works very well.

    In addition to the title showing at the right of the bar in the gantt chart, I would like a comment stored in another column in the list to show.
    Is this possible?

    I guess this is some of the same that Mat on May 6th, 2009 10:46 am and Mat on May 7th, 2009 7:08 am found a solution to, but i can’t get it to work.

Trackbacks

Check out what others are saying about this post...
  1. SharePoint Kaffeetasse #98…

    Tools und Addons Custom Content Editor Web Part for SharePoint jQuery http://jquery.com/ jQuery is a…

  2. [...] idea came from Carolyn on my post about Fixing the Gantt View. Do you have a similar trick for freezing column headings on sharepoint [...]

  3. [...] JQuery for Everyone: Fixing the Gantt View [...]

  4. [...] JQuery for Everyone: Fixing the Gantt View (61) [...]

  5. [...] JQuery for Everyone: Fixing the Gantt View [...]




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!