crfPortal.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. function print(config,msg){
  2. config.document.getElementById(config.debugId).value+="\n"+msg;
  3. }
  4. function drawForm(par){
  5. populateSourceTable(par); //populateSourceTableData
  6. let tableId="entryTable";
  7. generateTable(par,"formDiv",tableId);
  8. generateRow(par,tableId,"User");//generateTableRow
  9. populateSelectTableEntry(par,"User");//populateTableRow , populateSelect
  10. generateRow(par, tableId,"Site");
  11. generateRow(par, tableId, "FormStatus");
  12. generateRow(par, tableId,"Crf");
  13. populateSelectTableEntry(par,"Site");
  14. populateSelectTableEntry(par,"FormStatus");
  15. let formTableId="selectFormTable";
  16. generateTable(par,"selectFormDiv",formTableId);
  17. generateRow(par,formTableId,"Form");
  18. generateButtonRow(formTableId,"Add new CRF","Add", par, addNewEntry);
  19. }
  20. function generateQConfig(listName){
  21. let qConfig=new Object();
  22. qConfig.containerPath="TECANT/Data";
  23. qConfig.schemaName="lists";
  24. qConfig.queryName=listName;
  25. return qConfig;
  26. }
  27. function sourceVar(crfEntryName,elementId,sourceName){
  28. let f=new Object();
  29. f.masterSelectVarName=crfEntryName;
  30. f.selectId=elementId;
  31. f.inputType="innerHTML";
  32. f.sourceSelectVarName=sourceName;
  33. return f;
  34. }
  35. function getField(config, data, varName){
  36. let debug=false;
  37. if (debug) print(config, "getField");
  38. let fields=data.metaData.fields;
  39. for (f in fields){
  40. if (debug) print(config,"Checking "+f+": name "+fields[f].name+"/"+varName);
  41. if (fields[f].name!=varName) continue;
  42. return fields[f];
  43. }
  44. return null;
  45. }
  46. function selectEntry(data,config, row){
  47. let entry=data.rows[0];
  48. let varName=row.masterSelectVarName;
  49. let el=config.document.getElementById(row.selectId);
  50. for (let i=0;i< el.options.length;i++){
  51. print(config,"selectEntry: "+el.options[i].value+"/"+entry[varName]);
  52. if (el.options[i].value!=entry[varName]) continue;
  53. el.selectedIndex=i;
  54. return;
  55. }
  56. }
  57. function generateHead(config, headDivName,divName,title){
  58. print(config,"generateHead");
  59. let tb=config.document.createElement('table');
  60. tb.className='t2';
  61. let row=tb.insertRow();
  62. let cell=config.document.createElement('th');
  63. row.appendChild(cell);
  64. cell.setAttribute("colspan","4");
  65. cell.style.fontSize="20px";
  66. cell.style.textAlign="center";
  67. let cellData=config.document.createTextNode(title);
  68. cell.appendChild(cellData);
  69. cell=row.insertCell();
  70. cell.style.fontSize="20px";
  71. let input=config.document.createElement("input");
  72. input.type="button";
  73. input.value="Show";
  74. input.id="toggle"+divName+"VisbilityButton";
  75. input.onclick=function(){toggleVisibility(config,divName,input.id)};
  76. cell.appendChild(input);
  77. config.document.getElementById(headDivName).appendChild(tb);
  78. print(config,"generateHead: Done");
  79. }
  80. function toggleVisibility(config,divName,buttonName){
  81. let x = config.document.getElementById(divName);
  82. if (x.style.display === "none") {
  83. x.style.display = "block";
  84. config.document.getElementById(buttonName).value="Hide";
  85. } else {
  86. x.style.display = "none";
  87. config.document.getElementById(buttonName).value="Show";
  88. }
  89. }
  90. function selectRowsSuccess(config,data){
  91. print(config,"Select rows on "+data.queryName+" got "+data.rows.length+" rows.");
  92. }
  93. function selectRowsFailure(config,errorObj){
  94. print(config,"selectRowsFail: "+errorObj.exception)
  95. }
  96. function populateSourceTable(par){
  97. let debug=true;
  98. if (debug){
  99. print(par.config,"populateSourceTable: Starting");
  100. }
  101. let config=generateQConfig(par.source.queryName);
  102. config.schemaName=par.source.schemaName;
  103. if (!("source" in par)) return;
  104. if (debug){
  105. print(par.config,"populateSourceTable ["+par.source.queryName+"]");
  106. }
  107. config.success=function(data){populateSourceTableData(data,par)};
  108. //config.success=function(data){selectRowsSuccess(par.config,data)};
  109. config.failure=function(errorObj){selectRowsFailure(par.config,errorObj)};
  110. LABKEY.Query.selectRows(config);
  111. }
  112. function populateSourceTableData(data,par){
  113. let debug=true;
  114. if (debug){
  115. print(par.config, "populateSourceTableData: nrow: "+data.rows.length);
  116. }
  117. let entry=data.rows[0];
  118. for (let i=0;i < par.source.vars.length;i++){
  119. let srcVarName=par.source.vars[i];
  120. if (debug){
  121. print(par.config, "populateSourceTable ["+srcVarName+"]");
  122. }
  123. let row=par.vars[srcVarName];
  124. let el=par.config.document.getElementById(row.selectId);
  125. if (debug){
  126. print(par.config, "Element: "+el);
  127. }
  128. el.innerHTML=entry[row.sourceSelectVarName];
  129. }
  130. }
  131. function generateTable(par,divName,elementId){
  132. let debug=true;
  133. if (debug)
  134. print(par.config,"generateTable");
  135. let tb=par.config.document.createElement('table');
  136. tb.className="t2";
  137. tb.id=elementId;
  138. par.config.document.getElementById(divName).appendChild(tb);
  139. if (debug)
  140. print(par.config,"generateTable: Done");
  141. }
  142. function generateRow(par, tableId, rowId){
  143. let debug=true;
  144. if (debug)
  145. print(par.config,"generateRow: Start");
  146. let config=generateQConfig(par.masterQuery);
  147. config.success=function(data){generateTableRow(data, par, tableId, rowId)};
  148. LABKEY.Query.selectRows(config);
  149. if (debug)
  150. print(par.config,"generateRow: End");
  151. return;
  152. }
  153. function generateTableRow(data, par, tableId, rowId){
  154. let debug=true;
  155. if (debug)
  156. print(par.config,"generateTableRow: start");
  157. let tb=par.config.document.getElementById(tableId);
  158. let row=par.vars[rowId];
  159. if (debug)
  160. print(par.config,"getField for "+row.masterSelectVarName);
  161. let field=getField(par.config,data,row.masterSelectVarName);
  162. let trow=tb.insertRow();
  163. let cell=par.config.document.createElement('th');
  164. trow.appendChild(cell);
  165. let text = par.config.document.createTextNode(field.shortCaption);
  166. cell.appendChild(text);
  167. cell=trow.insertCell();
  168. let input = par.config.document.createElement("select");
  169. input.id = row.selectId;
  170. input.onchange=function(){row.callback(par,rowId)};
  171. cell.appendChild(input);
  172. if (debug)
  173. print(par.config,"generateTableRow: end");
  174. }
  175. function populateSelectTableEntry(par,rowId){
  176. let debug=true;
  177. let row=par.vars[rowId];
  178. if (debug)
  179. print(par.config,"populateSelectTableEntry:"+par.masterQuery+"/"+row.masterSelectVarName);
  180. let config=generateQConfig(par.masterQuery);
  181. if ("filter" in row){
  182. //populateSelect on authorizationQuery with authSelectVarName
  183. let filter=row.filter;
  184. if (debug){
  185. print(par.config,"Filter:"+filter.queryName);
  186. print(par.config,"FilterVar "+filter.filterVarName);
  187. }
  188. config.queryName=filter.queryName;
  189. config.filterArray=[];
  190. for (f in filter.filters){
  191. if (debug) print(par.config,"Adding filter: "+f+" val "+filter.filters[f]);
  192. config.filterArray.push(LABKEY.Filter.create(f,filter.filters[f]));
  193. }
  194. }
  195. else{
  196. config.queryName=par.masterQuery;
  197. }
  198. config.success=function(data){populateTableRow(data,par,rowId)};
  199. LABKEY.Query.selectRows(config);
  200. if (debug)
  201. print(par.config,"generateSelect: End");
  202. return;
  203. }
  204. function populateTableRow(data,par,rowId){
  205. //data is output of selectRows on either
  206. // * masterQuery looking at masterSelectVarName or
  207. // * authQuery looking at authSelectVarName
  208. //in both cases, query[varName] is a lookup variable, so do populateSelect with lookupData,queryData and par
  209. let debug=true;
  210. let row=par.vars[rowId];
  211. let varName=row.masterSelectVarName;
  212. if ("filter" in row){
  213. if (row.filter.queryName==data.queryName){
  214. varName=row.filter.filterVarName;
  215. }
  216. }
  217. if (debug)
  218. print(par.config,"generateSelectVar: "+data.queryName+"/"+varName+" size "+data.rows.length);
  219. let field=getField(par.config,data,varName);
  220. if (!field) {
  221. print(par.config,"Field "+varName+" not found");
  222. return;
  223. }
  224. if (debug)
  225. print(par.config,"Using field "+field.name);
  226. if (!("lookup" in field)){
  227. let entry=data.rows[0];
  228. print(par.config,"Field "+varName+" not a lookup");
  229. //populateSelectNotLookup(data,par,rowId, entry);
  230. return;
  231. }
  232. let config=generateQConfig(field.lookup.queryName);
  233. config.schemaName=field.lookup.schemaName;
  234. config.success=function(lookupData){populateSelect(lookupData,data,par,rowId)};
  235. //config.success=function(data){selectRowsSuccess(par.config,data)};
  236. config.failure=function(errorObj){selectRowsFailure(par.config,errorObj)};
  237. LABKEY.Query.selectRows(config);
  238. if (debug)
  239. print(par.config,"generateSelectVar: End");
  240. }
  241. function populateSelect(data,selectedData, par, rowId){
  242. //data is the set of lookup entries, selectedData is a subset of entries valued at lookup.keyColumn
  243. let debug=true;
  244. if (debug)
  245. print(par.config,"populateSelect Data: "+data.queryName+" selectedData:"+selectedData.queryName);
  246. let row=par.vars[rowId];
  247. let selectId=row.selectId;
  248. let varName=row.masterSelectVarName;
  249. if ("filter" in row){
  250. varName=row.filter.filterVarName;
  251. }
  252. let field=getField(par.config,selectedData,varName);
  253. let displayColumn=field.lookup.displayColumn;
  254. let keyColumn=field.lookup.keyColumn;
  255. if (debug){
  256. print(par.config,"Query: "+data.queryName);
  257. print(par.config,"ElementId: "+selectId);
  258. print(par.config,"keyColumn: "+keyColumn);
  259. print(par.config,"displayColumn: "+displayColumn);
  260. }
  261. let el = document.getElementById(selectId);
  262. if (debug)
  263. print(par.config,"Element: "+el);
  264. for(i = el.options.length; i >= 0; i--) {
  265. el.remove(i);
  266. }
  267. if ("addSelect" in row){
  268. let opt = par.config.document.createElement("option");
  269. opt.text = "<Select>";
  270. opt.value = -1;
  271. el.options[0] = opt;
  272. }
  273. if ("addNewFlag" in row){
  274. let opt = par.config.document.createElement("option");
  275. opt.text = "Add New"
  276. opt.value = row.addNewFlag;
  277. el.options[el.options.length] = opt;
  278. }
  279. for (var i = 0; i < data.rows.length; i++) {
  280. let key=data.rows[i][keyColumn];
  281. let skip=true;
  282. if (row.selectAll){
  283. skip=false;
  284. }
  285. else{
  286. if (debug)
  287. print(par.config,"Selecting from: "+selectedData.rows.length);
  288. for (let j=0; j< selectedData.rows.length; j++){
  289. let entry=selectedData.rows[j];
  290. if (debug)
  291. print(par.config,"Comparing: "+entry[varName]+"/"+key);
  292. if (key!=entry[varName]) continue;
  293. skip=false;
  294. break;
  295. }
  296. }
  297. if (skip) continue;
  298. let opt = par.config.document.createElement("option");
  299. opt.text = data.rows[i][displayColumn];
  300. opt.value = data.rows[i][keyColumn];
  301. if (debug)
  302. print(par.config,"Adding: "+opt.value+" : "+opt.text);
  303. el.options[el.options.length] = opt;
  304. if ("selectedKey" in row){
  305. if (debug)
  306. print(par.config,"Comparing: " + opt.value + "/" + row["selectedKey"]);
  307. if (opt.value==row["selectedKey"]){
  308. el.selectedIndex=el.options.length-1;
  309. if (debug)
  310. print(par.config,"Equal; "+el.selectedIndex);
  311. }
  312. }
  313. }
  314. if (debug)
  315. print(par.config,"Running callback");
  316. row.callback(par,rowId);
  317. }
  318. function generateListAndPopulateDaughterSelect(par,rowId){
  319. let debug=true;
  320. if (debug){
  321. print(par.config,"generateListAndPopulateDaughter");
  322. }
  323. generateList(par,rowId);
  324. let row=par.vars[rowId];
  325. if ("daughterSelect" in row){
  326. populateDaughterSelect(par,rowId,row["daughterSelect"],null);
  327. }
  328. }
  329. function populateDaughterSelect(par,rowId,daughterRowId,entry){//populateSelectNotLookup
  330. let debug=true;
  331. if (debug)
  332. print(par.config,"populateDaughterSelect: "+rowId+" "+daughterRowId);
  333. let row=par.vars[rowId];
  334. if (debug)
  335. print(par.config,"row["+rowId+"]:"+row);
  336. let daughterRow=par.vars[daughterRowId];
  337. if (debug)
  338. print(par.config,"daughterRow["+daughterRowId+"]:"+daughterRow);
  339. let el=par.config.document.getElementById(row.selectId);
  340. if (debug)
  341. print(par.config,"\n Element:"+el);
  342. let varValue=el.options[el.selectedIndex].value;
  343. if (debug)
  344. print(par.config,"\nAdding filter ["+row.masterSelectVarName+"]:"+varValue);
  345. let config=generateQConfig(par.masterQuery)
  346. config.filterArray=[];
  347. for (let i=0;i < par.filters.length;i++){
  348. let filterRowId=par.filters[i];
  349. let filterRow=par.vars[filterRowId];
  350. let filterValue=par.config.document.getElementById(filterRow.selectId).value;
  351. config.filterArray.push(LABKEY.Filter.create(filterRow.masterSelectVarName,filterValue));
  352. }
  353. config.success=function(data){populateSelectNotLookup(data,par,daughterRowId,entry)};
  354. LABKEY.Query.selectRows(config);
  355. }
  356. function populateSelectNotLookup(data,par,rowId, entry){
  357. //selectId
  358. //masterSelectVarName
  359. let debug=true;
  360. if (debug)
  361. print(par.config,"populateSelectNonLookup on "+data.queryName);
  362. let row=par.vars[rowId];
  363. let varName=row.masterSelectVarName;
  364. if (debug) print(par.config,"var "+varName+" rows "+data.rows.length);
  365. if (debug) print(par.config,"Getting element "+row.selectId);
  366. let el=par.config.document.getElementById(row.selectId);
  367. if (!el) {
  368. print(par.config,"Element not found");
  369. return;
  370. }
  371. if (debug) print(par.config,"Element "+el);
  372. if (debug) print(par.config,"Clearing entries");
  373. //remove previous options
  374. for(i = el.options.length; i >= 0; i--) {
  375. el.remove(i);
  376. }
  377. if (debug)
  378. print(par.config,"Adding entries");
  379. if ("addSelect" in row){
  380. if (debug)
  381. print(par.config,"adding <Select>");
  382. let opt = par.config.document.createElement("option");
  383. opt.text = "<Select>";
  384. opt.value = -2;
  385. el.options[0] = opt;
  386. }
  387. if ("addNewFlag" in row){
  388. if (debug) print(par.config,"adding Add new");
  389. let opt = par.config.document.createElement("option");
  390. opt.text = "Add New";
  391. opt.value = row.addNewFlag;
  392. el.options[el.options.length] = opt;
  393. }
  394. for (let i=0;i< data.rows.length;i++){
  395. let valEntry=data.rows[i];
  396. if (debug)
  397. print(par.config,"adding "+valEntry[varName]);
  398. let opt = par.config.document.createElement("option");
  399. opt.text = valEntry[varName];
  400. opt.value = valEntry[varName];
  401. if (entry){
  402. if (opt.value==entry[varName])
  403. el.selectedIndex=el.options.length-1;
  404. }
  405. el.options[el.options.length] = opt;
  406. }
  407. if (entry)
  408. row.callback(par,rowId);
  409. }
  410. function generateList(par,rowId){
  411. let row=par.vars[rowId];
  412. let debug=true;
  413. if (debug)
  414. print(par.config,"generateList: "+par.masterQuery);
  415. //ignore authorization, just select on select variable
  416. let el=par.config.document.getElementById(row.selectId);
  417. let varValue=el.options[el.selectedIndex].value;
  418. if (debug)
  419. print(par.config,"Using value "+varValue+" from "+row.selectId);
  420. let iValue=parseInt(varValue);
  421. let div=par.config.document.getElementById(par.addDiv);
  422. div.style.display="none";
  423. //add new crf entry
  424. if ("addNewFlag" in row){
  425. if (debug)
  426. print(par.config,"Comparing " + iValue + "/" + row.addNewFlag);
  427. if (iValue==row.addNewFlag) {
  428. addNew(par);
  429. return;
  430. }
  431. }
  432. //do filtering
  433. let filterArray=[];
  434. for (let i=0;i < par.filters.length;i++){
  435. let filterRowId=par.filters[i];
  436. let filterRow=par.vars[filterRowId];
  437. let filterValue=par.config.document.getElementById(filterRow.selectId).value;
  438. filterArray.push(LABKEY.Filter.create(filterRow.masterSelectVarName,filterValue));
  439. }
  440. //show all for system entries (Select, Add New)
  441. if (debug)
  442. print(par.config,"Using iValue "+iValue);
  443. if (iValue<0) {
  444. if (debug)
  445. print(par.config,"Ignoring ["+row.masterSelectVarName+ "]: "+varValue);
  446. }
  447. else{
  448. if (debug)
  449. print(par.config,"Filtering ["+row.masterSelectVarName+"]: "+varValue);
  450. if (rowId==="Crf"){
  451. filterArray.push(LABKEY.Filter.create(row.masterSelectVarName,varValue));
  452. if (debug)
  453. print(par.config,"Filtering ["+row.masterSelectVarName+"]: "+varValue);
  454. }
  455. }
  456. var config=generateQConfig(par.masterQuery);
  457. config.renderTo=par.dataDiv;
  458. config.buttonBarPosition='top';
  459. config.filters=filterArray;
  460. config.viewName="sparseView";
  461. config.success=function(data){updateSuccess(data,par)};
  462. config.failure=function(json){updateFailure(json,par)};
  463. LABKEY.QueryWebPart(config);
  464. }
  465. function updateSuccess(data,par){
  466. print(par.config,"Update success");
  467. }
  468. function updateFailure(json,par){
  469. print(par.config,"Update failed");
  470. }
  471. function addNew(par){
  472. print(par.config,"Show Add new");
  473. let div=par.config.document.getElementById(par.addDiv);
  474. div.style.display="block";
  475. }
  476. function generateButtonRow(tableId,caption,label,par,callback){
  477. let tb=par.config.document.getElementById(tableId);
  478. let trow=tb.insertRow();
  479. let cell=par.config.document.createElement('th');
  480. trow.appendChild(cell);
  481. let text = par.config.document.createTextNode(caption);
  482. cell.appendChild(text);
  483. cell=trow.insertCell();
  484. let input = par.config.document.createElement("input");
  485. input.type="button";
  486. input.value=label;
  487. input.onclick=function(){callback(par)};
  488. cell.appendChild(input);
  489. }
  490. //callback candidate
  491. function addNewEntry(par){
  492. print(par.config,"Add new, npar ");
  493. let entry=new Object();
  494. for (vv in par.vars){
  495. let f=par.vars[vv];
  496. print(par.config,"New: Adding "+f.masterSelectVarName);
  497. setValue(entry,f);
  498. }
  499. for (f in entry){
  500. print(par.config,"entry ["+f+"]="+entry[f]);
  501. }
  502. entry.entryId=Date.now();
  503. entry.Date=new Date();
  504. entry.formStatus=1;//In Progress
  505. let config=generateQConfig(par.masterQuery);
  506. config.rows=[entry];
  507. config.success=function(data){
  508. populateDaughterSelect(par,"Site","Crf",data.rows[0]);
  509. selectEntry(par.config,data,par.vars["Crf"]);
  510. generateList(par,"Crf");};
  511. LABKEY.Query.insertRows(config);
  512. }