Working Time

Each calendar in a GanttSheet is formed with working weeks, working days and working time, which you can customize.

Description
app.js
index.html
styles.css
Copy to CodeMine

Default Working Week

The working week is composed of 7 working days. To get the default working week, you can use the following code:

// get from project current calendar
var calendar = ganttSheet.project.calendar;
console.log(calendar.defaultWorkWeek);

// get from built-in namespace
console.log(GC.Spread.Sheets.GanttSheet.Calendar.standard);
console.log(GC.Spread.Sheets.GanttSheet.Calendar.hours24);
console.log(GC.Spread.Sheets.GanttSheet.Calendar.nightShift);

Modified the Working Week

If you want the change the working time, you can use the following code:

var calendar = GC.Spread.Sheets.GanttSheet.Calendar.standard;
var defaultWorkWeek = calendar.defaultWorkWeek;
var workday = defaultWorkWeek.getWorkDay(GC.Spread.Sheets.GanttSheet.DayOfWeek.Monday);
// The Working Day is formed with time range:
/*
    [
        { start: { hour: 8, minute: 0 }, end: { hour: 12, minute: 0 } },
        { start: { hour: 13, minute: 0 }, end: { hour: 17, minute: 0 } }
    ]
    // 8:00~12:00 13:00~17:00
*/
workday[1].end.hour = 13;

// apply the edited calendar
ganttSheet.project.calendar = GC.Spread.Sheets.GanttSheet.Calendar.standard;
Default Working Week The working week is composed of 7 working days. To get the default working week, you can use the following code: Modified the Working Week If you want the change the working time, you can use the following code:
/*REPLACE_MARKER*/ /*DO NOT DELETE THESE COMMENTS*/ var myTable; var ganttSheet; var Calendars = { standard: GC.Spread.Sheets.GanttSheet.Calendar.standard, hours24: GC.Spread.Sheets.GanttSheet.Calendar.hours24, nightShift: GC.Spread.Sheets.GanttSheet.Calendar.nightShift }; window.onload = function() { var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 0 }); initSpread(spread); initSplitView(spread); }; function initSpread(spread) { spread.suspendPaint(); initDataSource(spread); initGanttSheet(spread); spread.resumePaint(); } function initDataSource(spread) { var tableName = "Gantt_Id"; var baseApiUrl = getBaseApiUrl(); var apiUrl = baseApiUrl + "/" + tableName; var dataManager = spread.dataManager(); myTable = dataManager.addTable("myTable", { batch: true, remote: { read: { url: apiUrl } }, schema: { hierarchy: { type: "Parent", column: "parentId" }, columns: { id: { isPrimaryKey: true }, taskNumber: { dataType: "rowOrder" } } } }); } function initGanttSheet(spread) { ganttSheet = spread.addSheetTab(0, "GanttSheet", GC.Spread.Sheets.SheetType.ganttSheet); var view = myTable.addView("ganttView", [ { value: "taskNumber", caption: "NO.", width: 60 }, { value: "name", caption: "Task Name", width: 200 }, { value: "duration", caption: "Duration", width: 90 }, { value: "predecessors", caption: "Predecessors", width: 120, visible: false } ]); view.fetch().then(function() { ganttSheet.bindGanttView(view); ganttSheet.project.calendar = Calendars.standard; }); initSidePanel(ganttSheet); } function initSidePanel(ganttSheet) { var currentCustomWorkWeek = ganttSheet.project.calendar.defaultWorkWeek; var targetCalendarItem = document.getElementById("target-calendar"); var customTargetDayItem = document.getElementById("target-day"); var addWorkTimeItem = document.getElementById("add-work-time"); var addWorkWeekItem = document.getElementById("add-work-week"); var workTimeTableItem = document.getElementById("work-time-table"); updateWorkingTimeTable(ganttSheet.project.calendar.defaultWorkWeek, 0); targetCalendarItem.addEventListener("change", function() { var calendarType = targetCalendarItem.value; var calendar = Calendars[calendarType]; var workdayIndex = Number(customTargetDayItem.value); currentCustomWorkWeek = calendar.defaultWorkWeek; updateWorkingTimeTable(currentCustomWorkWeek, workdayIndex); ganttSheet.project.calendar = calendar; }); customTargetDayItem.addEventListener("change", function() { var workdayIndex = Number(customTargetDayItem.value); updateWorkingTimeTable(currentCustomWorkWeek, workdayIndex); }); addWorkTimeItem.addEventListener("click", function() { var workdayIndex = Number(customTargetDayItem.value); var workday = currentCustomWorkWeek.getWorkDay(workdayIndex); var workTime = { start: { hour: 0, minute: 0 }, end: { hour: 0, minute: 0 } }; workday.push(workTime); updateWorkingTimeTable(currentCustomWorkWeek, workdayIndex); }); workTimeTableItem.addEventListener("click", function(e) { var target = e.target; if (target.classList.contains("icon-delete")) { var targetWorkTimeIndex = target.dataset.row; var workdayIndex = Number(customTargetDayItem.value); // GC.Spread.Sheets.GanttSheet.DayOfWeek var workday = currentCustomWorkWeek.getWorkDay(workdayIndex); workday.splice(targetWorkTimeIndex, 1); updateWorkingTimeTable(currentCustomWorkWeek, workdayIndex); } }); addWorkWeekItem.addEventListener("click", function() { var calendar = ganttSheet.project.calendar; var workdayIndex = Number(customTargetDayItem.value); // GC.Spread.Sheets.GanttSheet.DayOfWeek var workday = currentCustomWorkWeek.getWorkDay(workdayIndex); updateWorkingTime(workday); calendar.defaultWorkWeek = currentCustomWorkWeek; ganttSheet.project.calendar = calendar; }); function updateWorkingTime(workday) { var rows = workTimeTableItem.getElementsByTagName("tr"); if (rows) { for (var i = 0; i < rows.length; i ++) { var row = rows[i]; var workTime = workday[i]; var startItemValue = row.getElementsByClassName("start-item")[0].value; var endItemValue = row.getElementsByClassName("end-item")[0].value; var start = parseTimeString(startItemValue); var end = parseTimeString(endItemValue); if (start) { workTime.start = start; } if (end) { workTime.end = end; } } } } function updateWorkingTimeTable(customWorkWeeks, workdayIndex) { var workday = customWorkWeeks.getWorkDay(workdayIndex); var tableInnerHTML = ""; for (var i = 0; i < workday.length; i ++) { var workTime = workday[i]; var from = `${convertTimeString(workTime.start.hour)}:${convertTimeString(workTime.start.minute)}`; var to = `${convertTimeString(workTime.end.hour)}:${convertTimeString(workTime.end.minute)}`; var rowHTML = ` <tr> <td><input type="text" class="input-date start-item" value="${from}" /></td> <td><input type="text" class="input-date end-item" value="${to}" /></td> ${getTableFunctionalColumn(false, true, i)} </tr> `; tableInnerHTML += rowHTML; } workTimeTableItem.innerHTML = tableInnerHTML; } function getTableFunctionalColumn(needEdit, needDelete, index) { return ` <td> ${needEdit ? `<span class="icon icon-edit" ${typeof index === "number" ? "data-row=" + index : ""}>edit</span>` : ""} ${needDelete ? `<span class="icon icon-delete" ${typeof index === "number" ? "data-row=" + index : ""}>delete</span>` : ""} </td> `; } function convertTimeString(num) { if (num < 10) { return "0" + num; } else { return num.toString(); } } function parseTimeString(timeString) { var hourAndMinute = timeString.split(":"); if (hourAndMinute && hourAndMinute.length === 2) { return { hour: Number(hourAndMinute[0]), minute: Number(hourAndMinute[1]) }; } } } function getBaseApiUrl() { return window.location.href.match(/http.+spreadjs\/demos\//)[0] + 'server/api'; } function initSplitView(spread) { var host = document.getElementById("split-view"); var content = host.getElementsByClassName("split-content")[0]; var panel = host.getElementsByClassName("split-panel")[0]; var defaultPanelWidth = 340; new SplitView({ host: host, content: content, panel: panel, defaultPanelWidth: defaultPanelWidth, refreshContent: function() { spread.refresh(); } }); }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/spread/source/splitView/splitView.css"> <!-- Promise Polyfill for IE, https://www.npmjs.com/package/promise-polyfill --> <script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/splitView/splitView.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <div id="split-view" class="sample-tutorial"> <div id="ss" class="sample-spreadsheets split-content"></div> <div class="options-container split-panel"> <div class="option-row option-title"> Config the working time. </div> <div class="option-block"> <div class="option-row selection-box"> <label for="target-calendar">Target Calendar</label> <select id="target-calendar"> <option value="standard" selected>Standard</option> <option value="hours24">24 Hours</option> <option value="nightShift">Night Shift</option> </select> </div> </div> <div class="option-block toggle"> <div class="option-row option-title clear-float"> <span class="float-left">Working Week Details</span> </div> <div class="option-row selection-box"> <label for="target-day">Workday</label> <select id="target-day"> <option value="0" selected>Sunday</option> <option value="1">Monday</option> <option value="2">Tuesday</option> <option value="3">Wednesday</option> <option value="4">Thursday</option> <option value="5">Friday</option> <option value="6">Saturday</option> </select> </div> <div class="option-row"> <input type="button" id="add-work-time" class="option-button" value="Add Working Time" /> </div> <div class="option-row table-box"> <table> <thead> <tr> <td>From</td> <td>To</td> <td></td> </tr> </thead> <tbody id="work-time-table"> <tr> <td>8:00</td> <td>17:00</td> <td> <span class="icon icon-delete">delete</span> </td> </tr> </tbody> </table> <div class="option-info valid">* valid value: format hh:mm</div> </div> <div class="option-row"> <input type="button" id="add-work-week" class="option-button" value="Apply" /> </div> </div> </div> </div> </html>
.clear-float:after { display: block; content: ""; clear: both; } .float-left { float: left; } .float-right { float: right; } .option-block { background: #fff; padding: 8px; margin: 12px 0; border-radius: 4px; border: 1px dashed #82bc00; box-shadow: 0px 0 6px 0 rgba(0,0,0,0.1); } .option-block.toggle { border: 1px dotted #f7a711; } .option-row { font-size: 14px; box-sizing: border-box; padding: 4px 0; } .option-title { font-weight: bold; color: #656565; } .option-info { font-size: 12px; color: #919191; margin-top: 6px; font-weight: normal; } .option-info.valid { color: #82bc00; } .option-info.toggle { color: #f7a711; } .option-button { width: 100%; padding: 0; line-height: 20px; background: #82bc00; color: #fff; transition: 0.3s; cursor: pointer; outline: none; border-radius: 4px; box-sizing: border-box; box-shadow: 0 1px 4px 0 rgba(0,0,0,0.3); border: none; } .option-button:hover { background: #82bc00; color: #fff; box-shadow: 0 3px 8px 0 rgba(0,0,0,0.4); } .option-checkbox { background: #fff; border: 1px dashed #f7a711; color: #f7a711; padding: 2px 4px; transition: 0.3s; box-sizing: border-box; cursor: pointer; } .option-checkbox.active { color: #fff; background: #f7a711; box-shadow: 0 1px 4px 0 rgba(0,0,0,0.3); border-radius: 4px; } .selection-box { position: relative; } .selection-box > select { text-align: left; width: 100%; height: 20px; padding: 0; line-height: 20px; background: transparent; border: none; border-bottom: 2px solid #656565; color: #656565; transition: 0.3s; cursor: pointer; outline: none; box-sizing: border-box; } .selection-box > select > option { background: white; } .selection-box > select:focus { border-bottom: 2px solid #82bc00; color: #82bc00; box-shadow: 0 2px 6px 0 rgba(0,0,0,0.3); } .selection-box > label { position: absolute; cursor: pointer; font-size: 12px; color: #fff; background: #656565; padding: 0 4px; right: 0; top: 6px; box-shadow: 0 1px 4px 0 rgba(0,0,0,0.3); } .input-box { position: relative; } .input-box > input[type=text] { width: 100%; background: transparent; border: none; color: #656565; border-bottom: 2px solid #656565; outline: none; box-sizing: border-box; transition: 0.3s; } .input-box > input[type=text]:focus { color: #82bc00; border-bottom: 2px solid #82bc00; } .input-box > label { cursor: pointer; position: absolute; right: 0; top: 5px; font-size: 12px; color: #fff; background: #656565; padding: 0 4px; box-shadow: 0 1px 4px 0 rgba(0,0,0,0.3); } .table-box > table { width: 100%; border-collapse: collapse; } .table-box > table > thead > tr { border-bottom: 1px solid #000; font-weight: bold; } .table-box > table > tbody > tr > td { margin-top: 8px; } .table-box .icon { padding: 0 2px; color: #fff; cursor: pointer; border: 1px solid #fff; border-radius: 3px; background: transparent; transition: 0.3s; } .table-box .icon:hover { color: #fff; box-shadow: 0 1px 4px 0 rgba(0,0,0,0.3); } .icon.icon-edit { border-color: #82bc00; color: #82bc00; } .icon.icon-edit:hover { background: #82bc00; } .icon.icon-delete { border-color: #f7a711; color: #f7a711; } .icon.icon-delete:hover { background: #f7a711; } .input-date { width: 100%; border: none; border-bottom: 1px solid ; } .input-date { width: 100%; background: transparent; border: none; color: #656565; border-bottom: 2px solid #656565; outline: none; box-sizing: border-box; transition: 0.3s; } .input-date:focus { color: #82bc00; border-bottom: 2px solid #82bc00; }