3

我想在材料 Input 中使用 ngb-datepicker 。我成功地将 datepicker 应用于 mat 输入。但是月份和年份的下拉菜单存在问题。

我尝试了以下代码段:

<mat-form-field>
<input matInput placeholder="Select Valid Till" name="GodownValidTill" [(ngModel)]="GodownValidTill" ngbDatepicker #d2="ngbDatepicker" required readonly>
<mat-icon style="float:right;height:20px;width:20px;" (click)="d2.toggle()" svgIcon="calendar" title="Calendar"></mat-icon>
</mat-form-field>

有没有完美工作的解决方案?

4

3 回答 3

7

I tried to reproduce the issue and found that by default ngbDatePicker is appends just below the input field it is attached to. And when we use matInput, the actual input field gets wrapped around various material classes which are causing the problem with the date picker.

So, what we can do is, we can append the date picker to the body using the container property of ngbDatepicker like this. container property currently only supports "body" as a value.

    <mat-form-field>
            <input matInput type="text" ngbDatepicker container="body" #d="ngbDatepicker" (click)="d.open()" placeholder="Date Picker with issue"/>
    </mat-form-field>

here is the stackblitz demo for the same. I hope this will help.

于 2019-10-07T15:50:03.483 回答
2

我不确定到底是什么问题,但是将两个库集成在一起没有问题。我使用了与您几乎完全相同的代码。

<mat-form-field class="example-full-width">
  <input matInput placeholder="Favorite food"  name="GodownValidTill" [(ngModel)]="GodownValidTill" (ngModelChange)="onSelect($event)" ngbDatepicker #d="ngbDatepicker" required readonly>
  <mat-icon (click)="d.toggle()">calendar-today</mat-icon>
</mat-form-field>

功能方面,没有问题。但当然,您需要对 CSS/样式进行自己的更改。我在这里复制了一个演示。

为什么不同时使用这两个库,为什么不使用 Angular Boostrap 或 Angular Material 呢?这样,您不需要管理不同的包。这两个库都有自己的 Datepicker 组件(Material Datepicker / Ngbootstrap Datepicker)。

于 2019-06-12T12:42:54.463 回答
1

另一种方法是形成材料日期选择器。看最终结果

第一步是创建一个自定义的 Header,

<div class="mat-calendar-header">
  <div class="mat-calendar-controls">
    <button mat-icon-button type="button" class="mat-calendar-previous-button arrow"
            [disabled]="!previousEnabled()" (click)="customPrev()"
            [attr.aria-label]="prevButtonLabel">
    </button>
    <select [ngModel]="dateMonth" (ngModelChange)="dateMonth=$event;select()"class="custom-select">
    <option *ngFor="let month of months;let i=index" [value]="i">{{month}}</option>
    </select>
    <select [ngModel]="dateYear" (ngModelChange)="dateYear=+$event;select()" class="custom-select" style="width:70%" >
    <option *ngFor="let i of [-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10]" [value]="dateYear+i">{{dateYear+i}}</option>
    </select>
    <button mat-icon-button type="button" class="mat-calendar-next-button arrow"
            [disabled]="!nextEnabled()" (click)="customNext()"
            [attr.aria-label]="nextButtonLabel">
    </button>
  </div>
</div>

用 .css 来看看类似于 ngb-datepicker

.custom-select {
    display: inline-block;
    width: 100%;
    height: calc(1.5em + .75rem + 2px);
    padding: .375rem 1.75rem .375rem .75rem;
    font-size: .8rem;
    font-weight: 200;
    line-height: 1.5;
    color: #495057;
    vertical-align: middle;
    background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat #fff;
    border: 1px solid #ced4da;
    border-radius: .25rem;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}
.arrow{
  margin-top: -.25rem;
}

如果我们的 header 扩展了 MatCalendarHeader,我们可以实现 OnInit - 将值放入 Year 和 Month 的组合框,并添加 ElementRef y Renderer2。我使用 Renderer2 添加/删除类 removeRow

.removeRow tbody tr:first-child td{
  display:none
}

这允许我们在当月第一天的日期是星期日、星期一或星期四时不显示第一行 - 在材料日期选择器中它显示月份,但我们在组合框中显示它。

export class ExampleHeader extends MatCalendarHeader<any> implements OnInit {
  calendar:any
  months=[
    "January","February","March","April","May","June","July","August","September","October","November","December"]

  dateYear:any
  dateMonth:any

  constructor(_intl:MatDatepickerIntl,
      _calendar: MatCalendar<any>, _dateAdapter: DateAdapter<any>,
      @Inject(MAT_DATE_FORMATS) _dateFormats: MatDateFormats, cdr: ChangeDetectorRef,private el:ElementRef,private render:Renderer2){
    super(_intl,_calendar,_dateAdapter,_dateFormats,cdr)
        this.calendar=_calendar;
        this.dateYear=this.calendar.activeDate?this.calendar.activeDate.getFullYear():new Date().getFullYear()
        this.dateMonth=this.calendar.activeDate?this.calendar.activeDate.getMonth():new Date().getMonth()
  }
  select()
  {
    this.calendar.activeDate=new Date(this.dateYear,this.dateMonth)
    this.refreshCombo(this.dateMonth,this.dateYear)
  }
  ngOnInit()
  {
    this.refreshCombo(this.calendar.activeDate.getMonth(),this.calendar.activeDate.getFullYear())
  }
  refreshCombo(month,year)
  {
     this.dateMonth=month;
     this.dateYear=year;
     const element=this.el.nativeElement.parentElement
     if (new Date(year,month,1).getDay()<=2)
      this.render.addClass(element,'removeRow')
     else
      this.render.removeClass(element,'removeRow')
  }

  /** Handles user clicks on the previous button. */
  customPrev(): void {
    this.previousClicked()
    this.refreshCombo(this.calendar.activeDate.getMonth(),this.calendar.activeDate.getFullYear());
  }

  /** Handles user clicks on the next button. */
  customNext(): void {
    this.nextClicked()
     this.refreshCombo(this.calendar.activeDate.getMonth(),this.calendar.activeDate.getFullYear());
 }
于 2019-10-08T19:27:28.257 回答