crfPortal.js 17 KB

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