github.com/vugu/vugu@v0.3.6-0.20240430171613-3f6f402e014b/vgform/select.vugu (about)

     1  <select
     2      @change='c.handleChange(event)'
     3      vg-attr='c.AttrMap'
     4      >
     5      <option vg-for='_, k := range c.buildKeys()' :value='k' :selected='c.isOptSelected(k)' vg-content='c.optText(k)'></option>
     6  </select>
     7  
     8  <script type="application/x-go">
     9  
    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  </script>