اعتبارسنجی فرم ها (به فصل 9 خوش آمدید)

15 اردیبهشت 1399
اعتبار سنجی فرم ها (به فصل 9 خوش آمدید)

اعتبارسنجی فرم ها (به فصل 9 خوش آمدید)

برنامه ی همبرگرساز ما به خوبی جلو رفته است و حالا می توانیم سفارشات را ثبت و آن ها را از پایگاه داده دریافت کنیم اما در طول این دوره هیچ صحبتی از اعتبارسنجی فرم ها (form validation) نکرده ایم. در حال حاضر فرمی را به کاربر نمایش می دهیم اما باز هم اطلاعات خودمان را ارسال می کنیم. بنابراین وقت آن رسیده است که فرم خود را بررسی کنیم.

برای شروع می خواهم input های فرم خود را (در فایل ContactData.js) درون یک کامپوننت جداگانه قرار بدهم. بنابراین وارد پوشه ی components و سپس UI شوید. درون UI یک پوشه ی جدید به نام Input بسازید که حاوی دو فایل input.js و input.module.css باشد. مثل همیشه کدهای ما برای شروع در فایل input.js به شکل زیر است:

import React from 'react';

const input = (props) => {

};

export default input;

حالا از یک Div به عنوان عنصر ریشه ای استفاده می کنیم و فعلا یک label را در آن می گذاریم. متن این label قرار است از بیرون این کامپوننت بیاید بنابراین متن را به صورت یک prop با نام دلخواه تعیین کنید:

const input = (props) => {

    return (
        <div>
            <label>{props.label}</label>
        </div>
    );
};

حالا باید در بالای تابع return ببینیم چه نوع input ای را بررسی خواهیم کرد. فعلا وارد مسائل پیچیده نمی شویم و فقط نوع input را می خواهیم بنابراین می گوییم:

let inputElement = null;

switch (props.inputType) {
    case ('input'):
        inputElement = <input />;
        break;
    case ('textarea'):
        inputElement = <textarea />
        break;
    default:
        inputElement = <input />;
}

من در اینجا از یک switch عادی جاوا اسکریپت استفاده کرده ام تا مشخص کنم که input ما از چه نوعی باشد و فکر می کنم نحوه ی کار آن بسیار ساده است و نیازی به توضیحات اضافی ندارد. حالا می خواهیم کاری کنیم که attribute های زبان HTML برای فرم ها را به صورت prop پاس دهیم تا بتوانیم آن ها را روی هر عنصر اعمال کنیم (همان inputType). بنابراین:

switch (props.inputType) {
    case ('input'):
        inputElement = <input {...props} />;
        break;
    case ('textarea'):
        inputElement = <textarea {...props} />
        break;
    default:
        inputElement = <input {...props} />;
}

با اپراتور spread کاری می کنیم که attribute های شما روی عنصر مورد نظر قرار بگیرند و دیگر از این جهت مشکلی نخواهیم داشت. در مرحله ی بعد باید inputElement را درون return قرار دهیم:

return (
    <div>
        <label>{props.label}</label>
        {inputElement}
    </div>
);

فعلا این کامپوننت را در همین حد ساده نگه می داریم و به سراغ استایل دهی آن می رویم. وارد فایل input.module.css شوید و کلاس های زیر را در آن ایجاد کنید:

.Input {
    width: 100%;
    padding: 10px;
    box-sizing: border-box;
}

سپس برای هر کدام از input ها نوع کلاس خودشان را تعیین کنیم:

.Input {
    width: 100%;
    padding: 10px;
    box-sizing: border-box;
}

.Label {
    font-weight: bold;
    display: block;
    margin-bottom: 8px;
}

.InputElement {
    outline: none;
    border: 1px solid #ccc;
    background-color: white;
    font: inherit;
    padding: 6px 10px;
    display: block;
    width: 100%;
    box-sizing: border-box;
}

.InputElement:focus {
    outline: none;
    background-color: #ccc;
}

این استایل های فرم ما خواهد بود که باید روی عناصر input خود اعمال کنیم. بنابراین به فایل input.js برگردید و این کار را انجام دهید. ابتدا کلاس ها را وارد فایل می کنیم:

import classes from './input.moduel.css';

سپس آن ها را روی input مورد نظرشان اعمال می کنیم:

const input = (props) => {
    let inputElement = null;

    switch (props.inputType) {
        case ('input'):
            inputElement = <input className={classes.InputElement} {...props} />;
            break;
        case ('textarea'):
            inputElement = <textarea className={classes.InputElement} {...props} />
            break;
        default:
            inputElement = <input className={classes.InputElement} {...props} />;
    }

    return (
        <div className={classes.Input}>
            <label className={classes.Label}>{props.label}</label>
            {inputElement}
        </div>
    );
};

ما کلاس های مورد نظر را روی هر کدام از input ها، روی div ریشه ای و روی label اعمال کرده ایم که در کد بالا قابل مشاهده است. در مرحله ی بعد وارد ContactData.js می شویم و input را وارد آن می کنیم:

import Input from '../../../components/UI/Input/Input';

اگر در حال حاضر به <Form> نگاه کنید کدهای زیر را می بینید:

        let form = (
            <form>
                <input className={classes.Input} type="text" name="name" placeholder="Your Name" />
                <input className={classes.Input} type="email" name="email" placeholder="Your Mail" />
                <input className={classes.Input} type="text" name="street" placeholder="Street" />
                <input className={classes.Input} type="text" name="postal" placeholder="Postal Code" />
                <Button btnType="Success" clicked={this.orderHandler}>ORDER</Button>
            </form>
        );

دیگر هیچ نیازی به className های این کد نداریم، بنابراین آن ها را حذف کنید. همچنین کلاس Input. را نیز از فایل ContactData.module.css حذف کنید. سپس این input های عادی را با Input خود (کامپوننتی که ساختیم) جایگزین می کنیم:

let form = (
    <form>
        <Input inputType="input" type="text" name="name" placeholder="Your Name" />
        <Input inputType="input" type="email" name="email" placeholder="Your Mail" />
        <Input inputType="input" type="text" name="street" placeholder="Street" />
        <Input inputType="input" type="text" name="postal" placeholder="Postal Code" />
        <Button btnType="Success" clicked={this.orderHandler}>ORDER</Button>
    </form>
);

توجه کنید که من prop ای به نام inputType را هم به آن پاس داده ام تا در آن ساختار switch که قبلا تعریف کردیم، نوع input به شکل صحیح مشخص شود. تمامی فایل ها را ذخیره کرده و به مرورگر بروید و یک همبرگر را تا صفحه ی checkout سفارش دهید. در این قسمت می بینید که فرم ما صحیح و سالم نمایش داده می شود  اما در console مرورگر به خطای جالبی برمی خوریم که به خاطر تغییرات نسخه ی 16 کتابخانه ی react است. در واقع از نسخه ی 16 به بعد دیگر اجازه ی استفاده از inputType به عنوان یک prop را نداریم به دلیل اینکه HTML به بزرگی و کوچکی حروف حساس نیست و inputType را به صورت inputtype درک می کند. برای حل این مشکل inputType را به صورت inputtype می نویسیم:

    switch (props.inputtype) {

همچنین در ContactData نیز همین کار را می کنیم:

let form = (
    <form>
        <Input inputtype="input" type="text" name="name" placeholder="Your Name" />
        <Input inputtype="input" type="email" name="email" placeholder="Your Mail" />
        <Input inputtype="input" type="text" name="street" placeholder="Street" />
        <Input inputtype="input" type="text" name="postal" placeholder="Postal Code" />
        <Button btnType="Success" clicked={this.orderHandler}>ORDER</Button>
    </form>
);

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

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری دوره جامع آموزش ری اکت توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.