如何突出显示所选月份的范围

问题描述 投票:1回答:2

我是Angular的新手。我遇到的所有答案都使用jqueryjavascript。几周前,我的团队要求我们只需要一个月的选择器。但是条件是我们不能从组织外部的任何地方外包组件。甚至没有bootstrapmaterialprimeng。因此,我决定使用HTML和CSS从头开始创建一个自定义的。这是屏幕截图:app-monthpicker是一个组件,在其顶部有一个父组件app-timeselector。拾月器工作正常。但是我无法实现突出显示所选月份范围的逻辑。 stackoverflow和其他网站上的所有解决方案都使用jqueryjs。但是这里我们正在谈论typescript。我创建了一个最小的stackblitz,这是其中一个应答者创建的另一个stackblitz。有人可以在这方面帮助我。仅使用HTMLCSSTypescript。我非常需要有人的帮助。我想要这个:

enter image description here

您可以看到上一年的6个飞蛾,以及nect年的所有月份。并且如果它们在范围内,则还需要突出显示。我只需要2017年至2025年的时间。

PS:恐怕我的整个实现都不正确。请纠正我。

html css angular typescript
2个回答
1
投票

理想情况下,对于这种用例,您不应该重新发明轮子,也不要利用能够解决此问题的好的库。但是,如果您想使当前代码适用于该用例,这就是我会做的事情:

https://stackblitz.com/edit/angular-dd1ygq

有很多更改,但我会尝试从高层次进行解释:

1。代替了类似“表格”的方法,我使用了一个简单的跨度列表,其中每个跨度元素都有“ display:inline-block” CSS,使所有这些月都呈现为3行,但简而言之跨度列表。

2。我创建了一个名为'months'的新数组,其中每个孩子都有其他属性:

    months = this.arr.map(month => {
      return {
        monthName: month,
        isInRange: false,
        isLowerEdge: false,
        isUpperEdge: false
      }
    })

3。创建的用于跟踪范围状态的简单对象:

    rangeState = {
      edge1Exists: false,
      edge2Exists: false,
      edgeIndexes: []
    }

4。我以此方式重写了您的onClick方法,希望代码能说明一切:

    onClick(x,indexClicked) {
      if (!this.rangeState.edge1Exists) {
        this.rangeState.edge1Exists = true;
        this.rangeState.edgeIndexes[0] = indexClicked;
        x.isInRange = true;
      } else
      if (!this.rangeState.edge2Exists) {
        this.rangeState.edge2Exists = true;
        this.rangeState.edgeIndexes[1] = indexClicked;
        this.rangeState.edgeIndexes.sort((a,b)=> a-b);
        this.months.forEach((month, index) => {
          if (this.rangeState.edgeIndexes[0] < index && index < this.rangeState.edgeIndexes[1]) {
            month.isInRange = true;
          };
          if (this.rangeState.edgeIndexes[0] === index) {
            month.isLowerEdge = true;
          };
          if (this.rangeState.edgeIndexes[1] === index) {
            month.isUpperEdge = true;
          };
        })
        console.log(this.months)
      } else {
        this.rangeState = {
          edge1Exists: false,
          edge2Exists: false,
          edgeIndexes: []
        }
        this.months.forEach((month) => {
          month.isInRange = false
          month.isLowerEdge = false;
          month.isUpperEdge = false;
        })
        this.onClick(x, indexClicked);
      };
    };

因此,作为您想要的原型,我认为它可以工作,但我并未将此小部件的所有点都连接起来。我希望您可以做得更好(您可能希望更多地使用CSS,考虑使用方形高光而不是圆角等)!


1
投票

我将采取另一种方式。您有四个变量:lboundMonth,lboundYear,uboundMonth和uboundYear。

我认为您可以在2020年10月至2021年2月之间找到类似的例子,>

lbound:{year:2020,month:10,yearMonth:"202010"} //yearMonth it's the way yyyyMM
ubound:{year:2020,month:1,ueatMonth:"202101"}

还有,您将创建一个带有月份的数组。正如@Sergey所说,我们可以创建一个数月的数组。但就我而言,我将采取这种方式

{monthName: "january",month:1,monthYear:202001}

所以,当您更改年份时

month=arr.map((x,index)=>{
   return {
     monthName:x,
     month:(index+1)
     monthYear:displayYear+('00'+(x+1)).slice(-2)
})

您只需要在循环monthYear中将lbound和ubound进行比较。像

<div *ngFor="let month of months>
<span [ngClass]="{'ubound':month.yearMonth==ubound.yearMonth,
                  'lbound':month.yearMonth==lbound.yearMonth,
                  'range':month.yearMonth>lbound.yearMonth && 
                          month.yearMonth<ubound.yearMonth
                 }"
       (click)="click(month)"
</div>

单击时进入

 click(month:any)
 {
    const my={
       year:this.displayYear
       month:month.month
       monthYear:month.monthYear
    }
    ..asing to lbound or tbound
    //you emit:
    this.ouputToparent({
        lbound:this.lbound,
        ubound:this.ubound,
     })
    //or
    this.ouputToparent({
        lbound:{year:this.lbound.year,month:this.lbound.month},
        ubound:{year:this.ubound.year,month:this.ubound.month},
     })
 }
© www.soinside.com 2019 - 2024. All rights reserved.