0

I have a List that gets populated based on Start Date and end Date range that user has provided on UI. Say for example, if Start Date = 01/02/2017 and End Date = 15/02/2017, than List of dateWrapper will contain 15 entires as per the date range.

Now I want to create an html table where static header will be week days i.e. 1 row (one tr) with 7 columns (7 td's) (Sunday to Saturday). Than the dynamically iterating over list, table rows and columns needs to be placed as the date range.

As an output, the table should look like:

Sun Mon Tue Wed Thu Fri Sat
                 1   2   3
 4   5   7   8   9  10  11
12  13  14  15

How do we achieve this?

Approach that I tried is below: Sunday Monday Tuesday Wednesday Thursday Friday Saturday

<!-- Dynamically display table data below-->
    <apex:repeat var="datewrap" value="{!dateWrapperList}">
    <tr>
      <td data-label="Sunday">
        <apex:outputpanel rendered="{!if(datewrap.dayOfWeek = 'Sun', true, false)}">
               <b>{!dateWrap.dateValue}</b>
            </apex:outputPanel>
      </td>
      <td data-label="Monday">
        <apex:outputpanel rendered="{!if(dateWrap.dayOfWeek = 'Mon', true, false)}">
               <b>{!dateWrap.dateValue}</b>
            </apex:outputPanel>
      </td>
      <td data-label="Tuesday">
        <apex:outputpanel rendered="{!if(dateWrap.dayOfWeek = 'Tue', true, false)}">
               <b>{!dateWrap.dateValue}</b>
            </apex:outputPanel>
      </td>
      <td data-label="Wednesday">
        <apex:outputpanel rendered="{!if(dateWrap.dayOfWeek = 'Wed', true, false)}">
               <b>{!dateWrap.dateValue}</b>
            </apex:outputPanel>
      </td>
      <td data-label="Thursday">
        <apex:outputpanel rendered="{!if(dateWrap.dayOfWeek = 'Thu', true, false)}">
               <b>{!dateWrap.dateValue}</b>
            </apex:outputPanel>
      </td>
      <td data-label="Friday">
        <apex:outputpanel rendered="{!if(dateWrap.dayOfWeek = 'Fri', true, false)}">
               <b>{!dateWrap.dateValue}</b>
            </apex:outputPanel>
      </td>
      <td data-label="Saturday">
        <apex:outputpanel rendered="{!if(dateWrap.dayOfWeek = 'Sat', true, false)}">
               <b>{!dateWrap.dateValue}</b>
            </apex:outputPanel>
      </td>
    </tr>
  </apex:repeat>
</table>

Incorrect Output:

Sun Mon Tue Wed Thu Fri Sat
                 1   
                     2   
                         3
 4   
     5   
         6
            7   
                8   
                    9  
                        10  
11
    12  
        13  
            14  
                15

Expected Output: Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 7 8 9 10 11 12 13 14 15

1
  • 1
    please edit your post to include what you have tried so far, and where you are stuck.
    – glls
    Feb 6, 2018 at 19:34

1 Answer 1

3

There's at least two basic ways to do this.

My preference is to have a higher-level wrapper, a WeekWrapper, to show the data. That makes the markup look like this:

<apex:repeat value="{!weeks}" var="week">
  <tr>
    <apex:repeat value="{!week.days}" var="day">
      <td> ... </td>
    </apex:repeat>
  </tr>
</apex:repeat>

If you want to just keep it as a list of days, consider using CSS instead:

<apex:page controller="CalendarExample">
    <style>
        .col7 {
            display: inline-block;
            width: 14%;
        }
    </style>
    <div>
        <span class="col7">Sunday   </span>
        <span class="col7">Monday   </span>
        <span class="col7">Tuesday  </span>
        <span class="col7">Wednesday</span>
        <span class="col7">Thursday </span>
        <span class="col7">Friday   </span>
        <span class="col7">Saturday </span>
        <apex:repeat value="{!month}" var="day">
            <span class="col7">{!day(day.dateValue)}</span>
        </apex:repeat>
    </div>
</apex:page>

public class CalendarExample {
    public class DateWrapper {
        public Date dateValue { get; set; }
        public DateWrapper(Date value) {
            dateValue = value;
        }
    }
    public DateWrapper[] month { get; set; }
    public CalendarExample() {
        Date startDate = Date.today().toStartOfMonth().toStartOfWeek(),
            endDate = Date.today().addMonths(1).toStartOfMonth().toStartOfWeek().addDays(7),
            dateIndex = startDate;
        Integer currentMonth = Date.today().month();
        month = new DateWrapper[0];
        while(dateIndex < endDate) {
            if(dateIndex.month() == currentMonth) {
                month.add(new DateWrapper(dateIndex.addDays(0)));
            } else {
                month.add(new DateWrapper(null));
            }
            dateIndex = dateIndex.addDays(1);
        }
    }
}

Note that in all of these solutions, you still want to have the blank day as cells (e.g. Sunday, Monday, Tuesday, and Wednesday on the first week in your example would be empty values).

8
  • The tricky part is to display blank cells for Sun, Mon, Tue, Wed using date wrapper. I tried the rendered attribute approach as shown in my code, but it displayed table in unexpected manner.
    – Shrey
    Feb 6, 2018 at 19:56
  • @Shrey Yes, as I said, you'd have extra array elements for Sun-Wed, as in your example, placed at the beginning of the list.
    – sfdcfox
    Feb 6, 2018 at 19:58
  • @Shrey And, you're rendering one tr per day, which is why it's 15 rows tall. Splitting the data into a WeekWrapper would make it easier to visualize, I think, and it's the way I wrote it as a novice. These days, I'd skip using a table at all and simply use a series of properly sized inline-block CSS elements.
    – sfdcfox
    Feb 6, 2018 at 20:00
  • @sfdcox so is it correct if I state that my expected output is not possible using this panelgrid approach: <apex:panelGrid columns="7"> <apex:repeat value="{!days}" var="day"> <apex:panel> {!day.number} </apex:panel> </apex:repeat> </apex:panelGrid> and I will have to use week wrapper to display the table in calendar fashion
    – Shrey
    Feb 6, 2018 at 20:02
  • @Shrey If you use the panelGrid, it should render your rows correctly for you. It's been a while since I've used it, but I think I could dredge up some old source code.
    – sfdcfox
    Feb 6, 2018 at 20:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.