github.com/vugu/vugu@v0.3.6-0.20240430171613-3f6f402e014b/vgform/select_gen.go (about) 1 // Code generated by vugu via vugugen DO NOT EDIT. 2 // Please regenerate instead of editing or add additional code in a separate file. 3 4 package vgform 5 6 import "fmt" 7 import "reflect" 8 import "github.com/vugu/vjson" 9 import "github.com/vugu/vugu" 10 import js "github.com/vugu/vugu/js" 11 12 /* 13 14 VARIOUS OLD NOTES: 15 16 // vg-js-create='c.el=value' vg-js-populate='c.handlePopulate()' 17 // vg-attr='vugu.VGAttributeListerFunc(c.makeAttrs)' 18 19 Things to figure out: 20 21 - `vg-ref=` We'll most likely need a way to access a DOM element directly after render. 22 (When exact 'after render' is I'm not sure yet). One way to do this would be to have 23 a vg-ref= attribute which tells the renderer to send this ID over to the JS side 24 and associate the element so we can look it up later. Then some method like 25 `vuguRef(id) element` can exist in JS and we can use it to access the element 26 via the `js` package. Other solutions are possible but the requirement is the 27 ability to get a js.Value reference to a specific element in your Vugu template. 28 29 - "Slots", developers should have the ability to provide their own <option> elements inside 30 of this component. E.g. <vgform:Select><option value="a">A</option></vgform:Select>. 31 There is a bit of info on ideas for slot here: https://github.com/vugu/vugu/wiki/Component-Related-Features-Design#slots 32 In this case there is only one "default" slot, but multiple names slots should be possible 33 and will be needed by component libraries. 34 35 - THIS WORKS NOW "Component Events", we'll need to define what <vgform:Select @Change='...'> means. 36 I think the same convention should be used where a capital letter indicates a corresopnding 37 Go field. The question is what it's type should be and what should the expression 38 for '...' be above. Another question is if there is a propagation model for these 39 events. Do we need the ability for these types of events to "bubble up" to parent 40 components? If we don't need that then I think simple function fields and calls to them 41 are fine (and I also really like that this keeps things type safe). But if we need 42 some bubbling system that probably won't work. 43 More info here: https://github.com/vugu/vugu/wiki/Component-Related-Features-Design#component-events 44 Idea: 45 46 @Something="log.Println(event)" 47 is shorthand for: 48 :Something='func(event SomethingEvent) { log.Println(event) }' 49 50 Convenient but also very straightforward, minimal magic. Easy to implement. 51 52 53 Those points resolved should provide what is needed to make sophisticated forms. 54 Once that is done we can look at things like automatic form validation and see if 55 there are any other features needed for that sort of thing. (E.g. in Vuetify 56 a <v-form> is aware of all of it's nested elements and it's `valid` property 57 reflects if all of it's elements are valid. I personally think this is way too 58 magical for Vugu but nonetheless a good and concise pattern should be found.) 59 60 ---- 61 62 Form components: 63 - Select 64 - Textarea 65 - Input 66 67 // for text types 68 <vgform:Input Text Value="some text"> 69 <vgform:Input Email Value=""> 70 <vgform:Input Number Value=""> // hm, would be great if we could use a proper type here 71 <vgform:Input Password Value=""> 72 <vgform:Input Radio Value=""> 73 74 // weird stuff like checkboxes probably should have their own thing 75 <vgform:InputCheckbox Checked> 76 <vgform:InputNumber :Value='1.5'> 77 78 // hm, maybe Input is a base Go struct, and other types extend it? 79 // perhaps just `input`, not exported. we should avoid exposing anything 80 // that is not actually useful 81 InputCheckbox 82 83 // also need the ability to put regular attrs on there - probably think about 84 // how this fits in with the vg-attr functionality 85 <vgform:InputCheckbox :Value='2.5' class="something"> 86 87 // so then what about value binding 88 <vgform:InputNumber :IntValue='vgform.IntPtr(&c.someInt)'> 89 90 type IntValue interface { 91 IntValue() int 92 SetIntValue(int) 93 } 94 95 type IntValuer interface { 96 IntValue() int 97 } 98 99 type SetIntValuer interface { 100 SetIntValue(int) 101 } 102 103 <input type="button"> 104 <input type="checkbox"> 105 <input type="color"> 106 <input type="date"> 107 <input type="datetime-local"> 108 <input type="email"> 109 <input type="file"> 110 <input type="hidden"> 111 <input type="image"> 112 <input type="month"> 113 <input type="number"> 114 <input type="password"> 115 <input type="radio"> 116 <input type="range"> 117 <input type="reset"> 118 <input type="search"> 119 <input type="submit"> 120 <input type="tel"> 121 <input type="text"> 122 <input type="time"> 123 <input type="url"> 124 <input type="week"> 125 126 127 Do not bother wrapping: 128 - <button> 129 130 More notes: 131 132 133 So if this is the HTML we're after: 134 ``` 135 <select> 136 <option value="k1" selected>t1</option> 137 <option value="k2">t2</option> 138 </select> 139 ``` 140 141 I can think of various ways developers might want to express this in a Vugu file (psuedocode, just to give the idea): 142 143 <!-- a static list might just need a way to easily set the selected value --> 144 <select :selected-id="c.curID"> 145 <option value="k1">t1</option> 146 <option value="k2">t2</option> 147 </select> 148 149 <!-- but a dynamic options list will be common too --> 150 <select :selected-id="c.curID"> 151 <option vg-for="k, v := range c.someList" :value="k" vg-html="v"></option> 152 </select> 153 154 <!-- and for the impatient, i can see some people wanting the convenience of being able to just give it a map[string]string 155 and it puts them in there, just sorted alphabetically --> 156 <select :selected-id="c.curID" :options-map="c.optsMap"></select> 157 158 159 */ 160 161 func (c *Select) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) { 162 163 vgout = &vugu.BuildOut{} 164 165 var vgiterkey interface{} 166 _ = vgiterkey 167 var vgn *vugu.VGNode 168 vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Namespace: "", Data: "select", Attr: []vugu.VGAttribute(nil)} 169 vgout.Out = append(vgout.Out, vgn) // root for output 170 vgn.AddAttrList(c.AttrMap) 171 vgn.DOMEventHandlerSpecList = append(vgn.DOMEventHandlerSpecList, vugu.DOMEventHandlerSpec{ 172 EventType: "change", 173 Func: func(event vugu.DOMEvent) { c.handleChange(event) }, 174 // TODO: implement capture, etc. mostly need to decide syntax 175 }) 176 { 177 vgparent := vgn 178 _ = vgparent 179 vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n "} 180 vgparent.AppendChild(vgn) 181 for vgiterkeyt, k := range c.buildKeys() { 182 var vgiterkey interface{} = vgiterkeyt 183 _ = vgiterkey 184 k := k 185 _ = k 186 vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Namespace: "", Data: "option", Attr: []vugu.VGAttribute(nil)} 187 vgparent.AppendChild(vgn) 188 vgn.AddAttrInterface("selected", c.isOptSelected(k)) 189 vgn.AddAttrInterface("value", k) 190 vgn.SetInnerHTML(c.optText(k)) 191 } 192 vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n"} 193 vgparent.AppendChild(vgn) 194 } 195 return vgout 196 } 197 198 // 'fix' unused imports 199 var _ fmt.Stringer 200 var _ reflect.Type 201 var _ vjson.RawMessage 202 var _ js.Value