Saya tahu bahwa XHTML tidak mendukung tag formulir bersarang dan saya sudah membaca jawaban lain di sini tentang Stack Overflow mengenai masalah ini, tapi saya masih belum menemukan solusi yang elegan untuk masalah ini.
Beberapa mengatakan Anda tidak membutuhkannya dan mereka tidak dapat memikirkan skenario jika ini diperlukan. Yah, secara pribadi saya tidak bisa memikirkan skenario yang saya tidak membutuhkannya.
Mari kita lihat contoh yang sangat sederhana:
Anda membuat aplikasi blog dan Anda memiliki formulir dengan beberapa bidang untuk membuat posting baru dan toolbar dengan "tindakan" seperti "Simpan", "Hapus", "Batalkan".
<form
action="/post/dispatch/too_bad_the_action_url_is_in_the_form_tag_even_though_conceptually_every_submit_button_inside_it_may_need_to_post_to_a_diffent_distinct_url"
method="post">
<input type="text" name="foo" /> <!-- several of those here -->
<div id="toolbar">
<input type="submit" name="save" value="Save" />
<input type="submit" name="delete" value="Delete" />
<a href="/home/index">Cancel</a>
</div>
</form>
Tujuan kami adalah menulis formulir dengan cara yang tidak memerlukan JavaScript , cukup formulir HTML lama dan kirim tombol.
Karena URL tindakan didefinisikan dalam tag Formulir dan bukan di setiap tombol kirim individual, satu-satunya pilihan kami adalah memposting ke URL umum dan kemudian mulai "jika ... lalu ... lain" untuk menentukan nama tombol yang telah diajukan. Tidak terlalu elegan, tetapi satu-satunya pilihan kami, karena kami tidak ingin bergantung pada JavaScript.
Satu-satunya masalah adalah bahwa menekan "Hapus", akan menyerahkan SEMUA bidang formulir di server meskipun satu-satunya hal yang diperlukan untuk tindakan ini adalah input tersembunyi dengan post-id. Bukan masalah besar dalam contoh kecil ini, tetapi saya memiliki formulir dengan ratusan (sehingga untuk berbicara) bidang dan tab di aplikasi LOB saya yang (karena persyaratan) harus menyerahkan semuanya dalam sekali jalan dan dalam hal apapun ini tampaknya sangat tidak efisien dan sia-sia. Jika form nesting didukung, setidaknya saya dapat membungkus tombol "Delete" di dalam form itu sendiri dengan hanya kolom post-id.
Anda dapat mengatakan "Cukup terapkan" Hapus "sebagai tautan alih-alih mengirim". Ini akan salah dalam banyak tingkatan, tetapi yang paling penting karena tindakan efek samping seperti "Hapus" di sini, seharusnya tidak pernah menjadi permintaan GET.
Jadi pertanyaan saya (terutama bagi mereka yang mengatakan mereka tidak perlu bersarang) adalah apa yang ANDA lakukan? Apakah ada solusi elegan yang saya lewatkan atau intinya adalah "Membutuhkan JavaScript atau mengirimkan semuanya"?
Jawaban:
Saya akan menerapkan ini persis seperti yang Anda jelaskan: kirimkan semuanya ke server dan lakukan sederhana jika / selain memeriksa tombol apa yang diklik.
Dan kemudian saya akan menerapkan panggilan Javascript yang mengikat ke acara onsub formulir yang akan memeriksa sebelum formulir dikirimkan, dan hanya mengirimkan data yang relevan ke server (mungkin melalui formulir kedua pada halaman dengan ID yang diperlukan untuk memproses hal itu sebagai input tersembunyi, atau me-refresh lokasi halaman dengan data yang Anda butuhkan diteruskan sebagai permintaan GET, atau melakukan posting Ajax ke server, atau ...).
Dengan cara ini orang-orang tanpa Javascript dapat menggunakan formulir dengan baik, tetapi beban server diimbangi karena orang-orang yang memiliki Javascript hanya mengirimkan satu bagian data yang diperlukan. Memfokuskan diri hanya dengan mendukung satu atau yang lain benar-benar membatasi pilihan Anda secara tidak perlu.
Atau, jika Anda bekerja di belakang firewall perusahaan atau sesuatu dan semua orang telah menonaktifkan Javascript, Anda mungkin ingin melakukan dua bentuk dan mengerjakan beberapa keajaiban CSS agar terlihat seperti tombol hapus adalah bagian dari formulir pertama.
sumber
Saya tahu ini adalah pertanyaan lama, tetapi HTML5 menawarkan beberapa opsi baru.
Yang pertama adalah memisahkan formulir dari bilah alat di markup, menambahkan formulir lain untuk tindakan hapus, dan mengaitkan tombol di bilah alat dengan formulir masing-masing menggunakan
form
atribut.Opsi ini cukup fleksibel, tetapi posting asli juga menyebutkan bahwa mungkin perlu melakukan tindakan yang berbeda dengan satu bentuk. HTML5 datang untuk menyelamatkan, lagi. Anda dapat menggunakan
formaction
atribut pada tombol kirim, sehingga tombol berbeda dalam bentuk yang sama dapat dikirimkan ke URL yang berbeda. Contoh ini hanya menambahkan metode klon ke bilah alat di luar formulir, tetapi akan berfungsi sama di dalam formulir.http://www.whatwg.org/specs/web-apps/current-work/#attributes-for-form-submission
Keuntungan dari fitur-fitur baru ini adalah bahwa mereka melakukan semua ini secara deklaratif tanpa JavaScript. Kerugiannya adalah mereka tidak didukung pada peramban yang lebih lama, jadi Anda harus melakukan beberapa pengisian untuk peramban yang lebih lama.
sumber
form=
itu - CanIUse tidak mengatakannya. caniuse.com/#feat=forms<input>
untuk mendeklarasikan tombol. yang<button>
unsur diperkenalkan 15 tahun yang lalu untuk tujuan ini. Sungguh orang.<input>
atau<button>
elemen tidak relevan, meskipun tombol biasanya lebih sesuai untuk bilah alat, seperti yang Anda katakan. Omong-omong, elemen tombol belum didukung oleh semua browser selama 15 tahun.Anda dapat memiliki formulir berdampingan di halaman, tetapi tidak bersarang. lalu gunakan CSS untuk membuat semua tombol berbaris cantik?
sumber
HTML5 memiliki gagasan "pemilik formulir" - atribut "formulir" untuk elemen input. Memungkinkan untuk meniru bentuk bersarang dan akan menyelesaikan masalah.
sumber
Agak topik lama, tapi yang ini mungkin berguna untuk seseorang:
Seperti seseorang yang disebutkan di atas - Anda dapat menggunakan formulir dummy. Saya harus mengatasi masalah ini beberapa waktu lalu. Pada awalnya saya benar-benar lupa tentang pembatasan HTML ini dan baru saja menambahkan formulir bersarang. Hasilnya menarik - saya kehilangan bentuk pertama saya dari sarang. Kemudian ternyata semacam "trik" untuk hanya menambahkan bentuk dummy (yang akan dihapus dari browser) sebelum bentuk bersarang yang sebenarnya.
Dalam kasus saya, tampilannya seperti ini:
Berfungsi baik dengan Chrome, FireFox dan Safari. IE hingga 9 (tidak yakin sekitar 10) dan Opera tidak mendeteksi parameter dalam bentuk utama. Global $ _REQUEST kosong, terlepas dari input apa pun. Bentuk batin tampaknya bekerja dengan baik di mana-mana.
Belum menguji saran lain yang dijelaskan di sini - fieldset di sekitar formulir bersarang.
EDIT : Frameset tidak berfungsi! Saya cukup menambahkan formulir Utama setelah yang lain (tidak ada lagi formulir bersarang) dan menggunakan "clone" jQuery untuk menduplikasi input dalam formulir pada klik tombol. Menambahkan .hide () ke masing-masing input yang dikloning agar tata letak tidak berubah dan sekarang berfungsi seperti pesona.
sumber
Saya pikir Jason benar. Jika tindakan "Hapus" Anda minimal, buatlah itu dalam bentuk dengan sendirinya, dan sejajarkan dengan tombol lain sehingga membuat antarmuka tampak seperti satu formulir yang disatukan, meskipun itu tidak.
Atau, tentu saja, mendesain ulang antarmuka Anda, dan biarkan orang menghapus tempat lain sama sekali yang tidak mengharuskan mereka untuk melihat bentuk luar biasa itu sama sekali.
sumber
Salah satu cara saya akan melakukan ini tanpa javascript adalah dengan menambahkan satu set tombol radio yang menentukan tindakan yang harus diambil:
Maka skrip tindakan akan mengambil tindakan berbeda tergantung pada nilai set tombol radio.
Cara lain adalah dengan meletakkan dua formulir pada halaman seperti yang Anda sarankan, hanya saja tidak bersarang. Tata letak mungkin sulit dikendalikan:
Menggunakan bidang "tugas" tersembunyi di skrip penanganan untuk bercabang dengan tepat.
sumber
Diskusi ini masih menarik bagi saya. Di belakang pos asli adalah "persyaratan" yang OP bagikan - yaitu formulir dengan kompatibilitas ke belakang. Sebagai seseorang yang karyanya pada saat penulisan terkadang harus mendukung kembali ke IE6 (dan selama bertahun-tahun yang akan datang), saya menggali itu.
Tanpa mendorong kerangka kerja (semua organisasi akan ingin meyakinkan diri mereka tentang kompatibilitas / ketahanan, dan saya tidak menggunakan diskusi ini sebagai pembenaran untuk kerangka kerja), solusi Drupal untuk masalah ini menarik. Drupal juga relevan secara langsung karena kerangka kerja telah memiliki kebijakan lama "itu harus bekerja tanpa Javascript (hanya jika Anda mau)" yaitu masalah OP.
Drupal menggunakan fungsi form.inc yang agak luas untuk menemukan triggering_element (ya, itulah nama dalam kode). Lihat bagian bawah kode yang tercantum pada halaman API untuk form_builder (jika Anda ingin menggali lebih detail, sumber direkomendasikan - drupal-x.xx / include / form.inc ). Builder menggunakan pembuatan atribut HTML otomatis dan, melalui itu, dapat kembali mendeteksi tombol mana yang ditekan, dan bertindak sesuai (ini dapat diatur untuk menjalankan proses terpisah juga).
Di luar pembuat formulir, Drupal membagi tindakan 'hapus' data menjadi url / formulir terpisah, kemungkinan karena alasan yang disebutkan dalam pos asli. Ini membutuhkan semacam langkah pencarian / daftar ( erang bentuk lain!, Tetapi mudah digunakan) sebagai awal. Tetapi ini memiliki keuntungan menghilangkan masalah "serahkan semuanya". Bentuk besar dengan data digunakan untuk tujuan yang dimaksudkan, pembuatan / pembaruan data (atau bahkan tindakan 'penggabungan').
Dengan kata lain, salah satu cara mengatasi masalah adalah dengan membagi formulir menjadi dua, kemudian masalahnya hilang (dan metode HTML juga dapat diperbaiki melalui POST).
sumber
Gunakan
iframe
untuk formulir bersarang. Jika mereka perlu berbagi bidang, maka ... itu tidak benar-benar bersarang.sumber
Solusi saya adalah memiliki tombol memanggil fungsi JS yang menulis dan kemudian mengirimkan formulir dengan formulir utama
sumber
Jika Anda benar-benar tidak ingin menggunakan banyak formulir (seperti saran Jason), maka gunakan tombol dan penangan onclick.
Dan kemudian di javascript (saya menggunakan jQuery di sini untuk kemudahan) (walaupun itu cukup berlebihan untuk menambahkan beberapa penangan onclick)
Saya juga tahu, ini akan membuat setengah halaman tidak berfungsi tanpa javascript.
sumber
Menanggapi pertanyaan yang diposting oleh Yar dalam komentar atas jawabannya sendiri, saya sajikan beberapa JavaScript yang akan mengubah ukuran iframe. Untuk kasus tombol formulir, aman untuk menganggap iframe akan berada di domain yang sama. Ini adalah kode yang saya gunakan. Anda harus mengubah matematika / konstanta untuk situs Anda sendiri:
Kemudian panggil seperti ini:
sumber
Saya baru saja datang dengan cara yang baik untuk melakukannya dengan jquery.
sumber
Nah, jika Anda mengirimkan formulir, browser juga mengirimkan input nama dan nilai pengiriman. Jadi yang bisa Anda lakukan adalah
jadi di sisi server Anda hanya mencari parameter yang memulai string lebar "action:" dan sisanya memberi tahu Anda tindakan apa yang harus diambil
jadi ketika Anda mengklik tombol Save browser mengirimi Anda sesuatu seperti foo = asd & action: save = Save
sumber
Saya mengatasi masalah dengan memasukkan kotak centang tergantung pada bentuk apa yang ingin dilakukan orang tersebut. Kemudian digunakan 1 tombol untuk mengirimkan seluruh formulir.
sumber
Sebagai alternatif, Anda dapat menetapkan formulir actiob dengan cepat ... mungkin bukan solusi terbaik, tetapi tentu saja meringankan logika sisi server ...
sumber