মূল বিষয়ে যান
বিভাগসমূহ
ভাষা, এখন বাংলা
Rastrillo ডিজাইন সিস্টেম

পছন্দ ও পদক্ষেপ

যে কন্ট্রোলগুলো দিয়ে বিকল্প থেকে বেছে নেওয়া হয়, আর যে সারিগুলো দিয়ে ফর্ম শেষ হয়। প্রতিটি বসে প্যাডিংযুক্ত rst-box-এ, কারণ এই পার্শিয়ালগুলো সেটাই ধরে নেয়।

প্রতিটি উদাহরণ সত্যিই চলে, কিন্তু এর লিংকগুলো কোথাও নিয়ে যায় না। HTML কপি করার জন্য মার্কআপ দেখায়।

field-select

নেটিভ select-এর চারপাশে field-এর মোড়ক। দশটির বেশি অপশন হলে select, select.js-এর ছেঁকে নেওয়া কম্বোবক্স চালু করে; তবু ফর্ম যা পাঠায় তা ওই নেটিভ select-ই।

তিনটি বিকল্প: নেটিভ select

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<div rst-field>
  <label rst-field-label for="sel_few">ভূমিকা</label>
  <select rst-input id="sel_few" name="sel_few">
    <option value="admin" selected>অ্যাডমিন</option>
    <option value="editor">সম্পাদক</option>
    <option value="member">সদস্য</option>
  </select>
</div>

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

{{template "field-select" dict
    "ID" "sel_few"
    "Name" "sel_few"
    "Label" "ভূমিকা"
    "Options" (list
        (dict "Label" "অ্যাডমিন" "Selected" true "Value" "admin")
        (dict "Label" "সম্পাদক" "Value" "editor")
        (dict "Label" "সদস্য" "Value" "member"))}}

বারোটি বিকল্প: ফিল্টারযোগ্য কম্বোবক্স

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<div rst-field>
  <label rst-field-label for="sel_many">শহর</label>
  <select rst-input id="sel_many" name="sel_many" data-rst-select data-rst-select-filter="ফিল্টার করতে টাইপ করুন" data-rst-select-results="{n}টি ফলাফল" data-rst-select-result-one="১টি ফলাফল" data-rst-select-no-matches="কোনো মিল নেই" aria-describedby="sel_many-help">
    <option value="dublin" selected>ডাবলিন</option>
    <option value="lisbon">লিসবন</option>
    <option value="madrid">মাদ্রিদ</option>
    <option value="berlin">বার্লিন</option>
    <option value="rome">রোম</option>
    <option value="athens">এথেন্স</option>
    <option value="helsinki">হেলসিঙ্কি</option>
    <option value="reykjavík">রেইকিয়াভিক</option>
    <option value="warsaw">ওয়ারশ</option>
    <option value="zagreb">জাগরেব</option>
    <option value="tallinn">তালিন</option>
    <option value="valletta">ভাল্লেত্তা</option>
  </select>
  <p rst-field-help id="sel_many-help">ছাঁকতে লিখতে শুরু করুন।</p>
</div>

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

{{template "field-select" dict
    "ID" "sel_many"
    "Name" "sel_many"
    "Label" "শহর"
    "Options" (list
        (dict "Label" "ডাবলিন" "Selected" true "Value" "dublin")
        (dict "Label" "লিসবন" "Value" "lisbon")
        (dict "Label" "মাদ্রিদ" "Value" "madrid")
        (dict "Label" "বার্লিন" "Value" "berlin")
        (dict "Label" "রোম" "Value" "rome")
        (dict "Label" "এথেন্স" "Value" "athens")
        (dict "Label" "হেলসিঙ্কি" "Value" "helsinki")
        (dict "Label" "রেইকিয়াভিক" "Value" "reykjavík")
        (dict "Label" "ওয়ারশ" "Value" "warsaw")
        (dict "Label" "জাগরেব" "Value" "zagreb")
        (dict "Label" "তালিন" "Value" "tallinn")
        (dict "Label" "ভাল্লেত্তা" "Value" "valletta"))
    "Help" "ছাঁকতে লিখতে শুরু করুন।"}}

দশটির বেশি অপশন হলে পার্শিয়ালটি select.js চালু করে। দশের কম হলে করে না: গুটিকয় জিনিসের মধ্যে খোঁজা আসবাব মাত্র, সাহায্য নয়।

বারোটি অপশন, Plain: উন্নতিটি নাকচ করা

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<div rst-field>
  <label rst-field-label for="sel_plain">শহর</label>
  <select rst-input id="sel_plain" name="sel_plain">
    <option value="dublin" selected>ডাবলিন</option>
    <option value="lisbon">লিসবন</option>
    <option value="madrid">মাদ্রিদ</option>
    <option value="berlin">বার্লিন</option>
    <option value="rome">রোম</option>
    <option value="athens">এথেন্স</option>
    <option value="helsinki">হেলসিঙ্কি</option>
    <option value="reykjavík">রেইকিয়াভিক</option>
    <option value="warsaw">ওয়ারশ</option>
    <option value="zagreb">জাগরেব</option>
    <option value="tallinn">তালিন</option>
    <option value="valletta">ভাল্লেত্তা</option>
  </select>
</div>

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

{{template "field-select" dict
    "ID" "sel_plain"
    "Name" "sel_plain"
    "Label" "শহর"
    "Options" (list
        (dict "Label" "ডাবলিন" "Selected" true "Value" "dublin")
        (dict "Label" "লিসবন" "Value" "lisbon")
        (dict "Label" "মাদ্রিদ" "Value" "madrid")
        (dict "Label" "বার্লিন" "Value" "berlin")
        (dict "Label" "রোম" "Value" "rome")
        (dict "Label" "এথেন্স" "Value" "athens")
        (dict "Label" "হেলসিঙ্কি" "Value" "helsinki")
        (dict "Label" "রেইকিয়াভিক" "Value" "reykjavík")
        (dict "Label" "ওয়ারশ" "Value" "warsaw")
        (dict "Label" "জাগরেব" "Value" "zagreb")
        (dict "Label" "তালিন" "Value" "tallinn")
        (dict "Label" "ভাল্লেত্তা" "Value" "valletta"))
    "Plain" true}}

আবশ্যিক, একটি ত্রুটিসহ

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<div rst-field>
  <label rst-field-label for="sel_error">ভূমিকা</label>
  <select rst-input id="sel_error" name="sel_error" required aria-invalid="true" aria-describedby="sel_error-error">
    <option value="admin" selected>অ্যাডমিন</option>
    <option value="editor">সম্পাদক</option>
    <option value="member">সদস্য</option>
  </select>
  <p rst-field-error id="sel_error-error" role="alert">এই ব্যক্তির জন্য একটি ভূমিকা বেছে নিন।</p>
</div>

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

{{template "field-select" dict
    "ID" "sel_error"
    "Name" "sel_error"
    "Label" "ভূমিকা"
    "Options" (list
        (dict "Label" "অ্যাডমিন" "Selected" true "Value" "admin")
        (dict "Label" "সম্পাদক" "Value" "editor")
        (dict "Label" "সদস্য" "Value" "member"))
    "Required" true
    "Error" "এই ব্যক্তির জন্য একটি ভূমিকা বেছে নিন।"}}

হাতে লেখা, optgroup সহ

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<div rst-field>
  <label rst-field-label for="sel_grouped">অঞ্চল</label>
  <select rst-input id="sel_grouped" name="sel_grouped" data-rst-select data-rst-select-filter="ফিল্টার করতে টাইপ করুন" data-rst-select-results="{n}টি ফলাফল" data-rst-select-result-one="১টি ফলাফল" data-rst-select-no-matches="কোনো মিল নেই">
    <optgroup label="ইউরোপ">
      <option value="dublin" selected>ডাবলিন</option>
      <option value="lisbon">লিসবন</option>
      <option value="warsaw">ওয়ারশ</option>
    </optgroup>
    <optgroup label="আমেরিকা মহাদেশ">
      <option value="montreal">মন্ট্রিয়ল</option>
      <option value="lima">লিমা</option>
      <option value="austin">অস্টিন</option>
    </optgroup>
    <optgroup label="এশিয়া">
      <option value="osaka">ওসাকা</option>
      <option value="hanoi">হ্যানয়</option>
      <option value="dhaka">ঢাকা</option>
    </optgroup>
    <optgroup label="আফ্রিকা">
      <option value="accra">আক্রা</option>
      <option value="nairobi">নাইরোবি</option>
      <option value="tunis">তিউনিস</option>
    </optgroup>
  </select>
</div>

এখানে Options একটি সমতল তালিকা, তাই দলবদ্ধ পছন্দগুলো অ্যাপ নিজেই মার্কআপ হিসেবে লেখে। select.js দলগুলো ফেলে না দিয়ে এঁকে দেয়; হাতে লেখা কোনো select চাইলে data-rst-select="false" দিয়ে উন্নতিটি একেবারেই নাকচ করতে পারে।

field-check

টগল করার একমাত্র উপায়: সত্যিকারের একটি চেকবক্স, সুইচের চেহারায়, কীবোর্ড আর স্ক্রিন রিডার অক্ষত।

চালু

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<label rst-switch>
  <input type="checkbox" name="notify_on" checked>
  <span rst-switch-track aria-hidden="true"></span>
  উত্তর এলে আমাকে ইমেল করুন
</label>

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

{{template "field-check" dict
    "Name" "notify_on"
    "Label" "উত্তর এলে আমাকে ইমেল করুন"
    "Checked" true}}

বন্ধ

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<label rst-switch>
  <input type="checkbox" name="notify_off">
  <span rst-switch-track aria-hidden="true"></span>
  কেউ উল্লেখ করলে আমাকে ইমেল করুন
</label>

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

{{template "field-check" dict
    "Name" "notify_off"
    "Label" "কেউ উল্লেখ করলে আমাকে ইমেল করুন"}}

নিষ্ক্রিয়

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<label rst-switch>
  <input type="checkbox" name="notify_disabled" disabled>
  <span rst-switch-track aria-hidden="true"></span>
  আমাকে সাপ্তাহিক সারসংক্ষেপ ইমেল করুন
</label>

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

{{template "field-check" dict
    "Name" "notify_disabled"
    "Label" "আমাকে সাপ্তাহিক সারসংক্ষেপ ইমেল করুন"
    "Disabled" true}}

choice-field

অপশন কার্ড: রেডিও বা চেকবক্স দলের পছন্দের রূপ। Title ছোট থাকে; ব্যাখ্যা করে Desc।

একটি বাছুন

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<fieldset rst-choice>
  <legend>প্ল্যান</legend>
  <div rst-choice-cards>
    <label>
      <input type="radio" name="plan" value="free">
      <span>
        <span rst-choice-title>বিনামূল্যে</span>
        <span rst-choice-desc>একটি প্রকল্প, কমিউনিটির সহায়তা।</span>
      </span>
    </label>
    <label>
      <input type="radio" name="plan" value="pro" checked>
      <span>
        <span rst-choice-title>প্রো</span>
        <span rst-choice-desc>সীমাহীন প্রকল্প আর একটি সহায়তা ইনবক্স।</span>
      </span>
    </label>
  </div>
</fieldset>

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

{{template "choice-field" dict
    "Legend" "প্ল্যান"
    "Name" "plan"
    "Options" (list
        (dict "Desc" "একটি প্রকল্প, কমিউনিটির সহায়তা।" "Title" "বিনামূল্যে" "Value" "free")
        (dict "Checked" true "Desc" "সীমাহীন প্রকল্প আর একটি সহায়তা ইনবক্স।" "Title" "প্রো" "Value" "pro"))}}

যেগুলো ইচ্ছা বাছুন

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<fieldset rst-choice>
  <legend>আমাকে পাঠান</legend>
  <div rst-choice-cards>
    <label>
      <input type="checkbox" name="digest" value="replies" checked>
      <span>
        <span rst-choice-title>উত্তর</span>
        <span rst-choice-desc>যখনই আসে।</span>
      </span>
    </label>
    <label>
      <input type="checkbox" name="digest" value="weekly">
      <span>
        <span rst-choice-title>সাপ্তাহিক সারসংক্ষেপ</span>
        <span rst-choice-desc>সোমবার সকালে।</span>
      </span>
    </label>
  </div>
</fieldset>

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

{{template "choice-field" dict
    "Legend" "আমাকে পাঠান"
    "Name" "digest"
    "Type" "checkbox"
    "Options" (list
        (dict "Checked" true "Desc" "যখনই আসে।" "Title" "উত্তর" "Value" "replies")
        (dict "Desc" "সোমবার সকালে।" "Title" "সাপ্তাহিক সারসংক্ষেপ" "Value" "weekly"))}}

form-foot

ফর্মের শেষ সারি: একটি প্রধান সাবমিট আর ঐচ্ছিক একটি বাতিল লিঙ্ক। বাতিল একটি লিঙ্ক, কারণ ফর্ম ছেড়ে যাওয়া মানে অন্য পাতায় যাওয়া।

সংরক্ষণ ও বাতিল

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<div rst-form-foot>
  <button rst-btn="primary lg" type="submit">পোস্ট সংরক্ষণ করুন</button>
  <a rst-btn="lg" href="/posts">পোস্টে ফিরে যান</a>
</div>

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

{{template "form-foot" dict
    "Submit" "পোস্ট সংরক্ষণ করুন"
    "CancelHref" "/posts"
    "CancelLabel" "পোস্টে ফিরে যান"}}

শুধু জমা দেওয়া

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<div rst-form-foot>
  <button rst-btn="primary lg" type="submit">আমন্ত্রণ পাঠান</button>
</div>

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

{{template "form-foot" dict "Submit" "আমন্ত্রণ পাঠান"}}

নিষ্ক্রিয়: কিছু ঘটার আগের বোতাম

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<div rst-form-foot>
  <button rst-btn="primary lg" type="submit">প্রকাশ করুন</button>
  <a rst-btn="lg" href="/posts">পোস্টে ফিরে যান</a>
</div>

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

{{template "form-foot" dict
    "Submit" "প্রকাশ করুন"
    "CancelHref" "/posts"
    "CancelLabel" "পোস্টে ফিরে যান"}}

যে বোতাম কিছু বদলায় সেটি লোডিং অবস্থা পায়; যে বোতাম শুধু কিছু দেখায় — যেমন ডিসক্লোজার, ড্রপডাউন, ট্যাব — সেটি পায় না। rastrillo.js এই নিয়ম প্রতিটি ফর্মের প্রতিটি সাবমিট বোতামে প্রয়োগ করে, আলাদা করে চালু করার কিছু নেই।

কাজ চলছে: ফর্ম বেরোনোর সময় rastrillo.js যা লেখে

প্রিভিউ

এটি <section rst-box><form rst-form>-এর ভেতরে রাখুন।

<div rst-form-foot>
  <button rst-btn="primary lg" type="submit" aria-busy="true" disabled>
    <span rst-spin aria-hidden="true"></span>
    প্রকাশ করুন
  </button>
  <a rst-btn="lg" href="/posts">পোস্টে ফিরে যান</a>
</div>

শুধু যে বোতামে ক্লিক হয়েছে সেটিই: ফর্মের অন্য সব সাবমিট বোতাম নিজের name আর value ধরে রাখে, আর ফর্মটি নিজেই দ্বিতীয়বার জমা পড়া থেকে রক্ষা পায়। data-busy="false" দিয়ে নিয়মটি বাদ দেওয়া যায়, ফর্মে বা কোনো একটি বোতামে; data-busy-label লেখাটা বদলে দেয়। স্ক্রিপ্ট বন্ধ থাকলে এর কিছুই ঘটে না, ফর্ম আগের মতোই জমা পড়ে, তাই idempotency এখনও সার্ভারের দায়িত্ব।

confirm-form

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

ধ্বংসাত্মক

প্রিভিউ

এটি <section rst-box>-এর ভেতরে রাখুন।

<form rst-form-actions method="post" action="/posts/1/delete">
  <input type="hidden" name="csrf" value="tok-123">
  <input type="hidden" name="id" value="1">
  <a rst-btn="ghost lg" href="/posts/1">বাতিল</a>
  <button type="submit" rst-btn="danger lg">এই পোস্টটি মুছুন</button>
</form>

এটি <section rst-box>-এর ভেতরে রাখুন।

{{template "confirm-form" dict
    "Action" "/posts/1/delete"
    "Label" "এই পোস্টটি মুছুন"
    "Danger" true
    "Hidden" (list (list "csrf" "tok-123") (list "id" "1"))
    "CancelHref" "/posts/1"}}

সাধারণ, বাতিলের পূর্বনির্ধারিত ভাষায়

প্রিভিউ

এটি <section rst-box>-এর ভেতরে রাখুন।

<form rst-form-actions method="post" action="/posts/1/publish">
  <a rst-btn="ghost lg" href="/posts/1">বাতিল</a>
  <button type="submit" rst-btn="primary lg">প্রকাশ করুন</button>
</form>

এটি <section rst-box>-এর ভেতরে রাখুন।

{{template "confirm-form" dict
    "Action" "/posts/1/publish"
    "Label" "প্রকাশ করুন"
    "CancelHref" "/posts/1"}}

কোনো CancelLabel নেই, তাই বাতিল লিঙ্কের কথাগুলো ক্যাটালগ থেকে আসে।