onChange (انتخابگر تکی)

تفاوت onChange در این پکیج با پکیج های دیگر در اینه که آرگومان آن به جای Date به عنوان DateObject ارسال میشه.

همانطور که در قسمت های قبلی هم گفتم، میتونید دیت آبجکت ارسال شده رو با استفاده از متد ()toDate به Date جاوااسکریپت تبدیل کنید.

import { useState } from "react"
import DatePicker from "react-multi-date-picker"
import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"

export default function Example() {
  const [value, setValue] = useState()
  
  return (
    <>
      <DatePicker
        value={value}
        onChange={setValue}
        calendar={persian}
        locale={persian_fa}
        calendarPosition="bottom-right"
      />
      {value?.toDate?.().toString()}
    </>
  )
}

onChange (تبدیل تاریخ انتخاب شده به همه ی تقویم ها)

//gregorian calendar & locale
import gregorian from "react-date-object/calendars/gregorian";
import gregorian_fa from "react-date-object/locales/gregorian_fa";

//persian calendar & locale
import persian from "react-date-object/calendars/persian";
import persian_fa from "react-date-object/locales/persian_fa";

//arabic calendar & locale
import arabic from "react-date-object/calendars/arabic";
import arabic_fa from "react-date-object/locales/arabic_fa";

//indian calendar & locale
import indian from "react-date-object/calendars/indian";
import indian_fa from "react-date-object/locales/indian_fa";
.
.
.
const [state, setState] = useState({ format: "MM/DD/YYYY" })
  
const convert = (date, format = state.format) => {
  let object = { date, format }
  
  setState({
    gregorian: new DateObject(object).convert(gregorian, gregorian_fa).format(),
    persian: new DateObject(object).format(),
    arabic: new DateObject(object).convert(arabic, arabic_fa).format(),
    indian: new DateObject(object).convert(indian, indian_fa).format(),
    jsDate: date.toDate(),
    ...object
  })
}
  
const Span = ({ children }) => <span style={{ fontWeight: "bold" }}>{children}</span>

return(
  <div>
    <div>
      <div>
        <Span>کلیک کنید: </Span>
        <DatePicker
          value={state.date}
          onChange={convert}
          calendar={persian}
          locale={persian_fa}
          calendarPosition="bottom-right"
        />
      </div>
      <div>
        <Span>فرمت: </Span>
        <select
          value={state.format}
          onChange={e => convert(state.date, e.target.value)}
          className="select"
        >
          <option>MM/DD/YYYY</option>
          <option>DD-MM-YYYY</option>
          <option>YYYY,MM,DD</option>
          <option>dddd DD MMMM YYYY</option>
          <option>ddd MMM DD YYYY HH:mm:ss</option>
          <option>MMM/DD/YYYY hh:mm:ss a</option>
          <option>MMM/DD/YYYY HH:mm:ss</option>
        </select>
      </div>
      <div>
        <Span>میلادی: </Span>
        <span>{state.gregorian}</span>
      </div>
      <div>
        <Span>هجری شمسی: </Span>
        <span>{state.persian}</span>
      </div>
      <div>
        <Span>هجری قمری: </Span>
        <span>{state.arabic}</span>
      </div>
      <div>
        <Span>هندی: </Span>
        <span>{state.indian}</span>
      </div>
      <div>
        <Span>تاریخ جاوااسکریپت: </Span>
        <span>{state.jsDate?.toString?.()}</span>
      </div>
    </div>
  </div>
)
کلیک کنید:
فرمت:
میلادی:
هجری شمسی:
هجری قمری:
هندی:
تاریخ جاوااسکریپت:

onChange (انتخابگر چند تایی)

import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"
.
.
.
<DatePicker
  multiple
  onChange={array => { //آرایه ای از دیت آبجکت ها
    alert("تاریخ های انتخاب شده :\n" + array.join(",\n"))
  }}
  calendar={persian}
  locale={persian_fa}
  calendarPosition="bottom-right"
/>

OnOpen

اگر شرط خاصی را برای باز شدن یا بسته شدن تقویم در نظر دارید ، میتوانید از event های onOpen و onClose استفاده کنید.

اگر در onOpen مقدار false را برگردانید ، تقویم باز نمیشود . و همچنین اگر در onClose مقدار false را برگردانید ، تقویم بسته نمیشود .

import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"
.
.
.
const [shouldOpenCalendar, setShouldOpenCalendar] = useState(false)
.
.
.
<div>
  <DatePicker
    onOpen={() => shouldOpenCalendar}
    calendar={persian}
    locale={persian_fa}
    calendarPosition="bottom-right"
  />
  <label>
    <input
      type="checkbox"
      checked={shouldOpenCalendar}
      onChange={() => setShouldOpenCalendar(!shouldOpenCalendar)}
    />
    باید تقویم باز شود
  </label>
</div>

OnClose

import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"
.
.
.
const [shouldCloseCalendar, setShouldCloseCalendar] = useState(false)
.
.
.
<div>
  <DatePicker
    onClose={() => shouldCloseCalendar}
    calendar={persian}
    locale={persian_fa}
    calendarPosition="bottom-right"
  />
  <label>
    <input
      type="checkbox"
      checked={shouldCloseCalendar}
      onChange={() => setShouldCloseCalendar(!shouldCloseCalendar)}
    />
    باید تقویم بسته شود
  </label>
</div>

onPositionChange

هروقت که دوباره محاسبات موقعیت تقویم انجام شود، فانکشن onChange در المنت-پاپر اجرا میشود .

به دلیل اینکه onChange در datepicker کار دیگری را انجام میدهد ، در اینجا اسم ان را به onPositionChange تغییر دادم.

فانکشن ای که در onPositionChange وارد میکنید در مواقع scroll ، resize ، باز شدن تقویم ، یا زمانی که refreshPosition را از ref دیت پیکر اجرا کنید ، اجرا میشود.

در فانکشن opPositionChange یک object به عنوان argument ارسال میشود که در آن موقعیت های محاسبه شده popper (تقویم) و arrow و همچنین المنت های والد دیت پیکر که قابل اسکرول شدن هستند قرار دارد.

در این مثال ابجکت نام برده شده در console لاگ میشود و شما میتوانید با باز کردن کنسول مرورگر خود (Ctrl + Shift + i در مرورگر کروم)، ان را مشاهده کنید .

import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"
.
.
.
<DatePicker
  onPositionChange={data => console.log(data)}
  calendar={persian}
  locale={persian_fa}
  calendarPosition="bottom-right"
/>

onPropsChange

این قابلیت برای پلاگین ها مناسب میباشد.

زیرا برای بعضی از آنها تنظیم پراپرتی های دیتپیکر (کامپوننت والد) از پلاگین (کامپونند فرزند) اجتناب ناپذیر است.

import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"
.
.
.
const [props, setProps] = useState({ 
  value: new Date(),
  format: "MM-DD-YYYY",
  onChange: (date) => console.log(date.format()),
  calendar: persian,
  locale: persian_fa,
  calendarPosition: "bottom-right"
});
.
.
.
<DatePicker 
  {...props} 
  onPropsChange={setProps} 
/> 

onMonthChange

در این مثال مقدار دهی به پراپرتی currentDate اختیاری است .

پراپرتی currentDate به این منظور مقدار دهی شده است تا تقویم در همان ماه انتخاب شده قبلی باز شود.

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

export default function Example() {
  const [dateObject, setDateObject] = useState(
    new DateObject({
      calendar: persian,
      locale: persian_fa
    })
  );

  return (
    <>
      <DatePicker
        onMonthChange={(date) => setDateObject(new DateObject(date))}
        onChange={(date) => setDateObject(new DateObject(date))}
        currentDate={dateObject}
        calendar={persian}
        locale={persian_fa}
        calendarPosition="bottom-right"
      />
      <p>نام ماه انتخاب شده: {dateObject.month.name}</p>
    </>
  )
}

نام ماه انتخاب شده: آبان

onYearChange

مانند onMonthChange ، تاریخی با نوع DateObject به عنوان آرگومان در فانکشن onYearChange ارسال می شود.

برای مثال اگر می خواهید حالتی از دیت پیکر را پیاده سازی کنید که در آن ماه و سال تاریخ انتخاب شده کاربر با تغییر ماه و سال، تغییر کند ، می توانید از پراپ های onYearChange و onMonthChange استفاده کنید.

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

export default function Example() {
  const [value, setValue] = useState();

  return (
    <DatePicker
      value={value}
      onChange={setValue}
      onYearChange={updateValue}
      onMonthChange={updateValue}
      calendar={persian}
      locale={persian_fa}
      calendarPosition="bottom-right"
    />
  )

  function updateValue({ year, month }) {
    setValue(
      new DateObject(value).set({
        day: value.day > month.length ? month.length : value.day,
        month,
        year,
      })
    );
  }
}

onFocusedDateChange

ویژگی onFocusedDateChange یک فانکشن را دریافت می کند و آن را با دو آرگومان فراخوانی می کند (آرگومان اول dateFocused و آرگومان دوم dateClicked) ، که می تواند توسط خود تقویم یا هر پلاگین دیگری فراخوانی شود.

تفاوت زمانی که onFocusedDateChange توسط خود تقویم فراخوانی می شود و هنگامی که توسط یکی از افزونه ها فراخوانی می شود این است که در حالت اول، آرگومان دوم (یعنی dateClicked) همیشه وجود دارد و در حالت دوم، آرگومان دوم همیشه تعریف نشده است.

ویژگی onFocusedDateChange در واقع دو چیز را مشخص می کند.

  1. کدام تاریخ در حال حاضر فوکوس شده است.

  2. کدام تاریخ در حال حاضر کلیک شده است.

ماهیت این دو با یکدیگر متفاوت است و به عنوان دو آرگومان برای تابعی ای که تعیین کرده اید ارسال می شوند.

در مورد این پراپرتی و آرگومان های آن باید چند نکته را بخاطر بسپارید:

  • هر دو این آرگومانها ممکن است یک نوع داشته باشند (یا DateObject یا تعریف نشده).

  • ممکن است یکی از آنها DateObject و دیگری تعریف نشده باشد.

در اینجا شرایط مختلف را بررسی می کنیم:

  • انتخابگر های تکی و دامنه:

    • هر دو آرگومان یک نوع دارند (DateObject).

    • این بدان معنی است که تاریخ متمرکز شده، همان تاریخی است که روی آن کلیک شده است.

  • انتخابگر چند تایی:

    • تا زمانی که کاربر در حال انتخاب تاریخ های جدید باشد، هر دو آرگومان از یک نوع میباشند (DateObject).

    • این بدان معنی است که تاریخ متمرکز شده، همان تاریخی است که روی آن کلیک شده است.

    • اما به محض اینکه کاربر روی تاریخی که قبلاً انتخاب کرده است کلیک کند، تاریخ انتخاب شده حذف می شود و یکی از موارد زیر ممکن است رخ دهد:

      • تاریخی که حذف می شود همان تاریخ فوکوس شده است، در این صورت اولین آرگومان (یعنی dateFocused) تعریف نشده و آرگومان دوم (یعنی dateClicked) تاریخ کلیک شده است.

      • تاریخ حذف شده با تاریخ فوکوس شده یکسان نیست، در این حالت آرگومان اول تاریخ فوکوس شده ی قبلی، و آرگومان دوم تاریخ حذف شده ی فعلی میباشد.

  • پنل تاریخ ها:

    • به عنوان افزونه ، آرگومان دوم همیشه تعریف نشده است.

    • با کلیک بر روی هر تاریخ نمایش داده شده در پنل تاریخ ها، این تاریخ فوکوس می شود، بنابراین اگر روی هر تاریخی از DatePanel کلیک کنید ، اولین آرگومان (یعنی dateFocused) همان تاریخ کلیک شده خواهد بود.

    • اگر کاربر یک تاریخ غیر متمرکز را از طریق پنل تاریخ ها حذف کند، اولین آرگومان همان تاریخ متمرکز قبلی میشود.

    • اگر کاربر یک تاریخ متمرکز را از طریق پنل تاریخ ها حذف کند، اولین آرگومان نیز تعریف نشده میشود.

import React, { useState } from "react";
import DatePicker from "react-multi-date-picker";
import DatePanel from "react-multi-date-picker/plugins/date_panel";
import persian from "react-date-object/calendars/persian"
import persian_fa from "react-date-object/locales/persian_fa"
.
.
.
const [state, setState] = useState({});
.
.
.
<>
  <DatePicker
    multiple
    onFocusedDateChange={(dateFocused, dateClicked) => {
      setState({ dateFocused, dateClicked });
    }}
    onClose={() => setState({})}
    plugins={[<DatePanel markFocused />]}
    calendar={persian}
    locale={persian_fa}
    calendarPosition="bottom-left"
  />
  <div>
    <p>
      <b>Date focused:</b> {state.dateFocused?.format?.()}
    </p>
    <p>
      <b>Date clicked:</b> {state.dateClicked?.format?.()}
    </p>
  </div>
</> 

تاریخ متمرکز شده:

تاریخ کلیک شده:

همچنین ببینید:

پنل تاریخ ها #شخصی سازی تاریخ متمرکز شده