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