source: trunk/grails-app/views/eventDescription/showMyProtocolFilled.gsp @ 242

Last change on this file since 242 was 242, checked in by jahn, 11 years ago

Functionality of dynamic protocol parameter selection improved further. Added delete buttons to dynamic dialog. The buttons remove options. The view does now cover all required specifications with an Ajax based model that requires relatively little communication between the client and the server.

Points of action:
(1) Clean up code and move JS into seperate file to be included with the according Grails tag.
(2) Custom buttons.
(3) Dialog box warning when changing option names.

File size: 9.3 KB
Line 
1<script type="text/javascript">
2
3/* The following JS functions provide the dynamics of this view.
4 * Mainly, rows of parameters can be added or removed by the user.
5 * Additionally, each parameter can contain a STRINGLIST. In this case
6 * the a link is activated. On following this link the user can activate
7 * a dialog that displays all options of the STRINGLIST and edit them. */
8var parametertypes= new Array();
9var newRows=0;
10<% dbnp.studycapturing.ProtocolParameterType.list().each{ print "parametertypes.push(\'${it}\');" } %>
11
12/* create a prefix for all members of a protocol */
13function setName(element,protocolId) {
14    element.name='protocolId_'+protocolId+'_'+element.id;
15}
16
17function addRowEmpty(id){
18    var tbody = document.getElementById(id);
19    var row = document.createElement("tr");
20    row.setAttribute('id','new' + (newRows++) );
21
22    addTextFieldToRow(row,'classification',20); addTextFieldToRow(row,'unit',6);
23    var textField=addSelector(row,null,[]); addTextFieldToRow(row,'reference',10); addTextFieldToRow(row,'description',20);
24    addElementToRow(row,textField,'option',6); addRowButton(row); tbody.appendChild(row);
25}
26
27
28function addRow(id,newId,name,unit,type,reference,description,options) {
29
30    var tbody = document.getElementById(id);
31    var row = document.createElement("tr");
32    row.setAttribute('id',newId);
33
34    addTextFieldToRow(row,'classification',20).value=name;
35    addTextFieldToRow(row,'unit',6).value=unit;
36    var textField=addSelector(row,type,options);
37    addTextFieldToRow(row,'reference',10).value=reference;
38    addTextFieldToRow(row,'description',20).value=description;
39    addElementToRow(row,textField,'option',6);
40    addRowButton(row);
41    tbody.appendChild(row);
42}
43
44
45  function addRowButton(parent) {
46     var removeButton=document.createElement("input");
47     var body=parent.parentNode;
48     removeButton.setAttribute('type','button');
49     removeButton.setAttribute('onclick',"removeRow('" + parent.id + "');");
50     removeButton.setAttribute('value','remove');
51     var td=document.createElement('td');
52     td.appendChild(removeButton);
53     parent.appendChild(td);
54  }
55
56
57  function addElementToRow(row,field,id,size){
58     var td=document.createElement('td');
59     td.setAttribute('id',id + '_' + row.id);
60     td.appendChild(field);
61     row.appendChild(td);
62     return field;
63  }
64
65
66  function addTextFieldToRow(row,id,size){
67     var input=document.createElement("input");
68     input.setAttribute('type','text');
69     input.setAttribute('id',id);
70     input.setAttribute('name', 'row_' + row.id + '__' + id);
71     input.setAttribute('size',size);
72     var td=document.createElement('td');
73     td.appendChild(input);
74     row.appendChild(td);
75     return input;
76  }
77
78
79  function removeRow(rowId){
80     var row = document.getElementById(rowId);
81     var body = row.parentNode;
82     body.removeChild(row);
83     jQuery(document.getElementById('dialog'+rowId)).remove();
84  }
85
86
87  // for the STRINGLIST type, display a link to show
88  // all optional values of the parameter.
89  function showLinkForSTRINGLIST(anchor,textNode,option,showDialogString,dialog) {
90        if(option.value=='STRINGLIST') {
91           textNode.nodeValue='edit';
92           anchor.setAttribute('onclick',showDialogString);
93        }
94        else {
95           textNode.nodeValue='n.a.';
96           anchor.setAttribute('onclick','');
97        }
98  }
99
100
101
102  function addRowToDialog(tbody,rowId) {
103        var input=document.createElement('input');
104        var id = tbody.rows.length + 1;
105        input.setAttribute('name','parameterStringValue__new'+id+'__protocol__'+rowId);
106        var tr=document.createElement('tr');
107        tr.insertCell(-1).appendChild(input);
108        tbody.appendChild(tr);
109        var button=document.createElement('input');
110        button.type='button';
111        button.value='delete';
112        button.onclick=function(){jQuery(tr).remove()};
113        tr.insertCell(-1).appendChild(button);
114  }
115
116
117   // create the dialog for this STRINGLIST.
118   // the dialog holds all possible values this parameter can take.
119   // moreover, it is extendable.
120   function addDialogForSelector(rowId,options) {
121     var dialog = document.createElement('div');
122     dialog.id='dialog'+rowId;
123     dialog.setAttribute('name','hiddenDialog');
124
125     var table=document.createElement('table');
126     var tbody=document.createElement('tbody'); tbody.id='options_'+dialog.id;
127     var tr=document.createElement('tr');
128     var th=document.createElement('th');
129     var tx=document.createTextNode('Parameter Values');
130     dialog.appendChild(table);
131     table.appendChild(tbody);
132     tbody.appendChild(tr);
133     tr.appendChild(tx);
134
135     for(i=0;i<options.length;i+=2){
136         var input=document.createElement('input');
137         input.value=unescape(options[i]);
138         input.name='parameterStringValue__'+options[i+1]+'__protocol__'+rowId;
139         var tr=document.createElement('tr');
140         tbody.appendChild(tr);
141         tr.insertCell(-1).appendChild(input);
142         var button=document.createElement('input');
143         button.type='button';
144         button.value='delete';
145         button.onclick=function(){jQuery(tr).remove()};
146         tr.insertCell(-1).appendChild(button);
147     }
148
149     var button=document.createElement('input');
150     button.setAttribute('type','Button');
151     button.value='Add Option';
152     dialog.appendChild(button);
153     button.onclick=function(){ addRowToDialog(tbody,rowId); }
154
155     return dialog;
156   }
157
158
159   function addSelector(row,selectedText,options){
160
161     // add dialog for displaying paramter options
162     // preserve row's id
163     var dialog = addDialogForSelector(row.id,options);
164
165
166     var selector=document.createElement("select");
167     selector.setAttribute('id',"type"+row.id);
168     setName(selector,row.id);
169     var selectedIndex=0;
170     for(i=0;i<parametertypes.length;i++) {
171         var option = document.createElement("option");
172         var text = document.createTextNode(parametertypes[i]);
173         option.appendChild(text);
174         selector.appendChild(option);
175         if(selectedText!=null&&selectedText==parametertypes[i]) { selectedIndex=i; }
176     }
177
178
179     //  td for the selector
180     var td=document.createElement('td');
181     td.appendChild(selector);
182     td.appendChild(dialog);                          // dialog
183     row.appendChild(td);
184     jQuery(dialog).dialog({ autoOpen:false, });
185
186
187     var showDialogString = "jQuery('#"+ dialog.id + "').dialog('open');"
188
189
190     // set label for selected element
191     selector.selectedIndex=selectedIndex;
192     var option=selector.options[selector.selectedIndex];
193
194     var anchor= document.createElement('a');
195     anchor.name='myanchor';
196     var textNode=document.createTextNode('');
197     option=selector.options[selector.selectedIndex];
198     textNode.nodeValue=(option.value=='STRINGLIST') ? 'edit' : 'n.a.';
199     showLinkForSTRINGLIST(anchor,textNode,option,showDialogString,dialog);
200     anchor.appendChild(textNode);
201
202
203     // show edit link for STRINGLIST
204     selector.onchange=function(){
205         option=this.options[this.selectedIndex];
206         showLinkForSTRINGLIST(anchor,textNode,option,showDialogString,dialog);
207     }
208
209
210     return anchor;
211  }
212
213
214  function getElementsByClass (className) {
215      var all = document.all ? document.all :
216      document.getElementsByTagName('*');
217      var elements = new Array();
218      for (var e = 0; e < all.length; e++)
219         if (all[e].className == className)
220         elements[elements.length] = all[e];
221      return elements;
222  }
223
224
225
226  function addHiddenDialogsToForm() {
227     var form=document.getElementById('showProtocolParameters');
228     var dialogs=document.getElementsByName('hiddenDialog');
229     for(i=0;i<dialogs.length;i++) {
230         form.appendChild(dialogs[i]);
231     }
232  }
233
234  function deleteHiddenDialogs() {
235      var dialogs=document.getElementsByName('hiddenDialog');
236      for(i=0;i<dialogs.length;i++) {
237          jQuery(dialogs[i]).remove();
238      }
239  }
240
241</script>
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257<tr class="prop">
258    <td id='test'>  Protocol </td>
259    <td> <g:select name="protocol" from="${dbnp.studycapturing.Protocol.list()}" value="${protocol}" optionKey="id"   optionValue="name"
260                   onchange= "${remoteFunction( action:'showProtocolParameters', update:'showProtocolParameters', params:'\'id=\'+this.value' )}; deleteHiddenDialogs();" />
261    </td>
262</tr>
263
264
265<tr><td></td>
266<td>
267
268<table id="someId" >
269
270
271<thead>
272    <tr class="prop">
273
274         <th valign="top" class="name" width=200>
275         <label for="protocolInstance">Name</label>
276         </th>
277
278         <th valign="top" class="name" width=200>
279         <label for="protocolInstance">Unit</label>
280         </th>
281
282         <th valign="top" class="name" width=200>
283         <label for="protocolInstance">Type</label>
284         </th>
285
286         <th valign="top" class="name" width=200>
287         <label for="protocolInstance">Reference</label>
288         </th>
289
290         <th valign="top" class="name" width=200>
291         <label for="protocolInstance">Description</label>
292         </th>
293
294         <th valign="top" class="name" width=200>
295         <label for="protocolInstance">Options</label>
296         </th>
297
298         <th valign="top" class="name" width=200>
299         <label for="protocolInstance">Delete </label>
300         </th>
301
302    </tr>
303</thead>
304
305
306
307<tbody id="showProtocolParameters">
308    <g:include action="showProtocolParameters" controller="eventDescription" id="${description.id} params="[protocol:protocol]" />
309</tbody>
310
311
312<tbody> <tr>
313<td></td> <td></td> <td></td> <td></td> <td></td> <td></td> <td> <input type="button" value="Add Parameter" onclick="addRowEmpty('showProtocolParameters')"/> </td>
314</tr> </tbody>
315
316</table>
317
318
319</td> </tr>
Note: See TracBrowser for help on using the repository browser.