diff --git a/lib/hyperscript/runtime.sx b/lib/hyperscript/runtime.sx index b3284eac..a356d826 100644 --- a/lib/hyperscript/runtime.sx +++ b/lib/hyperscript/runtime.sx @@ -1180,7 +1180,17 @@ (if (host-get node "multiple") (hs-select-multi-values node) - (host-get node "value"))) + (let + ((idx (host-get node "selectedIndex")) + (opts (host-get node "options")) + (raw-val (host-get node "value"))) + (if + (and (not (nil? raw-val)) (not (= raw-val ""))) + raw-val + (if + (and (not (nil? opts)) (>= idx 0)) + (host-get (if (list? opts) (nth opts idx) (host-get opts idx)) "value") + ""))))) ((or (= typ "checkbox") (= typ "radio")) (if (host-get node "checked") (host-get node "value") nil)) (true (host-get node "value")))))) diff --git a/shared/static/wasm/sx/hs-runtime.sx b/shared/static/wasm/sx/hs-runtime.sx index b3284eac..a356d826 100644 --- a/shared/static/wasm/sx/hs-runtime.sx +++ b/shared/static/wasm/sx/hs-runtime.sx @@ -1180,7 +1180,17 @@ (if (host-get node "multiple") (hs-select-multi-values node) - (host-get node "value"))) + (let + ((idx (host-get node "selectedIndex")) + (opts (host-get node "options")) + (raw-val (host-get node "value"))) + (if + (and (not (nil? raw-val)) (not (= raw-val ""))) + raw-val + (if + (and (not (nil? opts)) (>= idx 0)) + (host-get (if (list? opts) (nth opts idx) (host-get opts idx)) "value") + ""))))) ((or (= typ "checkbox") (= typ "radio")) (if (host-get node "checked") (host-get node "value") nil)) (true (host-get node "value")))))) diff --git a/spec/tests/test-hyperscript-behavioral.sx b/spec/tests/test-hyperscript-behavioral.sx index e739487b..8315a315 100644 --- a/spec/tests/test-hyperscript-behavioral.sx +++ b/spec/tests/test-hyperscript-behavioral.sx @@ -3817,11 +3817,15 @@ ) (deftest "converts multiple selects with programmatically changed selections" (let ((_node (dom-create-element "form"))) - (dom-set-inner-html _node "") - (let ((_result (eval-hs-locals "x as Values" (list (list (quote x) _node))))) - (assert= (nth (host-get _result "animal") 0) "cat") - (assert= (nth (host-get _result "animal") 1) "raccoon") - )) + (dom-set-inner-html _node "") + (let ((_sel (dom-query _node "select"))) + (let ((_opts (host-get _sel "options"))) + (host-set! (nth _opts 0) "selected" false) + (host-set! (nth _opts 1) "selected" true) + (let ((_result (eval-hs-locals "x as Values" (list (list (quote x) _node))))) + (assert= (nth (host-get _result "animal") 0) "cat") + (assert= (nth (host-get _result "animal") 1) "raccoon") + )))) ) (deftest "converts nested array as Flat" (assert= (eval-hs "[[1,2],[3,4]] as Flat") (list 1 2 3 4)) diff --git a/tests/playwright/generate-sx-tests.py b/tests/playwright/generate-sx-tests.py index c8205bcf..a8e9c586 100644 --- a/tests/playwright/generate-sx-tests.py +++ b/tests/playwright/generate-sx-tests.py @@ -128,6 +128,18 @@ SKIP_TEST_NAMES = { # Manually-written SX test bodies for tests whose upstream body cannot be # auto-translated. Key = test name; value = SX lines to emit inside deftest. MANUAL_TEST_BODIES = { + "converts multiple selects with programmatically changed selections": [ + ' (let ((_node (dom-create-element "form")))', + ' (dom-set-inner-html _node "")', + ' (let ((_sel (dom-query _node "select")))', + ' (let ((_opts (host-get _sel "options")))', + ' (host-set! (nth _opts 0) "selected" false)', + ' (host-set! (nth _opts 1) "selected" true)', + ' (let ((_result (eval-hs-locals "x as Values" (list (list (quote x) _node)))))', + ' (assert= (nth (host-get _result "animal") 0) "cat")', + ' (assert= (nth (host-get _result "animal") 1) "raccoon")', + ' ))))', + ], "iterate cookies values work": [ ' (hs-cleanup!)', ' (host-set! (host-global "cookies") "foo" "bar")',