mirror of
https://github.com/astaxie/beego.git
synced 2024-11-10 20:30:54 +00:00
Merge pull request #664 from kioopi/renderform-textarea
Makes RenderForm use textarea-element when form type is `textarea`
This commit is contained in:
commit
8b021c8ea1
@ -327,14 +327,6 @@ func ParseForm(form url.Values, obj interface{}) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// form types for RenderForm function
|
|
||||||
var FormType = map[string]bool{
|
|
||||||
"text": true,
|
|
||||||
"textarea": true,
|
|
||||||
"hidden": true,
|
|
||||||
"password": true,
|
|
||||||
}
|
|
||||||
|
|
||||||
var unKind = map[reflect.Kind]bool{
|
var unKind = map[reflect.Kind]bool{
|
||||||
reflect.Uintptr: true,
|
reflect.Uintptr: true,
|
||||||
reflect.Complex64: true,
|
reflect.Complex64: true,
|
||||||
@ -368,15 +360,50 @@ func RenderForm(obj interface{}) template.HTML {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fieldT := objT.Field(i)
|
fieldT := objT.Field(i)
|
||||||
|
|
||||||
|
label, name, fType, ignored := parseFormTag(fieldT)
|
||||||
|
if ignored {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
raw = append(raw, renderFormField(label, name, fType, fieldV.Interface()))
|
||||||
|
}
|
||||||
|
return template.HTML(strings.Join(raw, "</br>"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// renderFormField returns a string containing HTML of a single form field.
|
||||||
|
func renderFormField(label, name, fType string, value interface{}) string {
|
||||||
|
if isValidForInput(fType) {
|
||||||
|
return fmt.Sprintf(`%v<input name="%v" type="%v" value="%v">`, label, name, fType, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf(`%v<%v name="%v">%v</%v>`, label, fType, name, value, fType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// isValidForInput checks if fType is a valid value for the `type` property of an HTML input element.
|
||||||
|
func isValidForInput(fType string) bool {
|
||||||
|
validInputTypes := strings.Fields("text password checkbox radio submit reset hidden image file button search email url tel number range date month week time datetime datetime-local color")
|
||||||
|
for _, validType := range validInputTypes {
|
||||||
|
if fType == validType {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseFormTag takes the stuct-tag of a StructField and parses the `form` value.
|
||||||
|
// returned are the form label, name-property, type and wether the field should be ignored.
|
||||||
|
func parseFormTag(fieldT reflect.StructField) (label, name, fType string, ignored bool) {
|
||||||
tags := strings.Split(fieldT.Tag.Get("form"), ",")
|
tags := strings.Split(fieldT.Tag.Get("form"), ",")
|
||||||
label := fieldT.Name + ": "
|
label = fieldT.Name + ": "
|
||||||
name := fieldT.Name
|
name = fieldT.Name
|
||||||
fType := "text"
|
fType = "text"
|
||||||
|
ignored = false;
|
||||||
|
|
||||||
switch len(tags) {
|
switch len(tags) {
|
||||||
case 1:
|
case 1:
|
||||||
if tags[0] == "-" {
|
if tags[0] == "-" {
|
||||||
continue
|
ignored = true
|
||||||
}
|
}
|
||||||
if len(tags[0]) > 0 {
|
if len(tags[0]) > 0 {
|
||||||
name = tags[0]
|
name = tags[0]
|
||||||
@ -399,11 +426,7 @@ func RenderForm(obj interface{}) template.HTML {
|
|||||||
label = tags[2]
|
label = tags[2]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return
|
||||||
raw = append(raw, fmt.Sprintf(`%v<input name="%v" type="%v" value="%v">`,
|
|
||||||
label, name, fType, fieldV.Interface()))
|
|
||||||
}
|
|
||||||
return template.HTML(strings.Join(raw, "</br>"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isStructPtr(t reflect.Type) bool {
|
func isStructPtr(t reflect.Type) bool {
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSubstr(t *testing.T) {
|
func TestSubstr(t *testing.T) {
|
||||||
@ -147,9 +148,10 @@ func TestRenderForm(t *testing.T) {
|
|||||||
Sex string
|
Sex string
|
||||||
Email []string
|
Email []string
|
||||||
Intro string `form:",textarea"`
|
Intro string `form:",textarea"`
|
||||||
|
Ignored string `form:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
u := user{Name: "test"}
|
u := user{Name: "test", Intro: "Some Text"}
|
||||||
output := RenderForm(u)
|
output := RenderForm(u)
|
||||||
if output != template.HTML("") {
|
if output != template.HTML("") {
|
||||||
t.Errorf("output should be empty but got %v", output)
|
t.Errorf("output should be empty but got %v", output)
|
||||||
@ -159,8 +161,58 @@ func TestRenderForm(t *testing.T) {
|
|||||||
`Name: <input name="username" type="text" value="test"></br>` +
|
`Name: <input name="username" type="text" value="test"></br>` +
|
||||||
`年龄:<input name="age" type="text" value="0"></br>` +
|
`年龄:<input name="age" type="text" value="0"></br>` +
|
||||||
`Sex: <input name="Sex" type="text" value=""></br>` +
|
`Sex: <input name="Sex" type="text" value=""></br>` +
|
||||||
`Intro: <input name="Intro" type="textarea" value="">`)
|
`Intro: <textarea name="Intro">Some Text</textarea>`)
|
||||||
if output != result {
|
if output != result {
|
||||||
t.Errorf("output should equal `%v` but got `%v`", result, output)
|
t.Errorf("output should equal `%v` but got `%v`", result, output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRenderFormField(t *testing.T) {
|
||||||
|
html := renderFormField("Label: ", "Name", "text", "Value")
|
||||||
|
if html != `Label: <input name="Name" type="text" value="Value">` {
|
||||||
|
t.Errorf("Wrong html output for input[type=text]: %v ", html)
|
||||||
|
}
|
||||||
|
|
||||||
|
html = renderFormField("Label: ", "Name", "textarea", "Value")
|
||||||
|
if html != `Label: <textarea name="Name">Value</textarea>` {
|
||||||
|
t.Errorf("Wrong html output for textarea: %v ", html)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseFormTag(t *testing.T) {
|
||||||
|
// create struct to contain field with different types of struct-tag `form`
|
||||||
|
type user struct {
|
||||||
|
All int `form:"name,text,年龄:"`
|
||||||
|
NoName int `form:",hidden,年龄:"`
|
||||||
|
OnlyLabel int `form:",,年龄:"`
|
||||||
|
OnlyName int `form:"name"`
|
||||||
|
Ignored int `form:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
objT := reflect.TypeOf(&user{}).Elem()
|
||||||
|
|
||||||
|
label, name, fType, ignored := parseFormTag(objT.Field(0))
|
||||||
|
if !(name == "name" && label == "年龄:" && fType == "text" && ignored == false) {
|
||||||
|
t.Errorf("Form Tag with name, label and type was not correctly parsed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
label, name, fType, ignored = parseFormTag(objT.Field(1))
|
||||||
|
if !(name == "NoName" && label == "年龄:" && fType == "hidden" && ignored == false) {
|
||||||
|
t.Errorf("Form Tag with label and type but without name was not correctly parsed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
label, name, fType, ignored = parseFormTag(objT.Field(2))
|
||||||
|
if !(name == "OnlyLabel" && label == "年龄:" && fType == "text" && ignored == false) {
|
||||||
|
t.Errorf("Form Tag containing only label was not correctly parsed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
label, name, fType, ignored = parseFormTag(objT.Field(3))
|
||||||
|
if !(name == "name" && label == "OnlyName: " && fType == "text" && ignored == false) {
|
||||||
|
t.Errorf("Form Tag containing only name was not correctly parsed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
label, name, fType, ignored = parseFormTag(objT.Field(4))
|
||||||
|
if (ignored == false) {
|
||||||
|
t.Errorf("Form Tag that should be ignored was not correctly parsed.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user