# Flexible TimePicker in TB 1. Create Time-Series type Widget 2. Add time display in HTML ```htmlmixed <!-- an example --> <div class="timestamp">From {{timeStart}} to {{timeEnd}}</div> ``` 3. Use `self.ctx .timeWindow.maxTime` and `self.ctx .timeWindow.minTime` to get timeWindow data ```javascript self.onInit = function() { self.ctx.$scope.timeEnd = transferToDate(self.ctx .timeWindow.maxTime); self.ctx.$scope.timeStart = transferToDate(self.ctx .timeWindow.minTime); } self.onDataUpdated = function() { self.ctx.$scope.timeEnd = transferToDate(self.ctx .timeWindow.maxTime); self.ctx.$scope.timeStart = transferToDate(self.ctx .timeWindow.minTime); } function transferToDate(timestamp) { var dd = new Date(timestamp); const month = dd.getMonth() + 1; const day = dd.getDate(); let hour = dd.getHours(); let min = dd.getMinutes(); hour = timeZeroCheck(hour); min = timeZeroCheck(min); const date = month + '/' + day + ' ' + hour + ':' + min; return date; } function timeZeroCheck(num){ num = num.toString(); if(num.length === 1){ num = '0'+ num; } return num; } ``` 4. Add an action to handle time select and change * Method1 ![](https://hackmd.io/_uploads/SJFHL2Of6.png) ```html <!-- dialogHTML --> <div class="container" style="background: #000000; color: #ffffff; padding: 24px 24px 12px; width: 280px;"> <div class="box" style="margin-bottom: 12px; display: flex; justify-content: space-between;"> <label for="start">Start Date:</label> <input type="date" id="start" name="trip-start" /> </div> <div class="box" style="margin-bottom: 12px; display: flex; justify-content: space-between;"> <label for="start-time">Start Time:</label> <input type="time" id="start-time" name="appt" required /> </div> <div class="box" style="margin-bottom: 12px; display: flex; justify-content: space-between;"> <label for="end">End Date:</label> <input type="date" id="end" name="end" /> </div> <div class="box" style="margin-bottom: 12px; display: flex; justify-content: space-between;"> <label for="end-time">End Time:</label> <input type="time" id="end-time" name="end-time" required /> </div> <div class="btn-wrap" style="display: flex; justify-content: center;"> <button mat-flat-button (click)="cancel()" style="margin: 12px 4px;">Cancel</button> <button mat-stroked-button (click)="save()" style="background: #9c5f5f; color: #ffffff; margin: 12px 4px;">Confirm</button> </div> </div> ``` :::success Use `widgetContext.dashboard .dashboardTimewindowChangedSubject.next( newDashboardtimewindow);` to update timeWindow data ::: ```javascript let $injector = widgetContext.$scope.$injector; let customDialog = $injector.get(widgetContext.servicesMap .get('customDialog')); openDialog(); function openDialog() { customDialog.customDialog(dialogHTML, dialogController).subscribe(); } function dialogController(instance) { let vm = instance; vm.cancel = function() { vm.dialogRef.close(null); }; vm.save = function() { const start = getTargetValue(`start`) + 'T' + getTargetValue(`start-time`) +'+0800'; const end = getTargetValue(`end`) + 'T' + getTargetValue(`end-time`) +'+0800'; const startTime = Date.parse(start); const endTime = Date.parse(end); updateTimeWindow(startTime, endTime); var date1 = new Date(startTime); vm.dialogRef.close(null); }; function getTargetValue(name) { const newValue = document.querySelector(`#${name}`) .value; return newValue; } function updateTimeWindow(startTime, endTime) { const newDashboardtimewindow = { aggregation: { limit: 25000, type: "NONE" }, hideAggInterval: false, hideAggregation: false, hideInterval: false, history: { historyType: 1, fixedTimewindow: { startTimeMs: startTime, endTimeMs: endTime, } }, selectedTab: 1 }; widgetContext.dashboard .dashboardTimewindowChangedSubject.next( newDashboardtimewindow); } } ``` * A simple example to select time ![](https://hackmd.io/_uploads/H1C34xtG6.png) <br/> * Method2 (suggest) Write in the widgets library ```javascript self.onInit = function() { self.ctx.$scope.timeEnd = transferToDate(self.ctx .timeWindow.maxTime); self.ctx.$scope.timeStart = transferToDate(self.ctx .timeWindow.minTime); //for timePicker dialog self.ctx.$scope.openDialog = openDialog; const $injector = self.ctx.$scope.$injector; const customDialog = $injector.get(self.ctx .servicesMap .get( 'customDialog')); function openDialog() { customDialog.customDialog(dialogHTML, dialogController).subscribe(); } function dialogController(instance) { let vm = instance; vm.cancel = function() { vm.dialogRef.close(null); }; vm.save = function() { const start = getTargetValue(`start`) + 'T' + getTargetValue(`start-time`) + '+0800'; const end = getTargetValue(`end`) + 'T' + getTargetValue(`end-time`) + '+0800'; const startTime = Date.parse(start); const endTime = Date.parse(end); updateTimeWindow(startTime, endTime); var date1 = new Date(startTime); vm.dialogRef.close(null); }; function getTargetValue(name) { const newValue = document.querySelector( `#${name}`) .value; return newValue; } function updateTimeWindow(startTime, endTime) { const newDashboardtimewindow = { aggregation: { limit: 25000, type: "NONE" }, hideAggInterval: false, hideAggregation: false, hideInterval: false, history: { historyType: 1, fixedTimewindow: { startTimeMs: startTime, endTimeMs: endTime, } }, selectedTab: 1 }; self.ctx.dashboard .dashboardTimewindowChangedSubject.next( newDashboardtimewindow); } } } self.onDataUpdated = function() { self.ctx.$scope.timeEnd = transferToDate(self.ctx .timeWindow.maxTime); self.ctx.$scope.timeStart = transferToDate(self.ctx .timeWindow.minTime); } function transferToDate(timestamp) { var dd = new Date(timestamp); const month = dd.getMonth() + 1; const day = dd.getDate(); let hour = dd.getHours(); let min = dd.getMinutes(); hour = timeZeroCheck(hour); min = timeZeroCheck(min); const date = month + '/' + day + ' ' + hour + ':' + min; return date; } function timeZeroCheck(num) { num = num.toString(); if (num.length === 1) { num = '0' + num; } return num; } ```