diff options
author | Steve Manuel <nilslice@gmail.com> | 2017-01-02 10:27:44 -0800 |
---|---|---|
committer | Steve Manuel <nilslice@gmail.com> | 2017-01-02 10:27:44 -0800 |
commit | d61e0a214e394e66ad8cfdbdec6caddedd1d10f9 (patch) | |
tree | b162bf6119815470c6a2e213cda9c4be89c397ea /management | |
parent | ca002d0f447f0e9d7a71cd502a20b63277a612ce (diff) |
add reference.SelectRepeater and necessary struct and function exports
Diffstat (limited to 'management')
-rw-r--r-- | management/editor/dom.go | 231 | ||||
-rw-r--r-- | management/editor/elements.go | 146 | ||||
-rw-r--r-- | management/editor/repeaters.go | 88 | ||||
-rw-r--r-- | management/editor/values.go | 13 |
4 files changed, 255 insertions, 223 deletions
diff --git a/management/editor/dom.go b/management/editor/dom.go index 7a96bd4..5888db5 100644 --- a/management/editor/dom.go +++ b/management/editor/dom.go @@ -7,288 +7,291 @@ import ( "strings" ) -type element struct { - tagName string - attrs map[string]string - name string - label string - data string - viewBuf *bytes.Buffer +// Element is a basic struct for representing DOM elements +type Element struct { + TagName string + Attrs map[string]string + Name string + Label string + Data string + ViewBuf *bytes.Buffer } -func newElement(tagName, label, fieldName string, p interface{}, attrs map[string]string) *element { - return &element{ - tagName: tagName, - attrs: attrs, - name: tagNameFromStructField(fieldName, p), - label: label, - data: valueFromStructField(fieldName, p), - viewBuf: &bytes.Buffer{}, +// NewElement returns an Element with Name and Data already processed from the +// fieldName and content interface provided +func NewElement(tagName, label, fieldName string, p interface{}, attrs map[string]string) *Element { + return &Element{ + TagName: tagName, + Attrs: attrs, + Name: TagNameFromStructField(fieldName, p), + Label: label, + Data: ValueFromStructField(fieldName, p), + ViewBuf: &bytes.Buffer{}, } } -// domElementSelfClose is a special DOM element which is parsed as a +// DOMElementSelfClose is a special DOM element which is parsed as a // self-closing tag and thus needs to be created differently -func domElementSelfClose(e *element) []byte { - _, err := e.viewBuf.WriteString(`<div class="input-field col s12">`) +func DOMElementSelfClose(e *Element) []byte { + _, err := e.ViewBuf.WriteString(`<div class="input-field col s12">`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementSelfClose") + log.Println("Error writing HTML string to buffer: DOMElementSelfClose") return nil } - if e.label != "" { - _, err = e.viewBuf.WriteString( + if e.Label != "" { + _, err = e.ViewBuf.WriteString( `<label class="active" for="` + - strings.Join(strings.Split(e.label, " "), "-") + `">` + e.label + + strings.Join(strings.Split(e.Label, " "), "-") + `">` + e.Label + `</label>`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementSelfClose") + log.Println("Error writing HTML string to buffer: DOMElementSelfClose") return nil } } - _, err = e.viewBuf.WriteString(`<` + e.tagName + ` value="`) + _, err = e.ViewBuf.WriteString(`<` + e.TagName + ` value="`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementSelfClose") + log.Println("Error writing HTML string to buffer: DOMElementSelfClose") return nil } - _, err = e.viewBuf.WriteString(html.EscapeString(e.data) + `" `) + _, err = e.ViewBuf.WriteString(html.EscapeString(e.Data) + `" `) if err != nil { - log.Println("Error writing HTML string to buffer: domElementSelfClose") + log.Println("Error writing HTML string to buffer: DOMElementSelfClose") return nil } - for attr, value := range e.attrs { - _, err := e.viewBuf.WriteString(attr + `="` + value + `" `) + for attr, value := range e.Attrs { + _, err := e.ViewBuf.WriteString(attr + `="` + value + `" `) if err != nil { - log.Println("Error writing HTML string to buffer: domElementSelfClose") + log.Println("Error writing HTML string to buffer: DOMElementSelfClose") return nil } } - _, err = e.viewBuf.WriteString(` name="` + e.name + `" />`) + _, err = e.ViewBuf.WriteString(` name="` + e.Name + `" />`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementSelfClose") + log.Println("Error writing HTML string to buffer: DOMElementSelfClose") return nil } - _, err = e.viewBuf.WriteString(`</div>`) + _, err = e.ViewBuf.WriteString(`</div>`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementSelfClose") + log.Println("Error writing HTML string to buffer: DOMElementSelfClose") return nil } - return e.viewBuf.Bytes() + return e.ViewBuf.Bytes() } -// domElementCheckbox is a special DOM element which is parsed as a +// DOMElementCheckbox is a special DOM element which is parsed as a // checkbox input tag and thus needs to be created differently -func domElementCheckbox(e *element) []byte { - _, err := e.viewBuf.WriteString(`<p class="col s6">`) +func DOMElementCheckbox(e *Element) []byte { + _, err := e.ViewBuf.WriteString(`<p class="col s6">`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementCheckbox") + log.Println("Error writing HTML string to buffer: DOMElementCheckbox") return nil } - _, err = e.viewBuf.WriteString(`<` + e.tagName + ` `) + _, err = e.ViewBuf.WriteString(`<` + e.TagName + ` `) if err != nil { - log.Println("Error writing HTML string to buffer: domElementCheckbox") + log.Println("Error writing HTML string to buffer: DOMElementCheckbox") return nil } - for attr, value := range e.attrs { - _, err := e.viewBuf.WriteString(attr + `="` + value + `" `) + for attr, value := range e.Attrs { + _, err := e.ViewBuf.WriteString(attr + `="` + value + `" `) if err != nil { - log.Println("Error writing HTML string to buffer: domElementCheckbox") + log.Println("Error writing HTML string to buffer: DOMElementCheckbox") return nil } } - _, err = e.viewBuf.WriteString(` name="` + e.name + `" />`) + _, err = e.ViewBuf.WriteString(` name="` + e.Name + `" />`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementCheckbox") + log.Println("Error writing HTML string to buffer: DOMElementCheckbox") return nil } - if e.label != "" { - _, err = e.viewBuf.WriteString( + if e.Label != "" { + _, err = e.ViewBuf.WriteString( `<label for="` + - strings.Join(strings.Split(e.label, " "), "-") + `">` + - e.label + `</label>`) + strings.Join(strings.Split(e.Label, " "), "-") + `">` + + e.Label + `</label>`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementCheckbox") + log.Println("Error writing HTML string to buffer: DOMElementCheckbox") return nil } } - _, err = e.viewBuf.WriteString(`</p>`) + _, err = e.ViewBuf.WriteString(`</p>`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementCheckbox") + log.Println("Error writing HTML string to buffer: DOMElementCheckbox") return nil } - return e.viewBuf.Bytes() + return e.ViewBuf.Bytes() } -// domElement creates a DOM element -func domElement(e *element) []byte { - _, err := e.viewBuf.WriteString(`<div class="input-field col s12">`) +// DOMElement creates a DOM element +func DOMElement(e *Element) []byte { + _, err := e.ViewBuf.WriteString(`<div class="input-field col s12">`) if err != nil { - log.Println("Error writing HTML string to buffer: domElement") + log.Println("Error writing HTML string to buffer: DOMElement") return nil } - if e.label != "" { - _, err = e.viewBuf.WriteString( + if e.Label != "" { + _, err = e.ViewBuf.WriteString( `<label class="active" for="` + - strings.Join(strings.Split(e.label, " "), "-") + `">` + e.label + + strings.Join(strings.Split(e.Label, " "), "-") + `">` + e.Label + `</label>`) if err != nil { - log.Println("Error writing HTML string to buffer: domElement") + log.Println("Error writing HTML string to buffer: DOMElement") return nil } } - _, err = e.viewBuf.WriteString(`<` + e.tagName + ` `) + _, err = e.ViewBuf.WriteString(`<` + e.TagName + ` `) if err != nil { - log.Println("Error writing HTML string to buffer: domElement") + log.Println("Error writing HTML string to buffer: DOMElement") return nil } - for attr, value := range e.attrs { - _, err = e.viewBuf.WriteString(attr + `="` + string(value) + `" `) + for attr, value := range e.Attrs { + _, err = e.ViewBuf.WriteString(attr + `="` + string(value) + `" `) if err != nil { - log.Println("Error writing HTML string to buffer: domElement") + log.Println("Error writing HTML string to buffer: DOMElement") return nil } } - _, err = e.viewBuf.WriteString(` name="` + e.name + `" >`) + _, err = e.ViewBuf.WriteString(` name="` + e.Name + `" >`) if err != nil { - log.Println("Error writing HTML string to buffer: domElement") + log.Println("Error writing HTML string to buffer: DOMElement") return nil } - _, err = e.viewBuf.WriteString(html.EscapeString(e.data)) + _, err = e.ViewBuf.WriteString(html.EscapeString(e.Data)) if err != nil { - log.Println("Error writing HTML string to buffer: domElement") + log.Println("Error writing HTML string to buffer: DOMElement") return nil } - _, err = e.viewBuf.WriteString(`</` + e.tagName + `>`) + _, err = e.ViewBuf.WriteString(`</` + e.TagName + `>`) if err != nil { - log.Println("Error writing HTML string to buffer: domElement") + log.Println("Error writing HTML string to buffer: DOMElement") return nil } - _, err = e.viewBuf.WriteString(`</div>`) + _, err = e.ViewBuf.WriteString(`</div>`) if err != nil { - log.Println("Error writing HTML string to buffer: domElement") + log.Println("Error writing HTML string to buffer: DOMElement") return nil } - return e.viewBuf.Bytes() + return e.ViewBuf.Bytes() } -func domElementWithChildrenSelect(e *element, children []*element) []byte { - _, err := e.viewBuf.WriteString(`<div class="input-field col s6">`) +func DOMElementWithChildrenSelect(e *Element, children []*Element) []byte { + _, err := e.ViewBuf.WriteString(`<div class="input-field col s6">`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementWithChildrenSelect") + log.Println("Error writing HTML string to buffer: DOMElementWithChildrenSelect") return nil } - _, err = e.viewBuf.WriteString(`<` + e.tagName + ` `) + _, err = e.ViewBuf.WriteString(`<` + e.TagName + ` `) if err != nil { - log.Println("Error writing HTML string to buffer: domElementWithChildrenSelect") + log.Println("Error writing HTML string to buffer: DOMElementWithChildrenSelect") return nil } - for attr, value := range e.attrs { - _, err = e.viewBuf.WriteString(attr + `="` + value + `" `) + for attr, value := range e.Attrs { + _, err = e.ViewBuf.WriteString(attr + `="` + value + `" `) if err != nil { - log.Println("Error writing HTML string to buffer: domElementWithChildrenSelect") + log.Println("Error writing HTML string to buffer: DOMElementWithChildrenSelect") return nil } } - _, err = e.viewBuf.WriteString(` name="` + e.name + `" >`) + _, err = e.ViewBuf.WriteString(` name="` + e.Name + `" >`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementWithChildrenSelect") + log.Println("Error writing HTML string to buffer: DOMElementWithChildrenSelect") return nil } - // loop over children and create domElement for each child + // loop over children and create DOMElement for each child for _, child := range children { - _, err = e.viewBuf.Write(domElement(child)) + _, err = e.ViewBuf.Write(DOMElement(child)) if err != nil { - log.Println("Error writing HTML domElement to buffer: domElementWithChildrenSelect") + log.Println("Error writing HTML DOMElement to buffer: DOMElementWithChildrenSelect") return nil } } - _, err = e.viewBuf.WriteString(`</` + e.tagName + `>`) + _, err = e.ViewBuf.WriteString(`</` + e.TagName + `>`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementWithChildrenSelect") + log.Println("Error writing HTML string to buffer: DOMElementWithChildrenSelect") return nil } - if e.label != "" { - _, err = e.viewBuf.WriteString(`<label class="active">` + e.label + `</label>`) + if e.Label != "" { + _, err = e.ViewBuf.WriteString(`<label class="active">` + e.Label + `</label>`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementWithChildrenSelect") + log.Println("Error writing HTML string to buffer: DOMElementWithChildrenSelect") return nil } } - _, err = e.viewBuf.WriteString(`</div>`) + _, err = e.ViewBuf.WriteString(`</div>`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementWithChildrenSelect") + log.Println("Error writing HTML string to buffer: DOMElementWithChildrenSelect") return nil } - return e.viewBuf.Bytes() + return e.ViewBuf.Bytes() } -func domElementWithChildrenCheckbox(e *element, children []*element) []byte { - _, err := e.viewBuf.WriteString(`<` + e.tagName + ` `) +func DOMElementWithChildrenCheckbox(e *Element, children []*Element) []byte { + _, err := e.ViewBuf.WriteString(`<` + e.TagName + ` `) if err != nil { - log.Println("Error writing HTML string to buffer: domElementWithChildrenCheckbox") + log.Println("Error writing HTML string to buffer: DOMElementWithChildrenCheckbox") return nil } - for attr, value := range e.attrs { - _, err = e.viewBuf.WriteString(attr + `="` + value + `" `) + for attr, value := range e.Attrs { + _, err = e.ViewBuf.WriteString(attr + `="` + value + `" `) if err != nil { - log.Println("Error writing HTML string to buffer: domElementWithChildrenCheckbox") + log.Println("Error writing HTML string to buffer: DOMElementWithChildrenCheckbox") return nil } } - _, err = e.viewBuf.WriteString(` >`) + _, err = e.ViewBuf.WriteString(` >`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementWithChildrenCheckbox") + log.Println("Error writing HTML string to buffer: DOMElementWithChildrenCheckbox") return nil } - if e.label != "" { - _, err = e.viewBuf.WriteString(`<label class="active">` + e.label + `</label>`) + if e.Label != "" { + _, err = e.ViewBuf.WriteString(`<label class="active">` + e.Label + `</label>`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementWithChildrenCheckbox") + log.Println("Error writing HTML string to buffer: DOMElementWithChildrenCheckbox") return nil } } - // loop over children and create domElement for each child + // loop over children and create DOMElement for each child for _, child := range children { - _, err = e.viewBuf.Write(domElementCheckbox(child)) + _, err = e.ViewBuf.Write(DOMElementCheckbox(child)) if err != nil { - log.Println("Error writing HTML domElementCheckbox to buffer: domElementWithChildrenCheckbox") + log.Println("Error writing HTML DOMElementCheckbox to buffer: DOMElementWithChildrenCheckbox") return nil } } - _, err = e.viewBuf.WriteString(`</` + e.tagName + `><div class="clear padding"> </div>`) + _, err = e.ViewBuf.WriteString(`</` + e.TagName + `><div class="clear padding"> </div>`) if err != nil { - log.Println("Error writing HTML string to buffer: domElementWithChildrenCheckbox") + log.Println("Error writing HTML string to buffer: DOMElementWithChildrenCheckbox") return nil } - return e.viewBuf.Bytes() + return e.ViewBuf.Bytes() } diff --git a/management/editor/elements.go b/management/editor/elements.go index b82b220..4e0ff17 100644 --- a/management/editor/elements.go +++ b/management/editor/elements.go @@ -30,9 +30,9 @@ import ( // ) // } func Input(fieldName string, p interface{}, attrs map[string]string) []byte { - e := newElement("input", attrs["label"], fieldName, p, attrs) + e := NewElement("input", attrs["label"], fieldName, p, attrs) - return domElementSelfClose(e) + return DOMElementSelfClose(e) } // Textarea returns the []byte of a <textarea> HTML element with a label. @@ -49,9 +49,9 @@ func Textarea(fieldName string, p interface{}, attrs map[string]string) []byte { attrs["class"] = className } - e := newElement("textarea", attrs["label"], fieldName, p, attrs) + e := NewElement("textarea", attrs["label"], fieldName, p, attrs) - return domElement(e) + return DOMElement(e) } // Timestamp returns the []byte of an <input> HTML element with a label. @@ -60,23 +60,23 @@ func Textarea(fieldName string, p interface{}, attrs map[string]string) []byte { // form of the struct field that this editor input is representing func Timestamp(fieldName string, p interface{}, attrs map[string]string) []byte { var data string - val := valueFromStructField(fieldName, p) + val := ValueFromStructField(fieldName, p) if val == "0" { data = "" } else { data = val } - e := &element{ - tagName: "input", - attrs: attrs, - name: tagNameFromStructField(fieldName, p), - label: attrs["label"], - data: data, - viewBuf: &bytes.Buffer{}, + e := &Element{ + TagName: "input", + Attrs: attrs, + Name: TagNameFromStructField(fieldName, p), + Label: attrs["label"], + Data: data, + ViewBuf: &bytes.Buffer{}, } - return domElementSelfClose(e) + return DOMElementSelfClose(e) } // File returns the []byte of a <input type="file"> HTML element with a label. @@ -84,7 +84,7 @@ func Timestamp(fieldName string, p interface{}, attrs map[string]string) []byte // The `fieldName` argument will cause a panic if it is not exactly the string // form of the struct field that this editor input is representing func File(fieldName string, p interface{}, attrs map[string]string) []byte { - name := tagNameFromStructField(fieldName, p) + name := TagNameFromStructField(fieldName, p) tmpl := `<div class="file-input ` + name + ` input-field col s12"> <label class="active">` + attrs["label"] + `</label> @@ -98,7 +98,7 @@ func File(fieldName string, p interface{}, attrs map[string]string) []byte { </div> </div> <div class="preview"><div class="img-clip"></div></div> - <input class="store ` + name + `" type="hidden" name="` + name + `" value="` + valueFromStructField(fieldName, p) + `" /> + <input class="store ` + name + `" type="hidden" name="` + name + `" value="` + ValueFromStructField(fieldName, p) + `" /> </div>` script := @@ -161,25 +161,35 @@ func Richtext(fieldName string, p interface{}, attrs map[string]string) []byte { iso := []byte(`<div class="iso-texteditor input-field col s12"><label>` + attrs["label"] + `</label>`) isoClose := []byte(`</div>`) + if _, ok := attrs["class"]; ok { + attrs["class"] += "richtext " + fieldName + } else { + attrs["class"] = "richtext " + fieldName + } + + if _, ok := attrs["id"]; ok { + attrs["id"] += "richtext-" + fieldName + } else { + attrs["id"] = "richtext-" + fieldName + } + // create the target element for the editor to attach itself - attrs["class"] = "richtext " + fieldName - attrs["id"] = "richtext-" + fieldName - div := &element{ - tagName: "div", - attrs: attrs, - name: "", - label: "", - data: "", - viewBuf: &bytes.Buffer{}, + div := &Element{ + TagName: "div", + Attrs: attrs, + Name: "", + Label: "", + Data: "", + ViewBuf: &bytes.Buffer{}, } // create a hidden input to store the value from the struct - val := valueFromStructField(fieldName, p) - name := tagNameFromStructField(fieldName, p) + val := ValueFromStructField(fieldName, p) + name := TagNameFromStructField(fieldName, p) input := `<input type="hidden" name="` + name + `" class="richtext-value ` + fieldName + `" value="` + html.EscapeString(val) + `"/>` // build the dom tree for the entire richtext component - iso = append(iso, domElement(div)...) + iso = append(iso, DOMElement(div)...) iso = append(iso, []byte(input)...) iso = append(iso, isoClose...) @@ -257,26 +267,31 @@ func Select(fieldName string, p interface{}, attrs, options map[string]string) [ // <option value="{map key}">{map value}</option> // find the field value in p to determine if an option is pre-selected - fieldVal := valueFromStructField(fieldName, p) + fieldVal := ValueFromStructField(fieldName, p) - attrs["class"] = "browser-default" - sel := newElement("select", attrs["label"], fieldName, p, attrs) - var opts []*element + if _, ok := attrs["class"]; ok { + attrs["class"] += " browser-default" + } else { + attrs["class"] = "browser-default" + } + + sel := NewElement("select", attrs["label"], fieldName, p, attrs) + var opts []*Element // provide a call to action for the select element - cta := &element{ - tagName: "option", - attrs: map[string]string{"disabled": "true", "selected": "true"}, - data: "Select an option...", - viewBuf: &bytes.Buffer{}, + cta := &Element{ + TagName: "option", + Attrs: map[string]string{"disabled": "true", "selected": "true"}, + Data: "Select an option...", + ViewBuf: &bytes.Buffer{}, } // provide a selection reset (will store empty string in db) - reset := &element{ - tagName: "option", - attrs: map[string]string{"value": ""}, - data: "None", - viewBuf: &bytes.Buffer{}, + reset := &Element{ + TagName: "option", + Attrs: map[string]string{"value": ""}, + Data: "None", + ViewBuf: &bytes.Buffer{}, } opts = append(opts, cta, reset) @@ -286,17 +301,17 @@ func Select(fieldName string, p interface{}, attrs, options map[string]string) [ if k == fieldVal { optAttrs["selected"] = "true" } - opt := &element{ - tagName: "option", - attrs: optAttrs, - data: v, - viewBuf: &bytes.Buffer{}, + opt := &Element{ + TagName: "option", + Attrs: optAttrs, + Data: v, + ViewBuf: &bytes.Buffer{}, } opts = append(opts, opt) } - return domElementWithChildrenSelect(sel, opts) + return DOMElementWithChildrenSelect(sel, opts) } // Checkbox returns the []byte of a set of <input type="checkbox"> HTML elements @@ -305,13 +320,18 @@ func Select(fieldName string, p interface{}, attrs, options map[string]string) [ // The `fieldName` argument will cause a panic if it is not exactly the string // form of the struct field that this editor input is representing func Checkbox(fieldName string, p interface{}, attrs, options map[string]string) []byte { - attrs["class"] = "input-field col s12" - div := newElement("div", attrs["label"], fieldName, p, attrs) + if _, ok := attrs["class"]; ok { + attrs["class"] += "input-field col s12" + } else { + attrs["class"] = "input-field col s12" + } + + div := NewElement("div", attrs["label"], fieldName, p, attrs) - var opts []*element + var opts []*Element // get the pre-checked options if this is already an existing post - checkedVals := valueFromStructField(fieldName, p) + checkedVals := ValueFromStructField(fieldName, p) checked := strings.Split(checkedVals, "__ponzu") i := 0 @@ -329,22 +349,22 @@ func Checkbox(fieldName string, p interface{}, attrs, options map[string]string) } } - // create a *element manually using the modified tagNameFromStructFieldMulti + // create a *element manually using the modified TagNameFromStructFieldMulti // func since this is for a multi-value name - input := &element{ - tagName: "input", - attrs: inputAttrs, - name: tagNameFromStructFieldMulti(fieldName, i, p), - label: v, - data: "", - viewBuf: &bytes.Buffer{}, + input := &Element{ + TagName: "input", + Attrs: inputAttrs, + Name: TagNameFromStructFieldMulti(fieldName, i, p), + Label: v, + Data: "", + ViewBuf: &bytes.Buffer{}, } opts = append(opts, input) i++ } - return domElementWithChildrenCheckbox(div, opts) + return DOMElementWithChildrenCheckbox(div, opts) } // Tags returns the []byte of a tag input (in the style of Materialze 'Chips') with a label. @@ -352,10 +372,10 @@ func Checkbox(fieldName string, p interface{}, attrs, options map[string]string) // The `fieldName` argument will cause a panic if it is not exactly the string // form of the struct field that this editor input is representing func Tags(fieldName string, p interface{}, attrs map[string]string) []byte { - name := tagNameFromStructField(fieldName, p) + name := TagNameFromStructField(fieldName, p) // get the saved tags if this is already an existing post - values := valueFromStructField(fieldName, p) + values := ValueFromStructField(fieldName, p) var tags []string if strings.Contains(values, "__ponzu") { tags = strings.Split(values, "__ponzu") @@ -375,7 +395,7 @@ func Tags(fieldName string, p interface{}, attrs map[string]string) []byte { var initial []string i := 0 for _, tag := range tags { - tagName := tagNameFromStructFieldMulti(fieldName, i, p) + tagName := TagNameFromStructFieldMulti(fieldName, i, p) html += `<input type="hidden" class="__ponzu-tag ` + tag + `" name=` + tagName + ` value="` + tag + `"/>` initial = append(initial, `{tag: '`+tag+`'}`) i++ diff --git a/management/editor/repeaters.go b/management/editor/repeaters.go index 617caee..250f2d2 100644 --- a/management/editor/repeaters.go +++ b/management/editor/repeaters.go @@ -34,10 +34,10 @@ import ( // } func InputRepeater(fieldName string, p interface{}, attrs map[string]string) []byte { // find the field values in p to determine pre-filled inputs - fieldVals := valueFromStructField(fieldName, p) + fieldVals := ValueFromStructField(fieldName, p) vals := strings.Split(fieldVals, "__ponzu") - scope := tagNameFromStructField(fieldName, p) + scope := TagNameFromStructField(fieldName, p) html := bytes.Buffer{} _, err := html.WriteString(`<span class="__ponzu-repeat ` + scope + `">`) @@ -47,22 +47,22 @@ func InputRepeater(fieldName string, p interface{}, attrs map[string]string) []b } for i, val := range vals { - el := &element{ - tagName: "input", - attrs: attrs, - name: tagNameFromStructFieldMulti(fieldName, i, p), - data: val, - viewBuf: &bytes.Buffer{}, + el := &Element{ + TagName: "input", + Attrs: attrs, + Name: TagNameFromStructFieldMulti(fieldName, i, p), + Data: val, + ViewBuf: &bytes.Buffer{}, } // only add the label to the first input in repeated list if i == 0 { - el.label = attrs["label"] + el.Label = attrs["label"] } - _, err := html.Write(domElementSelfClose(el)) + _, err := html.Write(DOMElementSelfClose(el)) if err != nil { - log.Println("Error writing domElementSelfClose to InputRepeater buffer") + log.Println("Error writing DOMElementSelfClose to InputRepeater buffer") return nil } } @@ -84,7 +84,7 @@ func InputRepeater(fieldName string, p interface{}, attrs map[string]string) []b func SelectRepeater(fieldName string, p interface{}, attrs, options map[string]string) []byte { // options are the value attr and the display value, i.e. // <option value="{map key}">{map value}</option> - scope := tagNameFromStructField(fieldName, p) + scope := TagNameFromStructField(fieldName, p) html := bytes.Buffer{} _, err := html.WriteString(`<span class="__ponzu-repeat ` + scope + `">`) if err != nil { @@ -93,43 +93,47 @@ func SelectRepeater(fieldName string, p interface{}, attrs, options map[string]s } // find the field values in p to determine if an option is pre-selected - fieldVals := valueFromStructField(fieldName, p) + fieldVals := ValueFromStructField(fieldName, p) vals := strings.Split(fieldVals, "__ponzu") - attrs["class"] = "browser-default" + if _, ok := attrs["class"]; ok { + attrs["class"] += " browser-default" + } else { + attrs["class"] = "browser-default" + } // loop through vals and create selects and options for each, adding to html if len(vals) > 0 { for i, val := range vals { - sel := &element{ - tagName: "select", - attrs: attrs, - name: tagNameFromStructFieldMulti(fieldName, i, p), - viewBuf: &bytes.Buffer{}, + sel := &Element{ + TagName: "select", + Attrs: attrs, + Name: TagNameFromStructFieldMulti(fieldName, i, p), + ViewBuf: &bytes.Buffer{}, } // only add the label to the first select in repeated list if i == 0 { - sel.label = attrs["label"] + sel.Label = attrs["label"] } // create options for select element - var opts []*element + var opts []*Element // provide a call to action for the select element - cta := &element{ - tagName: "option", - attrs: map[string]string{"disabled": "true", "selected": "true"}, - data: "Select an option...", - viewBuf: &bytes.Buffer{}, + cta := &Element{ + TagName: "option", + Attrs: map[string]string{"disabled": "true", "selected": "true"}, + Data: "Select an option...", + ViewBuf: &bytes.Buffer{}, } // provide a selection reset (will store empty string in db) - reset := &element{ - tagName: "option", - attrs: map[string]string{"value": ""}, - data: "None", - viewBuf: &bytes.Buffer{}, + reset := &Element{ + TagName: "option", + Attrs: map[string]string{"value": ""}, + Data: "None", + ViewBuf: &bytes.Buffer{}, } opts = append(opts, cta, reset) @@ -139,19 +143,19 @@ func SelectRepeater(fieldName string, p interface{}, attrs, options map[string]s if k == val { optAttrs["selected"] = "true" } - opt := &element{ - tagName: "option", - attrs: optAttrs, - data: v, - viewBuf: &bytes.Buffer{}, + opt := &Element{ + TagName: "option", + Attrs: optAttrs, + Data: v, + ViewBuf: &bytes.Buffer{}, } opts = append(opts, opt) } - _, err := html.Write(domElementWithChildrenSelect(sel, opts)) + _, err := html.Write(DOMElementWithChildrenSelect(sel, opts)) if err != nil { - log.Println("Error writing domElementWithChildrenSelect to SelectRepeater buffer") + log.Println("Error writing DOMElementWithChildrenSelect to SelectRepeater buffer") return nil } } @@ -174,7 +178,7 @@ func SelectRepeater(fieldName string, p interface{}, attrs, options map[string]s // form of the struct field that this editor input is representing func FileRepeater(fieldName string, p interface{}, attrs map[string]string) []byte { // find the field values in p to determine if an option is pre-selected - fieldVals := valueFromStructField(fieldName, p) + fieldVals := ValueFromStructField(fieldName, p) vals := strings.Split(fieldVals, "__ponzu") addLabelFirst := func(i int, label string) string { @@ -251,7 +255,7 @@ func FileRepeater(fieldName string, p interface{}, attrs map[string]string) []by </script>` // 1=nameidx, 2=className - name := tagNameFromStructField(fieldName, p) + name := TagNameFromStructField(fieldName, p) html := bytes.Buffer{} _, err := html.WriteString(`<span class="__ponzu-repeat ` + name + `">`) @@ -262,7 +266,7 @@ func FileRepeater(fieldName string, p interface{}, attrs map[string]string) []by for i, val := range vals { className := fmt.Sprintf("%s-%d", name, i) - nameidx := tagNameFromStructFieldMulti(fieldName, i, p) + nameidx := TagNameFromStructFieldMulti(fieldName, i, p) _, err := html.WriteString(fmt.Sprintf(tmpl, nameidx, addLabelFirst(i, attrs["label"]), val, className, fieldName)) if err != nil { @@ -288,7 +292,7 @@ func FileRepeater(fieldName string, p interface{}, attrs map[string]string) []by // RepeatController generates the javascript to control any repeatable form // element in an editor based on its type, field name and HTML tag name func RepeatController(fieldName string, p interface{}, inputSelector, cloneSelector string) []byte { - scope := tagNameFromStructField(fieldName, p) + scope := TagNameFromStructField(fieldName, p) script := ` <script> $(function() { diff --git a/management/editor/values.go b/management/editor/values.go index 7d71d3f..bc97f99 100644 --- a/management/editor/values.go +++ b/management/editor/values.go @@ -6,7 +6,9 @@ import ( "strings" ) -func tagNameFromStructField(name string, post interface{}) string { +// TagNameFromStructField does a lookup on the `json` struct tag for a given +// field of a struct +func TagNameFromStructField(name string, post interface{}) string { // sometimes elements in these environments will not have a name, // and thus no tag name in the struct which correlates to it. if name == "" { @@ -26,16 +28,19 @@ func tagNameFromStructField(name string, post interface{}) string { return tag } +// TagNameFromStructFieldMulti calls TagNameFromStructField and formats is for +// use with gorilla/schema // due to the format in which gorilla/schema expects form names to be when // one is associated with multiple values, we need to output the name as such. // Ex. 'category.0', 'category.1', 'category.2' and so on. -func tagNameFromStructFieldMulti(name string, i int, post interface{}) string { - tag := tagNameFromStructField(name, post) +func TagNameFromStructFieldMulti(name string, i int, post interface{}) string { + tag := TagNameFromStructField(name, post) return fmt.Sprintf("%s.%d", tag, i) } -func valueFromStructField(name string, post interface{}) string { +// ValueFromStructField returns the string value of a field in a struct +func ValueFromStructField(name string, post interface{}) string { field := reflect.Indirect(reflect.ValueOf(post)).FieldByName(name) switch field.Kind() { |