GSI Object Oriented Online Offline (Go4)  GO4-5.3.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
pareditor.js
Go to the documentation of this file.
1 (function(){
2 
3  if (typeof JSROOT != "object") {
4  var e1 = new Error("pareditor.js requires JSROOT to be already loaded");
5  e1.source = "pareditor.js";
6  throw e1;
7  }
8 
9  if (typeof GO4 != "object") {
10  var e1 = new Error("pareditor.js requires GO4 to be already loaded");
11  e1.source = "pareditor.js";
12  throw e1;
13  }
14 
15  // ===========================================================================================
16 
17  GO4.ParameterEditor = function(par) {
18  JSROOT.TBasePainter.call(this);
19  this.par = par;
20  this.changes = ["dummy", "init"]; // TODO: put to common "base class" of condition and parameter editor
21  }
22 
23  GO4.ParameterEditor.prototype = Object.create(JSROOT.TBasePainter.prototype);
24 
25  GO4.ParameterEditor.prototype.CheckResize = function() {
26  }
27 
28  // TODO: put to common "base class" of condition and parameter editor
29  GO4.ParameterEditor.prototype.DabcCommand = function(cmd, option, callback) {
30  var pre="";
31  if (this.GetItemName()!="") { // note: check against !=null does not work here!
32  pre = this.GetItemName() + "/"; // suppress / if item name is empty
33  //console.log("Found non null itemname= -"+this.GetItemName()+"-");
34  }
35  pre +="exe.json\?method=";
36  var fullcom = pre + cmd + option;
37 
38  JSROOT.NewHttpRequest(fullcom, 'text', function(res) {
39  console.log("DabcCommand completed.");
40  callback(res!=null);
41  }).send(null);
42  }
43 
44  // TODO: put to common "base class" of condition and parameter editor
45  // add identifier of changed element to list, make warning sign visible
46  GO4.ParameterEditor.prototype.MarkChanged = function(key) {
47  // first avoid duplicate keys:
48  for (var index = 0; index < this.changes.length; index++) {
49  if (this.changes[index]== key) return;
50  }
51  this.changes.push(key);
52  console.log("Mark changed :%s", key);
53  var id = "#" + this.get_main_id();
54  $(id+" .buttonChangeLabel").show();// show warning sign
55  }
56 
57  // TODO: put to common "base class" of condition and parameter editor
58  GO4.ParameterEditor.prototype.ClearChanges = function() {
59  var index;
60  var len=this.changes.length;
61  for (index = 0; index < len ; index++) {
62  var removed=this.changes.pop();
63  console.log("Clear changes removed :%s", removed);
64  }
65  var id = "#" + this.get_main_id();
66  $(id+" .buttonChangeLabel").hide(); // hide warning sign
67  }
68 
69  // scan changed value list and return optionstring to be send to server
70  GO4.ParameterEditor.prototype.EvaluateChanges = function(optionstring) {
71  var id = "#" + this.get_main_id();
72  var len = this.changes.length;
73  for (var index = 0; index < len ; index++) {
74  //var cursor=changes.pop();
75  var key = this.changes[index];
76  console.log("Evaluate change key:%s", key);
77  // here mapping of key to editor field:
78  // key will be name of variable which is class name of input field:
79  var val=$(id+" ."+key.toString())[0].value;
80  //var opt= key.replace(/_/g, "[").replace(/-/g, "]"); // old with other placeholders
81  var arraysplit=key.split("_");
82  var opt="";
83  if(arraysplit.length>1)
84  {
85  // found array with index after separator, reformat it:
86  opt=arraysplit[0];
87  if(arraysplit.length>2)
88  {
89  if(arraysplit.length>3)
90  {
91  // 3dim array:
92  var ix=arraysplit[arraysplit.length -3]; //
93  var iy=arraysplit[arraysplit.length -2]; //
94  var iz=arraysplit[arraysplit.length -1]; //
95  opt+="["+ix+"]["+iy+"]["+iz+"]";
96  }
97  else
98  {
99  // 2dim array:
100  var ix=arraysplit[arraysplit.length -2]; //
101  var iy=arraysplit[arraysplit.length -1]; //
102  opt+="["+ix+"]["+iy+"]";
103  }
104  var iy=arraysplit[arraysplit.length -2]; //
105  }
106  else
107  {
108  // 1dim array:
109  opt=arraysplit[0];
110  var ix=arraysplit[arraysplit.length -1]; //
111  opt+="["+ix+"]";
112  }
113  }
114  else
115  {
116  opt=key;
117  }
118 
119  optionstring +="&"+opt+"="+val;
120  }// for index
121  console.log("Resulting option string:%s", optionstring);
122  return optionstring;
123  }
124 
125  GO4.ParameterEditor.prototype.fillComments = function() {
126  var editor = this;
127  if (editor.xreq || !this.GetItemName()) return; // avoid double requests
128  var pre = this.GetItemName() + "/";
129 
130  editor.xreq = JSROOT.NewHttpRequest(pre+"h.json?more", 'object', function(res) {
131  editor.xreq = null;
132  if (!res) return;
133  var id = "#" + editor.get_main_id();
134  $(id + " .par_values tbody").find("tr").each( function(i,tr) {
135  var name = $(tr).find("td:first").text();
136  var title = null;
137  var arrayinfo = null;
138  var typeinfo = null;
139  for (var i in res._childs) {
140  var n = res._childs[i]._name;
141  var arsplit=name.split("["); // remove array information at the end, if any
142  if (arsplit[0]==n) {
143  //if ((name==n) || (name.indexOf(n)==0)) {
144  title = res._childs[i]._title;
145  arrayinfo=res._childs[i]._arraydim;
146  typeinfo=res._childs[i]._typename;
147  //console.log("found title="+title+", arrayinfo="+arrayinfo);
148  break;
149  }
150  }
151  if (title!=null)
152  $(tr).find("td.par_comment").text(title).css('white-space', 'nowrap'); // comments from class member declaration
153  if (typeinfo!=null)
154  {
155  $(tr).find("td.par_class").text(typeinfo).css('white-space', 'nowrap'); // member type
156 
157  $(tr).parents('table.par_arraytable') .find('td.par_comment:first').text("Array").css('white-space', 'nowrap');
158  // if we are inside array table, indicate that we are an array
159 
160  if (arrayinfo!=null)
161  $(tr).parents('table.par_arraytable') .find('td.par_class:first').text(typeinfo+ " [" + arrayinfo+"]").css('white-space', 'nowrap');
162  else
163  $(tr).parents('table.par_arraytable') .find('td.par_class:first').text(typeinfo).css('white-space', 'nowrap');
164 
165  // put type information of array to subtable header
166  }
167 
168  });
169 
170  });
171  editor.xreq.send(null);
172  }
173 
174  GO4.ParameterEditor.prototype.fillMemberTable = function() {
175  var editor = this;
176  var id = "#" + this.get_main_id();
177  var par = this.par;
178  $(id + " .par_values tbody").html("");
179  var found_title = false;
180  for (var key in par) {
181  if (typeof par[key] == 'function') continue;
182  if (key == 'fTitle') { found_title = true; continue; }
183  if (!found_title) continue;
184  var value = (par[key]!=null ? (par[key] instanceof Array ? par[key] : par[key].toString()): "null");
185  var classname="";
186  if (value instanceof Array) {
187  // here put array table with clickable header:
188  // (thanks to Jonathan at http://mediaformations.com/accordion-tables-with-jquery/ for this idea!)
189  var arraytableclass=key.toString()+"_array";
190  var isTooBig=false;
191  $(id + " .par_values > tbody").append("<tr><td style='width:100%; padding:0px' colspan='4' > <table class='"+arraytableclass+" par_arraytable'><thead><tr><td class='par_key'> <bf>[+]</bf> "+ key.toString()+"</td><td class='par_class'></td><td class='par_value' >Click to expand</td><td class='par_comment'></td></tr></thead><tbody></tbody></table></td></tr>");
192  for(i = 0; i < value.length; i++) {
193  if(value[i] instanceof Array)
194  {
195  subvalue=value[i];
196  for (j = 0; j < subvalue.length; j++) {
197  if (subvalue[j] instanceof Array) {
198  subsubvalue = subvalue[j];
199  // here supress display of 3d arrays if too
200  // large:
201  if (subsubvalue.length * subvalue.length * value.length > 1000) {
202  isTooBig=true;
203  break;
204  }
205  else {
206  for (k = 0; k < subsubvalue.length; k++) {
207  // decode 3dim array
208  classname = key.toString() + "_" + i
209  + "_" + j + "_" + k;
210  // $(id + " .par_values
211  // tbody").append("<tr><td>" +
212  // key.toString() + "[" + i +
213  // "]["+j+"]["+k+"]</td><td><input
214  // type='text' value='" + subsubvalue[k]
215  // + "' class='"+ classname
216  // +"'/></td><td></td></tr>");
217  $(id + " ." + arraytableclass + " tbody").append(
218  "<tr><td class='par_key'>"
219  + key
220  .toString()
221  + "["
222  + i
223  + "]["
224  + j
225  + "]["
226  + k
227  + "]</td><td class='par_class'></td><td class='par_value'><input type='text' size='10' value='"
228  + subsubvalue[k]
229  + "' class='"
230  + classname
231  + "'/></td><td class='par_comment'></td></tr>");
232 
233  } // for k
234  }
235  }
236  else
237  {
238  // decode 2dim array
239  classname=key.toString()+"_"+ i+"_"+j;
240  //$(id + " .par_values tbody").append("<tr><td>" + key.toString() + "[" + i + "]["+j+"]</td><td><input type='text' value='" + subvalue[j] + "' class='"+ classname +"'/></td><td></td></tr>");
241  $(id + " ."+arraytableclass+" tbody").append("<tr><td class='par_key'>" + key.toString() + "[" + i + "]["+j+"]</td><td class='par_class'></td><td class='par_value'><input type='text' size='10' value='" + subvalue[j] + "' class='"+ classname +"'/></td><td class='par_comment'></td></tr>");
242 
243  }
244  } // for j
245  }
246  else
247  {
248  // decode 1dim array
249  //classname=key.toString()+"_"+ i+"-"; // old with placeholders instead brackets
250 
251  classname=key.toString()+"_"+ i;
252  //$(id + " .par_values tbody").append("<tr><td>" + key.toString() + "[" + i + "]</td><td><input type='text' value='" + value[i] + "' class='"+ classname +"'/></td><td></td></tr>");
253  $(id + " ."+arraytableclass+" tbody").append("<tr><td class='par_key'>" + key.toString() + "[" + i + "]</td><td class='par_class'></td><td class='par_value'><input type='text' size='10' value='" + value[i] + "' class='"+ classname +"'/></td><td class='par_comment'></td></tr>");
254 
255  }
256  } // for i
257 //
258  if(isTooBig)
259  {
260  $(id + " ." + arraytableclass + " tbody")
261  .append(
262  "<tr><td class='par_key'>" + key.toString()+ "</td><td colspan='3'> Sorry, Array dimension ["
263  + value.length
264  + "]["
265  + subvalue.length
266  + "]["
267  + subsubvalue.length
268  + "] too big to display!</td></tr>");
269  }
270 
271 
272  $(id + " table."+arraytableclass+" thead tr").click(
273  function() {
274  $(this) .parents('table.par_arraytable') .children('tbody') .toggle();
275  $(this) .parents('table.par_arraytable') .find('td:first').text(
276  function(i,origText){
277  var changed=origText;
278  if(origText.indexOf("[+]")!= -1)
279  changed=origText.replace("[+]","[-]");
280  if(origText.indexOf("[-]")!= -1)
281  changed=origText.replace("[-]","[+]");
282  //console.log("original text= "+origText+", changed="+changed);
283  return changed;
284  });
285  $(this) .parents('table.par_arraytable') .find('td.par_value:first').text(
286  function(i,origText){
287  var changed=origText;
288  if(origText.indexOf("expand")!= -1)
289  changed=origText.replace("expand","shrink");
290  if(origText.indexOf("shrink")!= -1)
291  changed=origText.replace("shrink","expand");
292  //console.log("original text= "+origText+", changed="+changed);
293  return changed;
294  });
295 
296  //console.log("Clicked on table header");
297  }
298  );
299  $(id + " table."+arraytableclass).children('tbody').hide();
300 
301  } else {
302  classname=key.toString();
303  $(id + " .par_values > tbody").append("<tr><td class='par_key'>" + key.toString() + "</td><td class='par_class'></td><td class='par_value'><input type='text' size='10' value='" + value + "' class='"+classname+"'/></td><td class='par_comment'></td></tr>");
304  }
305 
306 
307  }
308  // here set callbacks; referred classname must be evaluated dynamically in function!:
309  $(id + " .par_values tbody input").change(function(){ editor.MarkChanged($(this).attr('class'))});
310  $(id + " .par_values tbody td").addClass("par_membertable_style");
311  $(id + " .par_values > thead th").addClass("par_memberheader_style");
312  $(id + " .par_arraytable thead td").addClass("par_arrayheader_style");
313 
314  this.ClearChanges();
315  }
316 
317  GO4.ParameterEditor.prototype.fillEditor = function() {
318  var editor=this;
319  var par = this.par;
320  var id = "#" + this.get_main_id();
321  var width = $(id).width();
322  var height = $(id).height();
323 
324  $(id+" .par_name").text(par.fName);
325  $(id+" .par_type").text(par._typename);
326 
327  $(id).children().eq(0).width(width - 4).height(height - 4);
328 
329 
330  $(id+" .buttonGetParameter")
331  .button({text: false, icons: { primary: "ui-icon-blank MyButtonStyle"}}).click(function() {
332  console.log("update item = " + editor.GetItemName());
333  if (JSROOT.hpainter) JSROOT.hpainter.display(editor.GetItemName());
334  else console.log("dabc object not found!");
335  })
336  .children(":first") // select first button element, used for images
337  .css('background-image', "url(" + GO4.source_dir + "icons/right.png)");
338 
339 
340 
341  $(id+" .buttonSetParameter")
342  .button({text: false, icons: { primary: "ui-icon-blank MyButtonStyle" }})
343  .click(function() {
344  var options=""; // do not need to use name here
345  options = editor.EvaluateChanges(options); // complete option string from all changed elements
346  console.log("set - condition "+ editor.GetItemName()+ ", options="+options);
347  editor.DabcCommand("UpdateFromUrl",options,function(result) {
348  console.log(result ? "set parameter done. " : "set parameter FAILED.");
349  if(result) editor.ClearChanges();
350  });
351  })
352  .children(":first") // select first button element, used for images
353  .css('background-image', "url(" + GO4.source_dir + "icons/left.png)");
354 
355  $(id+" .buttonChangeLabel")
356  .button({text: false, icons: { primary: "ui-icon-blank MyButtonStyle"}}).click()
357  .children(":first") // select first button element, used for images
358  .css('background-image', "url(" + GO4.source_dir + "icons/info1.png)");
359 
360 
361  this.fillMemberTable();
362  console.log("fillEditor finished");
363 
364  }
365 
366  GO4.ParameterEditor.prototype.RedrawObject = function(obj) {
367  console.log("ParemeterEditor RedrawObject...");
368  if (this.UpdateObject(obj))
369  this.Redraw(); // no need to redraw complete pad
370  }
371 
372  GO4.ParameterEditor.prototype.UpdateObject = function(obj) {
373  if (obj._typename != this.par._typename) return false;
374  console.log("ParemeterEditor UpdateObject...");
375  this.par= JSROOT.clone(obj);
376  return true;
377  }
378 
379  GO4.ParameterEditor.prototype.Redraw = function() {
380  console.log("ParemeterEditor Redraw...");
381  this.fillMemberTable();
382  }
383 
384  GO4.ParameterEditor.prototype.drawEditor = function(divid) {
385  var pthis = this;
386 
387  $("#"+divid).empty();
388  $("#"+divid).load( GO4.source_dir + "html/pareditor.htm", "", function() {
389  pthis.SetDivId(divid);
390  pthis.fillEditor();
391  pthis.fillComments();
392  pthis.DrawingReady();
393  });
394 
395  return this;
396  }
397 
398  GO4.ParameterEditor.prototype.SetItemName = function(name) {
399  JSROOT.TBasePainter.prototype.SetItemName.call(this, name);
400  this.fillComments();
401  }
402 
403  GO4.drawParameter = function(divid, par, option) {
404  var h = $("#"+divid).height(), w = $("#"+divid).width();
405  if ((h<10) && (w>10)) $("#"+divid).height(w*0.4);
406  var editor = new GO4.ParameterEditor(par);
407  return editor.drawEditor(divid);
408  }
409 
410 })();