Adding radio and checkbox groups to formlets
This commit is contained in:
parent
4271fe4231
commit
ef1278d6e1
|
@ -259,13 +259,67 @@
|
||||||
(cons #"input_0" #"value"))
|
(cons #"input_0" #"value"))
|
||||||
(test-equal? "radio"
|
(test-equal? "radio"
|
||||||
(test-display (radio #"start" #t))
|
(test-display (radio #"start" #t))
|
||||||
'((input ((name "input_0") (type "radio") (checked "true")))))
|
'((input ((name "input_0") (type "radio") (value "start") (checked "true")))))
|
||||||
(test-equal? "radio"
|
(test-equal? "radio"
|
||||||
(test-display (radio #"start" #f))
|
(test-display (radio #"start" #f))
|
||||||
'((input ((name "input_0") (type "radio")))))
|
'((input ((name "input_0") (type "radio") (value "start")))))
|
||||||
(test-equal? "radio"
|
(test-equal? "radio"
|
||||||
(test-display (radio #"start" #t #:attributes '([test "Test"])))
|
(test-display (radio #"start" #t #:attributes '([test "Test"])))
|
||||||
'((input ((name "input_0") (type "radio") (checked "true") (test "Test")))))
|
'((input ((name "input_0") (type "radio") (value "start") (checked "true") (test "Test")))))
|
||||||
|
|
||||||
|
; radio-group
|
||||||
|
(test-equal? "radio-group"
|
||||||
|
(test-process (radio-group (list "1" "2" "3"))
|
||||||
|
(list (make-binding:form #"input_0" #"0")))
|
||||||
|
"1")
|
||||||
|
(test-equal? "radio-group"
|
||||||
|
(test-process (radio-group (list 1 2 3) #:display number->string)
|
||||||
|
(list (make-binding:form #"input_0" #"0")))
|
||||||
|
1)
|
||||||
|
(test-equal? "radio-group"
|
||||||
|
(test-process (radio-group (list 1 2 3) #:display number->string)
|
||||||
|
(list (make-binding:form #"input_0" #"0")
|
||||||
|
(make-binding:form #"input_0" #"1")))
|
||||||
|
1)
|
||||||
|
(test-equal? "radio-group"
|
||||||
|
(test-display (radio-group
|
||||||
|
(list 1 2 3)
|
||||||
|
#:display number->string
|
||||||
|
#:checked? even?
|
||||||
|
#:attributes (λ (e) (list (list 'plus-one (number->string (add1 e)))))))
|
||||||
|
'((input ((name "input_0") (type "radio") (value "0") (plus-one "2")))
|
||||||
|
"1"
|
||||||
|
(input ((name "input_0") (type "radio") (value "1") (checked "true") (plus-one "3")))
|
||||||
|
"2"
|
||||||
|
(input ((name "input_0") (type "radio") (value "2") (plus-one "4")))
|
||||||
|
"3"))
|
||||||
|
|
||||||
|
; checkbox-group
|
||||||
|
(test-equal? "checkbox-group"
|
||||||
|
(test-process (checkbox-group (list "1" "2" "3"))
|
||||||
|
(list (make-binding:form #"input_0" #"0")))
|
||||||
|
(list "1"))
|
||||||
|
(test-equal? "checkbox-group"
|
||||||
|
(test-process (checkbox-group (list 1 2 3) #:display number->string)
|
||||||
|
(list (make-binding:form #"input_0" #"0")))
|
||||||
|
(list 1))
|
||||||
|
(test-equal? "checkbox-group"
|
||||||
|
(test-process (checkbox-group (list 1 2 3) #:display number->string)
|
||||||
|
(list (make-binding:form #"input_0" #"0")
|
||||||
|
(make-binding:form #"input_0" #"1")))
|
||||||
|
(list 1 2))
|
||||||
|
(test-equal? "checkbox-group"
|
||||||
|
(test-display (checkbox-group
|
||||||
|
(list 1 2 3)
|
||||||
|
#:display number->string
|
||||||
|
#:checked? even?
|
||||||
|
#:attributes (λ (e) (list (list 'plus-one (number->string (add1 e)))))))
|
||||||
|
'((input ((name "input_0") (type "checkbox") (value "0") (plus-one "2")))
|
||||||
|
"1"
|
||||||
|
(input ((name "input_0") (type "checkbox") (value "1") (checked "true") (plus-one "3")))
|
||||||
|
"2"
|
||||||
|
(input ((name "input_0") (type "checkbox") (value "2") (plus-one "4")))
|
||||||
|
"3"))
|
||||||
|
|
||||||
; submit
|
; submit
|
||||||
(test-equal? "submit"
|
(test-equal? "submit"
|
||||||
|
|
|
@ -10,17 +10,22 @@
|
||||||
(define (next-name i)
|
(define (next-name i)
|
||||||
(values (format "input_~a" i) (add1 i)))
|
(values (format "input_~a" i) (add1 i)))
|
||||||
|
|
||||||
(define (make-input* render)
|
(define (make-input*/forest render)
|
||||||
(lambda (i)
|
(lambda (i)
|
||||||
(let-values ([(w i) (next-name i)])
|
(let-values ([(w i) (next-name i)])
|
||||||
(define wb (string->bytes/utf-8 w))
|
(define wb (string->bytes/utf-8 w))
|
||||||
(values (list (render w))
|
(values (render w)
|
||||||
(lambda (env)
|
(lambda (env)
|
||||||
(for/list ([b (in-list env)]
|
(for/list ([b (in-list env)]
|
||||||
#:when (bytes=? wb (binding-id b)))
|
#:when (bytes=? wb (binding-id b)))
|
||||||
b))
|
b))
|
||||||
i))))
|
i))))
|
||||||
|
|
||||||
|
(define (make-input* render)
|
||||||
|
(make-input*/forest
|
||||||
|
(lambda (w)
|
||||||
|
(list (render w)))))
|
||||||
|
|
||||||
(define (make-input render)
|
(define (make-input render)
|
||||||
(lambda (i)
|
(lambda (i)
|
||||||
(let-values ([(w i) (next-name i)])
|
(let-values ([(w i) (next-name i)])
|
||||||
|
@ -109,9 +114,74 @@
|
||||||
#:attributes [attrs empty])
|
#:attributes [attrs empty])
|
||||||
(input
|
(input
|
||||||
#:type "radio"
|
#:type "radio"
|
||||||
|
#:value value
|
||||||
#:attributes
|
#:attributes
|
||||||
(if checked? (append (list (list 'checked "true")) attrs) attrs)))
|
(if checked? (append (list (list 'checked "true")) attrs) attrs)))
|
||||||
|
|
||||||
|
(define (input-group l
|
||||||
|
#:kind kind
|
||||||
|
#:attributes [attrs (λ (x) empty)]
|
||||||
|
#:checked? [checked? (λ (x) #f)]
|
||||||
|
#:display [display (λ (x) x)])
|
||||||
|
(define value->element (make-hasheq))
|
||||||
|
(define i 0)
|
||||||
|
(define (remember! e)
|
||||||
|
(define this-i
|
||||||
|
(begin0 i (set! i (add1 i))))
|
||||||
|
(hash-set! value->element this-i e))
|
||||||
|
(define (recall i)
|
||||||
|
(hash-ref value->element i
|
||||||
|
(λ () (error 'input-group "Invalid selection: ~e" i))))
|
||||||
|
(for ([e l])
|
||||||
|
(remember! e))
|
||||||
|
(define (radio-first l)
|
||||||
|
(if (string=? kind "radio")
|
||||||
|
(first l)
|
||||||
|
l))
|
||||||
|
(cross
|
||||||
|
(pure
|
||||||
|
(lambda (bs)
|
||||||
|
(radio-first
|
||||||
|
(map (compose recall string->number
|
||||||
|
bytes->string/utf-8
|
||||||
|
binding:form-value)
|
||||||
|
bs))))
|
||||||
|
(make-input*/forest
|
||||||
|
(lambda (name)
|
||||||
|
(apply append
|
||||||
|
(for/list ([vn (in-range i)])
|
||||||
|
(define e (hash-ref value->element vn))
|
||||||
|
(define v (number->string vn))
|
||||||
|
(list
|
||||||
|
`(input ([name ,name]
|
||||||
|
[type ,kind]
|
||||||
|
[value ,v]
|
||||||
|
,@(if (checked? e)
|
||||||
|
'([checked "true"])
|
||||||
|
empty)
|
||||||
|
,@(attrs e)))
|
||||||
|
(display e))))))))
|
||||||
|
|
||||||
|
(define (radio-group l
|
||||||
|
#:attributes [attrs (λ (x) empty)]
|
||||||
|
#:checked? [checked? (λ (x) #f)]
|
||||||
|
#:display [display (λ (x) x)])
|
||||||
|
(input-group l
|
||||||
|
#:kind "radio"
|
||||||
|
#:attributes attrs
|
||||||
|
#:checked? checked?
|
||||||
|
#:display display))
|
||||||
|
|
||||||
|
(define (checkbox-group l
|
||||||
|
#:attributes [attrs (λ (x) empty)]
|
||||||
|
#:checked? [checked? (λ (x) #f)]
|
||||||
|
#:display [display (λ (x) x)])
|
||||||
|
(input-group l
|
||||||
|
#:kind "checkbox"
|
||||||
|
#:attributes attrs
|
||||||
|
#:checked? checked?
|
||||||
|
#:display display))
|
||||||
|
|
||||||
(define (submit value
|
(define (submit value
|
||||||
#:attributes [attrs empty])
|
#:attributes [attrs empty])
|
||||||
(input
|
(input
|
||||||
|
@ -265,6 +335,20 @@
|
||||||
(#:attributes (listof (list/c symbol? string?)))
|
(#:attributes (listof (list/c symbol? string?)))
|
||||||
. ->* .
|
. ->* .
|
||||||
(formlet/c (or/c false/c binding?)))]
|
(formlet/c (or/c false/c binding?)))]
|
||||||
|
[radio-group ((sequence?)
|
||||||
|
(#:attributes
|
||||||
|
(-> any/c (listof (list/c symbol? string?)))
|
||||||
|
#:checked? (any/c . -> . boolean?)
|
||||||
|
#:display (any/c . -> . pretty-xexpr/c))
|
||||||
|
. ->* .
|
||||||
|
(formlet/c any/c))]
|
||||||
|
[checkbox-group ((sequence?)
|
||||||
|
(#:attributes
|
||||||
|
(-> any/c (listof (list/c symbol? string?)))
|
||||||
|
#:checked? (any/c . -> . boolean?)
|
||||||
|
#:display (any/c . -> . pretty-xexpr/c))
|
||||||
|
. ->* .
|
||||||
|
(formlet/c (listof any/c)))]
|
||||||
[submit ((bytes?)
|
[submit ((bytes?)
|
||||||
(#:attributes (listof (list/c symbol? string?)))
|
(#:attributes (listof (list/c symbol? string?)))
|
||||||
. ->* .
|
. ->* .
|
||||||
|
|
|
@ -338,6 +338,34 @@ These @tech{formlet}s are the main combinators for form input.
|
||||||
This @tech{formlet} renders using an INPUT element with the RADIO type and the attributes given in the arguments.
|
This @tech{formlet} renders using an INPUT element with the RADIO type and the attributes given in the arguments.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@defproc[(radio-group [l sequence?]
|
||||||
|
[#:attributes attrs (any/c . -> . (listof (list/c symbol? string?))) (λ (x) empty)]
|
||||||
|
[#:checked? checked? (any/c . -> . boolean?) (λ (x) #f)]
|
||||||
|
[#:display display (any/c . -> . xexpr/c) (λ (x) x)])
|
||||||
|
(formlet/c any/c)]{
|
||||||
|
|
||||||
|
This @tech{formlet} renders using a sequence of INPUT elements of
|
||||||
|
RADIO type where each element gets its attributes from @racket[attrs]
|
||||||
|
that share a single NAME. An element is checked if @racket[checked?]
|
||||||
|
returns @racket[#t]. Elements are followed by the results of
|
||||||
|
@racket[display]. The result of processing this formlet is a single
|
||||||
|
element of the sequence.
|
||||||
|
}
|
||||||
|
|
||||||
|
@defproc[(checkbox-group [l sequence?]
|
||||||
|
[#:attributes attrs (any/c . -> . (listof (list/c symbol? string?))) (λ (x) empty)]
|
||||||
|
[#:checked? checked? (any/c . -> . boolean?) (λ (x) #f)]
|
||||||
|
[#:display display (any/c . -> . xexpr/c) (λ (x) x)])
|
||||||
|
(formlet/c (listof any/c))]{
|
||||||
|
|
||||||
|
This @tech{formlet} renders using a sequence of INPUT elements of
|
||||||
|
CHECKBOX type where each element gets its attributes from
|
||||||
|
@racket[attrs] that share a single NAME. An element is checked if
|
||||||
|
@racket[checked?] returns @racket[#t]. Elements are followed by the
|
||||||
|
results of @racket[display]. The result of processing this formlet is
|
||||||
|
a list of elements of the sequence.
|
||||||
|
}
|
||||||
|
|
||||||
@defproc[(submit [value bytes?]
|
@defproc[(submit [value bytes?]
|
||||||
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
||||||
(formlet/c (or/c false/c binding?))]{
|
(formlet/c (or/c false/c binding?))]{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user