فصل پیوست ۳: ارائه‌ی فیدبک اعتبارسنجی در UI

Validation Feedback in the UI

Vue.JS 2 - فصل پیوست 3: ارائه ی فیدبک اعتبارسنجی در UI - قسمت 129

در قسمت قبل به شما توضیح دادم که پکیج vuelidate از پکیج های معروف Vue.js برای اعتبارسنجی فرم ها است اما برای آشنایی بهتر با آن، شیء v$ را که توسط این پکیج ارائه می شد در کنار input خودمان (در فایل signup.vue) چاپ کردیم تا خروجی آن را ببینیم:

<div class="input">
  <label for="email">Mail</label>
  <input type="email" id="email" @input="$v.email.$touch()" v-model="email" />
  <div>{{ $v }}</div>
</div>

زمانی که این کد را در مرورگر اجرا می کردیم، اطلاعات زیر برایمان چاپ می شد:

{ "email": { "required": false, "email": true, "$model": "", "$invalid": true, "$dirty": false, "$anyDirty": false, "$error": false, "$anyError": false, "$pending": false, "$params": { "required": { "type": "required" }, "email": { "type": "email" } } }, "$model": null, "$invalid": true, "$dirty": false, "$anyDirty": false, "$error": false, "$anyError": false, "$pending": false, "$params": { "email": null } }

بنابراین می دانیم که به این خصوصیات دسترسی خواهیم داشت اما چاپ کردن یک شیء جاوا اسکریپتی بدین شکل اصلا مناسب نیست و ظاهر UI را کاملا بهم می ریزد بنابراین بهتر است راهی ایجاد کنیم که فیدبک خود به کاربر را در همان UI و با ظاهری مناسب بدهیم. در قدم اول باید کد چاپ v$ را حذف کنیم. سپس به سراغ div اصلی Email می رویم که هم input و هم label را در خود دارد و در آنجا می گوییم اگر روی فیلد email خطا یا error$ ای وجود داشت، کلاس invalid را به این div متصل کن:

<div class="input" :class="{invalid: $v.email.$error}">
  <label for="email">Mail</label>
  <input type="email" id="email" @input="$v.email.$touch()" v-model="email" />
</div>

اگر یادتان باشد برای متصل کردن کلاس های CSS به صورت شرطی می توانستیم class را با v-bind بنویسیم و سپس یک شیء جاوا اسکریپتی به آن پاس بدهیم. key این شیء، برابر نام آن کلاس خواهد بود و value نیز باید شرط شما برای اتصال کلاس باشد. همچنین در نظر داشته باشید که در ایجا از invalid به جای Error استفاده نکنید. اگر از invalid استفاده کنید، از همان بارگذاری اولیه فرم، فیلد ما دارای خطا محسوب می شود (چرا که چیزی درون فیلد ایمیل نیست) اما ما می خواهیم فقط زمانی که کاربر در این فیلد تایپ کرده است، خطاهایش را نمایش بدهیم. همچنین این کد به تنهایی کار خاصی نمی کند چرا که اصلا کلاسی به نام invalid نداریم بنابراین در همین فایل (signup.vue) به قسمت <style> می روم و می گویم:

.input.invalid input {
  border: 1px solid red;
  background-color: #ffc9aa;
}

.input.invalid label {
  color: red;
}

یعنی اگر کلاس input و invalid روی یک input یا label بود به شکل بالا border و background-color آن را تغییر خواهیم داد. حالا اگر به مرورگر برویم و یک مقدار اشتباهی را به عنوان ایمیل وارد کنیم، فیلد قرمز خواهد شد:

فیلد ایمیل ما قرمز رنگ شده است که نشانه ی وجود خطا است
فیلد ایمیل ما قرمز رنگ شده است که نشانه وجود خطا است

اما اگر ایمیل را کامل وارد کنم خطا از بین می رود. البته هنوز می توانیم این سیستم را بهتر کنیم. مثلا در زیر input ایمیل، یک تگ <p> قرار می دهیم که خطای رخ داده شده در آن توضیح داده شود:

<div class="input" :class="{invalid: $v.email.$error}">
  <label for="email">Mail</label>
  <input type="email" id="email" @input="$v.email.$touch()" v-model="email" />
  <p v-if="$v.email.$error">Please provide a valid email adress.</p>
</div>

من در اینجا گفته ام که این پاراگراف که حاوی متن «لطفا یک ایمیل معتبر را ارائه دهید» است فقط زمانی نمایش داده شود که email.$error داشته باشیم. بنابراین با یک v-if ساده جلوی نمایش همیشگی آن را گرفته ایم. من این کد را در مرورگر تست می کنم و به محض وارد کردن ایمیل اشتباه، این پاراگراف برایم نمایش داده می شود:

پیام خطای ما به هنگاه قرمز شدن فیلد نمایش داده می شود.
پیام خطای ما به هنگاه قرمز شدن فیلد نمایش داده می شود.

اما به محض وارد کردن ایمیل صحیح، این پاراگراف از بین می رود. البته در حال حاضر این پیام زمانی نمایش داده می شود که ایمیل وارد شده یا نامعتبر باشد یا اصلا ایمیلی در فیلد email تایپ نشده باشد (مثلا کاربر ایمیل را نوشته و بعدا آن را حذف کرده است). اگر می خواهید این پیام فقط زمانی نمایش داده شود که فیلد email پر شده باشد اما آدرس وارد شده یک آدرس معتبر نباشد، باید به شکل زیر عمل کنید:

<div class="input" :class="{invalid: $v.email.$error}">
  <label for="email">Mail</label>
  <input type="email" id="email" @input="$v.email.$touch()" v-model="email" />
  <p v-if="!$v.email.email">Please provide a valid email adress.</p>
</div>

حتما می پرسید که email.email یعنی چی؟! من در ابتدای این جلسه برایتان توضیح دادم که در شیء v$ به مقادیر زیر دسترسی داریم:

{ "email": { "required": false, "email": true, "$model": "", "$invalid": true, "$dirty": false, "$anyDirty": false, "$error": false, "$anyError": false, "$pending": false, "$params": { "required": { "type": "required" }, "email": { "type": "email" } } }, "$model": null, "$invalid": true, "$dirty": false, "$anyDirty": false, "$error": false, "$anyError": false, "$pending": false, "$params": { "email": null } }

این شیء JSON کمی بهم ریخته است بنابراین شاید بهتر باشد که آن را باز کنیم تا بهتر دیده شود:

{
    "email": {
        "required": false,
        "email": true,
        "$model": "",
        "$invalid": true,
        "$dirty": false,
        "$anyDirty": false,
        "$error": false,
        "$anyError": false,
        "$pending": false,
        "$params": {
            "required": {
                "type": "required"
            },
            "email": {
                "type": "email"
            }
        }
    },
    "$model": null,
    "$invalid": true,
    "$dirty": false,
    "$anyDirty": false,
    "$error": false,
    "$anyError": false,
    "$pending": false,
    "$params": {
        "email": null
    }
}

همانطور که می بینید در اینجا درون email به یک خصوصیت دیگر به نام Email دسترسی داریم. email اول ما در کد بالا، به دسته قوانین فیلد email اشاره می کند که توسط خود ما تعریف شده بود:

validations: {
  email: {
    required,
    email
  }
}

اما email دوم که درون email اول قرار دارد، مشخص کننده اعتبار ایمیل وارد شده است. یعنی آیا ایمیلی که کاربر وارد کرده است معتبر می باشد و ساختار صحیحی دارد؟ بدین صورت می توانیم فقط ایمیل بودن رشته وارد شده در فیلد email را بررسی کنیم. حالا کد اصلی ما معنی پیدا می کند:

  <p v-if="!$v.email.email">Please provide a valid email adress.</p>

اگر رشته وارد شده ایمیل نبود (علامت تعجب در ابتدای شرط، آن را برعکس می کند) این پاراگراف را نمایش بده. همچنین اگر می خواهید در هنگام خالی بودن فیلد، یک پیام دیگر نشان بدهیم می توانیم بگوییم:

<div class="input" :class="{invalid: $v.email.$error}">
  <label for="email">Mail</label>
  <input type="email" id="email" @input="$v.email.$touch()" v-model="email" />
  <p v-if="!$v.email.email">Please provide a valid email adress.</p>
  <p v-if="!$v.email.required">This field must not be empty.</p>
</div>

در اینجا بعد از email به خصوصیت required دسترسی پیدا کرده ایم و گفته ایم اگر فیلد ایمیل خالی بود، این پیام را نمایش بده.

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

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

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