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