Erstellen eines Kalenders mit React JS, LESS CSS und Font Awesome

Heute werde ich darüber sprechen, wie man ein Kalendersteuerelement mit erstellt Reagiere JS, WENIGER CSS, Schriftart genial und Augenblick JS. Ich gehe davon aus, dass Sie mit diesen Tools zumindest halbwegs vertraut sind, aber wenn Sie es nicht sind, schlage ich vor, dass Sie einen Blick auf die obigen Links werfen. Der Kalender selbst wird eine React JS-Klasse sein, die es dem Benutzer ermöglicht, ein Datum auszuwählen, das in der Eigenschaft eines Controllers festgelegt wird. Ich habe den Kalender gestylt und werde diesen Stil in dieses Tutorial aufnehmen, aber Sie können das Aussehen natürlich nach Herzenslust anpassen. Wenn Sie die Art von Leser sind, die es vorzieht, ein fertiges Produkt anzusehen und einfach die Quelle selbst zu überprüfen, habe ich eine Demoseite zusammengestellt, die den Kalender zeigt. Du kannst es sehen hier. Dieses Kalendersteuerelement sollte nicht als Lösung zum Kopieren und Einfügen eines Problems verwendet werden, das Sie haben. Es ist als Leitfaden für React selbst gedacht, im Gegensatz zur Bereitstellung eines produktionsreifen Kalenders.

Probe

Notiz: Das hier gezeigte CSS stimmt möglicherweise nicht genau mit dem überein, was Sie auf der Demoseite sehen, da ich möchte, dass die Demo mit einem hübschen Styling zumindest halbwegs anständig aussieht. Größtenteils werde ich jedoch versuchen, das CSS im Tutorial so einfach wie möglich zu halten.

Ich habe das Kalendersteuerelement in einige verschiedene Klassen aufgeteilt: Kalender, DayNames und Woche. Die Calendar-Klasse enthält die beiden anderen. DayNames ist ein einfacher Header für den Kalender, der (nicht überraschend) Wochennamen anzeigt, während die Week-Klasse für das Rendern jeder einzelnen Woche verantwortlich ist.

Kalender

var Calendar = React.createClass({
  getInitialState: function() {
    return {
      month: this.props.selected.clone()
    };
  },

  previous: function() {
    var month = this.state.month;
    month.add(-1, "M");
    this.setState({ month: month });
  },

  next: function() {
    var month = this.state.month;
    month.add(1, "M");
    this.setState({ month: month });
  },

  select: function(day) {
    this.props.selected = day.date;
    this.forceUpdate();
  },

  render: function() {
    return <div>
      <div className="header">
        <i className="fa fa-angle-left" onClick={this.previous}></i>
        {this.renderMonthLabel()}
        <i className="fa fa-angle-right" onClick={this.next}></i>
      </div>
      <DayNames />
      {this.renderWeeks()}
    </div>;
  },

  renderWeeks: function() {
    var weeks = [],
      done = false,
      date = this.state.month.clone().startOf("month").add("w" -1).day("Sunday"),
      monthIndex = date.month(),
      count = 0;

    while (!done) {
      weeks.push(<Week key={date.toString()} date={date.clone()} month={this.state.month} select=    {this.select} selected={this.props.selected} />);
      date.add(1, "w");
      done = count++ > 2 && monthIndex !== date.month();
      monthIndex = date.month();
    }

    return weeks;
  },

  renderMonthLabel: function() {
    return <span>{this.state.month.format("MMMM, YYYY")}</span>;
  }
});

Beim Rendern dieser Klasse ist die einzige Requisite, die sie benötigt, das anfänglich festgelegte Datum; alles andere leitet sich davon ab. In unserer getInitialState -Methode setzen wir den aktuellen Monat auf den gleichen Monat wie das ausgewählte Datum. Monat und ausgewähltes Datum sind zwei verschiedene Variablen, um zu berücksichtigen, dass der Benutzer beispielsweise von Februar in März wechselt, ohne ein neues Datum auszuwählen. Außerhalb des Renderns hat unsere Calendar-Klasse drei Methoden: previous, next und select. Das previous und next Methoden sind dafür verantwortlich, die Kalenderansicht des Benutzers vom aktuellen Monat in den vorherigen bzw. nächsten Monat zu verschieben, während die Methode select dafür sorgt, dass ein neues Datum als ausgewähltes Datum markiert wird. Wir müssen a ausführen forceUpdate hier, um ein Rendern der Ansicht zu erzwingen, da die Calendar-Klasse die ausgewählte Eigenschaft nicht überwacht.

Das render -Methode schreibt ziemlich standardmäßiges HTML. Hier verwenden wir Schriftart genial um einige vorherige und nächste Pfeile zu rendern, die die Bezeichnung des aktuellen Monats umschließen. Dann rendern wir die DayNames Klasse, gefolgt von der Liste der Week Klassen. Es gibt eine gewisse Logik, die es ermöglicht, auch nachlaufende und führende Tage anzuzeigen.

Tagesnamen

Das DayNames Klasse ist die einfachste der drei. Es ist allein dafür verantwortlich, die Namen der Tage oben im Kalender wiederzugeben.

var DayNames = React.createClass({
  render: function() {
    return <div className="week names">
      <span className="day">Sun</span>
      <span className="day">Mon</span>
      <span className="day">Tue</span>
      <span className="day">Wed</span>
      <span className="day">Thu</span>
       	<span className="day">Fri</span>
       	<span className="day">Sat</span>
    </div>;
  }
});

Dazu gibt es eigentlich nicht viel zu sagen. Beachten Sie die Verwendung von className Anstatt von class; Es ist ein leichter Fehler, den man machen kann, wenn man zum ersten Mal mit React beginnt.

Woche

var Week = React.createClass({
  render: function() {
    var days = [],
      date = this.props.date,
      month = this.props.month;

    for (var i = 0; i < 7; i++) {
      var day = {
        name: date.format("dd").substring(0, 1),
        number: date.date(),
        isCurrentMonth: date.month() === month.month(),
        isToday: date.isSame(new Date(), "day"),
        date: date
      };
      days.push(<span key={day.date.toString()} className={"day" + (day.isToday ? " today" : "") + (day.isCurrentMonth ? "" : " different-month") + (day.date.isSame(this.props.selected) ? " selected" : "")} onClick={this.props.select.bind(null, day)}>{day.number}</span>);
      date = date.clone();
      date.add(1, "d");

    }

    return <div className="week" key={days[0].toString()}>
      {days}
    </div>
  }
});

Das Week Die Klasse benötigt vier Requisiten: Datum, Monat, Auswählen und Ausgewählt. Der erste gibt den Beginn der Woche an, während der Monat den aktuellen Monat angibt, um festzustellen, ob wir nachfolgende oder führende Tage benötigen. Die dritte und vierte Stütze befassen sich mit der Auswahl eines Datums. Die Render-Methode rendert sieben Tage, wobei verschiedene CSS-Klassen für den Tag festgelegt werden, jeweils eine für ausgewählte, heutige oder nachlaufende/führende Tage.

CSS

.vertical-centre (@height) {
    height:@height;
    line-height:@height !important;
    display:inline-block;
    vertical-align:middle;
}

.border-box {
    box-sizing:border-box;
    -moz-box-sizing:border-box;
}

@border-colour:#CCC;
calendar {
    float:left;
    display:block;
    .border-box;
    background:white;
    width:300px;
    border:solid 1px @border-colour;
    margin-bottom:10px;
    
    @secondary-colour:#2875C7;
    @spacing:10px;
    @icon-width:40px;
    @header-height:40px;

    >div.header {
        float:left;
        width:100%;
        background:@secondary-colour;
        height:@header-height;
        color:white;
        
        >* { 
            .vertical-centre(@header-height);
        }
        
        >i {
            float:left;
            width:@icon-width;
            font-size:1.125em;
            font-weight:bold;
            position:relative;
            .border-box;
            padding:0 @spacing;
            cursor:pointer;
        }
        
        >i.fa-angle-left {
            text-align:left;
        }
        
        >i.fa-angle-right {
            text-align:right;
            margin-left:@icon-width*-1;
        }
        
        >span { 
            float:left;
            width:100%;
            font-weight:bold;
            text-transform:uppercase;
            .border-box;
            padding-left:@icon-width+@spacing;
            margin-left:@icon-width*-1;
            text-align:center;
            padding-right:@icon-width;
            color:inherit;
        }
    }
    >div.week {
        float:left;
        width:100%;
        border-top:solid 1px @border-colour;
        
        &:first-child {
            border-top:none;
        }
        
        >span.day {
            float:left;
            width:100%/7;
            .border-box;
            border-left:solid 1px @border-colour;
            font-size:0.75em;
            text-align:center;
            .vertical-centre(30px);
            background:white;
            cursor:pointer;
            color:black;
            
            &:first-child {
                border-left:none;
            }
            
            &.today {
                background:#E3F2FF;
            }
            
            &.different-month {
                color:#C0C0C0;
            }
            
            &.selected {
                background:@secondary-colour;
                color:white;
            }
        }
        
        &.names>span {
            color:@secondary-colour;
            font-weight:bold;
        }
    }
}

Die ersten paar Zeilen definieren ein paar hilfreiche Mixins mit LESS CSS. Die erste ermöglicht es uns, Elemente vertikal zu zentrieren, vorausgesetzt, wir haben die Höhe des Umhüllungselements. Die zweite legt die Box-Sizing-Eigenschaft fest, die Firefox ohne das Präfix -moz- nicht unterstützt.

Als Nächstes legen wir einige Variablen fest, die sich auf Stil und Abstände beziehen, die mehr als einmal verwendet werden. Wenn Sie beispielsweise die Farbe ändern möchten, müssen Sie die Sekundärfarbenvariable aktualisieren. Der Rest ist nur Standard-Styling, damit der Kalender etwas hübsch aussieht, und Abstandshalter, um sicherzustellen, dass er richtig ausgerichtet ist.

Fazit

Und das ist es! Wie oben erwähnt, habe ich eine Demoseite zusammengestellt, die den Kalender in seiner endgültigen Form zeigt. Du kannst es sehen hier. Danke fürs Lesen!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *