github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/server/frontend/bv/src/shared/fields/DateField.vue (about)

     1  <template>
     2    <b-form-group
     3      :label="label"
     4      :invalid-feedback="invalidFeedback"
     5      :state="state"
     6    >
     7      <b-form-row>
     8        <b-col cols="4">
     9          <b-form-input
    10            type="number"
    11            placeholder="JJ"
    12            required
    13            min="1"
    14            max="31"
    15            v-model.number="date.day"
    16            @change="onInput"
    17            :disabled="disabled"
    18          >
    19          </b-form-input>
    20        </b-col>
    21        <b-col cols="4">
    22          <b-form-input
    23            type="number"
    24            placeholder="MM"
    25            required
    26            min="1"
    27            max="12"
    28            v-model.number="date.month"
    29            @change="onInput"
    30            :disabled="disabled"
    31          >
    32          </b-form-input>
    33        </b-col>
    34        <b-col cols="4">
    35          <b-form-input
    36            type="number"
    37            placeholder="AAAA"
    38            min="1900"
    39            max="2100"
    40            required
    41            v-model.number="date.year"
    42            @change="onInput"
    43            :disabled="disabled"
    44            ref="year"
    45          >
    46          </b-form-input>
    47        </b-col>
    48      </b-form-row>
    49    </b-form-group>
    50  </template>
    51  
    52  <script lang="ts">
    53  import Vue from "vue";
    54  import Component from "vue-class-component";
    55  import { isNullTime } from "../logic/utils";
    56  import { Watch } from "vue-property-decorator";
    57  import { BFormInput } from "bootstrap-vue";
    58  import { Date_ } from "../logic/types";
    59  
    60  const DateFieldProps = Vue.extend({
    61    props: {
    62      dateString: (String as unknown) as () => Date_,
    63      label: String,
    64      invalidFeedback: String,
    65      required: Boolean,
    66      checkMajeur: Boolean,
    67      validated: Boolean,
    68      disabled: Boolean
    69    },
    70    model: {
    71      prop: "dateString",
    72      event: "change"
    73    }
    74  });
    75  
    76  interface InnerDate {
    77    day: number | null;
    78    month: number | null;
    79    year: number | null;
    80  }
    81  
    82  @Component({})
    83  export default class DateField extends DateFieldProps {
    84    date: InnerDate = this.parseDate();
    85  
    86    $refs!: {
    87      year: HTMLInputElement;
    88    };
    89  
    90    @Watch("dateString")
    91    onChange() {
    92      this.date = this.parseDate();
    93    }
    94  
    95    parseDate() {
    96      if (isNullTime(this.dateString)) {
    97        return { day: null, month: null, year: null };
    98      }
    99      const d = new Date(this.dateString);
   100  
   101      return {
   102        day: d.getDate(),
   103        month: d.getMonth() + 1,
   104        year: d.getFullYear()
   105      };
   106    }
   107  
   108    get state() {
   109      if (!this.validated) return null;
   110      if (this.required || this.checkMajeur) {
   111        if (this.currentDate == null) return false;
   112        if (this.checkMajeur) {
   113          return this.age(this.currentDate) >= 18;
   114        }
   115      }
   116      return true;
   117    }
   118  
   119    age(date: Date) {
   120      const diff = new Date(Date.now() - date.valueOf());
   121      diff.setHours(0, 0, 0, 0); // attention au jour d'anniversaire
   122      return diff.getFullYear() - 1970;
   123    }
   124  
   125    get currentDate(): Date | null {
   126      if (!(this.date.year && this.date.month && this.date.day)) return null;
   127      return new Date(
   128        Date.UTC(this.date.year, this.date.month - 1, this.date.day)
   129      );
   130    }
   131  
   132    onInput() {
   133      // reset custom validity
   134      this.$refs.year.setCustomValidity("");
   135  
   136      if (this.currentDate == null) return; // date en train d'être tappée
   137  
   138      if (this.checkMajeur) {
   139        this.$refs.year.setCustomValidity(
   140          this.state === false ? "not-majeur" : ""
   141        );
   142      }
   143      let v = "";
   144      if (!isNaN(this.currentDate.getTime())) {
   145        v = this.currentDate.toISOString().split("T")[0];
   146      }
   147      this.$emit("change", v);
   148    }
   149  }
   150  </script>
   151  
   152  <style scoped></style>