Perpustakaan Clojurescript untuk menyediakan binding data formulir untuk reagen, lihat di sini untuk demo langsung.
Perpustakaan menggunakan atom reagen sebagai toko dokumen. Komponen terikat pada dokumen menggunakan atribut :field . Kunci ini akan digunakan untuk memutuskan bagaimana jenis komponen tertentu harus diikat. Komponen juga harus memberikan atribut yang unik :id yang digunakan untuk mengkorelasikannya dengan dokumen. Sementara perpustakaan diarahkan untuk penggunaan dengan Bootstrap Twitter, itu cukup agnostik tentang jenis komponen yang Anda buat.
ID :id dapat menjadi kata kunci, misalnya: {:id :foo} , atau jalur kata kunci {:id :foo.bar} yang akan memetakan ke {:foo {:bar "value"}} . Atau, Anda dapat menentukan jalur vektor secara eksplisit [:foo 0 :bar] .
Secara default nilai komponen adalah bidang dokumen, namun semua komponen mendukung atribut fungsi :in-fn dan :out-fn . :in-fn menerima nilai dokumen saat ini dan mengembalikan apa yang akan ditampilkan dalam komponen. :out-fn menerima nilai komponen dan mengembalikan apa yang akan disimpan dalam dokumen.
Jenis -jenis bidang berikut didukung di luar kotak:
Bidang input dapat dari tipe :text , :numeric , :range , :password , :email , dan :textarea . Input berperilaku seperti input HTML reguler dan memperbarui status dokumen ketika :on-change dipicu.
[ :input.form-control { :field :text :id :first-name }]
[ :input.form-control { :field :numeric :id :age }] Bidang input dapat memiliki atribut opsional :fmt yang dapat memberikan string format untuk nilai:
[ :input.form-control
{ :field :numeric :fmt " %.2f " :id :bmi :disabled true }]Input Numerik Atribut Dukungan untuk Input Nomor HTML 5:
[ :input
{ :field :numeric
:id :volume
:fmt " %.2f "
:step " 0.1 "
:min 0
:max 10 }] Bidang TypeaHead menggunakan kunci :data-source yang terikat ke fungsi yang mengambil input saat ini dan mengembalikan daftar hasil yang cocok. Kontrol menggunakan elemen input untuk menangani input pengguna dan menjadikan daftar pilihan sebagai elemen daftar yang tidak dipesan yang berisi satu atau lebih elemen item daftar. Pengguna dapat menentukan kelas CSS yang digunakan untuk membuat masing-masing elemen ini menggunakan Keys: Input-Class ,: List-Class dan: Item-Class. Pengguna juga dapat menentukan kelas CSS untuk menangani penyorotan pilihan saat ini dengan: kunci kelas sorotan. Referensi Kelas CSS termasuk dalam file Sumber Daya/Publik/CSS/Reagen-Forms.css.
( defn friend-source [text]
( filter
#( -> % ( .toLowerCase %) ( .indexOf text) ( > -1 ))
[ " Alice " " Alan " " Bob " " Beth " " Jim " " Jane " " Kim " " Rob " " Zoe " ]))
[ :div { :field :typeahead
:id :ta
:input-placeholder " pick a friend "
:data-source friend-source
:input-class " form-control "
:list-class " typeahead-list "
:item-class " typeahead-item "
:highlight-class " highlighted " }]Bidang Typeahead mendukung pilihan mouse dan keyboard.
Anda dapat membuat nilai input yang ditampilkan berbeda dengan nilai yang disimpan dalam dokumen. Anda perlu menentukan :out-fn , a :result-fn dan opsional :in-fn . :data-source perlu mengembalikan vektor [display-value stored-value] .
( defn people-source [people]
( fn [text]
( ->> people
( filter #( -> ( :name %)
( .toLowerCase )
( .indexOf text)
( > -1 )))
( mapv #( vector ( :name %) ( :num %))))))
[ :div { :field :typeahead
:data-source ( people-source people)
:in-fn ( fn [num]
[( :name ( first ( filter #( = num ( :num %)) people))) num])
:out-fn ( fn [[name num]] num)
:result-fn ( fn [[name num]] name)
:id :author.num }]]] JIKA :data-source merespons dengan daftar opsi lengkap saat melewati kata kunci :all kemudian tombol arrow down-arrow akan menampilkan daftar.
Atribut :selections dapat ditentukan untuk melewati atom yang digunakan untuk menahan pilihan. Ini memberikan opsi untuk mengambil daftar menggunakan teks Typeahead - jika penangan respons AJAX mengatur atom, daftar akan mampir.
Jika disediakan, fungsi :get-index akan memastikan item yang dipilih disorot saat daftar muncul.
Contoh lengkap tersedia dalam kode sumber untuk halaman demonstrasi.
Bidang kotak centang membuat elemen kotak centang:
[ :div.row
[ :div.col-md-2 " does data binding make you happy? " ]
[ :div.col-md-5
[ :input.form-control { :field :checkbox :id :happy-bindings }]]] Kotak centang menerima Atribut Opsional :checked . Saat mengatur kotak centang akan dipilih dan jalur dokumen yang ditunjuk oleh :id akan diatur ke true .
[ :div.row
[ :div.col-md-2 " does data binding make you happy? " ]
[ :div.col-md-5
[ :input.form-control { :field :checkbox :id :happy-bindings :checked true }]]] Kontrol rentang menggunakan tombol :min dan :max untuk membuat input rentang html:
[ :input.form-control
{ :field :range :min 10 :max 100 :id :some-range }] Tombol radio tidak menggunakan tombol :id karena harus unik dan sebaliknya dikelompokkan menggunakan atribut :name . Atribut :value digunakan untuk menunjukkan nilai yang disimpan ke dokumen:
[ :input { :field :radio :value :a :name :radioselection }]
[ :input { :field :radio :value :b :name :radioselection }]
[ :input { :field :radio :value :c :name :radioselection }] Tombol Radio menerima Atribut Opsional :checked . Saat mengatur kotak centang akan dipilih dan jalur dokumen yang diarahkan oleh :name akan diatur ke true .
[ :input { :field :radio :value :a :name :radioselection }]
[ :input { :field :radio :value :b :name :radioselection :checked true }]
[ :input { :field :radio :value :c :name :radioselection }] Bidang file mengikat objek File dari <input type="file"/> .
[ :input { :field :file :type :file }] Sama seperti file, kecuali berfungsi dengan <input type="file" multiple/> dan mengikat seluruh objek FileList .
[ :input { :field :files :type :file :multiple true }] Daftar bidang berisi elemen anak yang nilainya diisi dalam dokumen ketika dipilih. Elemen anak masing -masing harus memiliki :key yang menunjuk pada nilai yang akan disimpan dalam dokumen. Nilai elemen harus menjadi kata kunci.
Elemen dapat memiliki opsional :visible? kata kunci yang menunjuk ke fungsi predikat. Fungsi harus menerima dokumen dan mengembalikan nilai boolean yang menunjukkan apakah bidang harus ditampilkan.
Bidang :list digunakan untuk membuat elemen select HTML yang berisi option elemen anak:
[ :select.form-control { :field :list :id :many-options }
[ :option { :key :foo } " foo " ]
[ :option { :key :bar } " bar " ]
[ :option { :key :baz } " baz " ]]
( def months
[ " January " " February " " March " " April " " May " " June "
" July " " August " " September " " October " " November " " December " ])
[ :select { :field :list :id :dob.day }
( for [i ( range 1 32 )]
[ :option
{ :key ( keyword ( str i))
:visible? #( let [month ( get-in % [ :dob :month ])]
( cond
( < i 29 ) true
( < i 31 ) ( not= month :February )
( = i 31 ) ( some #{month} [ :January :March :May :July :August :October :December ])
:else false ))}
i])]
[ :select { :field :list :id :dob.month }
( for [month months]
[ :option { :key ( keyword month)} month])]
[ :select { :field :list :id :dob.year }
( for [i ( range 1950 ( inc ( .getFullYear ( js/Date. ))))]
[ :option { :key ( keyword ( str i))} i])]Bidang terpilih tunggal berperilaku seperti daftar, tetapi mendukung berbagai jenis elemen dan memungkinkan bidang untuk dipilih:
[ :h3 " single-select buttons " ]
[ :div.btn-group { :field :single-select :id :unique-position }
[ :button.btn.btn-default { :key :left } " Left " ]
[ :button.btn.btn-default { :key :middle } " Middle " ]
[ :button.btn.btn-default { :key :right } " Right " ]]
[ :h3 " single-select list " ]
[ :ul.list-group { :field :single-select :id :pick-one }
[ :li.list-group-item { :key :foo } " foo " ]
[ :li.list-group-item { :key :bar } " bar " ]
[ :li.list-group-item { :key :baz } " baz " ]]Bidang multi-select memungkinkan beberapa nilai dipilih dan diatur dalam dokumen:
[ :h3 " multi-select list " ]
[ :div.btn-group { :field :multi-select :id :position }
[ :button.btn.btn-default { :key :left } " Left " ]
[ :button.btn.btn-default { :key :middle } " Middle " ]
[ :button.btn.btn-default { :key :right } " Right " ]] Label dapat dikaitkan dengan kunci dalam dokumen menggunakan atribut :id dan akan menampilkan nilai pada tombol itu. Lables dapat memiliki opsional :preamble dan :postamble dengan teks yang akan diberikan sebelum dan sesudah nilai masing -masing. Nilai juga dapat ditafsirkan menggunakan fungsi formatter yang ditetapkan untuk tombol :fmt . The :placeholder Key dapat digunakan untuk menyediakan teks yang akan ditampilkan tanpa adanya nilai:
[ :label { :field :label :id :volume }]
[ :label { :field :label :preamble " the value is: " :id :volume }]
[ :label { :field :label :preamble " the value is: " :postamble " ml " :id :volume }]
[ :label { :field :label :preamble " the value is: " :postamble " ml " :placeholder " N/A " :id :volume }]
[ :label { :field :label :preamble " the value is: " :id :volume :fmt ( fn [v] ( if v ( str v " ml " ) " unknown " )}] Lansiran terikat pada ID bidang yang memicu peringatan dan dapat memiliki kunci opsional :event . Kunci acara harus menunjuk ke fungsi yang mengembalikan nilai boolean.
Opsional :closeable? true/false dapat disediakan untuk mengontrol jika tombol tutup harus diterjemahkan (default ke true).
Ketika suatu peristiwa disediakan maka badan peringatan diberikan setiap kali acara kembali benar:
[ :input { :field :text :id :first-name }]
[ :div.alert.alert-success { :field :alert :id :last-name :event empty?} " first name is empty! " ]Ketika tidak ada acara yang disediakan, maka peringatan ditampilkan setiap kali nilai di ID tidak kosong dan menampilkan nilainya:
( def doc ( atom {}))
; ;define an alert that watches the `:errors.first-name` key for errors
[ :div.alert.alert-danger { :field :alert :id :errors.first-name }]
; ;trigger the alert by setting the error key
[ :button.btn.btn-default
{ :on-click
#( if ( empty? ( :first-name @doc))
( swap! doc assoc-in [ :errors :first-name ] " first name is empty! " ))}
" save " ][ :div { :field :datepicker :id :birthday :date-format " yyyy/mm/dd " :inline true }]Tanggal disimpan dalam dokumen menggunakan format berikut:
{ :year 2014 :month 11 :day 24 } DatePicker juga dapat mengambil opsional :auto-close? Kunci untuk menunjukkan bahwa itu harus ditutup ketika hari diklik. Ini default ke false .
Format tanggal dapat diatur menggunakan :date-format :
{ :field :datepicker :id :date :date-format " yyyy/mm/dd " } :date-format juga dapat menunjuk ke fungsi yang mengembalikan tanggal yang diformat:
{ :field :datepicker
:id :date
:date-format ( fn [{ :keys [year month day]}] ( str year " / " month " / " day))} Di atas berguna dalam hubungannya dengan :save-fn yang memungkinkan Anda menyediakan fungsi khusus untuk menyimpan nilai. Misalnya, jika Anda ingin menggunakan objek tanggal JavaScript, Anda dapat melakukan hal berikut:
[ :div.input-group.date.datepicker.clickable
{ :field :datepicker
:id :reminder
:date-format ( fn [date]
( str ( .getDate date) " / "
( inc ( .getMonth date)) " / "
( .getFullYear date)))
:save-fn ( fn [current-date { :keys [year month day]}]
( if current-date
( doto ( js/Date. )
( .setFullYear year)
( .setMonth ( dec month))
( .setDate day)
( .setHours ( .getHours current-date))
( .setMinutes ( .getMinutes current-date)))
( js/Date. year ( dec month) day)))
:auto-close? true }]Perhatikan bahwa Anda perlu mengembalikan objek tanggal baru dalam pembaruan untuk komponen untuk mengecat ulang.
DatePicker mengambil opsional :lang yang dapat Anda gunakan untuk mengatur lokasi datepicker. Saat ini ada bahasa Inggris, Rusia, Jerman, Prancis, Spanyol, Portugis, Finlandia dan Belanda yang dibangun dalam terjemahan. Untuk menggunakan lulus bahasa bawaan di :lang dengan kata kunci seperti pada tabel berikut:
| Bahasa | Kata kunci |
|---|---|
| Bahasa inggris | :en-US (default) |
| Rusia | :ru-RU |
| Jerman | :de-DE |
| Perancis | :fr-FR |
| Spanyol | :es-ES |
| Portugis | :pt-PT |
| Finlandia | :fi-FI |
| Belanda | :nl-NL |
Contoh penggunaan lokal bahasa bawaan:
{ :field :datepicker :id :date :date-format " yyyy/mm/dd " :inline true :lang :ru-RU } Anda juga dapat memberikan peta hash lokal khusus untuk datepicker. :first-day menandai hari pertama dalam seminggu mulai dari hari Minggu sebagai 0. Semua kunci harus ditentukan.
Contoh menggunakan peta hash lokal khusus:
{ :field :datepicker :id :date :date-format " yyyy/mm/dd " :inline true :lang
{ :days [ " First " " Second " " Third " " Fourth " " Fifth " " Sixth " " Seventh " ]
:days-short [ " 1st " " 2nd " " 3rd " " 4th " " 5th " " 6th " " 7th " ]
:months [ " Month-one " " Month-two " " Month-three " " Month-four " " Month-five " " Month-six "
" Month-seven " " Month-eight " " Month-nine " " Month-ten " " Month-eleven " " Month-twelve " ]
:months-short [ " M1 " " M2 " " M3 " " M4 " " M5 " " M6 " " M7 " " M8 " " M9 " " M10 " " M11 " " M12 " ]
:first-day 0 }} DatePicker membutuhkan CSS tambahan agar dapat diterjemahkan dengan benar. CSS default disediakan dalam reagent-forms.css di jalur sumber daya. Cukup pastikan itu termasuk di halaman. File dapat dibaca menggunakan:
( -> " reagent-forms.css " clojure.java.io/resource slurp)Elemen wadah dapat digunakan untuk mengelompokkan elemen yang berbeda. Wadah dapat digunakan untuk mengatur visibilitas beberapa elemen.
[ :div.form-group
{ :field :container
:visible? #( :show-name? %)}
[ :input { :field :text :id :first-name }]
[ :input { :field :text :id :last-name }]] Fungsi validator dapat dilampirkan ke komponen menggunakan kata kunci :validator . Fungsi ini menerima keadaan dokumen saat ini, dan mengembalikan koleksi kelas yang akan ditambahkan ke elemen:
[ :input
{ :field :text
:id :person.name.first
:validator ( fn [doc]
( when ( -> doc :person :name :first empty?)
[ " error " ]))}] Komponen dapat memasok opsional :visible? Kunci dalam atribut mereka yang menunjuk pada fungsi keputusan. Fungsi ini diharapkan mengambil nilai saat ini dari dokumen dan menghasilkan nilai kebenaran yang akan digunakan untuk memutuskan apakah komponen tersebut harus diterjemahkan, misalnya:
( def form
[ :div
[ :input { :field :text
:id :foo }]
[ :input { :field :text
:visible? ( fn [doc] ( empty? ( :foo doc)))
:id :bar }]]) Kunci :set-attributes dapat digunakan dalam kasus di mana Anda perlu melakukan pembaruan sewenang-wenang pada atribut komponen. Kunci harus menunjuk ke fungsi yang menerima nilai saat ini dari dokumen dan peta atribut untuk komponen. Fungsi harus mengembalikan peta atribut yang diperbarui:
[ :div
[ :input { :field :text
:id :person.name.first
:validator ( fn [doc]
( when ( = " Bob " ( -> doc :person :name :first ))
[ " error " ]))}]
[ :input { :field :text
:id :person.name.last
:set-attributes ( fn [doc attrs]
( assoc attrs :disabled ( = " Bob " ( -> doc :person :name :first ))))}]]Contoh di atas menonaktifkan input nama belakang ketika nilai input nama depan adalah "Bob".
Komponen lapangan berperilaku seperti komponen reagen lainnya dan dapat dicampur dengan mereka secara bebas. Contoh formulir lengkap dapat dilihat di bawah.
Elemen bentuk dapat terikat pada struktur bersarang dengan menggunakan . sebagai pemisah jalur. Misalnya, komponen berikut [:input {:field :text :id :person.first-name}] mengikat ke jalur berikut dalam atom status {:person {:first-name <field-value>}}
( defn row [label input]
[ :div.row
[ :div.col-md-2 [ :label label]]
[ :div.col-md-5 input]])
( def form-template
[ :div
( row " first name " [ :input { :field :text :id :first-name }])
( row " last name " [ :input { :field :text :id :last-name }])
( row " age " [ :input { :field :numeric :id :age }])
( row " email " [ :input { :field :email :id :email }])
( row " comments " [ :textarea { :field :textarea :id :comments }])])catatan penting
Template dievaluasi dengan penuh semangat, dan Anda harus selalu memanggil fungsi penolong seperti pada contoh di atas alih -alih menempatkannya di vektor. Ini akan digantikan oleh komponen reagen ketika bind-fields dipanggil untuk mengkompilasi templat.
Setelah templat formulir dibuat, ia dapat terikat pada dokumen menggunakan fungsi bind-fields :
( ns myform.core
( :require [reagent-forms.core :refer [bind-fields]]
[reagent.core :as r]))
( defn form []
( let [doc ( r/atom {})]
( fn []
[ :div
[ :div.page-header [ :h1 " Reagent Form " ]]
[bind-fields form-template doc]
[ :label ( str @doc)]])))
( reagent/render-component [form] ( .getElementById js/document " container " ))Formulir dapat diinisialisasi dengan dokumen berpenduduk, dan bidang akan diinisialisasi dengan nilai -nilai yang ditemukan di sana:
( def form-template
[ :div
( row " first name "
[ :input.form-control { :field :text :id :first-name }])
( row " last name "
[ :input.form-control { :field :text :id :last-name }])
( row " age "
[ :input.form-control { :field :numeric :id :age }])
( row " email "
[ :input.form-control { :field :email :id :email }])
( row " comments "
[ :textarea.form-control { :field :textarea :id :comments }])])
( defn form []
( let [doc ( atom { :first-name " John " :last-name " Doe " :age 35 })]
( fn []
[ :div
[ :div.page-header [ :h1 " Reagent Form " ]]
[bind-fields form-template doc]
[ :label ( str @doc)]]))) Fungsi bind-fields menerima acara opsional. Acara dipicu setiap kali dokumen diperbarui, dan akan dieksekusi dalam urutan terdaftar. Setiap acara melihat dokumen dimodifikasi oleh pendahulunya.
Acara harus mengambil 3 parameter, yang merupakan id , path , value , dan document . id cocok dengan :id bidang, path adalah jalur bidang dalam dokumen, value mewakili nilai yang diubah dalam formulir, dan dokumen berisi keadaan formulir. Acara ini dapat mengembalikan dokumen yang diperbarui atau nil , ketika nil dikembalikan maka keadaan dokumen tidak dimodifikasi.
Berikut ini adalah contoh dari suatu peristiwa untuk menghitung nilai tombol :bmi ketika tombol :weight dan :height diisi:
( defn row [label input]
[ :div.row
[ :div.col-md-2 [ :label label]]
[ :div.col-md-5 input]])
( def form-template
[ :div
[ :h3 " BMI Calculator " ]
( row " Height " [ :input { :field :numeric :id :height }])
( row " Weight " [ :input { :field :numeric :id :weight }])
( row " BMI " [ :input { :field :numeric :id :bmi :disabled true }])])
[bind-fields
form-template
doc
( fn [id path value { :keys [weight height] :as doc}]
( when ( and ( some #{id} [ :height :weight ]) weight height)
( assoc-in doc [ :bmi ] ( / weight ( * height height)))))] Anda dapat memberikan peta khusus fungsi acara untuk bind-fields untuk menggunakan bentuk reagen dengan perpustakaan seperti re-frame . Dalam hal ini, bentuk reagen tidak akan memiliki keadaan internal dan fungsi yang disediakan oleh Anda akan digunakan untuk mendapatkan, menyimpan, dan memperbarui nilai bidang. Inilah contohnya:
( ns foo.bar
( :require [re-frame.core :as re-frame]
[reagent-forms.core :refer [bind-fields]]))
; re-frame events
( re-frame/reg-event-db
:init
( fn [_ _]
{ :doc {}}))
( re-frame/reg-sub
:doc
( fn [db _]
( :doc db)))
( re-frame/reg-sub
:value
:<- [ :doc ]
( fn [doc [_ path]]
( get-in doc path)))
( re-frame/reg-event-db
:set-value
( fn [db [_ path value]]
( assoc-in db ( into [ :doc ] path) value)))
( re-frame/reg-event-db
:update-value
( fn [db [_ f path value]]
( update-in db ( into [ :doc ] path) f value)))
; Functions that will be called by each individual form field with an id and a value
( def events
{ :get ( fn [path] @( re-frame/subscribe [ :value path]))
:save! ( fn [path value] ( re-frame/dispatch [ :set-value path value]))
:update! ( fn [path save-fn value]
; save-fn should accept two arguments: old-value, new-value
( re-frame/dispatch [ :update-value save-fn path value]))
:doc ( fn [] @( re-frame/subscribe [ :doc ]))})
; bind-fields called with a form and a map of custom events
( defn foo
[]
[bind-fields
[ :div
[ :input { :field :text
:id :person.name.first
:valid? ( fn [doc]
( when ( = " Bob " ( -> doc :person :name :first ))
[ " error " ]))}]
[ :input { :field :text
:id :person.name.last }]]
events])Visibilitas elemen dapat ditetapkan dengan memberikan ID dalam dokumen yang akan diperlakukan sebagai nilai kebenaran, atau fungsi:
( re-frame/reg-event-db
:toggle-foo
( fn [db _]
( update-in db [ :doc :foo ] not)))
( re-frame/reg-sub
:bar-visible?
( fn [db _]
( :bar db)))
( re-frame/reg-event-db
:toggle-bar
( fn [db _]
( update db :bar not)))
( def form
[ :div
[ :input { :field :text
:id :foo-input
:visible? :foo }]
[ :input { :field :text
:id :bar-input
:visible? ( fn [doc] @( re-frame/subscribe [ :bar-visible? ]))}]
( defn page
[]
[ :div
[bind-fields
[ :input { :field :text
:id :foo-input
:visible? :foo-input-visible? }]
event-fns]
[ :button
{ :on-click #( re-frame/dispatch [ :toggle-foo ])}
" toggle foo " ]
[ :button
{ :on-click #( re-frame/dispatch [ :toggle-bar ])}
" toggle bar " ]])Jika Anda menggunakan bingkai ulang, maka Anda disarankan untuk menggunakan acara frame untuk memicu perhitungan ulang bidang dalam bentuk. Misalnya, mari kita lihat bidang BMI yang dihitung:
( re-frame/reg-sub
:value
:<- [ :doc ]
( fn [doc [_ path]]
( get-in doc path)))
( defn bmi [{ :keys [weight height] :as doc}]
( assoc doc :bmi ( / weight ( * height height))))
( defmulti rule ( fn [_ path _] path))
( defmethod rule [ :height ] [doc path value]
( bmi doc))
( defmethod rule [ :weight ] [doc path value]
( bmi doc))
( defmethod rule :default [doc path value]
doc )
( re-frame/reg-event-db
:set-value
( fn [{ :keys [doc] :as db} [_ path value]]
( -> db
( assoc-in ( into [ :doc ] path) value)
( update :doc rule path value))))
( def events
{ :get ( fn [path] @( re-frame/subscribe [ :value path]))
:save! ( fn [path value] ( re-frame/dispatch [ :set-value path value]))
:doc ( fn [] @( re-frame/subscribe [ :doc ]))})
( defn row [label input]
[ :div
[ :div [ :label label]]
[ :div input]])
( def form-template
[ :div
[ :h3 " BMI Calculator " ]
( row " Height " [ :input { :field :numeric :id :height }])
( row " Weight " [ :input { :field :numeric :id :weight }])
( row " BMI " [ :label { :field :label :id :bmi }])])
( defn home-page []
[ :div
[ :h2 " BMI example " ]
[bind-fields form-template events]]) rule Multiemthod akan dipicu ketika :set-value dipanggil, dan itu akan menghitung BMI kapan saja ketinggian atau beratnya diperbarui.
Bidang khusus dapat ditambahkan dengan mengimplementasikan reagent-forms.core/init-field multimethod. Metode harus mengambil dua parameter, di mana parameter pertama adalah komponen bidang dan yang kedua adalah opsi.
Secara default opsi akan berisi get dan save! , dan update! kunci. Poin Kunci get ke fungsi yang menerima ID dan mengembalikan nilai dokumen yang terkait dengannya. Simpan save! Fungsi menerima ID dan nilai yang akan dikaitkan dengannya. update! Fungsi menerima ID, fungsi yang akan menangani pembaruan, dan nilainya. Fungsi penanganan pembaruan akan menerima nilai -nilai lama dan baru.
Adaptor dapat disediakan untuk bidang untuk membuat format penyimpanan khusus untuk nilai lapangan. Ini adalah sepasang fungsi yang diteruskan ke lapangan melalui tombol :in-fn dan :out-fn . :in-fn memodifikasi item yang disimpan sehingga bidang dapat memanfaatkannya sementara :out-fn memodifikasi output bidang sebelum disimpan. Misalnya, untuk menggunakan objek js/Date asli sebagai format penyimpanan, datepicker dapat diinisialisasi dengan demikian:
[ :div { :field :datepicker :id :birthday :date-format " yyyy/mm/dd " :inline true
:in-fn #( when % { :year ( .getFullYear %) :month ( .getMonth %) :day ( .getDate %)})
:out-fn #( when % ( js/Date ( :year %) ( :month %) ( :day %)))}]Adaptor dapat dilewati nol sehingga mereka harus dapat menanganinya.
Safari di iOS akan memiliki penundaan 300ms untuk :on-click , dimungkinkan untuk mengatur acara pemicu khusus menggunakan :touch-event . Lihat di sini untuk daftar acara yang tersedia di React. Misalnya, jika kami ingin menggunakan :on-touch-start bukan :on-click untuk memicu acara maka kami dapat melakukan hal berikut:
[ :input.form-control { :field :text :id :first-name :touch-event :on-touch-start }] Perhatikan bahwa Anda juga harus mengatur gaya cursor: pointer untuk setiap elemen selain tombol agar acara berfungsi di iOS.
Tapeventplugin untuk React adalah opsi lain untuk membuat peristiwa responsif, sampai fungsionalitas tersedia di React sendiri.
Proyek ini menggunakan Doo untuk menjalankan tes. Anda harus menginstal salah satu lingkungan yang didukung Doo, merujuk ke dokumen untuk detailnya. Untuk menjalankan tes, misalnya menggunakan Phantom, lakukan:
lein doo slimer test
Hak Cipta © 2018 Dmitri Sotnikov
Didistribusikan di bawah Lisensi Publik Eclipse Versi 1.0 atau (atas opsi Anda) versi selanjutnya.