html-elements.scm 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. (define-module (html-elements)
  2. #:use-module (srfi srfi-9)
  3. #:export (my-input
  4. form-item))
  5. (define-syntax my-define-record-type
  6. (syntax-rules ()
  7. ((my-define-record-type type
  8. constructor
  9. constructor?
  10. (fieldname var1) ...)
  11. (define-record-type type
  12. (constructor fieldname ...)
  13. constructor?
  14. (fieldname var1) ... ))))
  15. (my-define-record-type <form-item>
  16. make-form-item
  17. form-item?
  18. (label form-item-label)
  19. (id form-item-id)
  20. (input-type form-item-input-type)
  21. (options form-item-options)
  22. (placeholder form-item-placeholder)
  23. (required form-item-required))
  24. (define* (my-select id
  25. #:key
  26. (required #t)
  27. (options #f))
  28. `(select (@ (id ,id)
  29. (name ,id)
  30. ,(if (eq? required #t)
  31. '(required)
  32. '(not-required))
  33. (class "custom-select"))
  34. (option (@ (value "")
  35. (selected ""))
  36. "Choose...")
  37. ,(let loop ([options options])
  38. (if (null? options)
  39. '()
  40. (cons `(option (@ (value ,(car options)))
  41. ,(car options))
  42. (loop (cdr options)))))))
  43. (define* (my-radio label
  44. #:optional
  45. #:key
  46. id
  47. name
  48. options)
  49. `(li
  50. ,(let loop ([options options])
  51. (if (null? options)
  52. '()
  53. `((label ,(car options))
  54. (input (@ (id, ,(car options))
  55. (name ,(car options))
  56. (value ,(car options))
  57. (type, "radio")))
  58. ,(loop (cdr options)))))))
  59. (define* (my-input label
  60. #:optional
  61. #:key
  62. id
  63. (input-type "text")
  64. (options #f)
  65. (placeholder "")
  66. (required #t)
  67. value
  68. )
  69. (let ([id (if (not id)
  70. label
  71. id)])
  72. (cond [(string= input-type "select")
  73. (my-select id #:options options #:required required)]
  74. [(string= input-type "textarea")
  75. `(textarea (@ (id ,id)
  76. (name ,id)
  77. (type ,input-type)
  78. ,(if (eq? required #t)
  79. '(required)
  80. '(not-required))
  81. ;; the "" is necessary to make sxml put a
  82. ;; closing </textarea>
  83. (placeholder ,placeholder)) "")]
  84. [else (let ([input "input"])
  85. (when (string= input-type "textarea")
  86. (set! input "textarea"))
  87. `(input (@ (id ,id)
  88. (name ,id)
  89. (type ,input-type)
  90. ,(if (eq? required #t)
  91. '(required))
  92. ,(if (not (boolean? value))
  93. `(value ,value)
  94. '(value))
  95. (placeholder ,placeholder))))])))
  96. (define* (form-item label
  97. #:key
  98. (id label)
  99. (input-type "text")
  100. (placeholder "")
  101. (required #t)
  102. options
  103. (width 8))
  104. (define form-item-a (make-form-item
  105. label
  106. id
  107. input-type
  108. options
  109. placeholder
  110. required))
  111. (if (string= input-type "radio")
  112. (my-radio label #:options options)
  113. `(li
  114. (label (@ (for ,(form-item-id form-item-a)))
  115. ,((lambda (label) ;;capitalize first letter
  116. (let ([string-list (string->list label)])
  117. (list->string (cons (char-upcase (car string-list))
  118. (cdr string-list)))))
  119. (form-item-label form-item-a)))
  120. ,(my-input (form-item-label form-item-a)
  121. #:id (form-item-id form-item-a)
  122. #:input-type (form-item-input-type form-item-a)
  123. #:options (form-item-options form-item-a)
  124. #:placeholder (form-item-placeholder form-item-a)
  125. #:required (form-item-required form-item-a)))))