How to create a month range picker in Angular

别等时光非礼了梦想. 提交于 2019-12-11 16:27:29

问题


I came across many similar questions on stackoverflow. But trust me I implement at least ten solutions but I'm not getting correct results and also that most of them are using jquery or javascript while I've to use typescript. I'm creating a simple month range picker with no other rocket science features. After implementing one solution after the other my actual code has become very dirty. So I'm creating a fresh minimal project on stackblitz, here. Also I'm giving my code before making any changes.

My monthpicker.component.html:

<div class="dropdown">
  <span>
    <input  placeholder="{{sampletext}}, {{inputText}}">
  </span>
  <div class="my-table-div dropdown-content">
    <div class="year-div">
      <input type="number" value="2018" min="2018" max="2024" [(ngModel)]="inputText">
    </div>
    <hr>
    <div *ngFor="let row of matrix" class="my-table">
      <span *ngFor="let x of row">
        <span class="month-name" (click)="onClick(x)">{{ x }}</span>
      </span>
    </div>
  </div>
</div>

monthpicker.component.ts

import ...;

@Component({
  ...
})
export class MonthpickerComponent implements OnInit {
  dt = new Date( );
  arr = [
    'Jan', 'Feb', 'Mar', 'Apr',
    'May', 'Jun', 'Jul', 'Aug',
    'Sep', 'Oct', 'Nov', 'Dec'
  ];

  sampletext = ""+this.arr[this.dt.getMonth()];
  inputText :number = this.dt.getFullYear();
  clickCount: number=0;

  n = 4;
  matrix = Array
    .from({ length: Math.ceil(this.arr.length / this.n) }, (_, i) => i)
    .map(i => this.arr.slice(i * this.n, i * this.n + this.n));

  constructor() { }

  onClick(x) {
    this.clickCount++;
    console.log("Month: " + x);
    this.sampletext = x;
    console.log("Year: " + this.inputText);
    console.log("Clicked "+this.clickCount +" times.");
    if(this.clickCount%2==0) {
      this.sampletext+=" " +this.sampletext+", "+this.inputText;
    }
  }

  ngOnInit() {
  }
}

Please suggest a solution.

PS: I don't want to use any third party library. Not even bootstrap. I've to make it from the scratch.


回答1:


I tried one more solution of my own. The trick is clickCount is even or odd. Here are some important changes in the code.

monthpicker.component.html

<div class="dropdown">
  <span>
    <input  placeholder="{{sampletext}}, {{inputText}} -> {{newmonth}} {{newyear}}">
  </span>
    <div class="my-table-div dropdown-content">
      NO CHANGES
    </div>
</div>

monthpicker.component.ts

import ...;

@Component({
  ...
})
export class MonthpickerComponent implements OnInit {
  ...

  sampletext = ""+this.arr[this.dt.getMonth()];
  inputText :any = this.dt.getFullYear();

  newmonth = ""+this.arr[this.dt.getMonth()];
  newyear :any = this.dt.getFullYear();

  clickCount: number =0;

  ...

  constructor() { }

  onClick(x) {
    this.clickCount++;
    console.log("Month: " + x);
    if(this.clickCount%2!=0) {
      this.sampletext = x;
    }
    console.log("Year: " + this.inputText);
    console.log("Clicked "+this.clickCount +" times.");
    if(this.clickCount%2==0) {
      this.newmonth=" "+x;
    }
  }

  ngOnInit() {
  }
}

Changelog

  1. In HTML code I've added two new properties in input field: newmonth and newyear
  2. Lets bind these two properties in typescript.
  3. Two new variables are declared in typescript:

newmonth = ""+this.arr[this.dt.getMonth()]; and

newyear :any = this.dt.getFullYear();

  1. In onclick method check if clickCount is even or odd using %2==0 and set their new values accordingly.



回答2:


You can simply use two select menus or auto completes for selecting month and year. For example you can have a simple code like this:

<form [formGroup]="MonthYearFormGroup">
  <h4>Select a month here:</h4>
  <mat-form-field>
    <mat-label>Month</mat-label>
    <mat-select formControlName="selected_month">
      <mat-option *ngFor="let month of monthList" [value]="month.value">
        {{month.viewValue}}
      </mat-option>
    </mat-select>
  </mat-form-field>

  <h4>Select a year here:</h4>
  <mat-form-field>
    <mat-label>Year</mat-label>
    <mat-select formControlName="selected_year">
      <mat-option *ngFor="let year of yearList" [value]="year.value">
        {{year.viewValue}}
      </mat-option>
    </mat-select>
  </mat-form-field>
  <button (click)="save()">Save Selected Date</button>
</form>
import {Component} from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';

export interface MonthYear {
  value: string;
  viewValue: string;
}

@Component({
  selector: 'select-overview-example',
  templateUrl: 'select-overview-example.html',
  styleUrls: ['select-overview-example.css'],
})
export class SelectOverviewExample {

  public MonthYearFormGroup: FormGroup();


 yearList: MonthYear[] = Array(50).fill(1).map( (_, index) => { return { value: String(index + 2019), viewValue: String(index + 2019) } })

  monthList: MonthYear[] = [
    {value: '1', viewValue: 'Jan'},
    {value: '2', viewValue: 'Feb'},
    {value: '3', viewValue: 'Mar'},
    {value: '4', viewValue: 'Apr'},
    {value: '5', viewValue: 'May'},
    {value: '6', viewValue: 'Jun'},
    {value: '7', viewValue: 'Jul'},
    {value: '8', viewValue: 'Aug'},
    {value: '9', viewValue: 'Sep'},
    {value: '10', viewValue: 'Oct'},
    {value: '11', viewValue: 'Nov'},
    {value: '12', viewValue: 'Dec'},
  ];

  constructor(
    private _formBuilder: FormBuilder,
  ) { }

  ngOnInit() {
    this.MonthYearFormGroup= this._formBuilder.group({
      selected_month: [{ value: '', required: true }],
      selected_year: [{ value: '', required: true }],
  });

  save() {
   //Your process here...
   console.log(this.MonthYearFormGroup.value.selected_month);
   console.log(this.MonthYearFormGroup.value.selected_year);
  }
}


来源:https://stackoverflow.com/questions/59122863/how-to-create-a-month-range-picker-in-angular

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!