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 lang="en-US"
25
26 charset="UTF-8"
27 Test FormFieldGenie.js
28 rel="icon" type="image/x-icon" href="images/SoftMoonWebWare.gif"
29 type='text/javascript'
30 // this is the namespace that the FormFieldGenie resides in:
31 const SoftMoon=Object.defineProperties({}, {WebWare: {value:{}, enumerable:true}});
32
33 type='text/javascript' src='JS_toolbucket/SoftMoon-WebWare/FormFieldGenie.js'
34 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
54
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
68
69
70
71 <?php if (isset($_POST['submit'])) echo "<h1>Var Dump</h1>\n<pre>",var_dump($_POST),"</pre>\n"; ?>
72
73 Additional fields appear automatically.
74 Previously filled fields disappear when cleared. Try using the TAB key to navigate.
75
76 This demo does not record your answers or “do” anything.
77 When submitted, this form simply spits back your answers formatted as the server receives them.
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: FormFieldGenie.js
80
81 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
85 Enter all the names you use
86 You may enter up to 10 names, one per box:
87
88
89 name='yourName[title][]'
90 Mr.
91 Ms.
92 Mrs.
93 Miss
94 selected='selected'The Honorable
95 the deplorable
96
97 first type='text' name='yourName[first][]' onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
98 onblur='Genie.popNewGroup(this.parentNode.parentNode, {maxTotal: 10, checkForFilled: "all"})'
99 last type='text' name='yourName[last][]' onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
100 onblur='Genie.popNewGroup(this.parentNode.parentNode, {maxTotal: 10, checkForFilled: "all"})'
101
102
103
104
105
106
107 Enter the nicknames that others call you. Select the appropriate attributes of each nickname.
108 Don't be shy and show your maturity: include all those you don't like.
109
110 style='display: inline-block;'favorable?
111 type='radio' name='Nickname[0][isliked]' value='yes' checkedyes
112 type='radio' name='Nickname[0][isliked]' value='no'no
113
114 nickname type='text' name='Nickname[0][called]' onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event
)'
115 onblur='Genie.popNewGroup(this.parentNode.parentNode, {indexTier:0})'
116 type='checkbox' name='Nickname[0][lifestage][]' value='childhood'from childhood
117 type='checkbox' name='Nickname[0][lifestage][]' value='college'from college
118 type='checkbox' name='Nickname[0][lifestage][]' value='adult'from adulthood
119
120
121
122
123
124 id='family'Enter your family tree
125 your kidsyour grandkids from each kid
126
127 <!-- note how the indxTier option below yields no affect on kids[], but does for grandkids[0][0] -->
128
129
130 kid name type='text' name='kids[]' onkeydown='Genie.catchTab(event)'
131 onblur='Genie.popNewGroup(this.parentNode.parentNode.parentNode, {indxTier: 0})'
132 onfocus='Genie.tabbedOut=false'
133 grandkid name type='text' name='grandkids[0][0]' onkeydown='Genie.catchTab(event)'
134 onblur='Genie.popNewGroup(this.parentNode)' onfocus='Genie.tabbedOut=false'
135
136
137
138
139
140
141 id='pets'Enter your pets’ names
142 CatsDogsBirdsFish
143
144
145 favorite? type='radio' name='catNames[favorite]' value="0" update-value-genie='myGenie'
146 type='text' name='catNames[]' onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
147 onblur='Genie.popNewGroup(this.parentNode)'
148
149 favorite? type='radio' name='dogNames[favorite]' value="0" update-value-genie='myGenie'
150 type='text' name='dogNames[]' onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
151 onblur='Genie.popNewGroup(this.parentNode)'
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 onfocusin='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
158 onfocusout='if (evet.target.type==="text") Genie.popNewGroup(this)'
159 favorite? type='radio' name='birdNames[favorite]' value="0" update-value-genie='myGenie'
160 type='text' name='birdNames[]'
161
162 <!-- this section works just like the two above, but the event-handlers are moved to the “batch” -->
163 onfocusin='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
164 onfocusout='if (evet.target.type==="text") Genie.popNewGroup(event.target.closest("fieldset"))'
165 favorite? type='radio' name='fishNames[favorite]' value="0" update-value-genie='myGenie'
166 type='text' name='fishNames[]'
167
168
169
170
171 class='list'Enter your favorite types of Music
172 (one per box)
173 type='checkbox' name='music[1]' value='Jazz' Jazz
174 type='checkbox' name='music[2]' value='Rock' Rock
175 type='checkbox' name='music[3]' value='Blues' Blues
176 type='checkbox' name='music[4]' value='Vocals' Vocals
177 type='checkbox' name='music[5]' value='Country' Country
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 type='text' name='music[20]' style='display: block'
182 onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
183 onblur='Genie.popNewGroup(this)'
184
185
186 class='list'Enter your favorite bands, most favorite first
187 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
191
192 Enter your favorite movies
193
194 style='display: inline'Title
195 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})'
197 Enter the actor's names
198 type='text' name='favoriteMovies[i][actors][]' style='display: block'
199 onfocus='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)' onblur='Genie.popNewGroup(this)'
200
201
202
203
204
205
206 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
214
215 modify how the “book” Genie (see next section) works:
216 style='display: block'require “Author” & “Title”
217 type='radio' name='GenieControl' onchange='PopBookOptions.checkField=2;' checked
218 style='display: block'require “Author” & “summery”
219 type='radio' name='GenieControl' onchange='PopBookOptions.checkField=[0,2];'
220
221
222 Enter your favorite books
223 class='books' onfocusin='Genie.tabbedOut=false' onkeydown='Genie.catchTab(event)'
224 onfocusout='Genie.popNewGroup(this, PopBookOptions)'
225 class='below'Author
226 type='text' name='favoriteBooks_i_[author]'
227 class='below'Title
228 name='favoriteBooks_i_[title]'
229 class='below'give a short summery
230 name='favoriteBooks_i_[summery]'
231
232
233
234
235
236
237
238 Enter your favorite cars and tell us about your feelings on them. One car per text-box.
239
240 optional Year type='text' name='year1618_314159_9' size='4' maxlength='4'
241 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 name='thoughts1618_314159_9'
244
245
246
247 Click type='submit' name='submit' value='submit this form' to see the resulting data format.
248
249
250
251