Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Custom Calendar with Element UI

Tech 1

To create a custom calendar with Element UI, we customize date cells to display additional data (e.g., people count, working hours) and control visible dates (only the target month: previous, current, or next).

Template Structure

<el-calendar v-model="currentMonthFirstDay">
  <template
    slot="dateCell"
    slot-scope="{ date, data }"
  >
    <!-- Render date only if it's in the valid month -->
    <template v-if="validDates.includes(data.day)">
      <div class="date-title">
        {{ data.day.split('-').slice(2).join('-') }}
        <i class="el-icon-edit"></i>
      </div>
      <!-- Render data if available for this date -->
      <template v-if="calendarDataMap[data.day]">
        <div class="calendar-left-content blue">
          <div>People</div>
          <div>{{ calendarDataMap[data.day].numPeople }} people</div>
        </div>
        <div class="calendar-left-content orange">
          <div>Hours</div>
          <div>{{ calendarDataMap[data.day].workingHours }} hours</div>
        </div>
      </template>
    </template>
  </template>
</el-calendar>


### Computed Property: Valid Dates  
The `validDates` property generates a list of dates for the selected month (previous, current, or next) to control which dates appear in the calendar:  

```javascript
validDates() {
  const now = this.currentDate; // Assumes `currentDate` is a Date instance
  let monthOffset = 0;
  switch (this.tabPosition) {
    case 'lastMonth':
      monthOffset = -1;
      break;
    case 'thisMonth':
      monthOffset = 0;
      break;
    case 'nextMonth':
      monthOffset = 1;
      break;
    default:
      monthOffset = 0;
  }

  let year = now.getFullYear();
  let month = now.getMonth() + 1 + monthOffset; // Convert to 1-based month

  // Adjust year for month overflow (e.g., month 13 → year +1, month 1)
  if (month > 12) {
    year += 1;
    month = 1;
  } else if (month < 1) {
    year -= 1;
    month = 12;
  }

  // Get total days in the target month
  const daysInMonth = new Date(year, month, 0).getDate();
  const validDatesList = [];

  // Generate all date in the month (formatted as YYYY-MM-DD)
  for (let day = 1; day <= daysInMonth; day++) {
    const formattedDay = String(day).padStart(2, '0');
    const formattedMonth = String(month).padStart(2, '0');
    const dateStr = `${year}-${formattedMonth}-${formattedDay}`;
    validDatesList.push(dateStr);
  }

  return validDatesList;
}

Mapping Calendar Data

To efficiently access data by date, we restructure the backend response into a map (using reduce):

processCalendarData() {
  this.calendarDataMap = this.calendarDatas.reduce((acc, item) => {
    acc[item.data] = { ...item }; // `item.data` is the date string (YYYY-MM-DD)
    return acc;
  }, {});
}

CSS: Disable Non-Target Month Dates

To ensure only the target month’s dates are interactive, we disable clicks on dates from other months:

/* Hide/Disable dates from other months */
:deep(.el-calendar-table td.next) {
  pointer-events: none;
  display: none;
}
:deep(.el-calendar-table td.prev) {
  pointer-events: none;
}

Key Logic

  • Date Validation: The validDates property ensures only dates from the selected month are rendered.
  • Data Lookup: calendarDataMap alllows quick access to date-specific data (e.g., people, hours) in the template.
  • Interaction Control: CSS disables interaction with non-target month dates to enforce the calender’s scope.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.