From e4fa817d305f701be0aeb34c079c93108940e2c3 Mon Sep 17 00:00:00 2001 From: Steve Manuel Date: Tue, 20 Dec 2016 13:13:54 -0800 Subject: adding style update to admin css --- system/admin/static/dashboard/css/admin.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/system/admin/static/dashboard/css/admin.css b/system/admin/static/dashboard/css/admin.css index 8d2fb89..4d6e444 100644 --- a/system/admin/static/dashboard/css/admin.css +++ b/system/admin/static/dashboard/css/admin.css @@ -185,6 +185,11 @@ li:hover .quick-delete-post, li:hover .delete-user { padding: 20px; } +.controls button { + padding: 0px 10px 5px 10px; + position: relative; + top: -10px; +} /* OVERRIDE Bootstrap + Materialize conflicts */ .iso-texteditor.input-field label { -- cgit v1.2.3 From f6b39f22c712a11842b83e12879c1ef899337291 Mon Sep 17 00:00:00 2001 From: Steve Manuel Date: Tue, 20 Dec 2016 13:15:06 -0800 Subject: adding generic RepeatController JS creator and working RepeatSelect repeater input --- management/editor/elements.go | 2 +- management/editor/repeaters.go | 204 +++++++++++++++++++++++++++++++++++++++++ management/manager/manager.go | 2 +- 3 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 management/editor/repeaters.go diff --git a/management/editor/elements.go b/management/editor/elements.go index 9b35c65..75c37e2 100644 --- a/management/editor/elements.go +++ b/management/editor/elements.go @@ -325,7 +325,7 @@ func Checkbox(fieldName string, p interface{}, attrs, options map[string]string) } } - // create a *element manually using the maodified tagNameFromStructFieldMulti + // create a *element manually using the modified tagNameFromStructFieldMulti // func since this is for a multi-value name input := &element{ TagName: "input", diff --git a/management/editor/repeaters.go b/management/editor/repeaters.go new file mode 100644 index 0000000..f9c4da6 --- /dev/null +++ b/management/editor/repeaters.go @@ -0,0 +1,204 @@ +package editor + +import ( + "bytes" + "strings" +) + +// RepeatSelect returns the []byte of a HTML element plus internal with a label. +// SelectRepeater returns the []byte of a HTML element with a label. +// IMPORTANT: +// 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 FileRepeater(fieldName string, p interface{}, attrs map[string]string) []byte { + name := tagNameFromStructField(fieldName, p) + tmpl := + `
+ +
+
+ Upload + +
+
+ +
+
+
+ +
` + + script := + `` + + html := `` + tmpl + `` + return append([]byte(html+script), RepeatController(fieldName, p, "input.store."+name, "div.file-input."+name)...) } // 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{}, htmlTagName string) []byte { +func RepeatController(fieldName string, p interface{}, inputSelector, cloneSelector string) []byte { scope := tagNameFromStructField(fieldName, p) script := ` ` + // 1=nameidx, 2=className + + name := tagNameFromStructField(fieldName, p) + + html := bytes.Buffer{} + html.WriteString(``) + for i, val := range vals { + className := fmt.Sprintf("%s-%d", name, i) + nameidx := tagNameFromStructFieldMulti(fieldName, i, p) + html.WriteString(fmt.Sprintf(tmpl, nameidx, addLabelFirst(i, attrs["label"]), val, className, fieldName)) + html.WriteString(fmt.Sprintf(script, nameidx, className)) + } + html.WriteString(``) - html := `` + tmpl + `` - return append([]byte(html+script), RepeatController(fieldName, p, "input.store."+name, "div.file-input."+name)...) + return append(html.Bytes(), RepeatController(fieldName, p, "input.upload", "div.file-input."+fieldName)...) } // RepeatController generates the javascript to control any repeatable form @@ -166,19 +246,45 @@ func RepeatController(fieldName string, p interface{}, inputSelector, cloneSelec var scope = $('.__ponzu-repeat.` + scope + `'); var getChildren = function() { - return scope.find('` + inputSelector + `') + return scope.find('` + cloneSelector + `') } var resetFieldNames = function() { // loop through children, set its name to the fieldName.i where // i is the current index number of children array var children = getChildren(); + for (var i = 0; i < children.length; i++) { - var el = children[i]; - $(el).attr('name', '` + scope + `.'+String(i)); - + var preset = false; + var $el = children.eq(i); + var name = '` + scope + `.'+String(i); + + $el.find('` + inputSelector + `').attr('name', name); + + // ensure no other input-like elements besides ` + inputSelector + ` + // get the new name by setting it to an empty string + $el.find('input, select, textarea').each(function(i, elem) { + var $elem = $(elem); + + // if the elem is not ` + inputSelector + ` and has no value + // set the name to an empty string + if (!$elem.is('` + inputSelector + `')) { + if ($elem.val() === '') { + $elem.attr('name', ''); + } else { + preset = true; + } + } + }); + + // if there is a preset value, remove the name attr from the + // ` + inputSelector + ` element so it doesn't overwrite db + if (preset) { + $el.find('` + inputSelector + `').attr('name', ''); + } + // reset controllers - $(el).find('.controls').remove(); + $el.find('.controls').remove(); } applyRepeatControllers(); @@ -190,18 +296,22 @@ func RepeatController(fieldName string, p interface{}, inputSelector, cloneSelec var add = e.target; // find and clone the repeatable input-like element - var subject = $(add).parent().closest('` + cloneSelector + `'); - var clone = subject.clone(); + var source = $(add).parent().closest('` + cloneSelector + `'); + var clone = source.clone(); - // if repeat has label, remove it + // if clone has label, remove it clone.find('label').remove(); // remove the pre-filled value from clone - clone.find('` + inputSelector + `').val(""); + clone.find('` + inputSelector + `').val(''); + clone.find('input').val(''); - // remove controls if already present + // remove controls from clone if already present clone.find('.controls').remove(); + // remove input preview on clone if copied from source + clone.find('.preview').remove(); + // add clone to scope and reset field name attributes scope.append(clone); @@ -260,10 +370,10 @@ func RepeatController(fieldName string, p interface{}, inputSelector, cloneSelec for (var i = 0; i < children.length; i++) { var el = children[i]; - $(el).parent().find('.controls').remove(); + $(el).find('` + inputSelector + `').parent().find('.controls').remove(); var controls = createControls(); - $(el).parent().append(controls); + $(el).append(controls); } } diff --git a/system/admin/handlers.go b/system/admin/handlers.go index e1487c5..ff30040 100644 --- a/system/admin/handlers.go +++ b/system/admin/handlers.go @@ -1403,10 +1403,11 @@ func editHandler(res http.ResponseWriter, req *http.Request) { if req.PostForm.Get(key) == "" { req.PostForm.Set(key, v[0]) - discardKeys = append(discardKeys, k) } else { req.PostForm.Add(key, v[0]) } + + discardKeys = append(discardKeys, k) } } diff --git a/system/api/external.go b/system/api/external.go index 86e4a99..302b7c9 100644 --- a/system/api/external.go +++ b/system/api/external.go @@ -85,10 +85,11 @@ func externalContentHandler(res http.ResponseWriter, req *http.Request) { if req.PostForm.Get(key) == "" { req.PostForm.Set(key, v[0]) - discardKeys = append(discardKeys, k) } else { req.PostForm.Add(key, v[0]) } + + discardKeys = append(discardKeys, k) } } diff --git a/system/db/config.go b/system/db/config.go index 0e49307..ce76021 100644 --- a/system/db/config.go +++ b/system/db/config.go @@ -34,10 +34,11 @@ func SetConfig(data url.Values) error { if data.Get(key) == "" { data.Set(key, v[0]) - discardKeys = append(discardKeys, k) } else { data.Add(key, v[0]) } + + discardKeys = append(discardKeys, k) } } -- cgit v1.2.3 From d9916ff0fbba3d2a24c709f44fd728ef862daf69 Mon Sep 17 00:00:00 2001 From: Steve Manuel Date: Thu, 22 Dec 2016 22:29:28 -0800 Subject: adding forgotten name attr to identified input --- management/editor/repeaters.go | 1 + 1 file changed, 1 insertion(+) diff --git a/management/editor/repeaters.go b/management/editor/repeaters.go index 81497a5..fea09d4 100644 --- a/management/editor/repeaters.go +++ b/management/editor/repeaters.go @@ -272,6 +272,7 @@ func RepeatController(fieldName string, p interface{}, inputSelector, cloneSelec if ($elem.val() === '') { $elem.attr('name', ''); } else { + $elem.attr('name', name); preset = true; } } -- cgit v1.2.3 From 91de4e0ad607aff54fa51914c08f357b535684b1 Mon Sep 17 00:00:00 2001 From: Steve Manuel Date: Thu, 22 Dec 2016 22:52:10 -0800 Subject: checking for bad inputs explicitly -- could be improved --- management/editor/repeaters.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/management/editor/repeaters.go b/management/editor/repeaters.go index fea09d4..f528894 100644 --- a/management/editor/repeaters.go +++ b/management/editor/repeaters.go @@ -269,7 +269,7 @@ func RepeatController(fieldName string, p interface{}, inputSelector, cloneSelec // if the elem is not ` + inputSelector + ` and has no value // set the name to an empty string if (!$elem.is('` + inputSelector + `')) { - if ($elem.val() === '') { + if ($elem.val() === '' || $elem.is('.file-path')) { $elem.attr('name', ''); } else { $elem.attr('name', name); @@ -378,7 +378,7 @@ func RepeatController(fieldName string, p interface{}, inputSelector, cloneSelec } } - applyRepeatControllers(); + resetFieldNames(); }); -- cgit v1.2.3 From 29959dc55482b04388bc0c8a426650215ac3d5b2 Mon Sep 17 00:00:00 2001 From: Steve Manuel Date: Thu, 22 Dec 2016 22:55:47 -0800 Subject: fixing docs --- management/editor/repeaters.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/management/editor/repeaters.go b/management/editor/repeaters.go index f528894..37fb982 100644 --- a/management/editor/repeaters.go +++ b/management/editor/repeaters.go @@ -13,16 +13,16 @@ import ( // 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 // type Person struct { -// Name string `json:"name"` +// Names []string `json:"names"` // } // // func (p *Person) MarshalEditor() ([]byte, error) { // view, err := editor.Form(p, // editor.Field{ -// View: editor.InputRepeater("Name", p, map[string]string{ -// "label": "Name", +// View: editor.InputRepeater("Names", p, map[string]string{ +// "label": "Names", // "type": "text", -// "placeholder": "Enter the Name here", +// "placeholder": "Enter a Name here", // }), // } // ) -- cgit v1.2.3