1    <?php  //character-encoding= UTF-8  tab spacing=2  editor width=120  auto-word-wrap=no
   2    
   3      /*/ test_FormFieldGenie.js   written by and Copyright © 2010, 2012, 2015, 2023 Joe Golembieski, SoftMoon WebWare
   4    
   5        See   http://softmoon-webware.com/FormFieldGenie-js_instructions.html
   6        See   http://softmoon-webware.com/code/
   7    
   8    
   9        This program is free software: you can redistribute it and/or modify
  10        it under the terms of the GNU General Public License as published by
  11        the Free Software Foundation, either version 3 of the License, or
  12        (at your option) any later version.
  13    
  14        This program is distributed in the hope that it will be useful,
  15        but WITHOUT ANY WARRANTY; without even the implied warranty of
  16        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17        GNU General Public License for more details.
  18    
  19        You should have received a copy of the GNU General Public License
  20        along with this program.  If not, see <http://www.gnu.org/licenses/>    /*/
  21    
  22    ?>
  23    <!DOCTYPE html>
  24    <html lang="en-US">
  25    <head>
  26    <meta charset="UTF-8">
  27    <title>Test FormFieldGenie.js</title>
  28    <link rel="icon" type="image/x-icon" href="images/SoftMoonWebWare.gif">
  29    <script type='text/javascript'>
  30    // this is the namespace that the FormFieldGenie resides in:
  31    const SoftMoon=Object.defineProperties({}, {WebWare: {value:{}, enumerable:true}});
  32    </script>
  33    <script type='text/javascript' src='JS_toolbucket/SoftMoon-WebWare/FormFieldGenie.js'></script>
  34    <script type='text/javascript'>
  35    // With this demo, we create one instance and pass options to match the application.
  36    // You can also create individual instances each with their own options by passing in the options to the constructor
  37    //  like this:  Genie1=new FormFieldGenie({ ...options...});  Genie2=new FormFieldGenie({ ...other options... });
  38    // You can also pass in options to the constructor AND the method, with the method options taking precedence.
  39    // By creating individual instances with different options, you clean up your HTML by simplifying the event handler
  40    //  code; however, it may be easier to see and comprehend what is going on by including the options object in the
  41    //  event handler code that calls the FormFieldGenie methods, as I did with this demo.
  42    // This demo does not show off the Genie's ability to insert or delete.  HTML forms that need that ability must use
  43    //  onclick event handlers that have the same options object as the onblur handler attached to the form element itself,
  44    //  the difference being that the options object for the insert/delete must have one additional property, "doso" that
  45    //  flags to do the inserting or deleting.  In this situation, it makes sense to create an individual instance, passing
  46    //  the main body of the options object to the constructor, then simply pass an additional option to the method
  47    //  like this:
  48    //    Genie=new FormFieldGenie({ ...options... });
  49    //  and:
  50    //    <div><input type='text' onblur='Genie.popNewGroup(this.parentNode)'><span onclick='Genie.popNewGroup(this.parentNode, 
        {doso:"insert"})'>insert above</span></div>
  51    const Genie=new SoftMoon.WebWare.FormFieldGenie;
  52    Genie.name='myGenie';  //this is used by the “update-value-genie” attribute in the “favorite pets” section.
  53    </script>
  54    <style>
  55    body { color: lime;  background-color: black; }
  56    fieldset { border: 1px solid white;  display: inline-block;  margin: .618em 2em .382em 0; }
  57    div { background-color: #000020;  border: 1px solid red; }
  58    table { border: 1px solid white;  margin-bottom: 1.618em; }
  59    caption { font-weight: bold; }
  60    table fieldset { margin: 0; }
  61    #family td { width: 50%;  border: 1px solid blue; }
  62    #pets td { width: 25%; }
  63    .list label, #family label { display: block; }
  64    .books { position: relative; padding-bottom: 4em; }
  65    .below { position: relative; display: inline-block; width: 13em; }
  66    .below input, .below textarea { position: absolute; top: 1.618em; left: 0 }
  67    </style>
  68    </head>
  69    <body>
  70    
  71    <?php if (isset($_POST['submit']))  echo "<h1>Var Dump</h1>\n<pre>",var_dump($_POST),"</pre>\n";  ?>
  72    
  73    <h1>Additional fields appear automatically.&nbsp;
  74    Previously filled fields disappear when cleared.&nbsp; Try using the TAB key to navigate.</h1>
  75    
  76    <p>This demo does not record your answers or “do” anything.&nbsp;
  77    When submitted, this form simply spits back your answers formatted as the server receives them.&nbsp;
  78    Feel free to make up anything you like, or use the personal info of the guy in the cubicle next to you
  79    to try out the features of this JavaScript Class:&nbsp; FormFieldGenie.js</p>
  80    
  81    <form action="test_FormFieldGenie-js.php" method='post'
  82      onkeydown='if (event.key==="Enter"  &&  event.target.tagName!=="TEXTAREA"  &&  event.target.type!=="submit")  event.preven
        tDefault();'>
  83    
  84    <fieldset>
  85    <legend>Enter all the names you use</legend>
  86    <p>You may enter up to 10 names, one per box:</p>
  87    <ol>
  88    <li>
  89    <select name='yourName[title][]'>
  90    <option>Mr.</option>
  91    <option>Ms.</option>
  92    <option>Mrs.</option>
  93    <option>Miss</option>
  94    <option selected='selected'>The Honorable</option>
  95    <option>the deplorable</option>
  96    </select>
  97    <label>first<input type='text' name='yourName[first][]' onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
  98     onblur='Genie.popNewGroup(this.parentNode.parentNode, {maxTotal: 10, checkForFilled: "all"})'></label>&nbsp;
  99    <label>last<input type='text' name='yourName[last][]' onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
 100     onblur='Genie.popNewGroup(this.parentNode.parentNode, {maxTotal: 10, checkForFilled: "all"})'></label></li>
 101     </ol>
 102    </fieldset><br>
 103    
 104    <br>
 105    
 106    <div>
 107    <p>Enter the nicknames that others call you.&nbsp; Select the appropriate attributes of each nickname.</p>
 108    <p>Don't be shy and show your maturity: include all those you don't like.</p>
 109    <fieldset>
 110    <fieldset style='display: inline-block;'><legend>favorable?</legend>
 111    <label><input type='radio' name='Nickname[0][isliked]' value='yes' checked>yes</label>
 112    <label><input type='radio' name='Nickname[0][isliked]' value='no'>no</label>
 113    </fieldset>
 114    <label>nickname<input type='text' name='Nickname[0][called]' onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event
        )'
 115     onblur='Genie.popNewGroup(this.parentNode.parentNode, {indexTier:0})'></label>
 116    <label><input type='checkbox' name='Nickname[0][lifestage][]' value='childhood'>from childhood</label>
 117    <label><input type='checkbox' name='Nickname[0][lifestage][]' value='college'>from college</label>
 118    <label><input type='checkbox' name='Nickname[0][lifestage][]' value='adult'>from adulthood</label>
 119    </fieldset>
 120    </div>
 121    
 122    <br>
 123    
 124    <table id='family'><caption>Enter your family tree</caption>
 125    <tr><th>your kids</th><th>your grandkids from each kid</th></tr>
 126    
 127    <!-- note how the indxTier option below yields no affect on kids[], but does for grandkids[0][0] -->
 128    
 129    <tr>
 130    <td><label>kid name<input type='text' name='kids[]' onkeydown='Genie.catchTab(event)'
 131     onblur='Genie.popNewGroup(this.parentNode.parentNode.parentNode, {indxTier: 0})'
 132     onfocus='Genie.tabbedOut=false'></label></td>
 133    <td><label>grandkid name<input type='text' name='grandkids[0][0]' onkeydown='Genie.catchTab(event)'
 134     onblur='Genie.popNewGroup(this.parentNode)' onfocus='Genie.tabbedOut=false'></label></td>
 135    </tr>
 136    
 137    </table>
 138    
 139    <br>
 140    
 141    <table id='pets'><caption>Enter your pets&rsquo; names</caption>
 142    <tr><th>Cats</th><th>Dogs</th><th>Birds</th><th>Fish</th></tr>
 143    
 144    <tr>
 145    <td><fieldset><label>favorite?<input type='radio' name='catNames[favorite]' value="0" update-value-genie='myGenie'></label>
 146    <input type='text' name='catNames[]' onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
 147     onblur='Genie.popNewGroup(this.parentNode)'></fieldset></td>
 148    
 149    <td><fieldset><label>favorite?<input type='radio' name='dogNames[favorite]' value="0" update-value-genie='myGenie'></label>
 150    <input type='text' name='dogNames[]' onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
 151     onblur='Genie.popNewGroup(this.parentNode)'></fieldset></td>
 152    
 153    <!-- In the next two sections, we check the input type because radio buttons may also have focus,
 154          and calling on the Genie when they loose focus is a waste of time.  -->
 155    
 156    <!-- this section works just like the two above, but the event-handlers are moved to the “group”  -->
 157    <td><fieldset onfocusin='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
 158        onfocusout='if (evet.target.type==="text")  Genie.popNewGroup(this)'>
 159    <label>favorite?<input type='radio' name='birdNames[favorite]' value="0" update-value-genie='myGenie'></label>
 160    <input type='text' name='birdNames[]'></fieldset></td>
 161    
 162    <!-- this section works just like the two above, but the event-handlers are moved to the “batch”  -->
 163    <td onfocusin='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
 164        onfocusout='if (evet.target.type==="text")  Genie.popNewGroup(event.target.closest("fieldset"))'>
 165    <fieldset><label>favorite?<input type='radio' name='fishNames[favorite]' value="0" update-value-genie='myGenie'></label>
 166    <input type='text' name='fishNames[]'></fieldset></td>
 167    </tr>
 168    
 169    </table>
 170    
 171    <fieldset class='list'><legend>Enter your favorite types of Music</legend>
 172    <p>(one per box)</p>
 173    <label><input type='checkbox' name='music[1]' value='Jazz'> Jazz</label>
 174    <label><input type='checkbox' name='music[2]' value='Rock'> Rock</label>
 175    <label><input type='checkbox' name='music[3]' value='Blues'> Blues</label>
 176    <label><input type='checkbox' name='music[4]' value='Vocals'> Vocals</label>
 177    <label><input type='checkbox' name='music[5]' value='Country'> Country</label>
 178    <!-- here we leave room for music[6] to music[19] for future expansion of defaults
 179        and we start again at [20] to reduce the need for our scripts to be updated in the future.
 180        The Genie will keep the user-entered values ordered correctly  -->
 181    <input type='text' name='music[20]' style='display: block'
 182      onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
 183      onblur='Genie.popNewGroup(this)'>
 184    </fieldset>
 185    
 186    <fieldset class='list'><legend>Enter your favorite bands, most favorite first</legend>
 187    <input type='text' name='favoriteBands[first]' style='display: block'
 188     onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
 189     onblur='Genie.popNewGroup(this, {updateName: SoftMoon.WebWare.FormFieldGenie.updateNameByList})'>
 190    </fieldset>
 191    
 192    <fieldset><legend>Enter your favorite movies</legend>
 193    <div>
 194    <label style='display: inline'>Title
 195    <input type='text' name='favoriteMovies[i][title]' onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
 196     onblur='Genie.popNewGroup(this.parentNode.parentNode, {updateName: SoftMoon.WebWare.FormFieldGenie.updateNameByList, cbPara
        ms: SoftMoon.WebWare.FormFieldGenie.updateNameByList.RomanOrder})'></label>
 197    <fieldset><legend>Enter the actor's names</legend>
 198    <input type='text' name='favoriteMovies[i][actors][]' style='display: block'
 199      onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)' onblur='Genie.popNewGroup(this)'>
 200    </fieldset>
 201    </div>
 202    </fieldset>
 203    
 204    <br>
 205    
 206    <script type='text/javascript'>
 207    const PopBookOptions={
 208      maxTotal: 7,
 209      checkForFilled: "some",  // ←↓ here we specify the first two fieldNodes
 210      checkField: 2,   //remember this is a ONE based count
 211      updateName: SoftMoon.WebWare.FormFieldGenie.updateNameByList,
 212      cbParams: {order: SoftMoon.WebWare.FormFieldGenie.updateNameByList.RomanOrder.order,  pcre: new RegExp(/_([a-z]+)/)}  }
 213    </script>
 214    
 215    <fieldset><legend>modify how the “book” Genie (see next section) works:</legend>
 216    <label style='display: block'>require “Author” &amp; “Title”
 217    <input type='radio' name='GenieControl' onchange='PopBookOptions.checkField=2;' checked></label>
 218    <label style='display: block'>require “Author” &amp; “summery”
 219    <input type='radio' name='GenieControl' onchange='PopBookOptions.checkField=[0,2];'></label>
 220    </fieldset>
 221    
 222    <fieldset><legend>Enter your favorite books</legend>
 223    <div class='books' onfocusin='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
 224     onfocusout='Genie.popNewGroup(this, PopBookOptions)'>
 225    <label class='below'>Author
 226    <input type='text' name='favoriteBooks_i_[author]'></label>
 227    <label class='below'>Title
 228    <textarea name='favoriteBooks_i_[title]'></textarea></label>
 229    <label class='below'>give a short summery
 230    <textarea name='favoriteBooks_i_[summery]'></textarea></label>
 231    </div>
 232    </fieldset>
 233    
 234    <br>
 235    <br>
 236    
 237    <div><p></p>
 238    <fieldset><legend>Enter your favorite cars and tell us about your feelings on them.&nbsp; One car per text-box.</legend>
 239    <div>
 240    <label>optional Year<input type='text' name='year1618_314159_9' size='4' maxlength='4'></label>
 241    <input type='text' name='cars1618_314159_9' onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
 242     onblur='Genie.popNewGroup(this.parentNode, {checkForFilled: "one", checkField: 1, focusField: 1})'>
 243    <textarea name='thoughts1618_314159_9'></textarea>
 244    </fieldset></div>
 245    
 246    
 247    <p>Click <input type='submit' name='submit' value='submit this form'> to see the resulting data format.</p>
 248    
 249    </form>
 250    </body>
 251    </html>