Search code examples
javascriptangularbootstrap-4timepickerng-bootstrap

How can I make a Timepicker appear in Dropdown in Angular?


On the Bootstrap 4 docs, you can have a toggleable dropdown that only includes the timepicker. However, I would like to add this using an Angular module for the timepicker instead of using vanilla bootstrap. You can accomplish something similar with an NgbDatepicker, however, there are no listed examples for accomplishing this with a timepicker.

I did try to just use the same code and change the mentions of NgbDatePicker to NgbTimePicker to no avail. The example below yields a Template parse errors: where the ngbTimepicker is not recognized as a directive.

<div class="input-group">
    <input class="form-control" name="startTime" [(ngModel)]="newEmployeeTime.StartTime" ngbTimepicker 
         #start="ngbTimepicker" [readonly]="true">

    <div class="input-group-append">
        <button class="btn btn-outline-secondary calendar" (click)="startTime.toggle()" type="button"><i 
            class="fa fa-clock"></i></button>
    </div>
</div>

Surely there must be a way to accomplish this that isn't complicated, but I just can't seem to think of it at the moment.


Solution

  • package.json

    "dependencies": {
      "@ng-bootstrap/ng-bootstrap": "5.1.4"
    }
    

    app.module.ts

    import { NgbdDatepickerPopup } from './datepicker-popup'
    declarations: [NgbdDatepickerPopup]
    exports: [NgbdDatepickerPopup]
    bootstrap: [NgbdDatepickerPopup]
    

    component.ts

    export class Component {
      model;
    }
    

    component.html

    <form class="form-inline">
      <div class="form-group">
        <div class="input-group">
          <input class="form-control" placeholder="yyyy-mm-dd"
                 name="dp" [(ngModel)]="model" ngbDatepicker #d="ngbDatepicker">
          <div class="input-group-append">
            <button class="btn btn-outline-secondary calendar" (click)="d.toggle()" type="button"></button>
          </div>
        </div>
      </div>
    </form>
    

    component.css

    /* Datepicker popup icon */
    
    button.calendar, button.calendar:active {
      width: 2.75rem;
      background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAcCAYAAAAEN20fAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAEUSURBVEiJ7ZQxToVAEIY/YCHGxN6XGOIpnpaEsBSeQC9ArZbm9TZ6ADyBNzAhQGGl8Riv4BLAWAgmkpBYkH1b8FWT2WK/zJ8ZJ4qiI6XUI3ANnGKWBnht2/ZBDRK3hgVGNsCd7/ui+JkEIrKtqurLpEWaphd933+IyI3LEIdpCYCiKD6HcuOa/nwOa0ScJEnk0BJg0UTUWJRl6RxCYEzEmomsIlPU3IPW+grIAbquy+q6fluy/28RIBeRMwDXdXMgXLj/B2uimRXpui4D9sBeRLKl+1N+L+t6RwbWrZliTTTr1oxYtzVWiTQAcRxvTX+eJMnlUDaO1vpZRO5NS0x48sIwfPc87xg4B04MCzQi8hIEwe4bl1DnFMCN2zsAAAAASUVORK5CYII=') !important;
      background-repeat: no-repeat;
      background-size: 23px;
      background-position: center;
    }
    
    /* Sortable table demo */
    
    th[sortable] {
      cursor: pointer;
      user-select: none;
      -webkit-user-select: none;
    }
    
    th[sortable].desc:before, th[sortable].asc:before {
      content: '';
      display: block;
      background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAmxJREFUeAHtmksrRVEUx72fH8CIGQNJkpGUUmakDEiZSJRIZsRQmCkTJRmZmJgQE0kpX0D5DJKJgff7v+ru2u3O3vvc67TOvsdatdrnnP1Y///v7HvvubdbUiIhBISAEBACQkAICAEhIAQ4CXSh2DnyDfmCPEG2Iv9F9MPlM/LHyAecdyMzHYNwR3fdNK/OH9HXl1UCozD24TCvILxizEDWIEzA0FcM8woCgRrJCoS5PIwrANQSMAJX1LEI9bqpQo4JYNFFKRSvIgsxHDVnqZgIkPnNBM0rIGtYk9YOOsqgbgepRCfdbmFtqhFkVEDVPjJp0+Z6e6hRHhqBKgg6ZDCvYBygVmUoEGoh5JTRvIJwhJo1aUOoh4CLPMyvxxi7EWOMgnCGsXXI1GIXlZUYX7ucU+kbR8NW8lh3O7cue0Pk32MKndfUxQFAwxdirk3fHappAnc0oqDPzDfGTBrCfHP04dM4oTV8cxr0SVzH9FF07xD3ib6xCDE+M+aUcVygtWzzbtGX2rPBrEUYfecfQkaFzYi6HjVnGBdtL7epqAlc1+jRdAap74RrnPc4BCijttY2tRcdN0g17w7HqZrXhdJTYAuS3hd8z+vKgK3V1zWPae0mZDMykadBn1hTQBLnZNwVrJpSe/NwEeDsEwCctEOsJTsgxLvCqUl2ACftEGvJDgjxrnBqkh3ASTvEWrIDQrwrnJpkB3DSDrGW7IAQ7wqnJtkBnLRztejXXVu4+mxz/nQ9jR1w5VB86ejLTFcnnDwhzV+F6T+CHZlx6THSjn76eyyBIOPHyDakhBAQAkJACAgBISAEhIAQYCLwC8JxpAmsEGt6AAAAAElFTkSuQmCC') no-repeat;
      background-size: 22px;
      width: 22px;
      height: 22px;
      float: left;
      margin-left: -22px;
    }
    
    th[sortable].desc:before {
      transform: rotate(180deg);
      -ms-transform: rotate(180deg);
    }
    
    /* Filtering table demo */
    ngbd-table-filtering span.ngb-highlight {
      background-color: yellow;
    }
    
    /* Complete table demo */
    ngbd-table-complete span.ngb-highlight {
      background-color: yellow;
    }
    
    ngb-carousel .picsum-img-wrapper {
      position: relative;
      height: 0;
      padding-top: 55%; /* Keep ratio for 900x500 images */
    }
    
    ngb-carousel .picsum-img-wrapper>img {
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
    }