Skip to content

Commit 992fee9

Browse files
committed
feat(dom): Handle checkbox input types
A checked checkbox will result in an 'on' value in the submitted form. Checkboxed value can be set by: - Calling `HTMLInputElement.SetChecked(bool)` - Calling `HTMLInputElement.Click()`
1 parent 43c359c commit 992fee9

6 files changed

+102
-6
lines changed

html/form_data.go

+5
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ func NewFormDataForm(form HTMLFormElement) *FormData {
3535
switch inputElement.Type() {
3636
case "submit":
3737
continue
38+
case "checkbox":
39+
name, _ := inputElement.GetAttribute("name")
40+
if inputElement.Checked() {
41+
formData.Append(name, "on")
42+
}
3843
default:
3944
// TODO, handle no values
4045
name, _ := inputElement.GetAttribute("name")
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package html_test
2+
3+
import (
4+
"net/http"
5+
"testing"
6+
7+
"github.com/gost-dom/browser/html"
8+
"github.com/gost-dom/browser/internal/testing/htmltest"
9+
"github.com/stretchr/testify/suite"
10+
)
11+
12+
type HTMLFormElementWithCheckboxTestSuite struct {
13+
suite.Suite
14+
}
15+
16+
func TestHTMLFormElementWithCheckbox(t *testing.T) {
17+
suite.Run(t, new(HTMLFormElementWithCheckboxTestSuite))
18+
}
19+
20+
// httpRequestRecorder is a very simple http.Handler that just records the
21+
// incoming requests, and returns a 200 status
22+
type httpRequestRecorder struct {
23+
t testing.TB
24+
requests []*http.Request
25+
}
26+
27+
func (rec *httpRequestRecorder) ServeHTTP(w http.ResponseWriter, r *http.Request) {
28+
r.ParseForm()
29+
rec.requests = append(rec.requests, r)
30+
}
31+
32+
// Single asserts that a single request was made
33+
func (r httpRequestRecorder) Single() *http.Request {
34+
r.t.Helper()
35+
if len(r.requests) != 1 {
36+
r.t.Errorf("Expected single recorded request. Got: %d", len(r.requests))
37+
}
38+
return r.requests[0]
39+
}
40+
41+
func (s *HTMLFormElementWithCheckboxTestSuite) TestSubmitWithCheckboxes() {
42+
rec := &httpRequestRecorder{t: s.T()}
43+
win := htmltest.NewWindowHelper(s.T(), NewWindowFromHandler(rec))
44+
win.LoadHTML(`<body>
45+
<form method="post">
46+
<input id="check-1" name="check-me-1" type="checkbox" />
47+
<label id="lbl-1" for="check">Check me 1</label>
48+
<input id="check-2" name="check-me-2" type="checkbox" />
49+
<label id="lbl-2" for="check">Check me 2</label>
50+
</form>
51+
</body>`)
52+
form := win.HTMLDocument().QuerySelectorHTML("form").(html.HTMLFormElement)
53+
check := win.HTMLDocument().GetHTMLElementById("check-1").(html.HTMLInputElement)
54+
check.SetChecked(true)
55+
form.Submit()
56+
req := rec.Single()
57+
s.Assert().Equal([]string{"on"}, req.PostForm["check-me-1"])
58+
s.Assert().Empty(req.PostForm["check-me-2"])
59+
}

html/html_form_element_submit_test.go

-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package html_test
22

33
import (
4-
"fmt"
54
"net/http"
65
"net/url"
76
"reflect"
@@ -65,7 +64,6 @@ type DefaultWindowFixture struct {
6564

6665
func (f *DefaultWindowFixture) Setup() {
6766
if !f.initialized {
68-
fmt.Println("Setup default window")
6967
f.HTTPHandlerFixture.ServeMux.HandleFunc(
7068
"/",
7169
func(res http.ResponseWriter, req *http.Request) {

html/html_input_element.go

+18-4
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,27 @@ type HTMLInputElement interface {
1010
SetType(value string)
1111
Name() string
1212
CheckValidity() bool
13+
Checked() bool
14+
SetChecked(bool)
1315
}
1416

15-
type htmlInputElement struct{ htmlElement }
17+
type htmlInputElement struct {
18+
htmlElement
19+
checked bool
20+
}
1621

1722
func NewHTMLInputElement(ownerDocument HTMLDocument) HTMLInputElement {
18-
result := &htmlInputElement{newHTMLElement("input", ownerDocument)}
23+
result := &htmlInputElement{
24+
htmlElement: newHTMLElement("input", ownerDocument),
25+
}
1926
result.SetSelf(result)
2027
return result
2128
}
2229

2330
func (e *htmlInputElement) Name() string { return e.GetAttributeNode("name").Value() }
2431
func (e *htmlInputElement) CheckValidity() bool { return true }
32+
func (e *htmlInputElement) Checked() bool { return e.checked }
33+
func (e *htmlInputElement) SetChecked(b bool) { e.checked = b }
2534

2635
func (e *htmlInputElement) Type() string {
2736
t, _ := e.GetAttribute("type")
@@ -36,9 +45,14 @@ func (e *htmlInputElement) SetType(val string) {
3645
}
3746

3847
func (e *htmlInputElement) Click() {
39-
ok := e.htmlElement.click()
40-
if ok && e.Type() == "submit" {
48+
if ok := e.htmlElement.click(); !ok {
49+
return
50+
}
51+
switch e.Type() {
52+
case "submit":
4153
e.trySubmitForm()
54+
case "checkbox":
55+
e.SetChecked(!e.checked)
4256
}
4357
}
4458

html/html_input_element_test.go

+13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"testing"
55

66
"github.com/gost-dom/browser/html"
7+
"github.com/gost-dom/browser/internal/testing/eventtest"
78
. "github.com/gost-dom/browser/internal/testing/gomega-matchers"
89
"github.com/gost-dom/browser/internal/testing/gosttest"
910
"github.com/stretchr/testify/suite"
@@ -21,3 +22,15 @@ func (s *HTMLInputElementTestSuite) TestDefaultValue() {
2122
e := html.NewHTMLInputElement(nil)
2223
s.Expect(e.Type()).To(Equal("text"))
2324
}
25+
26+
func (s *HTMLInputElementTestSuite) TestClickCheckbox() {
27+
e := html.NewHTMLInputElement(nil)
28+
e.SetType("checkbox")
29+
s.Assert().False(e.Checked())
30+
e.Click()
31+
s.Assert().True(e.Checked())
32+
33+
e.AddEventListener("click", eventtest.PreventDefaultHandler())
34+
e.Click()
35+
s.Assert().True(e.Checked(), "Checked should not change when default is prevented")
36+
}

internal/testing/eventtest/helper.go

+7
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,10 @@ func NewTestHandler(
77
) event.EventHandler {
88
return event.NewEventHandlerFunc(event.NoError(f))
99
}
10+
11+
// PreventDefaultHandler creates an event handler that will call PreventDefault.
12+
func PreventDefaultHandler() event.EventHandler {
13+
return NewTestHandler(func(e *event.Event) {
14+
e.PreventDefault()
15+
})
16+
}

0 commit comments

Comments
 (0)