I am trying to increase my LWC knowledge and set myself a little task that seems too big for me. I have asked some AI platforms, but I think a good human would be better.
I have a custom object with the fields 
I am trying to display the data like this :
The idea is to have the records to appear on the left and on the right columns representing the days. If Start date of record 1 = 06 Nov and End Date 8 Nov then a tile covering the 3 days show appear. if Status = A the tile is blue if B then green. Inside the tile there is a clickable icon when clicked we can change the status.
the tiles display and size changes depending on the number of days but the day colunms don't show.. The HTML doesn't like the line :
<div key={record.Id} class="slds-card calendar-item" style={record.style}>
And this is where I need help as this is too much for my knowledge..
here is the code so far: JS
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import getRecords from '@salesforce/apex/CalendarController.getRecords';
import updateStatus from '@salesforce/apex/CalendarController.updateStatus';
import { refreshApex } from '@salesforce/apex';
export default class CalendarComponent extends LightningElement {
@track records = [];
@track startDate = new Date().toISOString().split('T')[0];
@track endDate = new Date(new Date().setDate(new Date().getDate() + 10)).toISOString().split('T')[0];
@track country = 'All countries';
@track status = 'All statuses';
countryOptions = [
{ label: 'All countries', value: 'All countries' },
{ label: 'France', value: 'FR' },
{ label: 'Australia', value: 'AU' },
];
statusOptions = [
{ label: 'All statuses', value: 'All statuses' },
{ label: 'Promised', value: 'promised' },
{ label: 'Confirmed', value: 'confirmed' },
{ label: 'Live', value: 'live' },
];
wiredRecordsResult;
@wire(getRecords, { country: '$country', status: '$status', startDate: '$startDate', endDate: '$endDate' })
wiredRecords(result) {
this.wiredRecordsResult = result;
if (result.data) {
this.records = result.data.map(record => ({
...record,
style: this.calculateItemStyle(record)
}));
} else if (result.error) {
this.showToast('Error', 'Could not fetch records', 'error');
}
}
handleStartDateChange(event) {
this.startDate = event.target.value;
}
handleEndDateChange(event) {
this.endDate = event.target.value;
}
handleCountryChange(event) {
this.country = event.detail.value;
}
handleStatusChange(event) {
const recordId = event.target.dataset.id;
const newStatus = event.detail.value;
updateStatus({ recordId, status: newStatus })
.then(() => {
this.showToast('Success', 'Status updated successfully', 'success');
return refreshApex(this.wiredRecordsResult);
})
.catch(error => {
this.showToast('Error', 'Could not update status', 'error');
});
}
showToast(title, message, variant) {
const event = new ShowToastEvent({
title,
message,
variant,
});
this.dispatchEvent(event);
}
calculateItemStyle(record) {
const startDate = new Date(record.Start_Date__c);
const endDate = new Date(record.End_Date__c);
const daysSpan = Math.min((endDate - startDate) / (1000 * 60 * 60 * 24) + 1, 10);
return `grid-column: span ${daysSpan};`;
}
}
HTML:
<template>
<lightning-card title="Stuff">
<div class="slds-m-around_medium">
<lightning-input type="date" label="Start Date" value={startDate} onchange={handleStartDateChange}></lightning-input>
<lightning-input type="date" label="End Date" value={endDate} onchange={handleEndDateChange}></lightning-input>
<lightning-combobox label="Filter by Country" value={country} options={countryOptions} onchange={handleCountryChange}></lightning-combobox>
<lightning-combobox label="Filter by Status" value={status} options={statusOptions} onchange={handleStatusChange}></lightning-combobox>
</div>
<div class="calendar-container">
<template if:true={records.length}>
<template for:each={records} for:item="record">
<div key={record.Id} class="slds-card calendar-item" style={record.style}>
<div class="slds-card__header">
{record.Name} [{record.Country__c}]
</div>
<div class="slds-card__body">
<lightning-combobox data-id={record.Id} value={record.Status__c} options={statusOptions} onchange={handleStatusChange}></lightning-combobox>
</div>
</div>
</template>
</template>
<template if:false={records.length}>
<div class="slds-m-around_medium">
No records found.
</div>
</template>
</div>
</lightning-card>
</template>
CSS:
.calendar-container {
display: grid;
grid-template-columns: repeat(10, 1fr); /* Always show 10 days */
gap: 10px; /* Space between grid items */
}
.calendar-item {
border: 1px solid #dcdcdc;
padding: 10px;
background: #f4f6f9;
margin-bottom: 10px; /* Margin at the bottom for spacing */
}
Controller:
public with sharing class CalendarController {
@AuraEnabled(cacheable=true)
public static List<myObj__c> getRecords(String country, String status, Date startDate, Date endDate) {
String query = 'SELECT Id, Name, Country__c, Start_Date__c, End_Date__c, Status__c FROM myObj__c WHERE Start_Date__c >= :startDate AND End_Date__c <= :endDate';
if (country != 'All countries') {
query += ' AND Country__c = :country';
}
if (status != 'All statuses') {
query += ' AND Status__c = :status';
}
return Database.query(query);
}
@AuraEnabled
public static void updateStatus(Id recordId, String status) {
myObj__c record = [SELECT Id, Status__c FROM myObj__c WHERE Id = :recordId LIMIT 1];
record.Status__c = status;
update record;
}
}
enter code here
