Browse Source

Adding multiUse lists where a variable value allows re-use of the same list with different (pre-specified) values

Andrej Studen 2 years ago
parent
commit
0066782543
2 changed files with 133 additions and 37 deletions
  1. 2 0
      views/visit.html
  2. 131 37
      web/crf/crfVisit.js

+ 2 - 0
views/visit.html

@@ -11,6 +11,8 @@ div.d1 {text-align:center; width=400px; background-color:#e0e0e0;
         font-size:      20px; margin-bottom:20px}
 </style>
 
+<h1 id="formTitle">Title</h1>
+
 <table cellspacing="2" cellpadding="5" border="0">
 <tr><td>Version: </td><td><strong id="version">0.0</strong></td></tr>
 <tr><td>CRF ID: </td><td><strong id="crfRefId">1583163135258</strong></td></tr>

+ 131 - 37
web/crf/crfVisit.js

@@ -210,6 +210,17 @@ function getAdditionalData(formSetupEntry){
 	return ad;	
 }
 
+function generateSetup(){
+   let setup=new Object();
+ //setVariables contains special variables that have a 
+   //preset value in a specified table:
+   //A.) these values won't appear in the form 
+   //B.) will be submitted with value specified to the database
+   //make sure setVariables object is present in an object
+   setup.setVariables=new Object();
+   return setup;
+}	
+
 function fullAccessSetup(listName){
 	//generate setup object whcih should contain fields:
 	//readonlyFlag - whether the dataset is writeable
@@ -221,7 +232,7 @@ function fullAccessSetup(listName){
 	let debug=true;
 	if (debug) print("fullAccessSetup");
 
-	let setup=new Object();
+	let setup=generateSetup();
 	setup.queryName=listName;
 	setup.readonlyFlag=function(vName){return false};
 	setup.filters=new Object();
@@ -238,7 +249,7 @@ function readonlySetup(listName){
 	let debug=true;
 	if (debug) print("readonlySetup");
 
-	let setup=new Object();
+	let setup=generateSetup();
 	setup.queryName=listName;
 	setup.readonlyFlag=function(vName){return true};
 	setup.filters=new Object();
@@ -261,13 +272,31 @@ function getSetup(listName,writeAccess=true){
 	return fullAccessSetup(listName);
 }
 	
-//afterFormConfig replaced by afterFormSetup
+function parseVariableDefinition(formSetupEntry){
+   let fName='parseVariableDefinition['+formSetupEntry['title']+']';
+   let code=formSetupEntry['variableDefinition'];
+   print(fName+' '+code);
+   //helper function to decode content of variableDefinition 
+   //to a JS object
+   //
+   //should contain semicolon split var=value pairs
+   let vars=new Object();
+   if (code==undefined)
+      //variableDefinition field is empty, return empyt object
+      return vars;
+   let ar=code.split(';');
+   for (let i=0;i<ar.length;i++){
+      q=ar[i].split('=');
+      vars[q[0]]=q[1];
+   }
+   return vars;
+}
 
-//afterFormSetupLookup replaced by afterFormDatasets
 
-//function generateSection(listName, sectionTitle, accessMode, additionalData){
 function generateSection(formSetupEntry){
 
+   //generates a (hideable) section according to setup in formEntrySetup
+
 	let listName=config.formConfig.queryMap[formSetupEntry['queryName']];
 	let fName='[generateSection/'+listName+']';
 	let sectionTitle=formSetupEntry['title'];	
@@ -322,10 +351,12 @@ function generateSection(formSetupEntry){
 		div1.appendChild(div2);
 
 	}
-	if (debug) print("generate master table");
+	if (debug) print(fName+" master table");
 
 	let writeMode=accessMode=="EDIT";	
-	let setup=getSetup(listName,writeMode);
+
+   //setup stores some common values that get passed to generateTable
+   //most significantly, whether fields are changeable or not
 	
 	if ("isReview" in additionalData){
 		generateReviewSection(listName,div.id,generateReviewSectionCB);
@@ -333,11 +364,21 @@ function generateSection(formSetupEntry){
 	}
 	//master table is unique per visit
 
+	let setup=getSetup(listName,writeMode);
 	
 	setup.unique=true;
+
+   //set variables from formSetup variableDefinition field 
+   //to setup.setVariables
+   setup.setVariables=parseVariableDefinition(formSetupEntry);
+   for (x in setup.setVariables){
+      print(fName+' setVariables '+x+':'+setup.setVariables[x]);
+   }
+
+
 	generateTable(listName,divTable.id,additionalData,setup);
 	
-	if (debug) print("generate master table: done");
+	if (debug) print(fName+" master table: done");
 
 	let generateSubTable=true;
 	//generateSubTable equivalent to read/write access to section
@@ -351,15 +392,15 @@ function generateSection(formSetupEntry){
 		let dName=additionalData.divName;
 		
 
-		let setup=fullAccessSetup(qName);
+		let subSetup=fullAccessSetup(qName);
 		//only set master query for additionalData
-		setup.masterQuery=listName;
+		subSetup.masterQuery=listName;
 		//if (readonly) setup=readonlySetup(config);
-		generateTable(qName,dName,additionalData,setup);
+		generateTable(qName,dName,additionalData,subSetup);
 		//generateTable(formSetupEntry,qName,dName,additionalData,setup);
 	}
 
-	print("generate review");
+	print(fName+" generate review");
 
 	let divReviewList=config.document.createElement('div');
 	divReviewList.id=listName+"ReviewList";
@@ -374,6 +415,8 @@ function generateSection(formSetupEntry){
 	//we need listName also
 	//qconfig.queryName=config.setupQueryName;
 	generateReview(divReview.id,divReviewList.id,listName,accessMode);
+   
+   print(fName+" generate review complete");
 
 	if (accessMode!='GENERATE') return;
 	print('Adding generate button');	
@@ -803,7 +846,7 @@ function generateReview(divReviewId,divReviewListId, listName, accessMode){
 	let debug=true;
 	if (debug) print("Generate review for: "+listId+'/'+listName);
 	
-	let reviewSetup=new Object();
+	let reviewSetup=generateSetup();
 	reviewSetup.readonlyFlag=function(vName){
 		if (vName=="queryName") return true; 
 		if (vName=="queryname") return true; 
@@ -881,13 +924,17 @@ function updateListDisplay(divName,queryName,filters,readonlyFlag){
 	let fName="[updateListDisplay]";
 
 	if (debug) 
-		print(fName+": UpdateListDisplay: Query - "+queryName
+		print(fName+": Query - "+queryName
 			+" div - "+divName);
 
 	if (divName=="NONE") return;
+  
 
 	let crfRef=getCRFref();
 	let div=config.document.getElementById(divName);
+   print(fName+": setting border");
+   div.style.border="thin solid black";
+   div.style.width="800px";
 
 	if (debug)
 		print(fName+": generating WebPart: "+queryName);
@@ -1173,6 +1220,8 @@ function addFieldRow(tb,field,setup,additionalData){
 	print(fName+": Element: "+input);
 
 	//set the lut value (input is text label) for readonly
+   input.style.textAlign="center";
+   //input.style.textAlignLast="center";
 
    	//clear existing fields from input	
 	for(let i = input.options.length; i >= 0; i--) {
@@ -1200,7 +1249,30 @@ function addFieldRow(tb,field,setup,additionalData){
 	input.selectedIndex=0;	
 
 }
-		
+
+function selectEntry(entryRows,setVariables){
+   let fName='[selectEntry]';
+   for (let i=0;i<entryRows.length;i++){
+      let tE=entryRows[i];
+      //this could be empty, end will be reached
+      let doContinue=false;
+      for (v in setVariables){
+         print(fName+' '+v+' '+tE[v]+'/'+setVariables[v]);
+         if (tE[v]!=setVariables[v]){
+            doContinue=true;
+            break;
+         }
+      }
+      if (doContinue) continue;
+		return tE;
+   }
+   let tE=Object();
+   tE['notValid']=true;
+   return tE;
+}
+
+
+
 function populateFieldRow(entry,field,setup){
 	populateField(entry,field,setup);
 	populateSubQuery(entry,field,setup);
@@ -1339,16 +1411,18 @@ function populateField(entry,field,setup){
 }
 
 
-function populateTable(listName,writeMode){
+function populateTable(listName,writeMode,setup=undefined){
 //function populateTable(formSetupEntry){
 	//let listName=config.formConfig.queryMap[formSetupEntry['queryName']];
 	//let accessMode=config.formConfig.operator+'Mode';
 	//let writeMode=formSetupEntry[accessMode]=='EDIT';
 
 	let fName='[populateTable/'+listName+']';
-
-	let setup=getSetup(listName,writeMode);
-	let entry=new Object();
+   print(fName+' setup '+setup);
+	if (setup==undefined){
+      print(fName+' generating default setup');
+      setup=getSetup(listName,writeMode);
+   }
 	
 	//data snapshot
 	let fQuery=config.formConfig.dataQueries[listName];
@@ -1357,9 +1431,10 @@ function populateTable(listName,writeMode){
 	//so that rows was set (even if they are empty)
 	print(fName+"]: nrows "+fQuery.rows.length);
 	
-	if (fQuery.rows.length>0)
-		entry=fQuery.rows[0];
-	
+   //this makes sure that matching versus set variables is performed
+   //only entry with matching value of setVariable will be selected
+	let entry=selectEntry(fQuery.rows,setup.setVariables);
+
 	let fields=fQuery.fields;
 		
 	for (f in fields){	
@@ -1384,7 +1459,6 @@ function generateTable(listName,divName,additionalData,setup){
 	//assume data is set in config.formConfig.dataQueries[data.queryName].rows;
 	
 
-	let entry=new Object();
 
 	//data snapshot
 	let fQuery=config.formConfig.dataQueries[listName];
@@ -1393,8 +1467,7 @@ function generateTable(listName,divName,additionalData,setup){
 	//so that rows was set (even if they are empty)
 	print(fName+": Nrows "+fQuery.rows.length);
 	
-	if (fQuery.rows.length>0)
-		entry=fQuery.rows[0];
+	let entry=selectEntry(fQuery.rows,setup.setVariables);
 	
 	let tb=config.document.createElement('table');
 	tb.className="t2";
@@ -1409,6 +1482,8 @@ function generateTable(listName,divName,additionalData,setup){
 		print(fName+": Adding field: "+f+'/'+field.name);
 		if (field.hidden) continue;
 		if (field.name=="crfRef") continue;
+      //do not expose fields indicated in setVariables
+      if (field.name in setup.setVariables) continue;
 		addFieldRow(tb,field,setup,additionalData);
 		populateFieldRow(entry,field,setup);
 		
@@ -1449,12 +1524,12 @@ function saveReview(queryName,elementId,setup){
 
 	let fQuery=config.formConfig.dataQueries[queryName];
 
-	if (fQuery.rows.length==0) useInsert=true;
-	let entry=new Object();
+   let entry=selectEntry(fQuery.rows,setup.setVariables);
+
+	if ("notValid" in entry) useInsert=true;
+
+	if (useInsert) entry=new Object();
 	
-	if (!useInsert){
-		entry=fQuery.rows[0];
- 	}
 	entry.crfRef=getCRFrefData();
 
 	if (debug) print("Set crfRef="+entry.crfRef);
@@ -1553,6 +1628,11 @@ function saveReview(queryName,elementId,setup){
 
 
 	}
+
+   //update values from setup.setVariables 
+   for (v in setup.setVariables){
+      entry[v]=setup.setVariables[v];
+   }
 	
 	let qconfig=new Object();
 	qconfig.rows=[entry];
@@ -1584,7 +1664,7 @@ function updateLastSavedFlag(data,setup,elementId){
 	//refresh stored data!
 	let writeMode=!setup.readonlyFlag();
 	if ("unique" in setup)
-		setData(function (){populateTable(data.queryName,writeMode);});
+		setData(function (){populateTable(data.queryName,writeMode,setup);});
 	if ("masterQuery" in setup){
 		let ad=config.formConfig.additionalData[setup.masterQuery];
 		print('Updating list display: '+setup.queryName+'/'+ad.queryName);
@@ -2421,7 +2501,8 @@ function generateMasterForm(){
 //(fields defined in html file)
 function populateBasicData(){
 
-	config.document.getElementById('version').innerText=config.formConfig.softwareVersion;	
+	config.document.getElementById('version').innerText=
+      config.formConfig.softwareVersion;	
 	config.document.getElementById('eudraCTNumber').innerText=
 		config.formConfig.crfEntry.EudraCTNumber;
 	config.document.getElementById('studyCoordinator').innerText=
@@ -2434,6 +2515,10 @@ function populateBasicData(){
 		config.formConfig.currentSite['sitePhone'];
 	config.document.getElementById('investigatorName').innerText=
 		config.formConfig.user['DisplayName'];
+   let h1=config.formConfig.form['formName'];
+   config.document.getElementById('formTitle').innerText=h1;
+   print('Setting title to '+h1);
+
 }
 
 
@@ -2581,10 +2666,15 @@ function afterData(){
 	//operatorBasedAccessMode	
 	let accessMode=config.formConfig.operator+'Mode';
 	let rowsSetup=config.formConfig.formSetupRows;
+   print(fName+' list of sections');
+	for (let i=0;i<rowsSetup.length;i++){
+		let entry=rowsSetup[i];
+		let queryName=config.formConfig.queryMap[entry['queryName']];
+      print(fName+'\t'+queryName);
+   }	
 	for (let i=0;i<rowsSetup.length;i++){
 		let entry=rowsSetup[i];
 		let queryName=config.formConfig.queryMap[entry['queryName']];
-		
 		print(fName+" ["+queryName+"]: showFlag: "+entry["showFlag"]);
 		print(fName+" ["+queryName+"]: accessMode: "+entry[accessMode]);
 
@@ -2650,10 +2740,14 @@ function populateSection(queryName){
 	let aM=entry[accessMode];
 	print(fName+': accessMode '+aM);
 
+
 	if (aM!='GENERATE'){
-		let writeMode=entry[accessMode]=='EDIT';
-		print(fName+': mode='+writeMode);
-		populateTable(queryName,writeMode);
+		let writeMode=(aM=='EDIT');
+      print(fName+': writeMode '+writeMode);
+      let setup=getSetup(listName,writeMode);
+      setup.setVariables=parseVariableDefinition(entry);
+      //this fails for setVariables, although they are available via entry['variableDefinition']
+		populateTable(queryName,writeMode,setup);
 		return;
 	}
 
@@ -2928,7 +3022,7 @@ function setFormConfig(){
 	//add object to store form related data
 	config.formConfig=new Object();
 
-	config.formConfig.softwareVersion='0.14.18';
+	config.formConfig.softwareVersion='0.14.32';
 	let debug=true;
 
 	if (debug)