crfVisit.js 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805
  1. function clear(config){
  2. let el=config.document.getElementById(config.debugId);
  3. if (el===null) {
  4. //alert("Debug section not initialized");
  5. return;
  6. }
  7. config.document.getElementById(config.debugId).value="";
  8. }
  9. function print(config,msg){
  10. let el=config.document.getElementById(config.debugId);
  11. if (el===null) {
  12. //alert("Debug section not initialized. Message: "+msg);
  13. return;
  14. }
  15. el.value+="\n"+msg;
  16. }
  17. function getCRFref(config){
  18. //'crfRefId'
  19. return config.document.getElementById(config.crfRefId).innerHTML;
  20. }
  21. function onFailure(errorInfo, options, responseObj){
  22. if (errorInfo && errorInfo.exception)
  23. alert("Failure: " + errorInfo.exception);
  24. else
  25. alert("Failure: " + responseObj.statusText);
  26. }
  27. function generateDebugSection(config){
  28. //let debug=true;
  29. //if (debug) print(config,"generateDebugSection "+sectionName);
  30. let formName=config.debugDiv;
  31. let sectionName="debugSection";
  32. let sectionTitle="Debug Messages";
  33. let tb=config.document.createElement('table');
  34. tb.className='t2';
  35. let row=tb.insertRow();
  36. let cell=config.document.createElement('th');
  37. row.appendChild(cell);
  38. cell.setAttribute("colspan","4");
  39. cell.style.fontSize="20px";
  40. cell.style.textAlign="center";
  41. let cellData=config.document.createTextNode(sectionTitle);
  42. cell.appendChild(cellData);
  43. cell=row.insertCell();
  44. let input=config.document.createElement("input");
  45. input.type="button";
  46. input.value="Show";
  47. input.id="toggle"+sectionName+"VisbilityButton";
  48. input.onclick=function(){toggleVisibility(config,sectionName,input.id)};
  49. cell.appendChild(input);
  50. config.document.getElementById(formName).appendChild(tb);
  51. let div=config.document.createElement('div');
  52. div.id=sectionName;
  53. div.style.display="none";
  54. config.document.getElementById(formName).appendChild(div);
  55. let debugArea=config.document.createElement('textarea');
  56. debugArea.rows=10;
  57. debugArea.cols=95;
  58. debugArea.id=config.debugId;
  59. div.appendChild(debugArea);
  60. }
  61. function setAdditionalData(config, additionalData,entry){
  62. let debug=true;
  63. if (debug) print(config,"setAdditionalData");
  64. if (entry["showFlag"]==="NONE") {
  65. if (debug) print(config,"Returning empty additionalData");
  66. return additionalData;
  67. }
  68. additionalData.showFlag=entry["showFlag"];
  69. additionalData.showFlagValue=entry["showFlagValue"];
  70. additionalData.queryName=entry["showQuery"];
  71. additionalData.filters=new Object();
  72. additionalData.filters['crfRef']=getCRFref(config);
  73. return additionalData;
  74. }
  75. function fullAccessSetup(config,listName){
  76. let debug=true;
  77. if (debug) print(config,"fullAccessSetup");
  78. let setup=new Object();
  79. setup.readonlyFlag=function(vName){return false};
  80. setup.filters=new Object();
  81. setup.filters['crfRef']=getCRFref(config);
  82. setup.getInputId=function(vName){return listName+"_"+vName;}
  83. setup.addApply="Save";
  84. return setup;
  85. }
  86. function readonlySetup(config){
  87. let debug=true;
  88. if (debug) print(config,"readonlySetup");
  89. let setup=new Object();
  90. setup.readonlyFlag=function(vName){return true};
  91. setup.filters=new Object();
  92. setup.filters['crfRef']=getCRFref(config);
  93. setup.getInputId=function(vName){return vName;}
  94. return setup;
  95. }
  96. function afterFormSetup(config,formConfig,data){
  97. let debug=true;
  98. if (debug) print(config,"afterFormSetup ["+data.rows.length+"]");
  99. formConfig.formSetup=data;
  100. //get list of queries
  101. let fields=formConfig.formSetup.metaData.fields;
  102. if (debug) print(config,"generateForm: fields: "+fields);
  103. let field="NONE";
  104. //if (debug) printTableSetup(config,data);
  105. for (f in fields){
  106. if (fields[f]['name']!='queryName') continue;
  107. field=fields[f];
  108. break;
  109. }
  110. if (debug) print(config,"generateForm: field: "+field);
  111. let lookup=field.lookup;
  112. if (debug) print(config,"generateForm: lookup: "+lookup);
  113. let qconfig=new Object();
  114. qconfig.containerPath=config.containerPath;
  115. qconfig.schemaName=lookup.schemaName;
  116. qconfig.queryName=lookup.queryName;
  117. //qconfig.filterArray=[LABKEY.Filter.create(lookup.keyColumn,entry['queryName'])];
  118. qconfig.filterArray=[];
  119. qconfig.success=function(data){afterFormSetupLookup(config,formConfig,data)};
  120. LABKEY.Query.selectRows(qconfig);
  121. }
  122. function afterFormSetupLookup(config,formConfig,data){
  123. //walk through the list of datasets/list and generate tables for each list
  124. let debug=true;
  125. formConfig.formSetupLookup=data;
  126. let rows=formConfig.formSetup.rows;
  127. //extract list of forms from formConfig
  128. for (let i=0;i<rows.length;i++){
  129. //each from has multiple lists associated with it
  130. if (debug) print(config,"generateForm ["+i+"/"+rows.length+"]");
  131. let entry=rows[i];
  132. //this is actually a pointer into another list (==lookup)
  133. //another selectRows is needed to actually get the name for the queryName
  134. //id : entry[queryName]
  135. //name: dentry[queryName]
  136. let queryId=entry['queryName'];
  137. //walk over keys to get the right lookup entry
  138. let lookupRows=formConfig.formSetupLookup.rows;
  139. let dentry=undefined;
  140. for (let j=0;j<lookupRows.length;j++){
  141. if (lookupRows[j].Key!=queryId)
  142. continue;
  143. dentry=lookupRows[j];
  144. break;
  145. }
  146. if (dentry===undefined){
  147. print(config,"generateForm ["+i+"] no list found");
  148. return;
  149. }
  150. if (debug)
  151. for (f in dentry)
  152. print(config,"generateFormLookup field: "+f+" value: "+dentry[f]);
  153. let queryName=dentry["queryName"];
  154. if (debug) print(config,"generateFormLookup: ID: "+queryId+" name: "+queryName);
  155. //update fields for review
  156. if (!(queryName in config.fields))
  157. config.fields[queryName]=new Object();
  158. if (!(queryId in config.queryMap))
  159. config.queryMap[queryId]=queryName;
  160. let field=config.fields[queryName];
  161. field.title=entry["title"];
  162. field.queryId=queryId;
  163. if (debug) print(config,"entry[showFlag]: "+entry["showFlag"]);
  164. let additionalData=new Object();
  165. setAdditionalData(config,additionalData,entry);
  166. //section fits one dataset/list
  167. generateSection(config,formConfig,queryName,entry["title"],queryName, additionalData);
  168. }
  169. }
  170. function generateSection(config, formConfig, sectionName, sectionTitle, listName, additionalData){
  171. let formName=config.masterForm;//this is HTML designator of area on page
  172. let debug=true;
  173. if (debug) print(config,"generateSection "+sectionName);
  174. let tb=config.document.createElement('table');
  175. tb.className='t2';
  176. let row=tb.insertRow();
  177. let cell=config.document.createElement('th');
  178. row.appendChild(cell);
  179. cell.setAttribute("colspan","4");
  180. cell.style.fontSize="20px";
  181. cell.style.textAlign="center";
  182. let cellData=config.document.createTextNode(sectionTitle);
  183. cell.appendChild(cellData);
  184. cell=row.insertCell();
  185. let input=config.document.createElement("input");
  186. input.type="button";
  187. input.value="Show";
  188. input.id="toggle"+sectionName+"VisbilityButton";
  189. input.onclick=function(){toggleVisibility(config,sectionName,input.id)};
  190. cell.appendChild(input);
  191. config.document.getElementById(formName).appendChild(tb);
  192. let div=config.document.createElement('div');
  193. div.id=sectionName;
  194. div.style.display="none";
  195. config.document.getElementById(formName).appendChild(div);
  196. let divTable=config.document.createElement('div');
  197. divTable.id=sectionName+"Table";
  198. div.appendChild(divTable);
  199. if ("showFlag" in additionalData) {
  200. additionalData.divName=sectionName+"SubDiv";
  201. additionalData.divQueryName=sectionName+"SubDivList";
  202. let div1=config.document.createElement('div');
  203. div1.id=additionalData.divName;
  204. div1.style.display="none";
  205. div.appendChild(div1);
  206. let div2=config.document.createElement('div');
  207. div2.id=additionalData.divQueryName;
  208. div1.appendChild(div2);
  209. }
  210. if (debug) print(config,"generate master table");
  211. let setup=fullAccessSetup(config,listName);
  212. if (formConfig.formStatus=="Submitted")
  213. setup=readonlySetup(config);
  214. if (formConfig.formStatus=="Approved")
  215. setup=readonlySetup(config);
  216. //master table is unique per visit
  217. setup.unique=true;
  218. generateTable(config,formConfig,listName,divTable.id,true,additionalData,setup);
  219. if (debug) print(config,"generate master table: done");
  220. let generateSubTable=true;
  221. if (formConfig.formStatus=="Submitted")
  222. generateSubTable=false;
  223. if (formConfig.formStatus=="Approved")
  224. generateSubTable=false;
  225. if (! ("showFlag" in additionalData) ) generateSubTable=false;
  226. if (generateSubTable){
  227. let qName=additionalData.queryName;
  228. let dName=additionalData.divName;
  229. let setup=fullAccessSetup(config,qName);
  230. //if (readonly) setup=readonlySetup(config);
  231. generateTable(config,formConfig,qName,dName,false,additionalData,setup);
  232. }
  233. print(config,"generate review");
  234. let divReviewList=config.document.createElement('div');
  235. divReviewList.id=sectionName+"ReviewList";
  236. div.appendChild(divReviewList);
  237. let divReview=config.document.createElement('div');
  238. divReview.id=sectionName+"Review";
  239. div.appendChild(divReview);
  240. //assume we already have listId (content of config.setupQueryName is listId)
  241. //we need listName also
  242. //qconfig.queryName=config.setupQueryName;
  243. generateReview(config,formConfig,divReview.id,divReviewList.id,listName);
  244. }
  245. function generateReview(config,formConfig,divReviewId,divReviewListId, listName){
  246. let listId=config.fields[listName].queryId;
  247. let debug=true;
  248. if (debug) print(config,"Generate review for: "+listId);
  249. let reviewSetup=new Object();
  250. reviewSetup.readonlyFlag=function(vName){
  251. if (vName=="queryName") return true;
  252. if (vName=="queryname") return true;
  253. if (vName=="ModifiedBy") return true;
  254. return false;};
  255. reviewSetup.addApply="Add Review";
  256. let generateTableFlag=true;
  257. if (formConfig.formStatus == "Approved" ){
  258. delete reviewSetup.addApply;
  259. reviewSetup.readonlyFlag=function(vName){return false;}
  260. generateTableFlag=false;
  261. }
  262. reviewSetup.filters=new Object();
  263. reviewSetup.filters["crfRef"]=getCRFref(config);
  264. reviewSetup.filters["queryName"]=listId;//entry in reviewComments list is queryname, all in small caps
  265. //needs listName, in argument
  266. reviewSetup.getInputId=function(vName){return listName+"_add"+vName};
  267. reviewSetup.divReviewListId=divReviewListId;
  268. if (debug) {
  269. let msg="Review: divId: "+divReviewId;
  270. msg+=" inputId: "+reviewSetup.getInputId;
  271. print(config,msg);
  272. }
  273. updateListDisplay(config,divReviewListId,"reviewComments",reviewSetup.filters,true);
  274. if (! generateTableFlag) return;
  275. generateTable(config, formConfig,"reviewComments",divReviewId,false,new Object(),reviewSetup);
  276. }
  277. function setListVisibility(config, setup,additionalData,readonlyFlag){
  278. let debug=true;
  279. if (debug){
  280. print(config,"Set list visibility ");
  281. for (f in additionalData){
  282. print(config,"AdditionalData["+f+"]: "+additionalData[f]);
  283. }
  284. }
  285. let x = config.document.getElementById(additionalData.divName);
  286. if (debug) print(config,"\n Div: "+x);
  287. x.style.display="none";
  288. let eId=setup.getInputId(additionalData.showFlag);
  289. let e = config.document.getElementById(eId);
  290. let sText;
  291. if (readonlyFlag) sText=e.innerHTML;
  292. else sText=e.options[e.selectedIndex].text;
  293. if (debug) print(config,"\n Selected option text: "+sText);
  294. if (sText == additionalData.showFlagValue){
  295. let filters=new Object();
  296. if ("filters" in additionalData) filters=additionalData.filters;
  297. x.style.display = "block";
  298. updateListDisplay(config,
  299. additionalData.divQueryName,additionalData.queryName,filters,readonlyFlag);
  300. }
  301. }
  302. function updateListDisplay(config, divName,queryName,filters,readonlyFlag){
  303. let debug=true;
  304. if (debug) print(config,"UpdateListDisplay: Query - "+queryName+" div - "+divName);
  305. if (divName=="NONE") return;
  306. let crfRef=getCRFref(config);
  307. let div=config.document.getElementById(divName);
  308. if (debug)
  309. print(config,"Enabling display to queryName: "+queryName);
  310. var qconfig=new Object();
  311. qconfig.renderTo=divName;
  312. qconfig.containerPath=config.containerPath;
  313. qconfig.schemaName='lists';
  314. qconfig.queryName=queryName;
  315. qconfig.buttonBarPosition='top';
  316. qconfig.filters=[];
  317. for (f in filters){
  318. qconfig.filters.push(LABKEY.Filter.create(f, filters[f]));
  319. }
  320. qconfig.success=function(data){updateSuccess(config,data)};
  321. qconfig.failure=function(data){updateFailure(config,data)};
  322. //show only print button
  323. if (readonlyFlag){
  324. qconfig.buttonBar=new Object();
  325. qconfig.buttonBar.items=["print"];
  326. }
  327. LABKEY.QueryWebPart(qconfig);
  328. }
  329. function updateSuccess(config,data){
  330. print(config,"Update success");
  331. }
  332. function updateFailure(config,data){
  333. print(config,"Update failed");
  334. }
  335. function toggleVisibility(config, divName,buttonName){
  336. let x = config.document.getElementById(divName);
  337. if (x.style.display === "none") {
  338. x.style.display = "block";
  339. config.document.getElementById(buttonName).value="Hide";
  340. } else {
  341. x.style.display = "none";
  342. config.document.getElementById(buttonName).value="Show";
  343. }
  344. }
  345. function generateButton(config,divName,title,buttonName,callback,callbackParameters){
  346. let debug=true;
  347. if (debug) print(config,"generateButton");
  348. let tb=config.document.createElement('table');
  349. tb.className="t2";
  350. let r1=tb.insertRow();
  351. th=config.document.createElement('th');
  352. r1.appendChild(th);
  353. th.innerHTML=title;
  354. //*!*
  355. let c2=r1.insertCell();
  356. let i1=config.document.createElement("input");
  357. i1.type="button";
  358. i1.value=buttonName;
  359. i1.style.fontSize="20px";
  360. i1.onclick=function(){callback(callbackParameters);}
  361. c2.appendChild(i1);
  362. let c1=r1.insertCell();
  363. c1.setAttribute("colspan","1");
  364. c1.id=callbackParameters.submitReportId;
  365. let el=config.document.getElementById(divName);
  366. if (debug) print(config,"generateButton: element["+divName+"]: "+el);
  367. el.appendChild(tb);
  368. }
  369. function generateTable(config,formConfig,listName,divName,unique,additionalData,setup){
  370. let debug=true;
  371. if (debug) print(config,"generateTable: "+listName);
  372. //these objects will contain respective data for the entry
  373. //add temp variables
  374. //this will capture the state of the data prior to updating
  375. let qconfig=new Object();
  376. qconfig.containerPath=config.containerPath;
  377. qconfig.schemaName='lists';
  378. qconfig.queryName=listName;
  379. //apply filters on data to get right entries
  380. qconfig.filterArray=[];
  381. for (f in setup.filters){
  382. qconfig.filterArray.push(LABKEY.Filter.create(f,setup.filters[f]));
  383. }
  384. qconfig.success=function(data){populateTable(config,formConfig, data,divName,unique,additionalData,setup)};
  385. LABKEY.Query.selectRows(qconfig);
  386. }
  387. function printTableSetup(config,data){
  388. let obj=data.metaData.fields;
  389. for (f in obj){
  390. print(config,"Data["+f+"]: "+obj[f]);
  391. for (g in obj[f]){
  392. print(config,"Data.metaData.fields["+f+"]["+g+"]: "+obj[f][g]);
  393. }
  394. if ("lookup" in obj[f]){
  395. for (h in obj[f]["lookup"]){
  396. print(config,"Lookup["+h+"]: "+obj[f]["lookup"][h]);
  397. }
  398. }
  399. }
  400. }
  401. function populateTable(config,formConfig, data,divName,unique,additionalData,setup){
  402. //generate and populate table with the first suitable entry
  403. let debug=true;
  404. //avoid resetting of values
  405. if (!(data.queryName in formConfig.dataFields))
  406. formConfig.dataFields[data.queryName]=data.metaData.fields;
  407. if (debug){
  408. print(config,"populateTable Query: "+data.queryName+" divName: "+divName+" setup: "+setup);
  409. if (0) printTableSetup(config,data);
  410. }
  411. let crfRef=getCRFref(config);
  412. let entry=new Object();
  413. if (debug)
  414. print(config,"Data: nrows "+data.rows.length);
  415. //copy values from queryName to formConfig.entries
  416. if (data.rows.length > 0) formConfig.entries[data.queryName]=data.rows[0];
  417. //this is the current data snapshot
  418. if (data.queryName in formConfig.entries)
  419. entry=formConfig.entries[data.queryName];
  420. let tb=config.document.createElement('table');
  421. tb.className="t2";
  422. config.document.getElementById(divName).appendChild(tb);
  423. //this are the fields (probably constant)
  424. let fields=formConfig.dataFields[data.queryName];
  425. for (f in fields){
  426. let field=fields[f];
  427. if (field.hidden) continue;
  428. let vName=field.name;
  429. if (debug) print(config,"Field ["+vName+"]");
  430. if (vName=="crfRef") continue;
  431. let vType=field.type;
  432. if (debug) print(config,"Field ["+vName+"/"+vType+"]");
  433. let row=tb.insertRow();
  434. let cell=config.document.createElement('th');
  435. row.appendChild(cell);
  436. let text = config.document.createTextNode(fields[f].shortCaption);
  437. cell.appendChild(text);
  438. cell=row.insertCell();
  439. let varValue="UNDEF";
  440. if (vName in setup.filters) varValue=setup.filters[vName];
  441. if (vName in entry) varValue=entry[vName];
  442. if (vType=="date"){
  443. if (varValue==="UNDEF") varValue=new Date();
  444. else varValue=new Date(varValue);
  445. }
  446. if (debug) print(config,"value: "+varValue);
  447. let input;
  448. if (setup.readonlyFlag(vName)){
  449. input=config.document.createTextNode(varValue);
  450. cell.id=setup.getInputId(vName);
  451. }
  452. else{
  453. cell.colSpan="3";
  454. let cellClass="input";
  455. let cellType="text";
  456. if ("lookup" in field){
  457. input = config.document.createElement("select");
  458. }
  459. if (vType=="date"){
  460. input = config.document.createElement("input");
  461. input.type="date";
  462. }
  463. if (vType=="string" && !("lookup" in field)){
  464. if(vName.search("reviewComment")>-1){
  465. input = config.document.createElement("textarea");
  466. input.cols="65";
  467. input.rows="5";
  468. }
  469. else{
  470. input = config.document.createElement("input");
  471. input.type="text";
  472. }
  473. }
  474. if (vType=="float"){
  475. input = config.document.createElement("input");
  476. input.type="text";
  477. }
  478. if (vType=="boolean"){
  479. input = config.document.createElement("input");
  480. input.type="checkbox";
  481. print(config,"Creating checkbox");
  482. }
  483. input.id=setup.getInputId(vName);
  484. if (varValue != "UNDEF"){
  485. if (vType=="string") input.value=varValue;
  486. if (vType=="float") input.value=varValue;
  487. if (vType=="date") input.valueAsDate=varValue;
  488. if (vType=="boolean") input.checked=varValue;
  489. }
  490. }
  491. cell.appendChild(input);
  492. if ("lookup" in field){
  493. let lookup=field["lookup"];
  494. let qconfig=new Object();
  495. if (debug) print(config,"populateTable lookup: Query: "+lookup.queryName);
  496. qconfig.containerPath=config.containerPath;
  497. qconfig.schemaName=lookup.schemaName;
  498. qconfig.queryName=lookup.queryName;
  499. let parameters= new Object();
  500. parameters.elementId=setup.getInputId(vName);
  501. parameters.keyColumn=lookup.keyColumn;
  502. parameters.displayColumn=lookup.displayColumn;
  503. if (vName in setup.filters) parameters.selectedKey=setup.filters[vName];
  504. if (vName in entry) parameters.selectedKey=entry[vName];
  505. if ("showFlag" in additionalData) parameters.additionalData=additionalData;
  506. if (debug) print(config,"Populate select for "+parameters.elementId);
  507. qconfig.success=function(data){
  508. populateSelect(config,data,parameters,setup,setup.readonlyFlag(vName))
  509. };
  510. LABKEY.Query.selectRows(qconfig);
  511. }
  512. }
  513. //add comment field
  514. if (!("addApply" in setup)) {
  515. print(config,"populateTable: done");
  516. return;
  517. }
  518. let row=tb.insertRow();
  519. let th=config.document.createElement('th');
  520. row.appendChild(th);
  521. th.innerHTML=setup.addApply;
  522. let cell=row.insertCell();
  523. //cell.setAttribute("colspan","2");
  524. let input=config.document.createElement("input");
  525. input.type="button";
  526. input.value=setup.addApply;
  527. cell.appendChild(input);
  528. let cell1=row.insertCell();
  529. cell1.setAttribute("colspan","2");
  530. cell1.id=setup.getInputId("rerviewLastSave");
  531. cell1.innerHTML="No recent update";
  532. input.onclick=function(){saveReview(config,data.queryName,cell1.id,setup)};
  533. }
  534. function populateSelect(config,data,parameters,setup,readonlyFlag){
  535. let debug=true;
  536. if (debug)
  537. print(config,"populateSelect on "+data.queryName);
  538. let elementId=parameters.elementId;
  539. let keyColumn=parameters.keyColumn;
  540. let displayColumn=parameters.displayColumn;
  541. if (debug){
  542. print(config,"Query: "+data.queryName);
  543. print(config,"ElementId: "+elementId);
  544. print(config,"keyColumn: "+keyColumn);
  545. print(config,"displayColumn: "+displayColumn);
  546. print(config,"No of options: " +data.rows.length);
  547. if ("selectedKey" in parameters){
  548. print(config,"SelectedKey: "+parameters["selectedKey"]);
  549. }
  550. }
  551. let el = config.document.getElementById(elementId);
  552. if (debug)
  553. print(config,"Element: "+el);
  554. if (!readonlyFlag){
  555. //clear options
  556. for(i = el.options.length; i >= 0; i--) {
  557. el.remove(i);
  558. }
  559. let opt = config.document.createElement("option");
  560. opt.text = "<Select>";
  561. opt.value = -1;
  562. el.options[0] = opt;
  563. if (debug) print(config, "Adding <Select>");
  564. }
  565. for (let i = 0; i < data.rows.length; i++) {
  566. let displayText = data.rows[i][displayColumn];
  567. let keyValue = data.rows[i][keyColumn];
  568. if (!readonlyFlag){
  569. let opt = config.document.createElement("option");
  570. opt.text = displayText;
  571. opt.value = keyValue;
  572. el.options[el.options.length] = opt;
  573. }
  574. if (debug) print(config,"Adding: "+keyValue+" : "+displayText);
  575. let t1=checkVariable(config,el,keyValue,displayText,parameters,"selectedKey",readonlyFlag);
  576. if (t1) setup.keyValue=keyValue;
  577. }
  578. if (!("additionalData" in parameters)) return;
  579. if (debug) print(config,"\n Parsing additional data ");
  580. let additionalData=parameters["additionalData"];
  581. let expId=setup.getInputId(additionalData.showFlag);
  582. if (expId!=elementId) {
  583. print(config,"Element mismatch: got :"+expId+"/"+elementId);
  584. return;
  585. }
  586. if (debug)
  587. print(config,"Setting onChange to "+el.id);
  588. el.onchange=function(){setListVisibility(config,setup,additionalData,readonlyFlag)};
  589. setListVisibility(config,setup,additionalData,readonlyFlag);
  590. }
  591. function checkVariable(config,el,varValue,displayText, parameters,varName,readonlyFlag){
  592. let debug=true;
  593. if (!varName in parameters) return false;
  594. if (debug) print(config,"Comparing: " + varValue + "/" + parameters[varName]);
  595. if (varValue==parameters[varName]){
  596. if (readonlyFlag) el.innerHTML=displayText;
  597. else {
  598. el.selectedIndex=el.options.length-1;
  599. if (debug) print(config,"Equal; "+el.selectedIndex);
  600. }
  601. return true;
  602. }
  603. return false;
  604. }
  605. function failureSelect(config,errorInfo,resp,opt){
  606. print(config,"Error: ");
  607. }
  608. function saveReview(config,queryName,elementId,setup){
  609. let debug=true;
  610. if (debug) print(config,"saveReview: elementId "+elementId+" queryName "+queryName);
  611. let qconfig=new Object();
  612. qconfig.containerPath=config.containerPath;
  613. qconfig.schemaName='lists';//could be made more generic
  614. qconfig.queryName=queryName;
  615. if ("unique" in setup){
  616. qconfig.filterArray=[LABKEY.Filter.create("crfRef",getCRFref(config))];
  617. }
  618. qconfig.success=function(data){saveReviewToList(config,data,elementId,setup);}
  619. //to guess the fields, one must do selectRows first?
  620. LABKEY.Query.selectRows(qconfig);
  621. }
  622. function saveReviewToList(config,data,elementId,setup){
  623. let debug=true;
  624. if (debug) {
  625. let msg="saveReviewToList: "+" elementId "+elementId;
  626. msg+=" nrows "+data.rows.length;
  627. print(config,msg);
  628. }
  629. let useInsert=false;
  630. if (!("unique" in setup)) useInsert=true;
  631. if (data.rows.length==0) useInsert=true;
  632. let entry=new Object();
  633. if (!useInsert){
  634. entry=data.rows[0];
  635. }
  636. entry.crfRef=getCRFref(config);
  637. if (debug) print(config,"Set crfRef="+entry.crfRef);
  638. if ("queryName" in setup.filters) {
  639. entry.queryName=setup.filters["queryName"];
  640. if (debug) print(config,"Setting queryName: "+entry.queryName);
  641. }
  642. if ("queryname" in setup.filters) {
  643. entry.queryname=setup.filters["queryname"];
  644. if (debug) print(config,"Setting queryname: "+entry.queryname);
  645. }
  646. let fields=data.metaData.fields;
  647. for (f in fields){
  648. let field=fields[f];
  649. if (debug) print(config,"saveReview field: "+field.name);
  650. if (field.hidden) continue;
  651. let vName=fields[f].name;
  652. if (vName=="crfRef") continue;
  653. if (vName=="queryName") continue;
  654. if (vName=="queryname") continue;
  655. let eId=setup.getInputId(vName);
  656. let el=config.document.getElementById(eId);
  657. if (!el) {
  658. if (debug) print(config,"saveReview element: "+eId+" not found");
  659. continue;
  660. }
  661. if (debug) print(config,"saveReview element: "+eId);
  662. let vType=fields[f].type;
  663. if (debug) print(config,"vType: "+vType);
  664. if ("lookup" in fields[f]){
  665. if (el.nodeName==="SELECT"){
  666. entry[vName]=el.options[el.selectedIndex].value;
  667. }
  668. if (el.nodeName==="TD"){
  669. entry[vName]=el.innerHTML;
  670. }
  671. print(config,"Setting lookup to "+entry[vName]);
  672. continue;
  673. }
  674. if (vType=="date"){
  675. var date=el.valueAsDate;
  676. if (date==="null") continue;
  677. date.setUTCHours(12);
  678. entry[vName]=date.toString();
  679. print(config,"Setting date to "+entry[vName]);
  680. }
  681. if (vType=="string"){
  682. entry[vName]=el.value;
  683. }
  684. if (vType=="float"){
  685. entry[vName]=el.value;
  686. }
  687. if (vType=="boolean"){
  688. entry[vName]=el.checked;
  689. }
  690. }
  691. let qconfig=new Object();
  692. qconfig.rows=[entry];
  693. qconfig.containerPath=config.containerPath;
  694. qconfig.schemaName=data.schemaName;
  695. qconfig.queryName=data.queryName;
  696. //only update comments
  697. print(config,"modifyRows: useInsert "+useInsert);
  698. qconfig.success=function(data){updateLastSavedFlag(config,data,setup,elementId)};
  699. if (!useInsert){
  700. LABKEY.Query.updateRows(qconfig);
  701. }
  702. else{
  703. LABKEY.Query.insertRows(qconfig);
  704. }
  705. }
  706. function updateLastSavedFlag(config,data,setup,elementId){
  707. let debug=true;
  708. if (debug) print(config,"Update last saved flag to "+elementId);
  709. let el=config.document.getElementById(elementId);
  710. let dt=new Date();
  711. el.innerHTML="Last saved "+dt.toString();
  712. if (data.queryName=="reviewComments"){
  713. updateListDisplay(config,setup.divReviewListId,"reviewComments",setup.filters,true);
  714. }
  715. }
  716. //******************************************upload to database *********************
  717. function onDatabaseUpload(config){
  718. print(config,"Database upload");
  719. configUpload=new Object();
  720. //figure out the participantId
  721. let qconfig=new Object();
  722. qconfig.schemaName="lists";
  723. qconfig.queryName="Forms";
  724. qconfig.filterArray=[LABKEY.Filter.create('Key',config.formId)];
  725. //qconfig.filterArray=[LABKEY.Filter.create('formStatus',1)]
  726. qconfig.success=function(data){afterForms(config,configUpload,data)};
  727. LABKEY.Query.selectRows(qconfig);
  728. }
  729. function afterForms(config,configUpload,data){
  730. let formEntry=data.rows[0];
  731. configUpload.registrationQueryId=formEntry["masterQuery"];
  732. let qconfig=new Object();
  733. qconfig.queryName=config.queryMap[configUpload.registrationQueryId];
  734. //queryMap holds mapping for queries in visit;
  735. //masterQuery should be one of them, so this is safe.
  736. qconfig.schemaName='lists';
  737. qconfig.filterArray=[LABKEY.Filter.create('crfRef',getCRFref(config))];
  738. qconfig.success=function(data){afterRegistration(config,configUpload,data);}
  739. LABKEY.Query.selectRows(qconfig);
  740. //waitForCompleteUpload(config);//
  741. }
  742. function afterRegistration(config,configUpload,data){
  743. print(config,"afterRegistration: rows:"+data.rows.length);
  744. configUpload.registration=data;
  745. let registrationData=configUpload.registration;
  746. clearErr(config);
  747. if (registrationData.rows.length!=1){
  748. let msg="ERROR: Found "+registrationData.rows.length;
  749. msg+=" registration entries for crfrefid "+getCRFref(config);
  750. print(config,msg);
  751. return;
  752. }
  753. configUpload.participantId=
  754. registrationData.rows[0][config.registrationParticipantIdField];
  755. //could be a lookup field
  756. let fields=registrationData.metaData.fields;
  757. let field="NONE";
  758. for (f in fields){
  759. if (fields[f]["name"]==config.registrationParticipantIdField)
  760. field=fields[f];
  761. }
  762. if ("lookup" in field){
  763. let pid=configUpload.participantId;
  764. print(config,"Using lookup for participantId: "+pid);
  765. let lookup=field["lookup"];
  766. print(config,"Lookup: "+lookup);
  767. let qconfig=new Object();
  768. qconfig.containerPath=config.containerPath;
  769. qconfig.schemaName=lookup.schemaName;
  770. qconfig.queryName=lookup.queryName;
  771. qconfig.filterArray=
  772. [LABKEY.Filter.create(lookup.keyColumn,pid)];
  773. qconfig.success=function(data){
  774. afterRegistrationLookup(config,configUpload,data,lookup.displayColumn)};
  775. LABKEY.Query.selectRows(qconfig);
  776. }
  777. else{
  778. afterParticipantId(config,configUpload);
  779. }
  780. }
  781. function afterRegistrationLookup(config,configUpload,data,displayColumn){
  782. print(config,"afterRegistrationLookup");
  783. let entry=data.rows[0];
  784. configUpload.participantId=entry[displayColumn];
  785. afterParticipantId(config,configUpload);
  786. }
  787. function afterParticipantId(config,configUpload){
  788. print(config,"Setting participantId to "+configUpload.participantId);
  789. //another select rows to update all queries from setup
  790. //just use registration for test
  791. let qconfig=new Object();
  792. qconfig.schemaName='lists';
  793. //qconfig.queryName=config.setupQueryName;
  794. qconfig.queryName="FormSetup";
  795. qconfig.filterArray=[LABKEY.Filter.create("formName",config.formId)];
  796. qconfig.success=function(data){afterSetup(config,configUpload,data);}
  797. LABKEY.Query.selectRows(qconfig);
  798. }
  799. function afterSetup(config,configUpload,data){
  800. configUpload.queries=new Array();
  801. for (let i=0;i<data.rows.length;i++){
  802. let entry=data.rows[i];
  803. //use lookup table to convert from id to name
  804. let queryName=config.queryMap[entry.queryName];
  805. configUpload.queries.push({queryName:queryName,queryStatus:"QUEUED"});
  806. if (entry.showQuery=="NONE")
  807. continue
  808. configUpload.queries.push({queryName:entry.showQuery,queryStatus:"QUEUED"});
  809. }
  810. //add reviews
  811. configUpload.queries.push({queryName:"reviewComments",queryStatus:"QUEUED"});
  812. configUpload.queryId=0;
  813. copyToDataset(config,configUpload);
  814. //config.upload["start"]=true;
  815. //for (u in config.upload){
  816. // if (u=="start") continue;
  817. // if (u=="count") continue;
  818. // copyToDataset(config,u,participantId);
  819. //}
  820. //
  821. //print(config,"Database updated");
  822. }
  823. function copyToDataset(config,configUpload){
  824. if (configUpload.queryId==configUpload.queries.length) {
  825. updateFlag(config,3);//Approved
  826. return;
  827. }
  828. let queryName=configUpload.queries[configUpload.queryId].queryName;
  829. print(config,"copyToDataset["+configUpload.queryId+"/"+configUpload.queries.length+"]: "+queryName);
  830. let qconfig=new Object();
  831. qconfig.queryName=queryName;
  832. qconfig.schemaName="lists";
  833. qconfig.filterArray=[LABKEY.Filter.create('crfRef',getCRFref(config))];
  834. qconfig.success=function(data){afterListData(config,configUpload,data)};
  835. LABKEY.Query.selectRows(qconfig);
  836. }
  837. function afterListData(config,configUpload,data){
  838. let queryName=configUpload.queries[configUpload.queryId].queryName;
  839. let msg="["+queryName+"/list]: "+data.rows.length+" entries";
  840. print(config,msg);
  841. configUpload.listData=data;
  842. let qconfig=new Object();
  843. qconfig.queryName=queryName;
  844. qconfig.schemaName="study";
  845. qconfig.filterArray=[LABKEY.Filter.create('crfRef',getCRFref(config))];
  846. qconfig.filterArray.push(LABKEY.Filter.create('ParticipantId',configUpload.participantId));
  847. qconfig.success=function(data){afterStudyData(config,configUpload,data)};
  848. LABKEY.Query.selectRows(qconfig);
  849. }
  850. function afterStudyData(config,configUpload,data){
  851. configUpload.studyData=data;
  852. let queryName=configUpload.queries[configUpload.queryId].queryName;
  853. let msg="["+queryName+"/study]: "+data.rows.length+" entries";
  854. print(config,msg);
  855. let listRows=configUpload.listData.rows;
  856. //skip uploading an empty set
  857. if (listRows.length==0){
  858. printErr(config,"List "+queryName+" empty.");
  859. configUpload.queries[configUpload.queryId].queryStatus="DONE";
  860. configUpload.queryId+=1;
  861. copyToDataset(config,configUpload);
  862. return;
  863. }
  864. let studyRows=configUpload.studyData.rows;
  865. for (let i=0;i<studyRows.length;i++){
  866. let entry=studyRows[i];
  867. if (! (i<listRows.length) ) continue;
  868. let entryList=listRows[i];
  869. //keeps study only variables (ParticipantId, SequenceNum)
  870. for (let f in entryList) {
  871. entry[f]=entryList[f];
  872. print(config,"Copying ["+f+"]: "+entry[f]+"/"+entryList[f]);
  873. }
  874. }
  875. if (studyRows.length>0) {
  876. let qconfig=new Object();
  877. qconfig.queryName=queryName;
  878. qconfig.schemaName="study";
  879. qconfig.rows=studyRows;
  880. qconfig.success=function(data){afterStudyUpload(config,configUpload,data);}
  881. LABKEY.Query.updateRows(qconfig)
  882. }
  883. else{
  884. let data=new Object();
  885. data.rows=new Array();
  886. afterStudyUpload(config,configUpload,data);
  887. }
  888. }
  889. function afterStudyUpload(config,configUpload,data){
  890. let queryName=configUpload.queries[configUpload.queryId].queryName;
  891. printErr(config,"Updated "+data.rows.length+" rows to "+queryName);
  892. let studyRows=configUpload.studyData.rows;
  893. let listRows=configUpload.listData.rows;
  894. let rows=new Array();
  895. //also updating existing rows, if they exist
  896. for (let i=studyRows.length;i<listRows.length;i++){
  897. let entry=listRows[i];
  898. entry.ParticipantId=configUpload.participantId;
  899. entry.crfRef=getCRFref(config);
  900. entry.SequenceNum=getCRFref(config);
  901. entry.SequenceNum=entry.SequenceNum % 1000000000;
  902. if (listRows.length>1){
  903. entry.SequenceNum+=i/100;
  904. }
  905. print(config, "Adding sequence number "+entry.SequenceNum);
  906. rows.push(entry);
  907. }
  908. if (rows.length>0){
  909. let qconfig=new Object();
  910. qconfig.queryName=queryName;
  911. qconfig.schemaName="study";
  912. qconfig.success=function(data){
  913. afterListUpload(config,configUpload,data)};
  914. qconfig.rows=rows;
  915. LABKEY.Query.insertRows(qconfig);
  916. }
  917. else{
  918. let data=new Object();
  919. data.rows=rows;
  920. afterListUpload(config,configUpload,data);
  921. }
  922. }
  923. function afterListUpload(config,configUpload,data){
  924. let queryName=configUpload.queries[configUpload.queryId].queryName;
  925. printErr(config,"Inserted "+data.rows.length+" rows to "+queryName);
  926. configUpload.queries[configUpload.queryId].queryStatus="DONE";
  927. configUpload.queryId+=1;
  928. copyToDataset(config,configUpload);
  929. }
  930. //*************************update for further review *************************
  931. function onUpdateForReview(config){
  932. updateFlag(config,4);//Pending review
  933. }
  934. function updateFlag(config,flag){
  935. if (flag==4)
  936. print(config,"Sent to further review");
  937. let qconfig=new Object();
  938. qconfig.schemaName='lists';
  939. qconfig.queryName='crfEntry';
  940. qconfig.success=function(data){setFlag(config,data,flag);}
  941. qconfig.filterArray=[LABKEY.Filter.create("entryId",getCRFref(config))];
  942. LABKEY.Query.selectRows(qconfig);
  943. }
  944. function setFlag(config,data,flag){
  945. let debug=true;
  946. if (flag==4) print(config,"setFlagToReview");
  947. if (data.rows.length!=1){
  948. let msg="ERROR: Found "+data.rows.length;
  949. msg+=" entries for crfrefid "+getCRFref(config);
  950. print(config,msg);
  951. return;
  952. }
  953. let entry=data.rows[0];
  954. entry.FormStatus=flag;//Pending Review
  955. if (debug)
  956. print(config,"Set form status to "+entry.FormStatus);
  957. let qconfig=new Object();
  958. qconfig.schemaName='lists';
  959. qconfig.queryName='crfEntry';
  960. qconfig.rows=[entry];
  961. qconfig.success=function(data){completeWithFlag(config,data,flag);}
  962. LABKEY.Query.updateRows(qconfig);
  963. }
  964. function completeWithFlag(config,data,flag){
  965. let debug=true;
  966. if (debug){
  967. if (flag==4) print(config,"complete with review");
  968. }
  969. redirect(config);
  970. }
  971. //************************************************ submit *******************************************
  972. function onSubmit(config){
  973. let debug=true;
  974. hideErr(config);
  975. clearErr(config);
  976. printErr(config,"onSubmit");
  977. checkForm(config);
  978. let cb=new Object();
  979. cb.success=finalValidation;
  980. cb.failure=function(config){printErr(config,"waitForCheckForm failed")};
  981. waitForCheckForm(config,cb);
  982. }
  983. function finalValidation(config){
  984. let debug=true;
  985. if (debug) print(config,"validate");
  986. let completed=true;
  987. for (f in config.fields){
  988. let field=config.fields[f];
  989. if (field.status!="DONE") {
  990. printErr(config,"Missing entry for "+field.title);
  991. completed=false;
  992. }
  993. }
  994. if (debug) print(config,"valid: "+completed);
  995. if (completed){
  996. finalRedirect(config);
  997. }
  998. else{
  999. let el=document.getElementById(config.submitReportId);
  1000. el.innerHTML="Form invalid";
  1001. }
  1002. }
  1003. function finalRedirect(config){
  1004. printErr(config,"Form valid");
  1005. let c1=new Object();
  1006. c1.schemaName='lists';
  1007. c1.queryName='crfEntry';
  1008. c1.filterArray=[LABKEY.Filter.create('entryId',getCRFref(config))];
  1009. c1.success=function(data){uploadData(config,data)};
  1010. LABKEY.Query.selectRows(c1);
  1011. }
  1012. function uploadData(config,data){
  1013. let entry=data.rows[0];
  1014. entry.formStatus=2;//Submitted
  1015. let el=document.getElementById(config.submitReportId);
  1016. el.innerHTML="Submitting form";
  1017. let c1=new Object();
  1018. c1.schemaName=data.schemaName;
  1019. c1.queryName=data.queryName;
  1020. c1.containerPath=config.containerPath;
  1021. c1.rows=[entry];
  1022. //close window upon success
  1023. c1.success=function(data){redirect(config)};
  1024. LABKEY.Query.updateRows(c1);
  1025. }
  1026. function hideErr(config){
  1027. let el=config.document.getElementById("errorDiv");
  1028. el.style.display="none";
  1029. }
  1030. function clearErr(config){
  1031. let el=config.document.getElementById("errorTxt");
  1032. el.value="";
  1033. }
  1034. function showErr(config){
  1035. let el=config.document.getElementById("errorDiv");
  1036. el.style.display="block";
  1037. }
  1038. function printErr(config,msg){
  1039. showErr(config);
  1040. el=config.document.getElementById("errorTxt");
  1041. el.style.color="red";
  1042. el.value+="\n"+msg;
  1043. }
  1044. function checkForm(config){
  1045. let debug=false;
  1046. let crfRef=getCRFref(config)
  1047. config.status="UNKNOWN";
  1048. for (f in config.fields){
  1049. let field=config.fields[f];
  1050. field.status="UNKNOWN";
  1051. if (debug)
  1052. print(config,"Setting status for "+f+" to "+ field.status);
  1053. let selectRows=new Object();
  1054. selectRows.containerPath=config.containerPath;
  1055. selectRows.schemaName="lists";
  1056. selectRows.queryName=f;
  1057. selectRows.filterArray=[LABKEY.Filter.create('crfRef',crfRef)];
  1058. selectRows.success=function(data){checkData(data,config)};
  1059. selectRows.failure=function(errorObj){print(config,"checkData failed.")};
  1060. LABKEY.Query.selectRows(selectRows);
  1061. }
  1062. }
  1063. function waitForCheckForm(config,cb){
  1064. let debug=true;
  1065. if (!("i" in config)) config.i=0;
  1066. if (debug) print(config,"["+config.i+"] checkForm status "+config.status);
  1067. if (config.i>100) {
  1068. if (debug) print(config,"executing failure");
  1069. cb.failure(config);
  1070. return;
  1071. }
  1072. if (config.status=="DONE") {
  1073. if (debug) print(config,"executing success");
  1074. cb.success(config);
  1075. if (debug) print(config,"success executed");
  1076. return;
  1077. }
  1078. config.i+=1;
  1079. setTimeout(function(){waitForCheckForm(config,cb);},1000);
  1080. }
  1081. function checkData(data,config){
  1082. let debug=false;
  1083. if (debug) print(config,"checkData ");
  1084. let field=config.fields[data.queryName];
  1085. field.status="NONE";
  1086. if (debug) print(config,"Setting status for "+data.queryName+" to "+field.status);
  1087. if (data.rows.length>0)
  1088. field.status="DONE";
  1089. if (debug)
  1090. print(config,"checkData set status for "+data.queryName+" to "+field.status);
  1091. for (f in config.fields){
  1092. let subField=config.fields[f];
  1093. if (debug)
  1094. print(config,"checkData status["+f+"]: "+subField.status);
  1095. if (subField.status=="UNKNOWN") {
  1096. if (debug) print(config,"\t Status for "+f+" not set ["+ subField.status+"]");
  1097. return;
  1098. }
  1099. }
  1100. config.status="DONE";
  1101. }
  1102. //**************************************************
  1103. //
  1104. function onRemoveCRF(config){
  1105. let debug=true;
  1106. if (debug){
  1107. print(config,"Removing CRF");
  1108. }
  1109. let selectRows=new Object();
  1110. selectRows.containerPath=config.containerPath;
  1111. selectRows.schemaName="lists";
  1112. selectRows.queryName="inputLists";
  1113. selectRows.success=function(data){afterInputLists(data,config)};
  1114. LABKEY.Query.selectRows(selectRows);
  1115. }
  1116. function afterInputLists(data,config){
  1117. let debug=true;
  1118. if (debug)
  1119. print(config,"After input lists");
  1120. config.inputLists=data;
  1121. config.inputListsIterator=0;
  1122. removeCRFLoop(config);
  1123. }
  1124. function removeCRFLoop(config){
  1125. let debug=true;
  1126. let i=config.inputListsIterator;
  1127. if (debug)
  1128. print(config,"removeCRFLoop ["+i+"/"+config.inputLists.rows.length+"]");
  1129. if (i>config.inputLists.rows.length)
  1130. //return;
  1131. redirect(config);
  1132. let queryName="crfEntry";
  1133. let idVar="entryId";
  1134. if (i<config.inputLists.rows.length){
  1135. queryName=config.inputLists.rows[i].queryName;
  1136. idVar="crfRef";
  1137. }
  1138. if (debug)
  1139. print(config,"["+i+"/"+config.inputLists.rows.length+"] "+queryName+"/"+idVar);
  1140. let selectRows=new Object();
  1141. selectRows.containerPath=config.containerPath;
  1142. selectRows.schemaName="lists";
  1143. selectRows.queryName=queryName;
  1144. selectRows.filterArray=[LABKEY.Filter.create(idVar,getCRFref(config))];
  1145. selectRows.success=function(data){removeListCRF(data,config)};
  1146. LABKEY.Query.selectRows(selectRows);
  1147. }
  1148. function removeListCRF(data,config){
  1149. let debug=true;
  1150. if (debug)
  1151. print(config,data.queryName+": "+data.rows.length);
  1152. config.inputListsIterator+=1;
  1153. if (data.rows.length==0){
  1154. removeCRFLoop(config);
  1155. return;
  1156. }
  1157. let deleteRows=new Object();
  1158. deleteRows.containerPath=config.containerPath;
  1159. deleteRows.schemaName=data.schemaName;
  1160. deleteRows.queryName=data.queryName;
  1161. deleteRows.success=function(data){removeCRFLoop(config)};
  1162. deleteRows.rows=data.rows;
  1163. LABKEY.Query.deleteRows(deleteRows);
  1164. }
  1165. function redirect(config){
  1166. let formUrl="begin";
  1167. var params = {
  1168. "name": formUrl, // The destination wiki page. The name of this parameter is not arbitrary.
  1169. };
  1170. let containerPath= config.containerPath;
  1171. // This changes the page after building the URL.
  1172. //Note that the wiki page destination name is set in params.
  1173. var homeURL = LABKEY.ActionURL.buildURL("project", formUrl , containerPath, params);
  1174. print(config,"Redirecting to "+homeURL);
  1175. window.location = homeURL;
  1176. }
  1177. var blob;
  1178. var blobInterval;
  1179. function checkBlob(config){
  1180. print(config,"Blob: "+blob);
  1181. if (blob) {
  1182. clearInterval(blobInterval);
  1183. config.a.href = config.window.URL.createObjectURL(blob);
  1184. print(config,"HREF: "+config.a.href);
  1185. config.a.download = 'test.pdf';
  1186. config.a.click();
  1187. config.window.URL.revokeObjectURL(config.a.href);
  1188. }
  1189. config.count=config.count+1;
  1190. print(config,"Eval: "+config.count);
  1191. if (config.count>100){
  1192. clearInterval(blobInterval);
  1193. }
  1194. }
  1195. function printForm(config){
  1196. let doc=new PDFDocument();
  1197. doc.fontSize(25).text("Some text with standard font Andrej!", 100, 100);
  1198. doc.end();
  1199. let stream = doc.pipe(blobStream()).on("finish",function(){
  1200. blob=stream.toBlob("application/pdf");});
  1201. print(config,"BLob: "+blob);
  1202. config.a = config.document.createElement("a");
  1203. config.document.body.appendChild(config.a);
  1204. config.a.innerHTML="Download PDF";
  1205. config.a.style = "display: none";
  1206. config.count=0;
  1207. blobInterval=setInterval(checkBlob,1000,config);
  1208. //pick data from crfForm list
  1209. print(config,"Printing form");
  1210. for (let i=0;i<config.formConfig.formSetup.rows.length;i++){
  1211. let entry=config.formConfig.formSetup.rows[i];
  1212. let qName=config.formConfig.queryMap[entry['queryName']];
  1213. let selectRows=new Object();
  1214. print(config,'Adding data for '+qName);
  1215. selectRows.containerPath=config.containerPath;
  1216. selectRows.schemaName='lists';
  1217. selectRows.queryName=qName;
  1218. selectRows.filterArray=[LABKEY.Filter.create('crfRef',config.formConfig.crfEntry['entryId'])];
  1219. selectRows.success=function(data){collectFormData(config,data)};
  1220. LABKEY.Query.selectRows(selectRows);
  1221. //deal with additional data
  1222. }
  1223. }
  1224. function collectFormData(config,data){
  1225. config.formConfig.fields[data.queryName].data=data;
  1226. for (f in config.formConfig.fields){
  1227. let field=config.formConfig.fields[f];
  1228. if ("data" in field) continue;
  1229. return;
  1230. }
  1231. print(config,"All done");
  1232. formatFormData(config);
  1233. }
  1234. function formatFormData(config){
  1235. for (queryName in config.formConfig.fields){
  1236. formatDataset(config,queryName);
  1237. }
  1238. }
  1239. function formatDataset(config,queryName){
  1240. let data=config.formConfig.fields[queryName].data;
  1241. let fields=data.metaData.fields;
  1242. for (let i=0;i<data.rows.length;i++){
  1243. for (f in fields){
  1244. let field=fields[f];
  1245. if (field.hidden) continue;
  1246. let vName=field.name;
  1247. let vType=field.type;
  1248. print(config,'['+vName+'/'+vType+']: '+data.rows[i][vName]);
  1249. }
  1250. }
  1251. }
  1252. function generateMasterForm(config){
  1253. generateDebugSection(config);
  1254. setFormConfig(config);
  1255. }
  1256. function afterConfig(config){
  1257. let debug=true;
  1258. if (debug)
  1259. print(config,"generateMasterForm");
  1260. let selectRows=new Object();
  1261. selectRows.containerPath=config.containerPath;
  1262. selectRows.schemaName='lists';
  1263. selectRows.queryName='crfEntry';
  1264. selectRows.filterArray=[LABKEY.Filter.create('entryId',getCRFref(config))];
  1265. let formConfig=new Object();
  1266. //selectRows.success=function(data){populateBasicData(config,data)};
  1267. selectRows.success=function(data){afterCrf(config,formConfig,data)};
  1268. LABKEY.Query.selectRows(selectRows);
  1269. }
  1270. //requires populateBasicData
  1271. function afterCrf(config,formConfig,data){
  1272. formConfig.crfEntry=data.rows[0];
  1273. //schedule basic data for later
  1274. populateBasicData(config,data);
  1275. let selectRows=new Object();
  1276. selectRows.containerPath=config.containerPath;
  1277. selectRows.schemaName='lists';
  1278. selectRows.queryName='FormStatus';
  1279. selectRows.filterArray=[];
  1280. selectRows.success=function(data){afterFormStatus(config,formConfig,data)};
  1281. LABKEY.Query.selectRows(selectRows);
  1282. //use crfEntry['FormStatus'] to determine what configuration to display
  1283. //reviewMode equivalence table:
  1284. //
  1285. //FormStatus reviewMode
  1286. //In Progress undefined/EDIT
  1287. //Review Pending undefined/EDIT
  1288. //Submitted REVIEW
  1289. //Approved APPROVED
  1290. //two level indirect -
  1291. //
  1292. //1. learn of the FormStatus options by reading in the FormStatus list
  1293. //
  1294. //2. Load the crfEntry for this crfId
  1295. }
  1296. function afterFormStatus(config, formConfig, data){
  1297. print(config,"afterFormStatus: ");
  1298. formConfig.formStatusData=data;
  1299. let rows=formConfig.formStatusData.rows;
  1300. for (let i=0; i<rows.length; i++){
  1301. let key=rows[i].Key;
  1302. if (formConfig.crfEntry["FormStatus"]!=key)
  1303. continue;
  1304. formConfig.formStatus=rows[i].formStatus;
  1305. break;
  1306. }
  1307. print(config,"Generating buttons for formStatus \""+formStatus+"\"");
  1308. let done="FALSE";
  1309. if (formConfig.formStatus=="Submitted"){
  1310. generateButton(config,"submitDiv","Complete submission",
  1311. "Upload to database",onDatabaseUpload,config);
  1312. generateButton(config,"submitDiv","Review submission",
  1313. "Ask for further review",onUpdateForReview,config);
  1314. generateButton(config,"submitDiv","Remove submission",
  1315. "Remove CRF form",onRemoveCRF,config);
  1316. done="TRUE";
  1317. }
  1318. if (formConfig.formStatus=="Approved"){
  1319. generateButton(config,"submitDiv","Review submission",
  1320. "Restore form for further review",onUpdateForReview,config);
  1321. done="TRUE";
  1322. }
  1323. if (done=="FALSE"){
  1324. generateButton(config,"submitDiv","Complete submission",
  1325. "Submit",onSubmit,config);
  1326. generateButton(config,"submitDiv","Remove submission",
  1327. "Remove CRF form",onRemoveCRF,config);
  1328. }
  1329. generateButton(config,"submitDiv","Done","Exit",redirect,config);
  1330. //schedule actual forms
  1331. config.fields=new Object();
  1332. config.queryMap=new Object();
  1333. //data and layout of actual forms
  1334. //filled in generateTable
  1335. formConfig.entries=new Object();
  1336. formConfig.dataFields=new Object();
  1337. let configSelectRows=new Object();
  1338. configSelectRows.containerPath=config.containerPath;
  1339. configSelectRows.schemaName='lists';
  1340. configSelectRows.queryName=config.setupQueryName;
  1341. //this is new
  1342. configSelectRows.queryName="FormSetup";
  1343. configSelectRows.filterArray=[LABKEY.Filter.create("formName",config.formId)];
  1344. configSelectRows.success=function(data){afterFormSetup(config,formConfig,data);};
  1345. configSelectRows.failure=onFailure;//function(errorTxt){print(config,"generateForm fail" + errorTxt)};
  1346. LABKEY.Query.selectRows(configSelectRows);
  1347. }
  1348. function setFormConfig(config){
  1349. //generateDebugSection(config);
  1350. let debug=true;
  1351. if (debug)
  1352. print(config,"generateMasterForm1");
  1353. let selectRows=new Object();
  1354. selectRows.containerPath=config.containerPath;
  1355. selectRows.schemaName='lists';
  1356. selectRows.queryName='crfEntry';
  1357. selectRows.filterArray=[LABKEY.Filter.create('entryId',getCRFref(config))];
  1358. config.formConfig=new Object();
  1359. //store form related data to this object
  1360. selectRows.success=function(data){afterCRFEntry(config,data)};
  1361. //requires populateBasicData
  1362. LABKEY.Query.selectRows(selectRows);
  1363. }
  1364. function afterCRFEntry(config,data){
  1365. config.formConfig.crfEntry=data.rows[0];
  1366. print(config,"Setting crfEntry (x) to "+config.formConfig.crfEntry["entryId"]);
  1367. let selectRows=new Object();
  1368. selectRows.containerPath=config.containerPath;
  1369. selectRows.schemaName='lists';
  1370. selectRows.queryName='site';
  1371. selectRows.filterArray=[LABKEY.Filter.create('siteNumber',config.formConfig.crfEntry.Site)];
  1372. selectRows.success=function(data){afterSite(config,data)};
  1373. LABKEY.Query.selectRows(selectRows);
  1374. }
  1375. function afterSite(config,data){
  1376. print(config,"afterSite");
  1377. config.formConfig.site=data.rows[0];
  1378. print(config,"Setting site name to "+config.formConfig.site["siteName"]+" phone: "+config.formConfig.site["sitePhone"]);
  1379. let selectRows=new Object();
  1380. selectRows.containerPath=config.containerPath;
  1381. selectRows.schemaName='core';
  1382. selectRows.queryName='Users';
  1383. selectRows.filterArray=[LABKEY.Filter.create('siteNumber',config.formConfig.crfEntry.UserId)];
  1384. selectRows.success=function(data){afterUser(config,data)};
  1385. LABKEY.Query.selectRows(selectRows);
  1386. }
  1387. function afterUser(config,data){
  1388. config.formConfig.user=data.rows[0];
  1389. print(config,"Setting user to "+config.formConfig.user["DisplayName"]);
  1390. let selectRows=new Object();
  1391. selectRows.containerPath=config.containerPath;
  1392. selectRows.schemaName='lists';
  1393. selectRows.queryName='FormSetup';
  1394. selectRows.filterArray=[LABKEY.Filter.create('formName',config.formId)];
  1395. selectRows.success=function(data){afterFormSetup(config,data)};
  1396. LABKEY.Query.selectRows(selectRows);
  1397. }
  1398. function afterFormSetup(config,data){
  1399. config.formConfig.formSetup=data;
  1400. print(config,"Number of datasets for form ["+config.formId+"]: "+config.formConfig.formSetup.rows.length);
  1401. let fields=config.formConfig.formSetup.metaData.fields;
  1402. let formQueryName='queryName';
  1403. let field="NONE";
  1404. for (f in fields){
  1405. if (fields[f]['name']!=formQueryName) continue;
  1406. field=fields[f];
  1407. break;
  1408. }
  1409. let lookup=field.lookup;
  1410. print(config,"Getting dataset names from :"+lookup.queryName);
  1411. let selectRows=new Object();
  1412. selectRows.containerPath=config.containerPath;
  1413. selectRows.schemaName=lookup.schemaName;
  1414. selectRows.queryName=lookup.queryName;
  1415. selectRows.success=function(data){afterFormDatasets(config,data)};
  1416. LABKEY.Query.selectRows(selectRows);
  1417. }
  1418. function afterFormDatasets(config,data){
  1419. config.formConfig.formDatasets=data;
  1420. config.formConfig.fields=new Object();
  1421. config.formConfig.queryMap=new Object();
  1422. for (let i=0;i<config.formConfig.formSetup.rows.length;i++){
  1423. let entry=config.formConfig.formSetup.rows[i];
  1424. let queryId=entry['queryName'];
  1425. for (let j=0;j<config.formConfig.formDatasets.rows.length;j++){
  1426. if (queryId!=config.formConfig.formDatasets.rows[j]['Key']) continue;
  1427. let qName=config.formConfig.formDatasets.rows[j]['queryName'];
  1428. config.formConfig.fields[qName]=new Object();
  1429. config.formConfig.queryMap[queryId]=qName;
  1430. let field=config.formConfig.fields[qName];
  1431. field.title=entry['title'];
  1432. field.queryId=queryId;
  1433. //print(config," "+config.formConfig.formDatasets.rows[j]['queryName']);
  1434. break;
  1435. }
  1436. }
  1437. print(config,"List of datasets in form : ");
  1438. for (f in config.formConfig.fields){
  1439. let field=config.formConfig.fields[f];
  1440. print(config,"\t"+f+" ID: "+field.queryId+' title '+field.title);
  1441. }
  1442. afterConfig(config);
  1443. }