Đi tới nội dung
Mục
Ngôn ngữ, hiện là Tiếng Việt
Hệ thống thiết kế Rastrillo

Lựa chọn và thao tác

Các điều khiển để chọn trong số các lựa chọn, và những hàng kết thúc một biểu mẫu. Mỗi cái nằm trong một rst-box có đệm, vì đó là quy tắc mà các mảnh này mặc định.

Mỗi ví dụ đều hoạt động thật, nhưng các liên kết trong đó không dẫn đến đâu. HTML hiển thị mã đánh dấu để sao chép.

field-select

Lớp vỏ của field bọc quanh một select gốc. Quá mười lựa chọn thì select bật hộp kết hợp có lọc trong select.js; thứ biểu mẫu gửi đi vẫn là select gốc.

Ba lựa chọn: select gốc

Xem trước

Đặt đoạn này bên trong <section rst-box><form rst-form>.

<div rst-field>
  <label rst-field-label for="sel_few">Vai trò</label>
  <select rst-input id="sel_few" name="sel_few">
    <option value="admin" selected>Quản trị viên</option>
    <option value="editor">Biên tập viên</option>
    <option value="member">Thành viên</option>
  </select>
</div>

Đặt đoạn này bên trong <section rst-box><form rst-form>.

{{template "field-select" dict
    "ID" "sel_few"
    "Name" "sel_few"
    "Label" "Vai trò"
    "Options" (list
        (dict "Label" "Quản trị viên" "Selected" true "Value" "admin")
        (dict "Label" "Biên tập viên" "Value" "editor")
        (dict "Label" "Thành viên" "Value" "member"))}}

Mười hai lựa chọn: hộp chọn có lọc

Xem trước

Đặt đoạn này bên trong <section rst-box><form rst-form>.

<div rst-field>
  <label rst-field-label for="sel_many">Thành phố</label>
  <select rst-input id="sel_many" name="sel_many" data-rst-select data-rst-select-filter="Nhập để lọc" data-rst-select-results="{n} kết quả" data-rst-select-result-one="1 kết quả" data-rst-select-no-matches="Không có kết quả phù hợp" aria-describedby="sel_many-help">
    <option value="dublin" selected>Dublin</option>
    <option value="lisbon">Lisbon</option>
    <option value="madrid">Madrid</option>
    <option value="berlin">Berlin</option>
    <option value="rome">Roma</option>
    <option value="athens">Athens</option>
    <option value="helsinki">Helsinki</option>
    <option value="reykjavík">Reykjavík</option>
    <option value="warsaw">Warszawa</option>
    <option value="zagreb">Zagreb</option>
    <option value="tallinn">Tallinn</option>
    <option value="valletta">Valletta</option>
  </select>
  <p rst-field-help id="sel_many-help">Bắt đầu gõ để lọc.</p>
</div>

Đặt đoạn này bên trong <section rst-box><form rst-form>.

{{template "field-select" dict
    "ID" "sel_many"
    "Name" "sel_many"
    "Label" "Thành phố"
    "Options" (list
        (dict "Label" "Dublin" "Selected" true "Value" "dublin")
        (dict "Label" "Lisbon" "Value" "lisbon")
        (dict "Label" "Madrid" "Value" "madrid")
        (dict "Label" "Berlin" "Value" "berlin")
        (dict "Label" "Roma" "Value" "rome")
        (dict "Label" "Athens" "Value" "athens")
        (dict "Label" "Helsinki" "Value" "helsinki")
        (dict "Label" "Reykjavík" "Value" "reykjavík")
        (dict "Label" "Warszawa" "Value" "warsaw")
        (dict "Label" "Zagreb" "Value" "zagreb")
        (dict "Label" "Tallinn" "Value" "tallinn")
        (dict "Label" "Valletta" "Value" "valletta"))
    "Help" "Bắt đầu gõ để lọc."}}

Quá mười lựa chọn thì mảnh này bật select.js. Dưới mười thì không: tìm kiếm trong dăm ba mục là đồ trang trí, không phải trợ giúp.

Mười hai lựa chọn, Plain: đã từ chối phần tăng cường

Xem trước

Đặt đoạn này bên trong <section rst-box><form rst-form>.

<div rst-field>
  <label rst-field-label for="sel_plain">Thành phố</label>
  <select rst-input id="sel_plain" name="sel_plain">
    <option value="dublin" selected>Dublin</option>
    <option value="lisbon">Lisbon</option>
    <option value="madrid">Madrid</option>
    <option value="berlin">Berlin</option>
    <option value="rome">Roma</option>
    <option value="athens">Athens</option>
    <option value="helsinki">Helsinki</option>
    <option value="reykjavík">Reykjavík</option>
    <option value="warsaw">Warszawa</option>
    <option value="zagreb">Zagreb</option>
    <option value="tallinn">Tallinn</option>
    <option value="valletta">Valletta</option>
  </select>
</div>

Đặt đoạn này bên trong <section rst-box><form rst-form>.

{{template "field-select" dict
    "ID" "sel_plain"
    "Name" "sel_plain"
    "Label" "Thành phố"
    "Options" (list
        (dict "Label" "Dublin" "Selected" true "Value" "dublin")
        (dict "Label" "Lisbon" "Value" "lisbon")
        (dict "Label" "Madrid" "Value" "madrid")
        (dict "Label" "Berlin" "Value" "berlin")
        (dict "Label" "Roma" "Value" "rome")
        (dict "Label" "Athens" "Value" "athens")
        (dict "Label" "Helsinki" "Value" "helsinki")
        (dict "Label" "Reykjavík" "Value" "reykjavík")
        (dict "Label" "Warszawa" "Value" "warsaw")
        (dict "Label" "Zagreb" "Value" "zagreb")
        (dict "Label" "Tallinn" "Value" "tallinn")
        (dict "Label" "Valletta" "Value" "valletta"))
    "Plain" true}}

Bắt buộc, kèm lỗi

Xem trước

Đặt đoạn này bên trong <section rst-box><form rst-form>.

<div rst-field>
  <label rst-field-label for="sel_error">Vai trò</label>
  <select rst-input id="sel_error" name="sel_error" required aria-invalid="true" aria-describedby="sel_error-error">
    <option value="admin" selected>Quản trị viên</option>
    <option value="editor">Biên tập viên</option>
    <option value="member">Thành viên</option>
  </select>
  <p rst-field-error id="sel_error-error" role="alert">Chọn một vai trò cho người này.</p>
</div>

Đặt đoạn này bên trong <section rst-box><form rst-form>.

{{template "field-select" dict
    "ID" "sel_error"
    "Name" "sel_error"
    "Label" "Vai trò"
    "Options" (list
        (dict "Label" "Quản trị viên" "Selected" true "Value" "admin")
        (dict "Label" "Biên tập viên" "Value" "editor")
        (dict "Label" "Thành viên" "Value" "member"))
    "Required" true
    "Error" "Chọn một vai trò cho người này."}}

Viết tay, có optgroup

Xem trước

Đặt đoạn này bên trong <section rst-box><form rst-form>.

<div rst-field>
  <label rst-field-label for="sel_grouped">Khu vực</label>
  <select rst-input id="sel_grouped" name="sel_grouped" data-rst-select data-rst-select-filter="Nhập để lọc" data-rst-select-results="{n} kết quả" data-rst-select-result-one="1 kết quả" data-rst-select-no-matches="Không có kết quả phù hợp">
    <optgroup label="Châu Âu">
      <option value="dublin" selected>Dublin</option>
      <option value="lisbon">Lisbon</option>
      <option value="warsaw">Warszawa</option>
    </optgroup>
    <optgroup label="Châu Mỹ">
      <option value="montreal">Montréal</option>
      <option value="lima">Lima</option>
      <option value="austin">Austin</option>
    </optgroup>
    <optgroup label="Châu Á">
      <option value="osaka">Osaka</option>
      <option value="hanoi">Hà Nội</option>
      <option value="dhaka">Dhaka</option>
    </optgroup>
    <optgroup label="Châu Phi">
      <option value="accra">Accra</option>
      <option value="nairobi">Nairobi</option>
      <option value="tunis">Tunis</option>
    </optgroup>
  </select>
</div>

Options ở đây là một danh sách phẳng, nên các lựa chọn theo nhóm là phần mã do ứng dụng tự viết. select.js dựng các nhóm chứ không bỏ đi; một select viết tay cũng có thể từ chối hẳn phần tăng cường bằng data-rst-select="false".

field-check

Cơ chế bật tắt duy nhất: một hộp kiểm thật khoác vẻ ngoài công tắc, bàn phím và trình đọc màn hình vẫn nguyên vẹn.

Bật

Xem trước

Đặt đoạn này bên trong <section rst-box><form rst-form>.

<label rst-switch>
  <input type="checkbox" name="notify_on" checked>
  <span rst-switch-track aria-hidden="true"></span>
  Gửi email cho tôi khi có trả lời
</label>

Đặt đoạn này bên trong <section rst-box><form rst-form>.

{{template "field-check" dict
    "Name" "notify_on"
    "Label" "Gửi email cho tôi khi có trả lời"
    "Checked" true}}

Tắt

Xem trước

Đặt đoạn này bên trong <section rst-box><form rst-form>.

<label rst-switch>
  <input type="checkbox" name="notify_off">
  <span rst-switch-track aria-hidden="true"></span>
  Gửi email cho tôi khi được nhắc đến
</label>

Đặt đoạn này bên trong <section rst-box><form rst-form>.

{{template "field-check" dict
    "Name" "notify_off"
    "Label" "Gửi email cho tôi khi được nhắc đến"}}

Bị vô hiệu

Xem trước

Đặt đoạn này bên trong <section rst-box><form rst-form>.

<label rst-switch>
  <input type="checkbox" name="notify_disabled" disabled>
  <span rst-switch-track aria-hidden="true"></span>
  Gửi email tóm tắt hằng tuần cho tôi
</label>

Đặt đoạn này bên trong <section rst-box><form rst-form>.

{{template "field-check" dict
    "Name" "notify_disabled"
    "Label" "Gửi email tóm tắt hằng tuần cho tôi"
    "Disabled" true}}

choice-field

Thẻ lựa chọn: dạng nhóm nút chọn hoặc hộp kiểm được ưa dùng. Title giữ ngắn; phần giải thích để cho Desc.

Chọn một

Xem trước

Đặt đoạn này bên trong <section rst-box><form rst-form>.

<fieldset rst-choice>
  <legend>Gói</legend>
  <div rst-choice-cards>
    <label>
      <input type="radio" name="plan" value="free">
      <span>
        <span rst-choice-title>Miễn phí</span>
        <span rst-choice-desc>Một dự án, hỗ trợ từ cộng đồng.</span>
      </span>
    </label>
    <label>
      <input type="radio" name="plan" value="pro" checked>
      <span>
        <span rst-choice-title>Chuyên nghiệp</span>
        <span rst-choice-desc>Không giới hạn dự án và một hộp thư hỗ trợ.</span>
      </span>
    </label>
  </div>
</fieldset>

Đặt đoạn này bên trong <section rst-box><form rst-form>.

{{template "choice-field" dict
    "Legend" "Gói"
    "Name" "plan"
    "Options" (list
        (dict "Desc" "Một dự án, hỗ trợ từ cộng đồng." "Title" "Miễn phí" "Value" "free")
        (dict "Checked" true "Desc" "Không giới hạn dự án và một hộp thư hỗ trợ." "Title" "Chuyên nghiệp" "Value" "pro"))}}

Chọn bao nhiêu tùy ý

Xem trước

Đặt đoạn này bên trong <section rst-box><form rst-form>.

<fieldset rst-choice>
  <legend>Gửi cho tôi</legend>
  <div rst-choice-cards>
    <label>
      <input type="checkbox" name="digest" value="replies" checked>
      <span>
        <span rst-choice-title>Trả lời</span>
        <span rst-choice-desc>Ngay khi có.</span>
      </span>
    </label>
    <label>
      <input type="checkbox" name="digest" value="weekly">
      <span>
        <span rst-choice-title>Bản tóm tắt hằng tuần</span>
        <span rst-choice-desc>Sáng thứ Hai.</span>
      </span>
    </label>
  </div>
</fieldset>

Đặt đoạn này bên trong <section rst-box><form rst-form>.

{{template "choice-field" dict
    "Legend" "Gửi cho tôi"
    "Name" "digest"
    "Type" "checkbox"
    "Options" (list
        (dict "Checked" true "Desc" "Ngay khi có." "Title" "Trả lời" "Value" "replies")
        (dict "Desc" "Sáng thứ Hai." "Title" "Bản tóm tắt hằng tuần" "Value" "weekly"))}}

form-foot

Hàng kết thúc của biểu mẫu: một nút gửi chính và một liên kết hủy tùy chọn. Hủy là một liên kết, vì rời khỏi biểu mẫu là chuyển trang.

Lưu và hủy

Xem trước

Đặt đoạn này bên trong <section rst-box><form rst-form>.

<div rst-form-foot>
  <button rst-btn="primary lg" type="submit">Lưu bài viết</button>
  <a rst-btn="lg" href="/posts">Quay lại bài viết</a>
</div>

Đặt đoạn này bên trong <section rst-box><form rst-form>.

{{template "form-foot" dict
    "Submit" "Lưu bài viết"
    "CancelHref" "/posts"
    "CancelLabel" "Quay lại bài viết"}}

Chỉ có nút gửi

Xem trước

Đặt đoạn này bên trong <section rst-box><form rst-form>.

<div rst-form-foot>
  <button rst-btn="primary lg" type="submit">Gửi lời mời</button>
</div>

Đặt đoạn này bên trong <section rst-box><form rst-form>.

{{template "form-foot" dict "Submit" "Gửi lời mời"}}

Nghỉ: nút trước khi có chuyện gì xảy ra

Xem trước

Đặt đoạn này bên trong <section rst-box><form rst-form>.

<div rst-form-foot>
  <button rst-btn="primary lg" type="submit">Xuất bản</button>
  <a rst-btn="lg" href="/posts">Quay lại bài viết</a>
</div>

Đặt đoạn này bên trong <section rst-box><form rst-form>.

{{template "form-foot" dict
    "Submit" "Xuất bản"
    "CancelHref" "/posts"
    "CancelLabel" "Quay lại bài viết"}}

Nút LÀM THAY ĐỔI điều gì đó sẽ có trạng thái đang tải; nút chỉ mở ra điều gì đó — một khối bung, một menu thả xuống, một tab — thì không. rastrillo.js áp dụng quy tắc đó cho mọi nút gửi trong mọi biểu mẫu, không có gì phải bật lên.

Đang xử lý: thứ rastrillo.js viết ra khi biểu mẫu rời đi

Xem trước

Đặt đoạn này bên trong <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>
    Xuất bản
  </button>
  <a rst-btn="lg" href="/posts">Quay lại bài viết</a>
</div>

Chỉ nút đã được bấm: mọi nút gửi khác trong biểu mẫu vẫn giữ nguyên name và value của mình, còn bản thân biểu mẫu được chặn khỏi lần gửi thứ hai. data-busy="false" để bỏ quy tắc, đặt trên biểu mẫu hoặc trên một nút; data-busy-label thay phần chữ. Tắt script thì không có gì trong số này xảy ra và biểu mẫu vẫn gửi đúng như trước, nên tính lũy đẳng vẫn là việc của máy chủ.

confirm-form

Hàng hành động của trang xác nhận. Hành động phá hủy có tuyến riêng chứ không phải một hộp thoại, nên chẳng có gì để viết kịch bản.

Hành động phá hủy

Xem trước

Đặt đoạn này bên trong <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">Hủy</a>
  <button type="submit" rst-btn="danger lg">Xóa bài viết này</button>
</form>

Đặt đoạn này bên trong <section rst-box>.

{{template "confirm-form" dict
    "Action" "/posts/1/delete"
    "Label" "Xóa bài viết này"
    "Danger" true
    "Hidden" (list (list "csrf" "tok-123") (list "id" "1"))
    "CancelHref" "/posts/1"}}

Trường hợp thường, chữ hủy theo mặc định

Xem trước

Đặt đoạn này bên trong <section rst-box>.

<form rst-form-actions method="post" action="/posts/1/publish">
  <a rst-btn="ghost lg" href="/posts/1">Hủy</a>
  <button type="submit" rst-btn="primary lg">Xuất bản</button>
</form>

Đặt đoạn này bên trong <section rst-box>.

{{template "confirm-form" dict
    "Action" "/posts/1/publish"
    "Label" "Xuất bản"
    "CancelHref" "/posts/1"}}

Không có CancelLabel, nên chữ trên liên kết hủy lấy từ danh mục.