عناصر Checkbox و Radiobutton

Checkbox and Radiobutton Elements

Vue.JS 2: عناصر checkbox و radiobutton - قسمت 48

در جلسه قبل نگاهی به فیلدهای ساده متنی و همینطور فیلدهای چند خطی مانند Textarea ها داشتیم و در این قسمت نگاهی به منوهای checkbox و منوهای radiobutton و منوهای آبشاری خواهیم داشت. کدهای مربوط به checkbox در پروژه ما به شکل زیر است:

<div class="form-group">
  <label for="sendmail">
    <input type="checkbox" id="sendmail" value="SendMail" /> Send Mail
  </label>
  <label for="sendInfomail">
    <input type="checkbox" id="sendInfomail" value="SendInfoMail" /> Send Infomail
  </label>
</div>

دلیل این که من checkbox ها را درون یک label قرار داده ام این است که در فریم ورک بوت استرپ checkbox ها به این شکل نوشته می شوند. در قسمت های قبل فیلدها را به خصوصیت خاصی در قسمت data متصل کرده بودیم اما این بار برای checkbox ها نقشه دیگری دارم. checkbox های ما مربوط به دریافت ایمیل های ما توسط کاربر است. یعنی در این قسمت کاربر انتخاب خواهد کرد که ایمیل های عادی را دریافت کند یا ایمیل‌های عادی را به همراه infomail (مثلا ایمیل های دارای تخفیفات و تبلیغات) دریافت کند. از آنجایی که این دو checkbox به همدیگر مربوط هستند من می خواهم مقدار آن ها را درون یک آرایه ذخیره کنم نه یک خصوصیت جداگانه.  با ذخیره آن ها در یک آرایه می توانیم درون آن گردش کرده و سپس مقادیر آن را مشاهده کنیم (این مقادیر true یا false خواهند بود). سوال اینجاست که چطور به Vue چنین دستوری بدهیم؟

اولین کار تعریف کردن آرایه در data است:

<script>
export default {
  data() {
    return {
      userData: {
        email: "",
        password: "",
        age: 27
      },
      message: "A new text",
      sendMail: []
    };
  }
};
</script>

اگر ما هر دو input مربوط به checkbox ها را با یک دستور v-model یکسان به یک خصوصیت درون data متصل کنیم، فریم ورک Vue متوجه این تکرار می شود و با دیدن دستورات یکسان v-model برای دو checkbox مختلف سعی می‌کند که هر دو را درون یک آرایه ادغام کند. این آیه همان خصوصیتی است که در قسمت data تعریف کرده بودیم، بنابراین می گوییم:

<div class="form-group">
  <label for="sendmail">
    <input type="checkbox" id="sendmail" value="SendMail" v-model="sendMail" /> Send Mail
  </label>
  <label for="sendInfomail">
    <input type="checkbox" id="sendInfomail" value="SendInfoMail" v-model="sendMail" /> Send Infomail
  </label>
</div>

توجه کنید که v-model ها حتما روی خود input باشند. همانطور که گفتم حالا نوبت گردش درون آرایه است. برای نمایش مقادیر دورن sendMail درون قسمت panel-body باید درون این آرایه گردش کنیم. این کار به راحتی توسط یک دستور v-for انجام می شود من از قبل لیست HTML را برای شما آماده کرده ام بنابراین تنها کاری که باید انجام بدهید نوشتن کدهای v-for است.

<div class="panel-body">
  <p>Mail: {{ userData.email }}</p>
  <p>Password: {{ userData.password }}</p>
  <p>Age: {{ userData.age }}</p>
  <p style="white-space: pre">Message: {{ message }}</p>
  <p>
    <strong>Send Mail?</strong>
  </p>
  <ul>
    <li v-for="item in sendMail">{{ item }}</li>
  </ul>
  <p>Gender:</p>
  <p>Priority:</p>
  <p>Switched:</p>
</div>

حالا اگر به مرور گر بروید می توانید کدها را تست کنید. برنامه باید بدون اشکال برای شما اجرا شود و با فعال کردن هر checkbox مقدار آن را در قسمت panel-body مشاهده کنید. البته در نظر داشته باشید که الزامی به استفاده از این روش وجود ندارد و می توانید مانند فیلدهای قبلی هر دو checkbox را به دو خصوصیت جداگانه متصل کنید.

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

برای دریافت مقدار radiobutton ها که مربوط به جنسیت (gender) می شوند، ابتدا خصوصیتشان را تعریف می کنیم:

<script>
export default {
  data() {
    return {
      userData: {
        email: "",
        password: "",
        age: 27
      },
      message: "A new text",
      sendMail: [],
      gender: 'male'
    };
  }
};
</script>

من از آنجایی که مذکر هستم، مقدار male (مذکر) را به صورت پیش فرض قرار داده ام. سپس با دستور v-model آن ها را به این خصوصیت متصل می کنیم:

<div class="row">
  <div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 form-group">
    <label for="male">
      <input type="radio" id="male" value="Male" v-model="gender" /> Male
    </label>
    <label for="female">
      <input type="radio" id="female" value="Female" v-model="gender" /> Female
    </label>
  </div>
</div>

من در قسمت بالاتر به شما گفتم که اگر چندین checkbox را به یک خصوصیت درون data متصل کنید فریم ورک vue به صورت خودکار آن ها را درون یک آرایه قرار می‌دهد اما اگر مقادیر ما به جای checkbox از نوع rradiobutton  باشند انتخاب دستورات v-model یکسان برای آن ها باعث چنین رفتاری نمی شوند. زمانی که چندین radiobutton را با یک دستور v-model یکسان به هم می چسبانیم فریم ورک Vue متوجه می شود که radiobutton های ما جزو یک گروه واحد هستند. این مسئله باعث می شود که Vue برنامه ما را تصحیح کند تا کاربر فقط بتواند یکی از radiobutton ها را انتخاب کند و radiobutton دیگر به طور همزمان فعال نشود.

مسئله بعدی اینجاست که Vue متوجه است radiobutton برای انتخاب یک گزینه از بین چند گزینه هستند بنابراین به جای تبدیل مقدار آن به یک آرایه، مقدار value (از attibute های HTML) هر کدام را درون خصوصیت مورد نظر در data ذخیره می کند. بنابراین می توان برای نمایش آن در panel-body به شکل زیر عمل کرد:

<div class="panel-body">
  <p>Mail: {{ userData.email }}</p>
  <p>Password: {{ userData.password }}</p>
  <p>Age: {{ userData.age }}</p>
  <p style="white-space: pre">Message: {{ message }}</p>
  <p>
    <strong>Send Mail?</strong>
  </p>
  <ul>
    <li v-for="item in sendMail">{{ item }}</li>
  </ul>
  <p>Gender: {{ gender }}</p>
  <p>Priority:</p>
  <p>Switched:</p>
</div>

کد بالا به درستی در مرورگر کار می کند. در قسمت بعد به سراغ منوهای آبشاری (drop-down) می رویم.

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

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