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