اعتبار سنجی مقدار اینپوت

از نسخه چهار به بعد با استفاده از پارامتر دومی که به متد onChange پاس داده میشود میتوان تاریخ را validate کرد.

پارامتر دومی که به متد onChange پاس داده میشود یک آبجکت حاوی مقادیر زیر است:

isTyping

input

validatedValue

پراپ isTyping مشخص میکند که آیا متد onChange با تایپ کردن کاربر صدا زده شده یا خیر.

اگر isTyping برابر با true باشد به این معنی است که متد onChange با تایپ کردن کاربر در اینپوت صدا زده شده است و اگر برابر با false باشد به این معنی است که این متد با انتخاب یک تاریخ درکامپوننت Calendar صدا زده شده است.

پراپ input در حقیقت رفرنس اینپوت است که در صورت استفاده نکردن از custom input برابر یا اینپوت داخلی دیت پیکر و در صورت استفاده از custom input حاوی یک div است که دربرگیرنده کامپوننت سفارشی شما میباشد.

مقدار validatedValue یک استرینگ است که قرار است در اینپوت نشان داده شود.

توجه داشته باشبد که فقط در صورتی استیت داخلی DatePicker مقدار دهی نمیشود که مقدار false را return کنید.

import DatePicker from "react-multi-date-picker";
import persian from "react-date-object/ccalendars/persian";
import persian_fa from "react-date-object/locales/persian_fa";

const digits = persian_fa.digits;
.
.
.
const [value, setValue] = useState();

<DatePicker
  value={value}
  onChange={(date, { input, isTyping }) => {
    if (!isTyping) return setValue(date); // user selects the date from the calendar and no needs for validation.

    let value = input.value;

    for (let digit of digits) {
      value = value.replace(
        new RegExp(digit, "g"),
        digits.indexOf(digit)
      );
    }

    const strings = value.split("/");
    const numbers = strings.map(Number);
    const [year, month, day] = numbers;

    if (input.value && numbers.some((number) => isNaN(number))) {
      return false; //in case user enter something other than digits
    }

    if (month > 12 || month < 0) return false; //month < 0 in case user want to type 01
    if (day < 0 || (date && day > date.day)) return false;
    if (strings.some((val) => val.startsWith("00"))) return false;

    setValue(date);
  }}
    calendar="persian"
    locale="persian_fa"
    calendarPosition="bottom-right"
/>
    

اعتبار سنجی دامنه ای از تاریخ ها

این مثال نشان می دهد که چگونه می توان محدوده ای از تاریخ ها را در کامپوننت DatePicker اعتبار سنجی کرد. در این مثال، هدف رزرو یک اتاق برای یک محدوده تاریخی خاص است. کامپوننت Calendar با پراپ های multiple و range استفاده می شود تا امکان انتخاب چندین محدوده تاریخ را فراهم کند. مقادیر اولیه برای تاریخ های رزرو شده و در حال سرویس در دو آرایه به نام های reserved و inService تعریف شده است.

توابع isReserved و isInService بررسی می کنند که آیا یک تاریخ معین در محدوده های رزرو شده یا درون سرویس قرار می گیرد.

پراپ mapDays برای اعمال یک کلاس به عناصر تاریخ استفاده می‌شود تا نشان دهد که آیا آنها رزرو شده یا در حال سرویس هستند.

import React, { useState } from "react";
import { Calendar, DateObject } from "react-multi-date-picker";
import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"
.
.
.

const reserved = [
  [new DateObject({ calendar: persian, locale: persian_fa}).setDay(1).format(), new DateObject({ calendar: persian, locale: persian_fa}).setDay(5).format()],
  [new DateObject({ calendar: persian, locale: persian_fa}).setDay(7).format(), new DateObject({ calendar: persian, locale: persian_fa}).setDay(8).format()],
];

const inService = [
  [new DateObject({ calendar: persian, locale: persian_fa}).setDay(12).format(), new DateObject({ calendar: persian, locale: persian_fa}).setDay(13).format()],
  [new DateObject({ calendar: persian, locale: persian_fa}).setDay(27).format(), new DateObject({ calendar: persian, locale: persian_fa}).setDay(27).format()],
];

const initialValue = [...reserved, ...inService];

function isReserved(strDate) {
  return reserved.some(([start, end]) => strDate >= start && strDate <= end);
}

function isInService(strDate) {
  return inService.some(([start, end]) => strDate >= start && strDate <= end);
}

export default function Example() {
  const [values, setValues] = useState(initialValue);

  return (
    <div>
      <h5>رزرو اتاق</h5>
      <p>لطفا محدوده تاریخ هایی را که می خواهید رزرو کنید انتخاب کنید</p>

      <div style={{ margin: "10px " }}>
        <div className="un-availble">
          <div className="reserved" />
          <p>قبلا رزرو شده است</p>
        </div>
        <div className="un-availble">
          <div className="in-service" />
          <p>انجام تعمیرات</p>
        </div>
      </div>

      <Calendar
        multiple
        range
        value={values}
        onChange={(ranges) => {
          const isClickedOutsideUnAvailbleDates = initialValue.every(
            ([start, end]) => ranges.some((range) => range[0]?.format?.() === start && range[1]?.format?.() === end)
          );
          
          if (!isClickedOutsideUnAvailbleDates) return false;
          
          setValues(ranges);
        }}
        mapDays={({ date }) => {
          let className;
          const strDate = date.format();
        
          if (isReserved(strDate)) className = "reserved";
          if (isInService(strDate)) className = "in-service";
          if (className) return { className };
        }}
      />
    </div>
  )
رزرو اتاق

لطفا محدوده تاریخ هایی را که می خواهید رزرو کنید انتخاب کنید

قبلا رزرو شده است

انجام تعمیرات

فایل سی اس اس :

.rmdp-range:has(.reserved) {
  background-color: #8fb4f9;
}

.rmdp-range:has(.in-service) {
  background-color: #cc0303;
}

div.reserved {
  background-color: #8fb4f9;
  width: 20px;
  height: 20px;
  border-radius: 50%;
}

div.in-service {
  background-color: #cc0303;
  width: 20px;
  height: 20px;
  border-radius: 50%;
}

.un-availble {
  display: flex;
  align-items: center;
  column-gap: 10px;
}

.un-availble p {
  margin: 0;
}