একটি মাল্টি-সিলেক্ট কম্পোনেন্ট তৈরি করা

ব্যবহারকারীর অভিজ্ঞতা বাছাই এবং ফিল্টার করার জন্য কীভাবে একটি প্রতিক্রিয়াশীল, অভিযোজিত এবং অ্যাক্সেসযোগ্য, মাল্টিসিলেক্ট উপাদান তৈরি করা যায় তার একটি ভিত্তিগত ওভারভিউ।

এই পোস্টে আমি একটি বহু-নির্বাচন উপাদান তৈরি করার উপায় সম্পর্কে চিন্তাভাবনা ভাগ করতে চাই। ডেমো চেষ্টা করুন.

ডেমো

আপনি যদি ভিডিও পছন্দ করেন তবে এখানে এই পোস্টটির একটি YouTube সংস্করণ রয়েছে:

ওভারভিউ

ব্যবহারকারীদের প্রায়ই আইটেম, কখনও কখনও প্রচুর আইটেম উপস্থাপন করা হয়, এবং এই ক্ষেত্রে পছন্দ ওভারলোড প্রতিরোধ করার জন্য তালিকা কমানোর একটি উপায় প্রদান করা একটি ভাল ধারণা হতে পারে৷ এই ব্লগ পোস্টটি পছন্দগুলি কমানোর উপায় হিসাবে ফিল্টারিং UI অন্বেষণ করে৷ এটি আইটেম বৈশিষ্ট্য উপস্থাপন করে এটি করে যা ব্যবহারকারীরা নির্বাচন বা অনির্বাচন করতে পারে, ফলাফলগুলি হ্রাস করে এবং তাই পছন্দ ওভারলোড হ্রাস করে।

মিথস্ক্রিয়া

লক্ষ্য হল সমস্ত ব্যবহারকারী এবং তাদের বিভিন্ন ধরণের ইনপুটগুলির জন্য ফিল্টার বিকল্পগুলির দ্রুত ট্রাভার্সাল সক্ষম করা৷ এটি একটি অভিযোজিত এবং প্রতিক্রিয়াশীল উপাদানগুলির সাথে সরবরাহ করা হবে। ডেস্কটপ, কীবোর্ড এবং স্ক্রিন রিডারগুলির জন্য চেকবক্সগুলির একটি প্রথাগত সাইডবার এবং স্পর্শ ব্যবহারকারীদের জন্য একটি <select multiple>

একটি মাল্টি-সিলেক্ট এলিমেন্ট সহ চেকবক্স বনাম মোবাইল আইওএস এবং অ্যান্ড্রয়েডের সাইডবার সহ ডেস্কটপ আলো এবং অন্ধকার দেখায় তুলনামূলক স্ক্রিনশট।

স্পর্শের জন্য বিল্ট-ইন মাল্টিসিলেক্ট ব্যবহার করার এই সিদ্ধান্ত, ডেস্কটপের জন্য নয়, কাজ বাঁচায় এবং কাজ তৈরি করে, তবে আমি বিশ্বাস করি যে একটি উপাদানে সম্পূর্ণ প্রতিক্রিয়াশীল অভিজ্ঞতা তৈরি করার চেয়ে কম কোড ঋণের সাথে উপযুক্ত অভিজ্ঞতা প্রদান করে।

স্পর্শ

স্পর্শ উপাদান স্থান সংরক্ষণ করে এবং মোবাইলে ব্যবহারকারীর মিথস্ক্রিয়া নির্ভুলতা সাহায্য করে। এটি একটি <select> অন্তর্নির্মিত ওভারলে স্পর্শ অভিজ্ঞতায় চেকবক্সগুলির একটি সম্পূর্ণ সাইডবার ভেঙে স্থান সংরক্ষণ করে৷ এটি সিস্টেম দ্বারা প্রদত্ত একটি বড় স্পর্শ ওভারলে অভিজ্ঞতা দেখিয়ে ইনপুট নির্ভুলতা সাহায্য করে।

Android, iPhone এবং iPad-এ Chrome-এ মাল্টি-সিলেক্ট এলিমেন্টের একটি স্ক্রিনশট প্রিভিউ। আইপ্যাড এবং আইফোনে মাল্টি-সিলেক্ট টগলড ওপেন রয়েছে এবং প্রত্যেকে স্ক্রীন সাইজের জন্য অপ্টিমাইজ করা একটি অনন্য অভিজ্ঞতা পান।

কীবোর্ড এবং গেমপ্যাড

নীচে কীবোর্ড থেকে <select multiple> ব্যবহার করার একটি প্রদর্শন রয়েছে।

এই বিল্ট-ইন মাল্টি-সিলেক্ট স্টাইল করা যাবে না এবং এটি শুধুমাত্র একটি কমপ্যাক্ট লেআউটে দেওয়া হয় যা অনেকগুলি বিকল্প উপস্থাপনের জন্য উপযুক্ত নয়। দেখুন কিভাবে আপনি সত্যিই সেই ছোট্ট বাক্সে বিকল্পের প্রস্থ দেখতে পাচ্ছেন না? যদিও আপনি এর আকার পরিবর্তন করতে পারেন, এটি এখনও চেকবক্সের সাইডবারের মতো ব্যবহারযোগ্য নয়।

মার্কআপ

উভয় উপাদান একই <form> উপাদানে থাকবে। এই ফর্মের ফলাফল, চেকবক্স বা একাধিক-নির্বাচন, পর্যবেক্ষণ করা হবে এবং গ্রিড ফিল্টার করতে ব্যবহার করা হবে, তবে এটি একটি সার্ভারে জমা দেওয়া যেতে পারে।

<form>

</form>

চেকবক্স উপাদান

চেকবক্সের গ্রুপগুলিকে একটি <fieldset> উপাদানে মোড়ানো উচিত এবং একটি <legend> দেওয়া উচিত। যখন HTML এইভাবে গঠন করা হয়, তখন স্ক্রিন রিডার এবং ফর্মডেটা স্বয়ংক্রিয়ভাবে উপাদানগুলির সম্পর্ক বুঝতে পারবে।

<form>
  <fieldset>
    <legend>New</legend>
    … checkboxes …
  </fieldset>
</form>

গ্রুপিং এর জায়গায়, প্রতিটি ফিল্টারের জন্য একটি <label> এবং <input type="checkbox"> যোগ করুন। আমি একটি <div> এ খনি মোড়ানো বেছে নিয়েছি যাতে CSS gap প্রপার্টি তাদের সমানভাবে স্থান দিতে পারে এবং লেবেলগুলি মাল্টিলাইন হয়ে গেলে সারিবদ্ধতা বজায় রাখতে পারে।

<form>
  <fieldset>
    <legend>New</legend>
    <div>
      <input type="checkbox" id="last 30 days" name="new" value="last 30 days">
      <label for="last 30 days">Last 30 Days</label>
    </div>
    <div>
      <input type="checkbox" id="last 6 months" name="new" value="last 6 months">
      <label for="last 6 months">Last 6 Months</label>
    </div>
   </fieldset>
</form>

কিংবদন্তি এবং ফিল্ডসেট উপাদানগুলির জন্য একটি তথ্যপূর্ণ ওভারলে সহ একটি স্ক্রিনশট, রঙ এবং উপাদানের নাম দেখায়৷

<select multiple>

<select> উপাদানটির একটি কদাচিৎ ব্যবহৃত বৈশিষ্ট্য multiple । যখন অ্যাট্রিবিউটটি একটি <select> উপাদানের সাথে ব্যবহার করা হয়, ব্যবহারকারীকে তালিকা থেকে অনেকগুলি বেছে নেওয়ার অনুমতি দেওয়া হয়। এটি একটি রেডিও তালিকা থেকে একটি চেকবক্স তালিকায় মিথস্ক্রিয়া পরিবর্তন করার মত।

<form>
  <select multiple="true" title="Filter results by category">
    …
  </select>
</form>

একটি <select> এর ভিতরে লেবেল এবং গ্রুপ তৈরি করতে, <optgroup> উপাদানটি ব্যবহার করুন এবং এটিকে একটি label বৈশিষ্ট্য এবং মান দিন। এই উপাদান এবং বৈশিষ্ট্য মান <fieldset> এবং <legend> উপাদানের অনুরূপ।

<form>
  <select multiple="true" title="Filter results by category">
    <optgroup label="New">
      …
    </optgroup>
  </select>
</form>

এখন ফিল্টারের জন্য <option> উপাদান যোগ করুন।

<form>
  <select multiple="true" title="Filter results by category">
    <optgroup label="New">
      <option value="last 30 days">Last 30 Days</option>
      <option value="last 6 months">Last 6 Months</option>
    </optgroup>
  </select>
</form>

একটি বহু-নির্বাচিত উপাদানের ডেস্কটপ রেন্ডারিংয়ের একটি স্ক্রিনশট৷

সহায়ক প্রযুক্তি জানাতে কাউন্টারগুলির সাথে ট্র্যাকিং ইনপুট

এই ব্যবহারকারীর অভিজ্ঞতায় স্ট্যাটাস রোল টেকনিক ব্যবহার করা হয়, স্ক্রিন রিডার এবং অন্যান্য সহায়ক প্রযুক্তির জন্য ফিল্টার ট্র্যাক এবং বজায় রাখতে। ইউটিউব ভিডিও বৈশিষ্ট্যটি প্রদর্শন করে। ইন্টিগ্রেশন HTML এবং অ্যাট্রিবিউট role="status" দিয়ে শুরু হয়।

<div role="status" class="sr-only" id="applied-filters"></div>

এই উপাদানটি বিষয়বস্তুতে করা পরিবর্তনগুলি জোরে জোরে পড়বে। ব্যবহারকারীরা চেকবক্সগুলির সাথে ইন্টারঅ্যাক্ট করার সাথে সাথে আমরা CSS কাউন্টারগুলির সাথে বিষয়বস্তু আপডেট করতে পারি। এটি করার জন্য আমাদের প্রথমে ইনপুট এবং স্টেট এলিমেন্টের প্যারেন্ট এলিমেন্টে একটি নাম সহ একটি কাউন্টার তৈরি করতে হবে।

aside {
  counter-reset: filters;
}

ডিফল্টরূপে, গণনা হবে 0 , যা দুর্দান্ত, কিছুই নেই :checked

এর পরে, আমাদের নতুন তৈরি কাউন্টার বৃদ্ধি করতে, আমরা <aside> উপাদানের বাচ্চাদের লক্ষ্য করব যেগুলি :checked । ব্যবহারকারী ইনপুটগুলির অবস্থা পরিবর্তন করার সাথে সাথে, filters কাউন্টারটি মিলিত হবে।

aside :checked {
  counter-increment: filters;
}

CSS এখন চেকবক্স UI-এর সাধারণ ট্যালি সম্পর্কে সচেতন এবং স্ট্যাটাস রোল এলিমেন্ট খালি এবং মান অপেক্ষা করছে। যেহেতু CSS মেমরিতে ট্যালি বজায় রাখে, counter() ফাংশন ছদ্ম উপাদান বিষয়বস্তু থেকে মান অ্যাক্সেস করার অনুমতি দেয়:

aside #applied-filters::before {
  content: counter(filters) " filters ";
}

স্ট্যাটাস রোল এলিমেন্টের জন্য HTML এখন একটি স্ক্রিন রিডারে "2 ফিল্টার" ঘোষণা করবে। এটি একটি ভাল শুরু, তবে আমরা আরও ভাল করতে পারি, যেমন ফিল্টারগুলি আপডেট করা ফলাফলের সংখ্যা ভাগ করে নেওয়া। আমরা জাভাস্ক্রিপ্ট থেকে এই কাজটি করব, কারণ কাউন্টাররা যা করতে পারে তার বাইরে।

সক্রিয় ফিল্টারের সংখ্যা ঘোষণাকারী MacOS স্ক্রিন রিডারের একটি স্ক্রিনশট।

নেস্টিং উত্তেজনা

কাউন্টার অ্যালগরিদম CSS নেস্টিং -1 এর সাথে দুর্দান্ত অনুভব করেছিল, কারণ আমি সমস্ত যুক্তি একটি ব্লকে রাখতে সক্ষম হয়েছিলাম। পড়া এবং আপডেট করার জন্য বহনযোগ্য এবং কেন্দ্রীভূত বোধ করে।

aside {
  counter-reset: filters;

  & :checked {
    counter-increment: filters;
  }

  & #applied-filters::before {
    content: counter(filters) " filters ";
  }
}

বিন্যাস

এই বিভাগটি দুটি উপাদানের মধ্যে বিন্যাস বর্ণনা করে। বেশিরভাগ লেআউট শৈলী ডেস্কটপ চেকবক্স উপাদানের জন্য।

ফর্ম

ব্যবহারকারীদের জন্য সুস্পষ্টতা এবং স্ক্যানযোগ্যতা অপ্টিমাইজ করার জন্য, ফর্মটিকে সর্বাধিক 30 অক্ষরের প্রস্থ দেওয়া হয়, মূলত প্রতিটি ফিল্টার লেবেলের জন্য একটি অপটিক্যাল লাইন প্রস্থ সেট করে। ফর্মটি ফিল্ডসেটগুলিকে ফাঁক করার জন্য গ্রিড লেআউট এবং gap বৈশিষ্ট্য ব্যবহার করে।

form {
  display: grid;
  gap: 2ch;
  max-inline-size: 30ch;
}

<select> উপাদান

লেবেল এবং চেকবক্সের তালিকা উভয়ই মোবাইলে খুব বেশি জায়গা খরচ করে। অতএব, লেআউটটি স্পর্শের জন্য অভিজ্ঞতা পরিবর্তন করতে ব্যবহারকারীর প্রাথমিক পয়েন্টিং ডিভাইসটি দেখতে পরীক্ষা করে।

@media (pointer: coarse) {
  select[multiple] {
    display: block;
  }
}

coarse একটি মান নির্দেশ করে যে ব্যবহারকারী তাদের প্রাথমিক ইনপুট ডিভাইসের সাথে উচ্চ পরিমাণে নির্ভুলতার সাথে স্ক্রিনের সাথে যোগাযোগ করতে সক্ষম হবে না। একটি মোবাইল ডিভাইসে, পয়েন্টারের মান প্রায়শই coarse হয়, কারণ প্রাথমিক মিথস্ক্রিয়াটি স্পর্শ। একটি ডেস্কটপ ডিভাইসে, পয়েন্টার মান প্রায়ই fine থাকে কারণ এটি একটি মাউস বা অন্যান্য উচ্চ নির্ভুল ইনপুট ডিভাইস সংযুক্ত থাকা সাধারণ।

ফিল্ডসেট

একটি <legend> সহ একটি <fieldset> এর ডিফল্ট স্টাইলিং এবং বিন্যাস অনন্য:

একটি ফিল্ডসেট এবং কিংবদন্তির জন্য ডিফল্ট শৈলীগুলির একটি স্ক্রিনশট৷

সাধারনত, আমার চাইল্ড এলিমেন্ট স্পেস করার জন্য আমি gap প্রোপার্টি ব্যবহার করব, কিন্তু <legend> এর অনন্য পজিশনিং বাচ্চাদের সমানভাবে ব্যবধানযুক্ত সেট তৈরি করা কঠিন করে তোলে। gap পরিবর্তে, সন্নিহিত ভাইবোন নির্বাচক এবং margin-block-start ব্যবহার করা হয়।

fieldset {
  padding: 2ch;

  & > div + div {
    margin-block-start: 2ch;
  }
}

এটি শুধুমাত্র <div> শিশুদের লক্ষ্য করে এটির স্থান সামঞ্জস্য করা থেকে <legend> কে এড়িয়ে যায়।

স্ক্রিনশট ইনপুটগুলির মধ্যে মার্জিন ব্যবধান দেখাচ্ছে কিন্তু কিংবদন্তি নয়।

ফিল্টার লেবেল এবং চেকবক্স

একটি <fieldset> এর সরাসরি সন্তান হিসাবে এবং ফর্মের 30ch এর সর্বাধিক প্রস্থের মধ্যে, লেবেল পাঠ্যটি খুব দীর্ঘ হলে মোড়ানো হতে পারে। টেক্সট মোড়ানো দুর্দান্ত, কিন্তু টেক্সট এবং চেকবক্সের মধ্যে মিসলাইনমেন্ট নয়। ফ্লেক্সবক্স এর জন্য আদর্শ।

fieldset > div {
  display: flex;
  gap: 2ch;
  align-items: baseline;
}
একটি মাল্টি-লাইন র‌্যাপিং পরিস্থিতিতে চেকমার্ক কীভাবে পাঠ্যের প্রথম লাইনের সাথে সারিবদ্ধ হয় তা স্ক্রিনশট দেখাচ্ছে।
এই কোডপেনে আরও খেলুন

অ্যানিমেটেড গ্রিড

লেআউট অ্যানিমেশন আইসোটোপ দ্বারা সম্পন্ন করা হয়। ইন্টারেক্টিভ বাছাই এবং ফিল্টারের জন্য একটি কার্যকরী এবং শক্তিশালী প্লাগইন।

জাভাস্ক্রিপ্ট

একটি ঝরঝরে অ্যানিমেটেড, ইন্টারেক্টিভ গ্রিড অর্কেস্ট্রেট করতে সাহায্য করার পাশাপাশি, জাভাস্ক্রিপ্টটি কয়েকটি রুক্ষ প্রান্তকে পালিশ করতে ব্যবহৃত হয়।

ব্যবহারকারীর ইনপুট স্বাভাবিককরণ

ইনপুট প্রদানের দুটি ভিন্ন উপায় সহ এই নকশাটির একটি ফর্ম রয়েছে এবং তারা একই ক্রমিককরণ করে না। যদিও কিছু জাভাস্ক্রিপ্ট দিয়ে, আমরা ডেটা স্বাভাবিক করতে পারি।

DevTools JavaScript কনসোলের স্ক্রিনশট যা লক্ষ্য, স্বাভাবিক ডেটা ফলাফল দেখায়।

আমি <select> এলিমেন্ট ডাটা স্ট্রাকচারকে গ্রুপ করা চেকবক্স স্ট্রাকচারের সাথে সারিবদ্ধ করতে বেছে নিয়েছি। এটি করার জন্য, একটি input ইভেন্ট লিসেনারকে <select> উপাদানে যোগ করা হয়, যেখানে এটি selectedOptions হয় বিকল্পগুলি ম্যাপ করা হয়।

document.querySelector('select').addEventListener('input', event => {
  // make selectedOptions iterable then reduce a new array object
  let selectData = Array.from(event.target.selectedOptions).reduce((data, opt) => {
    // parent optgroup label and option value are added to the reduce aggregator
    data.push([opt.parentElement.label.toLowerCase(), opt.value])
    return data
  }, [])
})

এখন ফর্মটি জমা দেওয়া নিরাপদ, অথবা এই ডেমোর ক্ষেত্রে, আইসোটোপকে নির্দেশ দিন কী দ্বারা ফিল্টার করতে হবে৷

স্থিতি ভূমিকা উপাদান সমাপ্তি

উপাদানটি কেবলমাত্র চেকবক্স ইন্টারঅ্যাকশনের উপর ভিত্তি করে ফিল্টার গণনা মেলাচ্ছে এবং ঘোষণা করছে তবে আমি অনুভব করেছি অতিরিক্ত ফলাফলের সংখ্যা ভাগ করে নেওয়া এবং <select> উপাদান পছন্দগুলিও গণনা করা হয়েছে তা নিশ্চিত করা একটি ভাল ধারণা।

<select> উপাদান পছন্দ counter()

ডেটা স্বাভাবিককরণ বিভাগে, একটি শ্রোতা ইতিমধ্যেই ইনপুটে তৈরি করা হয়েছে। এই ফাংশনের শেষে নির্বাচিত ফিল্টারের সংখ্যা এবং সেই ফিল্টারগুলির ফলাফলের সংখ্যা জানা যায়। মান এই মত রাষ্ট্র ভূমিকা উপাদান পাস করা যেতে পারে.

let statusRoleElement = document.querySelector('#applied-filters')
statusRoleElement.style.counterSet = selectData.length

role="status" উপাদানে ফলাফল প্রতিফলিত হয়

:checked স্ট্যাটাস রোল এলিমেন্টে নির্বাচিত ফিল্টারের সংখ্যা পাস করার একটি অন্তর্নির্মিত উপায় প্রদান করে, কিন্তু ফিল্টার করা ফলাফলের সংখ্যায় দৃশ্যমানতার অভাব রয়েছে। জাভাস্ক্রিপ্ট চেকবক্সগুলির সাথে ইন্টারঅ্যাকশনের জন্য দেখতে পারে এবং গ্রিড ফিল্টার করার পরে, <select> উপাদানের মতো textContent যোগ করুন।

document
  .querySelector('aside form')
  .addEventListener('input', e => {
    // isotope demo code
    let filterResults = IsotopeGrid.getFilteredItemElements().length
    document.querySelector('#applied-filters').textContent = `giving ${filterResults} results`
})

সব মিলিয়ে এই কাজটি "2টি ফিল্টার 25টি ফলাফল দেয়" ঘোষণাটি সম্পূর্ণ করে।

ফলাফল ঘোষণাকারী MacOS স্ক্রিন রিডারের একটি স্ক্রিনশট।

এখন আমাদের চমৎকার সহায়ক প্রযুক্তি অভিজ্ঞতা সকল ব্যবহারকারীদের কাছে পৌঁছে দেওয়া হবে, যদিও তারা এটির সাথে যোগাযোগ করে।

উপসংহার

এখন যেহেতু আপনি জানেন যে আমি কীভাবে এটি করেছি, আপনি কেমন হবে‽ 🙂৷

আসুন আমাদের পদ্ধতির বৈচিত্র্য আনুন এবং ওয়েবে তৈরি করার সমস্ত উপায় শিখি। একটি ডেমো তৈরি করুন, আমাকে লিঙ্কগুলি টুইট করুন এবং আমি নীচের সম্প্রদায়ের রিমিক্স বিভাগে এটি যুক্ত করব!

কমিউনিটি রিমিক্স

এখানে এখনো দেখার কিছু নেই!