+ Start a Discussion
HalcyonandonHalcyonandon 

Nested Lists of custom objects

We're building a help system, one with a similar hierarchy as the salesforce help.  I've been having trouble finding documentation on structuring and populating nested lists using visualforce.  We have our content divided into custom objects as follows...

application - top level, not displayed, used to control the content being displayed in multiple customer portals
grouping - Above the list, names act as headers above the tree
category - these categories exand out to show topics
topic - When clicked these open directions in a div to the right of the menu.

so where I'm at...

I have a custom controller that populates the grouping list.  I'm not sure if this should even be a list since its the header for the lists contained with .

public class CODhelp {

List<grouping__c> grouping;

public List<grouping__c> getgrouping() {
if(grouping == null) grouping = [select name from Grouping__c where application__r.name = 'cod'];
return grouping;
}
}


Then I'm creating the list in the visualforce page using the following markup...

<apex:dataList value="{!grouping}" var="grouping__c" id="theList">
<apex:outputText value="{!grouping__c.name}" styleclass="treeHeader"/>
</apex:dataList>


This currently works to populate a list of grouping names for the application "cod".  However I need to go deeper for categories, topics and then the directions (which is a custom field of topic).

The html needed to generate our menu looks like this...

<ul class="tree">
<dt class="treeHeader">Grouping</dt>
<li class="closed"><a href="#">Category 1</a>
<ul>
<li><a href="directions">Topic 1</a></li>
<li><a href="directions">Topic 2</a></li>
</ul>
</li>
</ul>

Unfortunately, I'm at a loss on how to generate this structure using visualforce and populate it with the data from our custom objects.  I would greatly appreciate any suggestions or assistance on how to successfully achieve the desired result.

Thanks.


Best Answer chosen by Admin (Salesforce Developers) 
Ron HessRon Hess
I have a fair example of lists inside of lists, i will drop the code here and explain it. 

It's not exactly your same UI design but it does demonstrate the key concept of an array of custom classes (and getter methods), which contain other classes or sobjects.  Note: this code uses simple standard objects so you can try it out without adding custom fields or tables.

my example is a simple calendar, which is a list of lists. 
The outer list is the list of weeks, 4 or 5 weeks in a month, each week is a list of 7 days.

then these are drawn using nested repeat tags.  You will end up using nested repeat tags (or datalist)  in your design to achieve your final design.

here goes, first the Apex Controller

Code:
public class repeatCon {

public void next() {
addMonth(1);
}

public void prev() {
addMonth(-1);
}

public repeatCon() {

Date d = system.today(); // default to today
Integer mo = d.month();
String m_param = System.currentPageReference().getParameters().get('mo');
String y_param = System.currentPageReference().getParameters().get('yr');

// allow a month to be passed in on the url as mo=10
if (m_param != null) {
Integer mi = Integer.valueOf(m_param);
if (mi > 0 && mi <= 12) {
d = Date.newInstance(d.year(),mi,d.day());
}
}
// and year as yr=2008
if (y_param != null) {
Integer yr = Integer.valueOf(y_param);
d = Date.newInstance(yr, d.month(), d.day());
}

setMonth(d);
}

public List<Month.Week> getWeeks() {
system.assert(month!=null,'month is null');
return month.getWeeks();
}

public Month getMonth() { return month; }


private void setMonth(Date d) {
month = new Month(d);
system.assert(month != null);

Date[] da = month.getValidDateRange(); // gather events that fall in this month
events = [ select id,subject,description,activitydate,activitydatetime,DurationInMinutes
from Event
where activitydate >= :da[0] AND activityDate <= :da[1]
order by activitydatetime];

month.setEvents(events); // merge those events into the month class
}

private void addMonth(Integer val) {
Date d = month.getFirstDate();
d = d.addMonths(val);
setMonth(d);
}

private List<Event> events;
private Month month;
}


now the custom code to implement the month, week and day classes in apex code
study the constructor of the Month() class, then the Week() class , then the Day() class to see how these are built.


Code:
public class Month {
 private List<Week> weeks; 
 public Date firstDate; // always the first of the month
 private Date upperLeft; 
 
 public List<Date> getValidDateRange() { 
  // return one date from the upper left, and one from the lower right
  List<Date> ret = new List<Date>();
  ret.add(upperLeft);
  ret.add(upperLeft.addDays(5*7) );
  return ret;
 }
 
 public String getMonthName() { 
  return DateTime.newInstance(firstDate.year(),firstdate.month(),firstdate.day()).format('MMMM');
 } 
 
 public String getYearName() { 
  return DateTime.newInstance(
  firstDate.year(),firstdate.month(),firstdate.day()).format('yyyy');
 } 
 
 public String[] getWeekdayNames() { 
  Date today = system.today().toStartOfWeek();
  DateTime dt = DateTime.newInstanceGmt(today.year(),today.month(),today.day());  
  list<String> ret = new list<String>();
  for(Integer i = 0; i < 7;i++) { 
   ret.add( dt.formatgmt('EEEE') );
   dt= dt.addDays(1);
  } 
  return ret;
 }
 
 public Date getfirstDate() { return firstDate; } 

 public Month( Date value ) {
  weeks = new List<Week>();
  firstDate = value.toStartOfMonth();
  upperLeft = firstDate.toStartOfWeek();
  Date tmp = upperLeft;
  for (Integer i = 0; i < 5; i++) {
   Week w = new Week(i+1,tmp,value.month()); 
   system.assert(w!=null); 
   this.weeks.add( w );
   tmp = tmp.addDays(7);
  }

 }
 
 public void setEvents(List<Event> ev) { 
  // merge these events into the proper day 
  for(Event e:ev) { 
   for(Week w:weeks) { 
    for(Day c: w.getDays() ) { 
     if ( e.ActivityDate.isSameDay(c.theDate))  { 
      // add this event to this calendar date
      c.eventsToday.add(new EventItem(e));
      // add only three events, then a More... label if there are more
     } 
    } 
   } 
  }
 }
 
 public List<Week> getWeeks() { 
  system.assert(weeks!=null,'could not create weeks list');
  return this.weeks; 
 }
  

 /* 
  * helper classes to define a month in terms of week and day
  */
 public class Week {
  public List<Day> days;
  public Integer weekNumber; 
  public Date startingDate; // the date that the first of this week is on
  // so sunday of this week
  
  public List<Day> getDays() { return this.days; }
  
  public Week () { 
   days = new List<Day>();  
  }
  public Week(Integer value,Date sunday,Integer month) { 
   this();
   weekNumber = value;
   startingDate = sunday;
   Date tmp = startingDate;
   for (Integer i = 0; i < 7; i++) {
    Day d = new Day( tmp,month ); 
    tmp = tmp.addDays(1);
    d.dayOfWeek = i+1;    
   // system.debug(d);
    days.add(d);
   } 
   
  }
  public Integer getWeekNumber() { return this.weekNumber;}
  public Date getStartingDate() { return this.startingDate;}
  
 }
 
 public class Day {
   
  public Date   theDate;
  public List<EventItem>  eventsToday; // list of events for this date
  public Integer   month, dayOfWeek;
  public String   formatedDate; // for the formated time  
  private String   cssclass = 'calActive';
   
  public Date   getDate() { return theDate; }
  public Integer   getDayOfMonth() { return theDate.day(); }
  public String   getDayOfMonth2() { 
   if ( theDate.day() <= 9 ) 
    return '0'+theDate.day(); 
   return String.valueof( theDate.day()); 
  }
  public Integer getDayOfYear() { return theDate.dayOfYear(); }
  public List<EventItem>  getDayAgenda() { return eventsToday; }
  public String   getFormatedDate() { return formatedDate; }
  public Integer   getDayNumber() { return dayOfWeek; }
  public List<EventItem>  getEventsToday() { return eventsToday; }
  public String   getCSSName() {  return cssclass; }
  
  public Day(Date value,Integer vmonth) { 
   theDate=value; month=vmonth;   
   formatedDate = '12 21 08';// time range..
   //9:00 AM - 1:00 PM
   eventsToday = new List<EventItem>();  
   // three possible Inactive,Today,Active  
   if ( theDate.daysBetween(System.today()) == 0 ) cssclass ='calToday';
   // define inactive, is the date in the month—
   if ( theDate.month() != month) cssclass = 'calInactive';
  }
   
 }

/* static testMethod void testMe() {
  Month m = new Month( Date.newInstance(2007,11,1) );
  system.assert(m!=null); 
  List<Week> l = m.getWeeks(); 
  repeatcon r = new repeatcon(); 
  system.debug(m.getMonthName());
  Month mm = r.getMonth();
  //system.debug(mm); 
  system.debug(m.getFirstDate());
  system.debug(m.getWeekdayNames());
  for(Week w:r.getWeeks()) { 
   for(Day c:w.days) {   
    if (c.eventsToday.size() > 0 ) { 
     String ss = String.valueOf(c.eventsToday[0].ev.ActivityDate);
     ss = c.eventsToday[0].ev.ActivityDateTime.format('MMMM a');
     //system.debug(ss);
     //system.debug(c.eventsToday[0].ev);
    } 
   } 
  } 
 }*/
}

 



and now the Visualforce page

Code:
<apex:page controller="repeatCon" id="thePage" >
<apex:stylesheet value="/sCSS/Theme2/default/homeCalendar.css" />

<apex:form id="theForm">
<apex:outputPanel id="theCalendar" >

<div class="mCalendar" style="width:182px;" ><div class="topLeft" ><div class="topRight"/></div>
<div class="body">
<table cellspacing="0" cellpadding="2" border="0">
<tbody>
<tr class="header">
<td><apex:commandLink action="{!prev}" rerender="theCalendar">
<img title="Previous Month" class="prevCalArrow" alt="Previous Month" src="/s.gif" />
</apex:commandLink></td>
<td colspan="5" >
{!month.monthname} {!month.yearname}
</td>
<td><apex:commandLink action="{!next}" rerender="theCalendar">
<img title="Next Month" class="nextCalArrow" alt="Next Month"
src="/s.gif" />
</apex:commandLink></td>
</tr>

<tr>
<th scope="col" class="calDays">Sun</th>
<th scope="col" class="calDays">Mon</th>
<th scope="col" class="calDays">Tue</th>
<th scope="col" class="calDays">Wed</th>
<th scope="col" class="calDays">Thu</th>
<th scope="col" class="calDays">Fri</th>
<th scope="col" class="calDays">Sat</th>
</tr>

<apex:repeat value="{!weeks}" var="wk" id="foreachWeek">
<tr class="days">
<!-- or highlight -->
<apex:repeat value="{!wk.days}" var="day" id="foreachday">
<td valign="top"><a class="calActive"
href="/00U/c—md0=2008&md3={!day.dayOfYear}" target="_blank"
title="Day View - {!day.date}">{!day.dayofmonth2}</a></td>
</apex:repeat>
</tr>
</apex:repeat>

</tbody>
</table>
</div>
<div class="bottomLeft"><div class="bottomRight"/></div>
</div>

</apex:outputPanel>
</apex:form>
</apex:page>

 

So for your design you would write a topic Apex class, which held the topic data and a getTopic() method
then you would create a custom class called category, which held a list of topics, and exposed a getTopics() method to return that list.

then you would construct a list of groupings which holds a list of categories, and has a method getCategories()

in pesudo code the visualforce would look something like this

<apex:repeat value ="{ !groupings }"  var ="g" >
   <li > g.categoryName </li>
    < ul> < apex : repeat value = "{ ! g.categories }"  var=" cat" >
      <li > { ! cat.topic } </li >
   </apex : repeat >
  < /ul>
....

</apex : repeat >


i'm not capturing the nice UI that you are proposing, just the layout logic, let me know if this helps, or if you have a specific problem as you implement your page.

also, please post your code with the SRC button so i can easily drop your code directly into my developer environment to test things out,  thanks.



Message Edited by Ron Hess on 04-18-2008 02:37 PM

All Answers

Ron HessRon Hess
I have a fair example of lists inside of lists, i will drop the code here and explain it. 

It's not exactly your same UI design but it does demonstrate the key concept of an array of custom classes (and getter methods), which contain other classes or sobjects.  Note: this code uses simple standard objects so you can try it out without adding custom fields or tables.

my example is a simple calendar, which is a list of lists. 
The outer list is the list of weeks, 4 or 5 weeks in a month, each week is a list of 7 days.

then these are drawn using nested repeat tags.  You will end up using nested repeat tags (or datalist)  in your design to achieve your final design.

here goes, first the Apex Controller

Code:
public class repeatCon {

public void next() {
addMonth(1);
}

public void prev() {
addMonth(-1);
}

public repeatCon() {

Date d = system.today(); // default to today
Integer mo = d.month();
String m_param = System.currentPageReference().getParameters().get('mo');
String y_param = System.currentPageReference().getParameters().get('yr');

// allow a month to be passed in on the url as mo=10
if (m_param != null) {
Integer mi = Integer.valueOf(m_param);
if (mi > 0 && mi <= 12) {
d = Date.newInstance(d.year(),mi,d.day());
}
}
// and year as yr=2008
if (y_param != null) {
Integer yr = Integer.valueOf(y_param);
d = Date.newInstance(yr, d.month(), d.day());
}

setMonth(d);
}

public List<Month.Week> getWeeks() {
system.assert(month!=null,'month is null');
return month.getWeeks();
}

public Month getMonth() { return month; }


private void setMonth(Date d) {
month = new Month(d);
system.assert(month != null);

Date[] da = month.getValidDateRange(); // gather events that fall in this month
events = [ select id,subject,description,activitydate,activitydatetime,DurationInMinutes
from Event
where activitydate >= :da[0] AND activityDate <= :da[1]
order by activitydatetime];

month.setEvents(events); // merge those events into the month class
}

private void addMonth(Integer val) {
Date d = month.getFirstDate();
d = d.addMonths(val);
setMonth(d);
}

private List<Event> events;
private Month month;
}


now the custom code to implement the month, week and day classes in apex code
study the constructor of the Month() class, then the Week() class , then the Day() class to see how these are built.


Code:
public class Month {
 private List<Week> weeks; 
 public Date firstDate; // always the first of the month
 private Date upperLeft; 
 
 public List<Date> getValidDateRange() { 
  // return one date from the upper left, and one from the lower right
  List<Date> ret = new List<Date>();
  ret.add(upperLeft);
  ret.add(upperLeft.addDays(5*7) );
  return ret;
 }
 
 public String getMonthName() { 
  return DateTime.newInstance(firstDate.year(),firstdate.month(),firstdate.day()).format('MMMM');
 } 
 
 public String getYearName() { 
  return DateTime.newInstance(
  firstDate.year(),firstdate.month(),firstdate.day()).format('yyyy');
 } 
 
 public String[] getWeekdayNames() { 
  Date today = system.today().toStartOfWeek();
  DateTime dt = DateTime.newInstanceGmt(today.year(),today.month(),today.day());  
  list<String> ret = new list<String>();
  for(Integer i = 0; i < 7;i++) { 
   ret.add( dt.formatgmt('EEEE') );
   dt= dt.addDays(1);
  } 
  return ret;
 }
 
 public Date getfirstDate() { return firstDate; } 

 public Month( Date value ) {
  weeks = new List<Week>();
  firstDate = value.toStartOfMonth();
  upperLeft = firstDate.toStartOfWeek();
  Date tmp = upperLeft;
  for (Integer i = 0; i < 5; i++) {
   Week w = new Week(i+1,tmp,value.month()); 
   system.assert(w!=null); 
   this.weeks.add( w );
   tmp = tmp.addDays(7);
  }

 }
 
 public void setEvents(List<Event> ev) { 
  // merge these events into the proper day 
  for(Event e:ev) { 
   for(Week w:weeks) { 
    for(Day c: w.getDays() ) { 
     if ( e.ActivityDate.isSameDay(c.theDate))  { 
      // add this event to this calendar date
      c.eventsToday.add(new EventItem(e));
      // add only three events, then a More... label if there are more
     } 
    } 
   } 
  }
 }
 
 public List<Week> getWeeks() { 
  system.assert(weeks!=null,'could not create weeks list');
  return this.weeks; 
 }
  

 /* 
  * helper classes to define a month in terms of week and day
  */
 public class Week {
  public List<Day> days;
  public Integer weekNumber; 
  public Date startingDate; // the date that the first of this week is on
  // so sunday of this week
  
  public List<Day> getDays() { return this.days; }
  
  public Week () { 
   days = new List<Day>();  
  }
  public Week(Integer value,Date sunday,Integer month) { 
   this();
   weekNumber = value;
   startingDate = sunday;
   Date tmp = startingDate;
   for (Integer i = 0; i < 7; i++) {
    Day d = new Day( tmp,month ); 
    tmp = tmp.addDays(1);
    d.dayOfWeek = i+1;    
   // system.debug(d);
    days.add(d);
   } 
   
  }
  public Integer getWeekNumber() { return this.weekNumber;}
  public Date getStartingDate() { return this.startingDate;}
  
 }
 
 public class Day {
   
  public Date   theDate;
  public List<EventItem>  eventsToday; // list of events for this date
  public Integer   month, dayOfWeek;
  public String   formatedDate; // for the formated time  
  private String   cssclass = 'calActive';
   
  public Date   getDate() { return theDate; }
  public Integer   getDayOfMonth() { return theDate.day(); }
  public String   getDayOfMonth2() { 
   if ( theDate.day() <= 9 ) 
    return '0'+theDate.day(); 
   return String.valueof( theDate.day()); 
  }
  public Integer getDayOfYear() { return theDate.dayOfYear(); }
  public List<EventItem>  getDayAgenda() { return eventsToday; }
  public String   getFormatedDate() { return formatedDate; }
  public Integer   getDayNumber() { return dayOfWeek; }
  public List<EventItem>  getEventsToday() { return eventsToday; }
  public String   getCSSName() {  return cssclass; }
  
  public Day(Date value,Integer vmonth) { 
   theDate=value; month=vmonth;   
   formatedDate = '12 21 08';// time range..
   //9:00 AM - 1:00 PM
   eventsToday = new List<EventItem>();  
   // three possible Inactive,Today,Active  
   if ( theDate.daysBetween(System.today()) == 0 ) cssclass ='calToday';
   // define inactive, is the date in the month—
   if ( theDate.month() != month) cssclass = 'calInactive';
  }
   
 }

/* static testMethod void testMe() {
  Month m = new Month( Date.newInstance(2007,11,1) );
  system.assert(m!=null); 
  List<Week> l = m.getWeeks(); 
  repeatcon r = new repeatcon(); 
  system.debug(m.getMonthName());
  Month mm = r.getMonth();
  //system.debug(mm); 
  system.debug(m.getFirstDate());
  system.debug(m.getWeekdayNames());
  for(Week w:r.getWeeks()) { 
   for(Day c:w.days) {   
    if (c.eventsToday.size() > 0 ) { 
     String ss = String.valueOf(c.eventsToday[0].ev.ActivityDate);
     ss = c.eventsToday[0].ev.ActivityDateTime.format('MMMM a');
     //system.debug(ss);
     //system.debug(c.eventsToday[0].ev);
    } 
   } 
  } 
 }*/
}

 



and now the Visualforce page

Code:
<apex:page controller="repeatCon" id="thePage" >
<apex:stylesheet value="/sCSS/Theme2/default/homeCalendar.css" />

<apex:form id="theForm">
<apex:outputPanel id="theCalendar" >

<div class="mCalendar" style="width:182px;" ><div class="topLeft" ><div class="topRight"/></div>
<div class="body">
<table cellspacing="0" cellpadding="2" border="0">
<tbody>
<tr class="header">
<td><apex:commandLink action="{!prev}" rerender="theCalendar">
<img title="Previous Month" class="prevCalArrow" alt="Previous Month" src="/s.gif" />
</apex:commandLink></td>
<td colspan="5" >
{!month.monthname} {!month.yearname}
</td>
<td><apex:commandLink action="{!next}" rerender="theCalendar">
<img title="Next Month" class="nextCalArrow" alt="Next Month"
src="/s.gif" />
</apex:commandLink></td>
</tr>

<tr>
<th scope="col" class="calDays">Sun</th>
<th scope="col" class="calDays">Mon</th>
<th scope="col" class="calDays">Tue</th>
<th scope="col" class="calDays">Wed</th>
<th scope="col" class="calDays">Thu</th>
<th scope="col" class="calDays">Fri</th>
<th scope="col" class="calDays">Sat</th>
</tr>

<apex:repeat value="{!weeks}" var="wk" id="foreachWeek">
<tr class="days">
<!-- or highlight -->
<apex:repeat value="{!wk.days}" var="day" id="foreachday">
<td valign="top"><a class="calActive"
href="/00U/c—md0=2008&md3={!day.dayOfYear}" target="_blank"
title="Day View - {!day.date}">{!day.dayofmonth2}</a></td>
</apex:repeat>
</tr>
</apex:repeat>

</tbody>
</table>
</div>
<div class="bottomLeft"><div class="bottomRight"/></div>
</div>

</apex:outputPanel>
</apex:form>
</apex:page>

 

So for your design you would write a topic Apex class, which held the topic data and a getTopic() method
then you would create a custom class called category, which held a list of topics, and exposed a getTopics() method to return that list.

then you would construct a list of groupings which holds a list of categories, and has a method getCategories()

in pesudo code the visualforce would look something like this

<apex:repeat value ="{ !groupings }"  var ="g" >
   <li > g.categoryName </li>
    < ul> < apex : repeat value = "{ ! g.categories }"  var=" cat" >
      <li > { ! cat.topic } </li >
   </apex : repeat >
  < /ul>
....

</apex : repeat >


i'm not capturing the nice UI that you are proposing, just the layout logic, let me know if this helps, or if you have a specific problem as you implement your page.

also, please post your code with the SRC button so i can easily drop your code directly into my developer environment to test things out,  thanks.



Message Edited by Ron Hess on 04-18-2008 02:37 PM
This was selected as the best answer
HalcyonandonHalcyonandon
Hi, thanks for posting the calendar example, I've been going through it and trying to take your advice.  I've been having some difficulty writing my controller though.

Currently, I have the menu tree built where it goes through each grouping then populates each with all categories and topics.

At this point, I've been fumbling about with writing the controller classes and methods necessary to return a list of groupings holding a list of categories, which contain the category's topics.  So far, I havent made much progress to that end.

I was wondering if you could post some pseudo code for how this controller would be put together?

I'll post my solution if I happen to find it before a response.

Thanks again for your help
JPSeaburyJPSeabury

Wow, Ron, thanks for posting that code -- brilliant!

I made a few tweaks to it for a custom visualforce page I'm developing for my Customer Support organization.  They schedule maintenance windows with customers "after hours", and wanted a view of all those maintenance events in a monthly calendar. 

They had other requests, like color coding of activities (black=request, blue=scheduled / resource allocated, green=success, red=failed / problems encountered, olive green=canceled activity).  Clicking on a calender item should open that Maintenance detail record.

I was on the path of developing something with a public group calendar, but ran into some API roadblocks there.  Your code got me moving in the right direction, thanks!

NLNL
Hi,
 
I'm new to Salesforce. I tried your codes 'cause I'm trying to create a calendar of vacation days for our Reps. Would you have any idea why I am getting the following error:
 
Compile Error: Invalid type: EventItem at line 57 column 29

Thanks!

JPSeaburyJPSeabury

I believe EventItem is defined in a class not included in Ron's sample code above.  The sample code was not intended to be run "as is" -- it was just posted to demonstrate how to make nested Lists (i.e., Month is a List of weeks, which is a List of Days, which is a list of EventItems).

Substitute in whatever object you're using to track vacation days.

Cool_DevloperCool_Devloper

Hello Ron,

 

I need to build a tree with any number of levels.

 

Can you please give me a direction on this?? 

 

Would be really obliged....

Cool_D 

nellymnjnellymnj

Hello,

I need to buld something very similar - the multiuser week calendar, where columns are days of week showing in every row user name and events (Subject and Location) for this user. I tried to modify this code, made week an upper class, and added List of Lists of Strings for User name and event's subject and location (I don't need to have any links to a calendar). I does not show me the rows, could you please take a lokk and tell me what I am doing wrong?

Thank you very much for any help.

Here is the code:

public class WeekCalendar {

private Week week;

private List<Event> events;  public void next() {

addWeek(1);

}

public void prev() {

addWeek(-1);

}

public Week getWeek() { return week; }

public List<Week.Day> getDays() {system.assert(week!=

null,'week is null'); return week.getDays();

}

 

private void addWeek(Integer val) {

Date d = week.getStartingDate();

Integer wk = week.getWeekNumber();

wk += val;

d = d.addDays(val*7);

Integer mo = d.month();

setWeek(wk,d,mo);

}

private void setWeek(Integer value,Date sunday,Integer month) {

week = new Week(value,sunday,month);system.assert(week !=

null);

Date[] da = week.getValidDateRange(); // gather events that fall in this month

 Event[] events = [select e.Id, e.Subject, e.Owner.Name, e.OwnerId, e.Location,

e.ActivityDate, e.ActivityDateTime from Event e where e.ActivityDate >= :da[0] and e.ActivityDate <= :da[1]

order by e.Owner.Name, e.ActivityDateTime];

 

week.setEvents(events); // merge those events into the month class

}

 

public WeekCalendar() {

Date d = system.today(); // default to today

Date startingDate = d.toStartOfWeek();

Integer mo = d.month();

Integer yr = d.year();

Integer wk = 0;

String m_param = System.currentPageReference().getParameters().get('mo');

String y_param = System.currentPageReference().getParameters().get('yr');String w_param = System.currentPageReference().getParameters().

get('wk');

 

// allow a month to be passed in on the url as mo=10

 if (m_param != null) {

Integer m = Integer.valueOf(m_param);

if (m > 0 && m <= 12) {

mo = m;

}

}

// and year as yr=2008

 if (y_param != null) {

Integer y = Integer.valueOf(y_param);

if (y > yr -10 && y < yr + 10){

yr = y;

}

}

// and week as wk=2

 if (w_param != null) {

Integer w = Integer.valueOf(w_param);

if (w > 0 && w <= 6){

wk = w;

}

}

d = Date.newInstance(yr,mo,d.day());

Date firstDate = d.toStartOfMonth(); // the first of the month

Date firstWeek = firstDate.toStartOfWeek();

// the date that the first of this week is on so sunday of this week

 if (wk > 0){

startingDate = firstDate.addDays((wk-1) * 7);

}

else{

startingDate = d.toStartOfWeek();

wk = firstWeek.daysBetween(startingDate)/7 +1;

}

 

setWeek(wk,startingDate,mo);

}

 

static testMethod void testWeekCalendar() {

Date dt = system.today(); // default to today

Integer mo = dt.month();

Date startingDate = dt.toStartOfWeek();

Date firstDate = dt.toStartOfMonth(); // the first of the month

Date firstWeek = firstDate.toStartOfWeek();

Integer wn = firstWeek.daysBetween(startingDate)/7 +1;

Week wk = new Week(wn,startingDate,mo);system.assert(wk!=null);

List<Week.Day> l = wk.getDays();

WeekCalendar wc = new WeekCalendar();

system.debug(wk.getTitle());

Week curw = wc.getWeek();

//system.debug(mm);

system.debug(wk.getWeekdayNames());

system.debug(wk.getWeekdays());

for(Week.Day d:wc.getDays()) {  if (d.eventsToday.size() > 0 ) {

String ss = String.valueOf(d.eventsToday[0].ActivityDate);

ss = d.eventsToday[0].ActivityDateTime.format('MMMM a');

//system.debug(ss);

//system.debug(c.eventsToday[0].ev);

}

}

}

}

nellymnjnellymnj

this is the other part of code:

public class Week {

public List<Day> days;

private String title;

private String[] weekdays;

private Integer weekNumber; private Map<String, List<Event>> mapUsEvents;

private Date startingDate;

private List<String> userColomns;  

private List<List<String>> userRows; public List<List<String>> getuserRows(){

Set<String> lUsr = mapUsEvents.keySet();

for (String u : lUsr){

userColomns.add(u);

List<Event> usev = mapUsEvents.get(u);

List<Day> pds = this.getDays();

for(Integer k = 0; k < pds.size(); k++) {

for(Event e : usev) { if ( e.ActivityDate.isSameDay(pds[k].theDate)) {  

pds[k].eventsToday.add(e);

userColomns.add(e.Subject + ' at ' + e.Location);

}

else{userColomns.add('');}

}

}

userRows.add(userColomns);

userColomns.clear();

}

return userRows;}

public List<Date> getValidDateRange() {  

// return the beginning and the end of the week

List<Date> ret = new List<Date>();

ret.add(this.startingDate);

ret.add(this.startingDate.addDays(6) );

return ret;

}

}

public List<Day> getDays() { return this.days; }

public Week () { days =

new List<Day>();

userColomns = new List<String>(); userRows =

new List<List<String>>();

}

public Week(Integer value,Date sunday,Integer month) {  

this();

weekNumber = value;

startingDate = sunday;

Date tmp = startingDate;

userColomns = new List<String>();  

userRows = new List<List<String>>();

for (Integer i = 0; i < 7; i++) {Day d = new Day( tmp,month );  

tmp = tmp.addDays(1);

d.dayOfWeek = i+1;

days.add(d);

}

}

public void setEvents(List<Event> ev) {    

mapUsEvents= new Map<String, List<Event>>();  

List<Event> usev = new List<Event>();

if (ev.size()> 0){

Integer i = 0;

Event t = ev[i];String us = t.Owner.Name;

usev.add(ev[i]);

for( i = 1; i < ev.size(); i++) {

t = ev[i];

String nextus = t.Owner.Name;

if (nextus != us){

mapUsEvents.put(us, usev);

usev.clear();

us = nextus;

}

usev.add(t);

}

mapUsEvents.put(us, usev);

}

}

public String getTitle() {title = 'Week of ';

Date enddt = startingDate.addDays(6);

title += DateTime.newInstance(startingDate.year(),startingDate.month(),startingDate.day()).format('MMMM');title +=

' ';

Integer iday = startingDate.day();

title += String.valueOf(iday); 

return title;

}

public String[] getWeekdays() {  

Date today = system.today().toStartOfWeek();

DateTime dt = DateTime.newInstanceGmt(today.year(),today.month(),today.day());

list<String> ret = new list<String>();

for(Integer i = 0; i < 7;i++) { ret.add( dt.formatgmt(

'EEEE, MMM d') );

dt= dt.addDays(1);

}

return ret;

}

public Integer getWeekNumber() { return this.weekNumber;} public Date getStartingDate() { return this.startingDate;}  

public class Day {//all the same

}

nellymnjnellymnj

and here is the page:

<apex:page controller="WeekCalendar" id="thePage">
    <apex:stylesheet value="/sCSS/Theme2/default/homeCalendar.css" />
    <apex:form id="theForm" style="width:100%">
    <apex:outputPanel id="theCalendar" style="width:100%">
    <div class="mCalendar" style="width:182px;"><div class="topLeft"><div class="topRight"/></div>
        <div class="body" style="width:100%">
        <table cellspacing="0" cellpadding="2" border="0">
        <tbody>
        <tr class="header"> <td colspan="2">&nbsp;</td> <td colspan="5" align="center">Team Calendar</td>
        <td>&nbsp;</td>
        </tr>
        <tr class="header"> <td>&nbsp;</td>
            <td><apex:commandLink action="{!prev}" rerender="theCalendar">
                <img title="Previous Week" class="prevCalArrow" alt="Previous Week" src="/s.gif" />
                    </apex:commandLink></td>
            <td colspan="5" align="center">{!week.title}</td>
            <td><apex:commandLink action="{!next}" rerender="theCalendar">
                <img title="Next Week" class="nextCalArrow" alt="Next Week" src="/s.gif" />
                    </apex:commandLink></td></tr>
        <tr>
            <th scope="col" class="calDays">Team Member</th>
            <apex:repeat first="0" id="wday" rows="7" value="{!week.weekdays}" var="wd">
             <th scope="col" class="calDays">{!wd}</th></apex:repeat>
        </tr>
        <apex:repeat value="{!week.userRows}" var="urows" id="foreachUser">
        <tr class="days">
            <apex:repeat value="{!urows}" var="col" id="foreachday">
                <td valign="top">{!col}</td>
            </apex:repeat>
        </tr>
        </apex:repeat>
    </tbody>
    </table>
    </div>
    <div class="bottomLeft"><div class="bottomRight"/></div>
    </div>

</apex:outputPanel>
</apex:form>

</apex:page>

Ron HessRon Hess

one more thing, here is the link to EventItem.cls

 

http://code.google.com/p/visualforce-components/source/browse/#svn/trunk/CalendarSimple/src/classes

 

Marco_MaltesiMarco_Maltesi

Hi,

Please, Can i replace the Object Event by another custom object.

If yes , what i should change in the code

maggiefmaggief

We used this code as well, thanks Ron for posting it. One issue that we have noticed is that the day is off by one  when the locales of the user is in Europe. Has anyone encountered this issue ?

Thanks.

maggiefmaggief

Ok - I see that toStartofWeek

Returns the start of the week for the Date that called the method, depending on the context user's locale. For example, the start of a week is Sunday in the United States locale, and Monday in European locales. For example:

date myDate = date.today();
date weekStart = myDate.toStartofWeek();
SFDC-vishnuSFDC-vishnu

Hi Marco_Maltesi

 

Did u got the solution ,If so please share the code.