diff --git a/components/input/list-binder.go b/components/input/list-binder.go index c3bbf7e..0765fa5 100644 --- a/components/input/list-binder.go +++ b/components/input/list-binder.go @@ -1,10 +1,18 @@ package input -import "strconv" +import ( + "fmt" + "strconv" -// ListBinder describes the interface that anything that wants to present key value pairs needs to implement. + "golang.org/x/exp/slices" +) + +// ListBinder describes an interface that simple lists can implement to be compatible with list based UI components. type ListBinder interface { ListKeyValuePairs() []ListKeyValuePair + ListDeleteKey(key string) bool // Removes the entry with the given key, and returns true if it got deleted successfully. + ListAddKeyValuePair(key, value string) error // Adds the key value pair to the list. + ListLen() int // Returns the length of the list. } type ListKeyValuePair struct { @@ -14,36 +22,165 @@ type ListKeyValuePair struct { // ListBindGenericSlice implements ListBinder for slices that are of some arbitrary type. // For this to work, you need to supply a function that returns key value pairs for every slice entry. type ListBindGenericSlice[T any] struct { - Slice *[]T - KeyValueFunc func(index int, entry T) ListKeyValuePair + Slice *[]T } func (l ListBindGenericSlice[T]) ListKeyValuePairs() []ListKeyValuePair { - if l.Slice == nil || l.KeyValueFunc == nil { - return nil - } - - result := make([]ListKeyValuePair, 0, len(*l.Slice)) - for i, entry := range *l.Slice { - result = append(result, l.KeyValueFunc(i, entry)) - } - return result -} - -// ListBindSlice implements ListBinder for string slices. -// The list index (as a string) is used as a key. -type ListBindSlice struct { - Slice *[]string -} - -func (l ListBindSlice) ListKeyValuePairs() []ListKeyValuePair { if l.Slice == nil { return nil } result := make([]ListKeyValuePair, 0, len(*l.Slice)) for i, entry := range *l.Slice { - result = append(result, ListKeyValuePair{Key: strconv.Itoa(i), Value: entry}) + + var str string + switch v := any(entry).(type) { + case string: + str = v + case int: + str = strconv.FormatInt(int64(v), 10) + case int8: + str = strconv.FormatInt(int64(v), 10) + case int16: + str = strconv.FormatInt(int64(v), 10) + case int32: + str = strconv.FormatInt(int64(v), 10) + case int64: + str = strconv.FormatInt(int64(v), 10) + case uint: + str = strconv.FormatUint(uint64(v), 10) + case uint8: + str = strconv.FormatUint(uint64(v), 10) + case uint16: + str = strconv.FormatUint(uint64(v), 10) + case uint32: + str = strconv.FormatUint(uint64(v), 10) + case uint64: + str = strconv.FormatUint(uint64(v), 10) + case float32: + str = strconv.FormatFloat(float64(v), 'f', -1, 32) // TODO: Format number in current user's locale + case float64: + str = strconv.FormatFloat(float64(v), 'f', -1, 64) + } + + result = append(result, ListKeyValuePair{Key: strconv.Itoa(i), Value: str}) } return result } + +func (l ListBindGenericSlice[T]) ListDeleteKey(key string) bool { + if l.Slice == nil { + return false + } + + index, err := strconv.Atoi(key) + if err != nil { + return false + } + + if index < 0 || index >= len(*l.Slice) { + return false + } + + *l.Slice = slices.Delete(*l.Slice, index, index+1) + return true +} + +func (l ListBindGenericSlice[T]) ListAddKeyValuePair(key, value string) error { + var val T + switch v := any(&val).(type) { + case *string: + *v = value + case *int: + val, err := strconv.ParseInt(value, 10, 0) + if err != nil { + return err + } + *v = int(val) + case *int8: + val, err := strconv.ParseInt(value, 10, 8) + if err != nil { + return err + } + *v = int8(val) + case *int16: + val, err := strconv.ParseInt(value, 10, 16) + if err != nil { + return err + } + *v = int16(val) + case *int32: + val, err := strconv.ParseInt(value, 10, 32) + if err != nil { + return err + } + *v = int32(val) + case *int64: + val, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return err + } + *v = int64(val) + case *uint: + val, err := strconv.ParseUint(value, 10, 0) + if err != nil { + return err + } + *v = uint(val) + case *uint8: + val, err := strconv.ParseUint(value, 10, 8) + if err != nil { + return err + } + *v = uint8(val) + case *uint16: + val, err := strconv.ParseUint(value, 10, 16) + if err != nil { + return err + } + *v = uint16(val) + case *uint32: + val, err := strconv.ParseUint(value, 10, 32) + if err != nil { + return err + } + *v = uint32(val) + case *uint64: + val, err := strconv.ParseUint(value, 10, 64) + if err != nil { + return err + } + *v = uint64(val) + case *float32: + val, err := strconv.ParseFloat(value, 32) + if err != nil { + return err + } + *v = float32(val) + case *float64: + val, err := strconv.ParseFloat(value, 64) + if err != nil { + return err + } + *v = float64(val) + default: + return fmt.Errorf("bound type %T is not supported", v) + } + + index, err := strconv.Atoi(key) + if err != nil { + return fmt.Errorf("failed to parse index: %w", err) + } + + if index < 0 || index > len(*l.Slice) { + return fmt.Errorf("index %d out of bounds", index) + } + + *l.Slice = slices.Insert(*l.Slice, index, val) + + return nil +} + +func (l ListBindGenericSlice[T]) ListLen() int { + return len(*l.Slice) +} diff --git a/components/input/tags.go b/components/input/tags.go new file mode 100644 index 0000000..467db53 --- /dev/null +++ b/components/input/tags.go @@ -0,0 +1,52 @@ +package input + +import ( + "strconv" + + "github.com/vugu/vugu" + "golang.org/x/exp/slices" +) + +// Tags provides a way for the user to add/remove entries from a slice. +type Tags struct { + AttrMap vugu.AttrMap + + Bind ListBinder // Binds the shown tags to some slice. + + fieldValue string +} + +func (c *Tags) keyValuePairs() []ListKeyValuePair { + if c.Bind == nil { + return nil + } + + return c.Bind.ListKeyValuePairs() +} + +func (c *Tags) handleButtonAdd(event vugu.DOMEvent) { + if c.Bind == nil { + return + } + + // Don't allow empty entries. + if c.fieldValue == "" { + return + } + + // Don't allow duplicate entries. + values := c.Bind.ListKeyValuePairs() + if slices.ContainsFunc(values, func(k ListKeyValuePair) bool { return k.Value == c.fieldValue }) { + return + } + + c.Bind.ListAddKeyValuePair(strconv.Itoa(c.Bind.ListLen()), c.fieldValue) +} + +func (c *Tags) handleButtonDelete(event vugu.DOMEvent, index int) { + if c.Bind == nil { + return + } + + c.Bind.ListDeleteKey(strconv.Itoa(index)) +} diff --git a/components/input/tags.vugu b/components/input/tags.vugu new file mode 100644 index 0000000..073a65e --- /dev/null +++ b/components/input/tags.vugu @@ -0,0 +1,33 @@ +
+ +
+
+ + + + diff --git a/components/input/tags_vgen.go b/components/input/tags_vgen.go new file mode 100644 index 0000000..a985355 --- /dev/null +++ b/components/input/tags_vgen.go @@ -0,0 +1,165 @@ +package input + +// Code generated by vugu via vugugen. Please regenerate instead of editing or add additional code in a separate file. DO NOT EDIT. + +import "fmt" +import "reflect" +import "github.com/vugu/vjson" +import "github.com/vugu/vugu" +import js "github.com/vugu/vugu/js" + +import ( + "git.d3nexus.de/Dadido3/D3vugu-components/icons" + "git.d3nexus.de/Dadido3/D3vugu-components/utils" +) + +func (c *Tags) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { + + vgout = &vugu.BuildOut{} + + var vgiterkey interface{} + _ = vgiterkey + var vgn *vugu.VGNode + vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Namespace: "", Data: "div", Attr: []vugu.VGAttribute(nil)} + vgout.Out = append(vgout.Out, vgn) // root for output + vgn.AddAttrList(utils.AttributesAppend{AttrMap: c.AttrMap, Classes: "d3c-1685640525"}) + { + vgparent := vgn + _ = vgparent + vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t"} + vgparent.AppendChild(vgn) + { + vgcompKey := vugu.MakeCompKey(0x10CE996FF2CD6A72^vgin.CurrentPositionHash(), vgiterkey) + // ask BuildEnv for prior instance of this specific component + vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*Field) + if vgcomp == nil { + // create new one if needed + vgcomp = new(Field) + vgin.BuildEnv.WireComponent(vgcomp) + } + vgin.BuildEnv.UseComponent(vgcompKey, vgcomp) // ensure we can use this in the cache next time around + vgcomp.Bind = FieldBindAny{Value: &c.fieldValue} + vgcomp.DefaultSlot = vugu.NewBuilderFunc(func(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { + vgn := &vugu.VGNode{Type: vugu.VGNodeType(3)} + vgout = &vugu.BuildOut{} + vgout.Out = append(vgout.Out, vgn) + vgparent := vgn + _ = vgparent + + { + vgcompKey := vugu.MakeCompKey(0x3C003477D780B326^vgin.CurrentPositionHash(), vgiterkey) + // ask BuildEnv for prior instance of this specific component + vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*Button) + if vgcomp == nil { + // create new one if needed + vgcomp = new(Button) + vgin.BuildEnv.WireComponent(vgcomp) + } + vgin.BuildEnv.UseComponent(vgcompKey, vgcomp) // ensure we can use this in the cache next time around + vgcomp.Click = ClickFunc(func(event ClickEvent) { c.handleButtonAdd(event) }) + vgcomp.DefaultSlot = vugu.NewBuilderFunc(func(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { + vgn := &vugu.VGNode{Type: vugu.VGNodeType(3)} + vgout = &vugu.BuildOut{} + vgout.Out = append(vgout.Out, vgn) + vgparent := vgn + _ = vgparent + + { + vgcompKey := vugu.MakeCompKey(0xE13B38C095FCE92C^vgin.CurrentPositionHash(), vgiterkey) + // ask BuildEnv for prior instance of this specific component + vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LPlus) + if vgcomp == nil { + // create new one if needed + vgcomp = new(icons.LPlus) + vgin.BuildEnv.WireComponent(vgcomp) + } + vgin.BuildEnv.UseComponent(vgcompKey, vgcomp) // ensure we can use this in the cache next time around + vgout.Components = append(vgout.Components, vgcomp) + vgn = &vugu.VGNode{Component: vgcomp} + vgparent.AppendChild(vgn) + } + return + }) + vgout.Components = append(vgout.Components, vgcomp) + vgn = &vugu.VGNode{Component: vgcomp} + vgparent.AppendChild(vgn) + } + return + }) + vgout.Components = append(vgout.Components, vgcomp) + vgn = &vugu.VGNode{Component: vgcomp} + vgparent.AppendChild(vgn) + } + vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t"} + vgparent.AppendChild(vgn) + for i, entry := range c.keyValuePairs() { + var vgiterkey interface{} = i + _ = vgiterkey + i := i + _ = i + entry := entry + _ = entry + vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Namespace: "", Data: "div", Attr: []vugu.VGAttribute{vugu.VGAttribute{Namespace: "", Key: "class", Val: "d3c-1685640525-tag d3c-color-layer-1 d3c-button-borderless"}}} + vgparent.AppendChild(vgn) + { + vgparent := vgn + _ = vgparent + vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Namespace: "", Data: "span", Attr: []vugu.VGAttribute(nil)} + vgparent.AppendChild(vgn) + vgn.SetInnerHTML(entry.Value) + { + vgcompKey := vugu.MakeCompKey(0x1FB470EBF2186CBA^vgin.CurrentPositionHash(), vgiterkey) + // ask BuildEnv for prior instance of this specific component + vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*Button) + if vgcomp == nil { + // create new one if needed + vgcomp = new(Button) + vgin.BuildEnv.WireComponent(vgcomp) + } + vgin.BuildEnv.UseComponent(vgcompKey, vgcomp) // ensure we can use this in the cache next time around + vgcomp.Click = ClickFunc(func(event ClickEvent) { c.handleButtonDelete(event, i) }) + vgcomp.DefaultSlot = vugu.NewBuilderFunc(func(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { + vgn := &vugu.VGNode{Type: vugu.VGNodeType(3)} + vgout = &vugu.BuildOut{} + vgout.Out = append(vgout.Out, vgn) + vgparent := vgn + _ = vgparent + + { + vgcompKey := vugu.MakeCompKey(0xA2FB9E15EF6D040C^vgin.CurrentPositionHash(), vgiterkey) + // ask BuildEnv for prior instance of this specific component + vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LDelete) + if vgcomp == nil { + // create new one if needed + vgcomp = new(icons.LDelete) + vgin.BuildEnv.WireComponent(vgcomp) + } + vgin.BuildEnv.UseComponent(vgcompKey, vgcomp) // ensure we can use this in the cache next time around + vgout.Components = append(vgout.Components, vgcomp) + vgn = &vugu.VGNode{Component: vgcomp} + vgparent.AppendChild(vgn) + } + return + }) + vgout.Components = append(vgout.Components, vgcomp) + vgn = &vugu.VGNode{Component: vgcomp} + vgparent.AppendChild(vgn) + } + } + } + vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n"} + vgparent.AppendChild(vgn) + } + vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Data: "style", Attr: []vugu.VGAttribute(nil)} + { + vgn.AppendChild(&vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t.d3c-1685640525 {\n\t\tdisplay: inline-flex;\n\t\tflex-direction: column;\n\t\tgap: 0.5em;\n\t\t/*padding: 0.25em 0.5em;*/\n\t\t/*margin: 0.5em 0;*/\n\t\tmin-width: 10em;\n\t}\n\n\t.d3c-1685640525-tag {\n\t\tdisplay: flex;\n\t\tjustify-content: space-between;\n\t\talign-items: center;\n\t\tpadding-left: 0.5em;\n\t\tborder-radius: 4px;\n\t\tgap: 1em;\n\t\tbackground-color: var(--d3c-color-background);\n\t\tcolor: var(--d3c-color-text);\n\t}\n", Attr: []vugu.VGAttribute(nil)}) + } + vgout.AppendCSS(vgn) + return vgout +} + +// 'fix' unused imports +var _ fmt.Stringer +var _ reflect.Type +var _ vjson.RawMessage +var _ js.Value diff --git a/page-input.go b/page-input.go index 6fb15cd..593ca31 100644 --- a/page-input.go +++ b/page-input.go @@ -15,8 +15,11 @@ type PageInput struct { dropdown1Slice []string `vugu:"data"` dropdown1Index int `vugu:"data"` + + tags1Slice []string `vugu:"data"` } func (c *PageInput) Init(ctx vugu.InitCtx) { c.dropdown1Slice = []string{"This", "is", "a", "list", "of", "things!"} + c.tags1Slice = []string{"some", "tags"} } diff --git a/page-input.vugu b/page-input.vugu index 3e86168..f93ebe8 100644 --- a/page-input.vugu +++ b/page-input.vugu @@ -79,9 +79,13 @@

Drop-down

- + +

Tags

+

Select or change the list of tags

+ + diff --git a/page-input_vgen.go b/page-input_vgen.go index 0e5ed77..13a780f 100644 --- a/page-input_vgen.go +++ b/page-input_vgen.go @@ -31,7 +31,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xB26EBEB1D8E73BFF^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x615B183A39086BAD^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*layout.Container) if vgcomp == nil { @@ -62,7 +62,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "Clickable components support the "} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0x61A9ED57B2D7FC0C^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x144927BBBE822C9D^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*view.CodeInline) if vgcomp == nil { @@ -89,7 +89,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: " event that handlers can be registered to with "} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xB81D4F0D1B7B2451^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x14FD40DE21F3B5A9^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*view.CodeInline) if vgcomp == nil { @@ -117,7 +117,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0x8B3FBE62D7FA14E0^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x170617C61FF19735^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*view.Code) if vgcomp == nil { @@ -166,7 +166,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0x23A75C8C62CC7ACD^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x7DC7020BB251F184^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*view.Code) if vgcomp == nil { @@ -198,7 +198,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xAE9F9A663C5516CE^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0xD796F89AFC5AFF02^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*input.Button) if vgcomp == nil { @@ -232,7 +232,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xF589A6C162306426^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x6F80C7C729EAD6B7^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*view.Code) if vgcomp == nil { @@ -267,7 +267,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xD1D77E8F211E03BE^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x84BE4EA2C6B25413^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*input.Button) if vgcomp == nil { @@ -284,7 +284,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { _ = vgparent { - vgcompKey := vugu.MakeCompKey(0xFC981C2DDF2A88D0^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x8C7F8502EBBA648^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LDocument) if vgcomp == nil { @@ -330,7 +330,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "Use the "} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xA543BA04FA033BC^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x42521B1B8BA38C19^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*view.CodeInline) if vgcomp == nil { @@ -360,7 +360,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xFB49E11243E269C4^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0xAD2AC147785AC8D1^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*view.Code) if vgcomp == nil { @@ -395,7 +395,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0x912307B559566958^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0xB9256E7634F07044^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*input.Button) if vgcomp == nil { @@ -414,7 +414,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { _ = vgparent { - vgcompKey := vugu.MakeCompKey(0x551841C4245C4D9C^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x812673DC183AC45E^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LGlobe) if vgcomp == nil { @@ -454,7 +454,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0x5F3C6AE687A90906^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x482382C587C006C3^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*view.Code) if vgcomp == nil { @@ -486,7 +486,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xC1E721EE39A2E365^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x25F0462B514B1151^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*input.Button) if vgcomp == nil { @@ -529,7 +529,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xB50AB6DDFCE0F888^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x31B5453F49A04DDC^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*view.Code) if vgcomp == nil { @@ -567,7 +567,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xA262AF139BBC7695^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x30CEFACA214DCAC3^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*input.Field) if vgcomp == nil { @@ -601,7 +601,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xE6214B61489F970C^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0xEE8003837DFEF834^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*input.Field) if vgcomp == nil { @@ -635,7 +635,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xADA936494B3AA8DD^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0xF92AC9CBF6C0F591^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*input.Field) if vgcomp == nil { @@ -666,7 +666,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "For passwords you have to use the "} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0x1FA84C8CB03D8627^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0xD147584B819A6C0E^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*view.CodeInline) if vgcomp == nil { @@ -701,7 +701,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0x4B1753F5FE40444B^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x99A4B5C7546E1588^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*input.Field) if vgcomp == nil { @@ -735,7 +735,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xFBFF656CD8DD1D02^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0xD7881C719A131300^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*input.Field) if vgcomp == nil { @@ -757,7 +757,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0x9E80AFDA2C83321E^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x8A0444B34DF33F9B^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*input.Button) if vgcomp == nil { @@ -778,7 +778,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgparent.AppendChild(vgn) if !c.inputField5Bool { { - vgcompKey := vugu.MakeCompKey(0x3B3A5A3B4A9E4726^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x8DA586C1EA6AC2F^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LLockOpened) if vgcomp == nil { @@ -798,7 +798,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgparent.AppendChild(vgn) if c.inputField5Bool { { - vgcompKey := vugu.MakeCompKey(0x6EB9CA19A9C5ADD6^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0xC024DEF46FCAC5C^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LLockClosed) if vgcomp == nil { @@ -825,7 +825,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0x224D34D59F84E415^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x1BC4315231335E47^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*input.Button) if vgcomp == nil { @@ -844,7 +844,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0x4DF16B456825F66A^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x4144F85FC2E531FE^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LGlobe) if vgcomp == nil { @@ -886,7 +886,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} vgparent.AppendChild(vgn) { - vgcompKey := vugu.MakeCompKey(0xC3DF5DFFB763B333^vgin.CurrentPositionHash(), vgiterkey) + vgcompKey := vugu.MakeCompKey(0x32C555F078A970D4^vgin.CurrentPositionHash(), vgiterkey) // ask BuildEnv for prior instance of this specific component vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*input.Dropdown) if vgcomp == nil { @@ -896,7 +896,7 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { } vgin.BuildEnv.UseComponent(vgcompKey, vgcomp) // ensure we can use this in the cache next time around vgcomp.Bind = input.FieldBindAny{Value: &c.dropdown1Index} - vgcomp.BindList = input.ListBindSlice{Slice: &c.dropdown1Slice} + vgcomp.BindList = input.ListBindGenericSlice[string]{Slice: &c.dropdown1Slice} vgcomp.AttrMap = make(map[string]interface{}, 8) vgcomp.AttrMap["id"] = "page-dropdown-1" vgout.Components = append(vgout.Components, vgcomp) @@ -908,6 +908,35 @@ func (c *PageInput) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Namespace: "", Data: "span", Attr: []vugu.VGAttribute(nil)} vgparent.AppendChild(vgn) vgn.SetInnerHTML(fmt.Sprintf("The selected index is %d.", c.dropdown1Index)) + vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\n\t\t"} + vgparent.AppendChild(vgn) + vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Namespace: "", Data: "h2", Attr: []vugu.VGAttribute(nil)} + vgparent.AppendChild(vgn) + vgn.SetInnerHTML(vugu.HTML("Tags")) + vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} + vgparent.AppendChild(vgn) + vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Namespace: "", Data: "p", Attr: []vugu.VGAttribute(nil)} + vgparent.AppendChild(vgn) + vgn.SetInnerHTML(vugu.HTML("Select or change the list of tags")) + vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t"} + vgparent.AppendChild(vgn) + { + vgcompKey := vugu.MakeCompKey(0xD57B23C7C9B6D8F8^vgin.CurrentPositionHash(), vgiterkey) + // ask BuildEnv for prior instance of this specific component + vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*input.Tags) + if vgcomp == nil { + // create new one if needed + vgcomp = new(input.Tags) + vgin.BuildEnv.WireComponent(vgcomp) + } + vgin.BuildEnv.UseComponent(vgcompKey, vgcomp) // ensure we can use this in the cache next time around + vgcomp.Bind = input.ListBindGenericSlice[string]{Slice: &c.tags1Slice} + vgcomp.AttrMap = make(map[string]interface{}, 8) + vgcomp.AttrMap["id"] = "page-tags-1" + vgout.Components = append(vgout.Components, vgcomp) + vgn = &vugu.VGNode{Component: vgcomp} + vgparent.AppendChild(vgn) + } vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\n\t"} vgparent.AppendChild(vgn) return