برنامه نویس وب و اپلیکیشن
تقویم شمسی ری اكت و اعتبارسنجی فرم
سلام دوستان
حدود چند روزی در گیر این بودم که چطور در ریاکت از تقویم شمسی استفاده کنم، راه حل ساده بود اما مشکل از اون جایی به وجود اومد که نیاز بود فیلد اجباری باشه.
خوب راه حل ساده تقویم شمسی ، استفاده از Date Picker هست که خیلی از پکیج هارو تست کردم اما... قبل از این مبحث بزارید فیلد اجباری رو بگم.
برای فیلد اجباری از react hook form استفاده کردم که واقعا عالی هست.
روش استفاده به شکل زیر هست?
import React , {useState , useEffect} from 'react';
import { useForm } from "react-hook-form"
function Main(){
const { register , handleSubmit, errors } = useForm();
const errorsMassage = <p className="errors-massage">اطلاعات را وارد نمایید</p>
const = data => {
const token = localStorage.getItem("token")
addSkillData({
newItem: {
"title" : data.title,
"expense" : data.expense,
"startDate" : data.startDate,
},
config : {
headers : {
"Authorization" : `Bearer ${token}
}}})};
return (<>
<form ={handleSubmit()}>
<div className="form-group col-lg-4 col-md-12">
<label className="mr-1" htmlFor="">عنوان</label>
<input className="form-control" id="addskill-title"
name="title" ref={register({ required: true })} />
{errors.title && errorsMassage}
</div>
<div className="form-group col-lg-4 col-md-12">
<label className="mr-1" htmlFor="">میزان هزینه</label>
<input type="text" className="form-control" id="addskill-expense"
name="expense" ref={register({ required: true })} />
{errors.expense && errorsMassage}
</div>
<div className="form-group col-lg-4 col-md-12">
<label className="mr-1" htmlFor="">تاریخ شروع</label>
<input type="date" className="form-control" id="addskill-start-date"
name="startDate" ref={register({ required: true })} />
{errors.startDate && errorsMassage}
</div>
<input className="btn btn-primary btn-user btn-block" type="submit" value="ثبت" />
</form>
</>
)}
خوب در بالا همان طور که میبینید در هر input از اتریبیوتی به نام ref استفاده کرده تا مقادیر را علاوه بر ارسال به استیت، اعتبار سنجی هم کنه و در نهایت مقادیر در تابع که به handleSubmit در تگ اصلی فرم در دسترس ما هستند.
حالا من در همین شرایط از دیتا پیکر استفاده کردم مثل زیر ?
import React , {useState , useEffect} from 'react';
import { useForm } from "react-hook-form"
import { DatePicker } from "davood-react-persian-datepicker"
function Main(){
const { register , handleSubmit, errors } = useForm();
const errorsMassage = <p className="errors-massage">اطلاعات را وارد نمایید</p>
const = data => {
const token = localStorage.getItem("token")
addSkillData({
newItem: {
"title" : data.title,
"expense" : data.expense,
"startDate" : data.startDate,
},
config : {
headers : {
"Authorization" : `Bearer ${token}`
}
}})};
return (<>
<form ={handleSubmit()}>
<div className="form-group col-lg-4 col-md-12">
<label className="mr-1" htmlFor="">عنوان</label>
<input className="form-control" id="addskill-title"
name="title" ref={register({ required: true })} />
{errors.title && errorsMassage}
</div>
<div className="form-group col-lg-4 col-md-12">
<label className="mr-1" htmlFor="">میزان هزینه</label>
<input type="text" className="form-control" id="addskill-expense"
name="expense" ref={register({ required: true })} />
{errors.expense && errorsMassage}
</div>
<div className="form-group col-lg-4 col-md-12">
<label className="mr-1" htmlFor="">تاریخ شروع</label>
<input type="hidden" className="form-control" id="addskill-start-date"
name="startDate" ref={register({ required: true })} />
<DatePicker />
{errors.startDate && errorsMassage}
</div>
<input className="btn btn-primary btn-user btn-block" type="submit" value="ثبت" />
</form>
</>
)}
همان طور که مشخص هست ، سعی داشتم input تاریخ میلادی را hidden کنم و تاریخ خروجی DatePicker را به value اینپوت پاس بدم که موفق هم شدم ( بدون استفاده از queryselector ) اما دیگه ref اجرا نمیشد و ارور عمل نمیکرد.
اینجا بود که یکم کلافه شدم و با پرس و جو چند روزه ای که داشتم به یک جواب بسیار شیک رسیدم.
ما در react-hook-form یک متد داریم به نام Controller که اگر در جایی امکان استفاده مستقیم خود input نبود یا ref در دسترس نبود میشه ازش استفاده کرد.
روش استفاده به شکل زیر هست ?
import React , {useState , useEffect} from 'react';
import { useForm , Controller } from "react-hook-form"
import { DatePicker } from "davood-react-persian-datepicker"
function Main(){
const { register , handleSubmit, errors , control } = useForm();
const errorsMassage = <p className="errors-massage">اطلاعات را وارد نمایید</p>
const = data => {
const token = localStorage.getItem("token")
let date = moment(data.startDate).format('YYYY/M/D')
addSkillData({
newItem: {
"title" : data.title,
"expense" : data.expense,
"startDate" : date,
},
config : {
headers : {
"Authorization" : `Bearer ${token}`
}
}})};
return (<>
<form ={handleSubmit()}>
<div className="form-group col-lg-4 col-md-12">
<label className="mr-1" htmlFor="">عنوان</label>
<input className="form-control" id="addskill-title"
name="title" ref={register({ required: true })} />
{errors.title && errorsMassage}
</div>
<div className="form-group col-lg-4 col-md-12">
<label className="mr-1" htmlFor="">میزان هزینه</label>
<input type="text" className="form-control" id="addskill-expense"
name="expense" ref={register({ required: true })} />
{errors.expense && errorsMassage}
</div>
<div className="form-group col-lg-4 col-md-12">
<label className="mr-1" htmlFor="">تاریخ شروع</label>
<Controller
control={control}
name="startDate"
rules={{ required: true }}
defaultValue={moment(skillEditingData.startDate)}
render={({on4Change, on5Blur, va6lue }) => (
<DatePicker
calendarStyles={styles}
inputFormat="jYYYY/jM/jD"
v1alue={va4lue}
o2nBlur={on6Blur}
o3nChange={on5Change}
/>
)}
/>
{errors.startDate && errorsMassage}
</div>
<input className="btn btn-primary btn-user btn-block" type="submit" value="ثبت" />
</form>
</>
)}
در Controller به جای ref آمده از rules استفاده کرده و گفته در render هر آنچه دوست داری رندر کن فقط onChang1e, onBlu2r, valu3e هارو پاس بده بهش و تمام. ( اعداد به خاطر اينه كه ويرگول كاراكتر هاي مشابه رو حذف ميكنه ،شما حتما پاک کنید )
و در آخر منابع رو هم بررسی کنیم:
برای DatePicker از https://www.npmjs.com/package/davood-react-persian-datepicker استفاده کردم البته آن زمانی که داشتم پکیج های مختلف رو تست میکردم تمرکزم روی ref بود ، احتمال زیاد با این خاصیت Controller راحت میشه از هر پکیج دیگه ای استفاده کرد.
برای Controller هم https://react-hook-form.com/api/#Controller را بررسی کنید.
و در نهایت خروجی که DatePicker بهتون میده رو به https://github.com/jalaali/moment-jalaali بدید به شکل زیر ?
let date = moment(data.startDate).format('YYYY/M/D') //میلادی
let dateJalali = moment(data.startDate).format('jYYYY/jM/jD') //شمسی
امیدوارم مورد استفاده قرار گرفته باشه
سوالی داشتید حتما بپرسید
مطلبی دیگر از این انتشارات
ایجاد چندین boilerplate جذاب در ری اکت
مطلبی دیگر از این انتشارات
ری اکت سریعتر و دوست داشتنی تر
مطلبی دیگر از این انتشارات
تفاوت کامپایل در React و Angular