Quellcode durchsuchen

Working version

Andrej Studen vor 2 Jahren
Ursprung
Commit
d160cd5158
3 geänderte Dateien mit 227 neuen und 55 gelöschten Zeilen
  1. 3 3
      config/module.xml
  2. 1 1
      views/visit.html
  3. 223 51
      web/crf/crfVisit.js

+ 3 - 3
config/module.xml

@@ -5,11 +5,11 @@
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
     <bean id="moduleBean" class="org.labkey.api.module.SimpleModule">
         <property name="name" value="CRF"/>
-        <property name="version" value="0.1"/>
+		<!--<property name="version" value="0.1"/>-->
         <property name="requiredServerVersion" value="0.0"/>
         <property name="moduleDependencies" value=""/>
-        <property name="svnRevision" value="0"/>
-        <property name="svnUrl" value="Not built from a source control working copy"/>
+		<!--<property name="svnRevision" value="0"/>-->
+		<!--<property name="svnUrl" value="Not built from a source control working copy"/>-->
         <property name="buildUser" value="astuden"/>
         <property name="buildTime" value="March 5 2020, 11:43 AM"/>
         <property name="buildOS" value="Ubuntu"/>

+ 1 - 1
views/visit.html

@@ -35,7 +35,7 @@ div.d1 {text-align:center; width=400px; background-color:#e0e0e0;
 <textarea id="errorTxt" cols="95" rows="10"></textarea>
 </div>
 
-<div id="debugDiv"/>
+<div id="debugDiv" style="display:block"/>
 <!--<div id="debug" style="display:block">
 <textarea cols="95" rows="10" name="formStatus" id="formStatus">
 Loading

+ 223 - 51
web/crf/crfVisit.js

@@ -19,6 +19,8 @@ function print(msg){
 }
 
 function makeQuery(containerName,queryName,fieldName,filterArray){
+   //generates an instruction entry that looks up queryName from container and stores
+   //the resulting table to fieldName potentially using filterArray
 	let e=new Object();
 	e.containerName=containerName;
 	e.queryName=queryName;
@@ -221,7 +223,7 @@ function generateSetup(){
    return setup;
 }	
 
-function fullAccessSetup(listName){
+function fullAccessSetup(sectionId,listName){
 	//generate setup object whcih should contain fields:
 	//readonlyFlag - whether the dataset is writeable
 	//filters - selection fields that allow creation of LABKEY.Filter.create()
@@ -237,14 +239,15 @@ function fullAccessSetup(listName){
 	setup.readonlyFlag=function(vName){return false};
 	setup.filters=new Object();
 	setup.filters['crfRef']=getCRFref();
-	setup.getInputId=function(vName){return listName+"_"+vName;}
+	setup.getInputId=function(vName){return sectionId+"_"+vName;}
 	setup.addApply="Save";
 	setup.isReview=false;
+   setup.sectionId=sectionId;
 	return setup;
 
 }
 
-function readonlySetup(listName){
+function readonlySetup(sectionId,listName){
 	//see definition of setup object above
 	let debug=true;
 	if (debug) print("readonlySetup");
@@ -254,22 +257,23 @@ function readonlySetup(listName){
 	setup.readonlyFlag=function(vName){return true};
 	setup.filters=new Object();
 	setup.filters['crfRef']=getCRFref();
-	setup.getInputId=function(vName){return listName+'_'+vName;}
+	setup.getInputId=function(vName){return sectionId+'_'+vName;}
 	setup.isReview=false;
+   setup.sectionId=sectionId;
 	return setup;
 }
 
-function getSetup(listName,writeAccess=true){
+function getSetup(sectionId,listName,writeAccess=true){
 	//change to section granulated permission of type EDIT, COMMENT, READ
 	//let formStatus=config.formConfig.formStatus;
 	//equivalent to READ
 
 	if (!writeAccess)
 	//if (formStatus=="Submitted")
-		return readonlySetup(listName);
+		return readonlySetup(sectionId,listName);
 	//if (formStatus=="Approved")
 	//	return readonlySetup(listName);
-	return fullAccessSetup(listName);
+	return fullAccessSetup(sectionId,listName);
 }
 	
 function parseVariableDefinition(formSetupEntry){
@@ -292,13 +296,30 @@ function parseVariableDefinition(formSetupEntry){
    return vars;
 }
 
+function setHelp(setup,formSetupEntry){
+   let helpRows=config.formConfig.help.rows;
+   for (let i=0;i<helpRows.length;i++){
+      let eh=helpRows[i];
+      if (eh['query']==formSetupEntry['queryName']){
+         if (!("help" in setup)){
+            setup["help"]=new Object();
+            setup["help"].rows=new Array();
+         }
+         setup["help"].rows.push(eh);
+         print('Adding help to '+config.formConfig.queryMap[eh['query']]);
+      }
+   }
+   //this updates setup
+}
+
 
 function generateSection(formSetupEntry){
 
    //generates a (hideable) section according to setup in formEntrySetup
 
 	let listName=config.formConfig.queryMap[formSetupEntry['queryName']];
-	let fName='[generateSection/'+listName+']';
+   let sectionId='section'+formSetupEntry['Key'];
+	let fName='[generateSection/'+listName+'/'+sectionId+']';
 	let sectionTitle=formSetupEntry['title'];	
 	let accessModeColumn=config.formConfig.operator+'Mode';
 	let accessMode=formSetupEntry[accessModeColumn];
@@ -322,24 +343,26 @@ function generateSection(formSetupEntry){
 	let input=config.document.createElement("input");	
 	input.type="button";
 	input.value="Show";
-	input.id="toggle"+listName+"VisbilityButton";
-	input.onclick=function(){toggleVisibility(listName,input.id)};
+	input.id="toggle"+sectionId+"VisbilityButton";
+	input.onclick=function(){toggleVisibility(sectionId,input.id)};
+   //toggleVisibilityArgumentList changed!
 	cell.appendChild(input);
 	config.document.getElementById(formName).appendChild(tb);
 
 	let div=config.document.createElement('div');
-	div.id=listName;
+   //relabel this to allow multiple entries for the same list
+	div.id=sectionId;
 	div.style.display="none";
 	config.document.getElementById(formName).appendChild(div);	
 
 	let divTable=config.document.createElement('div');
-	divTable.id=listName+"Table";
+	divTable.id=sectionId+"Table";
 	div.appendChild(divTable);
 	
 	if ("showFlag" in additionalData) {
 
-		additionalData.divName=listName+"SubDiv";
-		additionalData.divQueryName=listName+"SubDivList";
+		additionalData.divName=sectionId+"SubDiv";
+		additionalData.divQueryName=sectionId+"SubDivList";
 
 		let div1=config.document.createElement('div');
 		div1.id=additionalData.divName;
@@ -364,10 +387,12 @@ function generateSection(formSetupEntry){
 	}
 	//master table is unique per visit
 
-	let setup=getSetup(listName,writeMode);
+	let setup=getSetup(sectionId,listName,writeMode);
 	
 	setup.unique=true;
 
+   setHelp(setup,formSetupEntry);
+
    //set variables from formSetup variableDefinition field 
    //to setup.setVariables
    setup.setVariables=parseVariableDefinition(formSetupEntry);
@@ -392,7 +417,7 @@ function generateSection(formSetupEntry){
 		let dName=additionalData.divName;
 		
 
-		let subSetup=fullAccessSetup(qName);
+		let subSetup=fullAccessSetup(sectionId,qName);
 		//only set master query for additionalData
 		subSetup.masterQuery=listName;
 		//if (readonly) setup=readonlySetup(config);
@@ -403,11 +428,11 @@ function generateSection(formSetupEntry){
 	print(fName+" generate review");
 
 	let divReviewList=config.document.createElement('div');
-	divReviewList.id=listName+"ReviewList";
+	divReviewList.id=sectionId+"ReviewList";
 	div.appendChild(divReviewList);
 	
 	let divReview=config.document.createElement('div');
-	divReview.id=listName+"Review";
+	divReview.id=sectionId+"Review";
 	div.appendChild(divReview);
 
 
@@ -415,6 +440,7 @@ function generateSection(formSetupEntry){
 	//we need listName also
 	//qconfig.queryName=config.setupQueryName;
 	generateReview(divReview.id,divReviewList.id,listName,accessMode);
+   //generateReview depends on listName
    
    print(fName+" generate review complete");
 
@@ -422,7 +448,7 @@ function generateSection(formSetupEntry){
 	print('Adding generate button');	
 	//add generateButton
 	let divGenerateButton=config.document.createElement('div');
-	divGenerateButton.id=listName+'GenerateButton';
+	divGenerateButton.id=sectionId+'GenerateButton';
 	div.appendChild(divGenerateButton);
 	print('Adding generate button completed to here');	
 	let cb=function(){onGenerateQuery(listName);};
@@ -971,18 +997,17 @@ function updateFailure(data){
 }
 
 
-//TODO: this should trigger a data refresh on section, ie populateData(field)
-function toggleVisibility(divName,buttonName){
-	let fName='[toggleVisibility/'+divName+']';
+function toggleVisibility(sectionId,buttonName){
+	let fName='[toggleVisibility/'+sectionId+']';
 	print(fName);
 
-	let x = config.document.getElementById(divName);
+	let x = config.document.getElementById(sectionId);
 	if (x.style.display === "none") {
 		//exclude non data sections (like debug)...
 		print(fName+': issuing setData(populateSection)');
     		x.style.display = "block";
 		config.document.getElementById(buttonName).value="Hide";
-		let cb=function(){populateSection(divName);};
+		let cb=function(){populateSection(sectionId);};
 		setData(cb);
 
   	} else {
@@ -1354,6 +1379,8 @@ function populateField(entry,field,setup){
 	//figure out the element type
 	let eType=input.nodeName.toLowerCase();
 	print('Element type: '+eType);
+   print('Value '+varValue);
+
 
 	//change varValue for printing
 	if (varValue=="UNDEF") varValue="";
@@ -1411,7 +1438,7 @@ function populateField(entry,field,setup){
 }
 
 
-function populateTable(listName,writeMode,setup=undefined){
+function populateTable(listName,writeMode,setup){
 //function populateTable(formSetupEntry){
 	//let listName=config.formConfig.queryMap[formSetupEntry['queryName']];
 	//let accessMode=config.formConfig.operator+'Mode';
@@ -1419,10 +1446,6 @@ function populateTable(listName,writeMode,setup=undefined){
 
 	let fName='[populateTable/'+listName+']';
    print(fName+' setup '+setup);
-	if (setup==undefined){
-      print(fName+' generating default setup');
-      setup=getSetup(listName,writeMode);
-   }
 	
 	//data snapshot
 	let fQuery=config.formConfig.dataQueries[listName];
@@ -1436,19 +1459,151 @@ function populateTable(listName,writeMode,setup=undefined){
 	let entry=selectEntry(fQuery.rows,setup.setVariables);
 
 	let fields=fQuery.fields;
-		
+	let helpRows=new Array();
+
 	for (f in fields){	
 		let field=fields[f];
 		//each field is a new row
 		print(fName+": Adding field: "+f+'/'+field.name+' hidden: '+field.hidden);
 		if (field.hidden) continue;
 		if (field.name=="crfRef") continue;
-		populateFieldRow(entry,field,setup);
-		
+      if (field.name in setup.setVariables) continue; 
+      populateFieldRow(entry,field,setup);
+	   let helpItem=getHelpItem(field,setup);
+      if (helpItem) helpRows.push(helpItem);
 	}
 
+   populateHelp(listName,helpRows,setup);
+
 }
 
+function getHelpVar(queryName,code,setup){
+   let fName='[getHelpVar('+code+')]';
+
+   let subs=code.match(/_[^_]*_/g);
+   if (!subs){
+      print(fName+' no match for '+code);
+      return code;
+   }
+   let rpc=new Object();
+   for (let i=0;i<subs.length;i++){
+      let c=subs[i].replace(/_/g,'');
+      let qf=c.match(/\[[^\]]*\]/g);
+      let lField=undefined;
+      if (qf){
+         qf[0]=qf[0].replace(/[\[\]]/g,'');
+         lField=qf[0];
+      }
+      //drop field
+      c=c.replace(/\[[^\]]*\]/,'');
+      
+      //field in lookup (if not lookup.keyColumn)
+      //query
+      let query=queryName;
+      let vField=c;
+      let qq=c.split(':');
+      if (qq.length>1){
+         query=qq[0];
+         vField=qq[1];
+      }
+      let value='';
+      if (vField in setup.setVariables){
+         value=setup.setVariables[vField];
+      }
+      else{
+         value=config.formConfig.dataQueries[query].rows[0][vField];
+      }
+      if (lField==undefined){
+         rpc[subs[i]]=value;
+         continue;
+      }
+      let fQuery=config.formConfig.dataQueries[query];
+      //variable vField must be a lookup
+      //let field=fQuery.fields[vField];
+      let field=undefined;
+      for (let f in fQuery.fields){
+         if (fQuery.fields[f].name==vField){
+            field=fQuery.fields[f];
+         }
+      }
+      let lookup=config.formConfig.lookup[field.lookup.queryName];
+
+      for (let j=0;j<lookup.rows.length;j++){
+         let o=lookup.rows[j];
+         if (o[lookup.keyColumn]==value){
+            rpc[subs[i]]=o[lField];
+            break;
+         }
+      }
+   }
+   for (let x in rpc){
+      code=code.replace(x,rpc[x]);
+   }
+   print('Returning '+code);
+   return code;
+}
+
+function getHelpItem(field,setup){
+   if (!("help" in setup)) return undefined;
+
+   let fName='[getHelpItem]';
+   print(fName);
+
+   for (let i=0;i<setup["help"].rows.length;i++){
+      if (setup["help"].rows[i]["variable"]==field.name){
+         helpItem=new Object();
+         helpItem.setup=setup["help"].rows[i];
+         helpItem.field=field;
+         print(fName+' adding help for '+field.name);
+         return helpItem;
+      }
+   }
+   return undefined;
+}
+
+function generateHelp(tb,helpRows,setup){
+   let fName='[generateHelp]';
+   for (let i=0; i<helpRows.length; i++){
+      let eh=helpRows[i];
+      let row=tb.insertRow();
+      let th=config.document.createElement('th');
+      row.appendChild(th);
+      th.innerHTML=eh.setup['helpTitle']; 
+      let cell=row.insertCell();
+      cell.setAttribute('colspan','3');
+      let el=config.document.createElement('textarea');
+      //el.id=sectionId+'_help';
+      el.cols="70";
+      el.rows="10";
+      el.value="Loading";
+      el.id=setup.sectionId+"_help"+eh.setup['Key'];
+      print(fName+' creating '+el.id);
+      cell.appendChild(el);
+   }
+}
+
+function populateHelp(listName,helpRows,setup){
+   let fName='[populateHelp]';
+   for (let i=0; i<helpRows.length; i++){
+      let eh=helpRows[i];
+      let lookup=eh.field['lookup'];
+      let qName=lookup.queryName;
+      let tLookup=config.formConfig.lookup[qName];
+      let varName=getHelpVar(listName,eh.setup['fieldDescriptor'],setup);
+      let text="";
+      for (let j=0;j<tLookup.rows.length;j++){
+         print(tLookup.rows[j][tLookup.keyColumn]+' '+tLookup.rows[j][tLookup.displayColumn]+
+         ' '+tLookup.rows[j][varName]);
+         text+=tLookup.rows[j][tLookup.displayColumn]+" - "+tLookup.rows[j][varName]+"\n";
+      }
+      let id=setup.sectionId+'_help'+eh.setup['Key']
+      let el=config.document.getElementById(id);
+      print(fName+' setting '+id+': '+el);
+      el.value=text;
+   }
+}
+
+
 function generateTable(listName,divName,additionalData,setup){
 	let debug=true;
 	let fName="[generateTable/"+listName+"]";	
@@ -1475,7 +1630,8 @@ function generateTable(listName,divName,additionalData,setup){
 
 	//this are the fields (probably constant)
 	let fields=fQuery.fields;
-		
+	let helpRows=new Array();
+
 	for (f in fields){
 		let field=fields[f];
 		//each field is a new row
@@ -1486,11 +1642,17 @@ function generateTable(listName,divName,additionalData,setup){
       if (field.name in setup.setVariables) continue;
 		addFieldRow(tb,field,setup,additionalData);
 		populateFieldRow(entry,field,setup);
-		
+      let helpItem=getHelpItem(field,setup);
+      if (helpItem) helpRows.push(helpItem);
 	}
+
+   generateHelp(tb,helpRows,setup);
+   populateHelp(listName,helpRows,setup);
+   
+
 	//add comment field	
 	if (!("addApply" in setup)) {
-		print(fName+"populateTable: done");
+		print(fName+"generateTable: done");
 		return;
 	}
 	
@@ -2699,28 +2861,32 @@ function afterData(){
 
 }
 
-function findSetupRow(queryName){
+function findSetupRow(sectionId){
 	let rowsSetup=config.formConfig.formSetupRows;
+   let key=sectionId.replace('section','');
 	for (let i=0;i<rowsSetup.length;i++){
 		let e=rowsSetup[i];
-		let queryName1=config.formConfig.queryMap[e['queryName']];
+		//let queryName1=config.formConfig.queryMap[e['queryName']];
 		if (e.formName!=config.formId) continue;
-		if (queryName1!=queryName) continue;
-		return e;
+      if (e['Key']==key) return e;
+		//if (queryName1!=queryName) continue;
 	}
 	return null;
 }
 
-function populateSection(queryName){
-	let fName='[populateSection/'+queryName+']';
+function populateSection(sectionId){
+   //queryName should be found from setup
+	let fName='[populateSection/'+sectionId+']';
 	print(fName);
 
-	let entry=findSetupRow(queryName);
+	let entry=findSetupRow(sectionId);
 	//ignore names without associated entry in formSetup
 	if (entry==undefined){
 		print(fName+': no matching FormSetup entry found');
 		return;
 	}
+  
+   let queryName=config.formConfig.queryMap[entry['queryName']];
 	//populate comes after generate, we should be pretty safe in taking
 	//already generated additionalData
 	
@@ -2744,8 +2910,9 @@ function populateSection(queryName){
 	if (aM!='GENERATE'){
 		let writeMode=(aM=='EDIT');
       print(fName+': writeMode '+writeMode);
-      let setup=getSetup(listName,writeMode);
+      let setup=getSetup(sectionId,queryName,writeMode);
       setup.setVariables=parseVariableDefinition(entry);
+      setHelp(setup,entry);
       //this fails for setVariables, although they are available via entry['variableDefinition']
 		populateTable(queryName,writeMode,setup);
 		return;
@@ -2754,11 +2921,11 @@ function populateSection(queryName){
 	//deal with generate
 	//
 	//already available -> shift to READ mode
-	let divTable=queryName+'Table';
+	let divTable=sectionId+'Table';
 	let divObj=config.document.getElementById(divTable);
-	let divRev=config.document.getElementById(queryName+'Review');
-	let divRLi=config.document.getElementById(queryName+'ReviewList');
-	let divGBu=config.document.getElementById(queryName+'GenerateButton');
+	let divRev=config.document.getElementById(sectionId+'Review');
+	let divRLi=config.document.getElementById(sectionId+'ReviewList');
+	let divGBu=config.document.getElementById(sectionId+'GenerateButton');
 
 	print('div GBU: '+divGBu);
 	divObj.style.display="block";
@@ -2769,7 +2936,10 @@ function populateSection(queryName){
 	let nData=config.formConfig.dataQueries[queryName].rows.length;
 	print('['+queryName+']: nrows '+nData);
 	if (nData>0){
-		populateTable(queryName,0);
+      let setup=getSetup(sectionId,queryName,false);
+      setup.setVariables=parseVariableDefinition(entry);
+      //this fails for setVariables, although they are available via entry['variableDefinition']
+		populateTable(queryName,false,setup);
 		return;
 	}
 	//hide table
@@ -3022,7 +3192,7 @@ function setFormConfig(){
 	//add object to store form related data
 	config.formConfig=new Object();
 
-	config.formConfig.softwareVersion='0.14.32';
+	config.formConfig.softwareVersion='0.15.02';
 	let debug=true;
 
 	if (debug)
@@ -3139,6 +3309,7 @@ function collectData(){
 		let crfFilter=LABKEY.Filter.create('entryId',parentCrf);
 		queryArray.push(makeQuery('data','crfEntry','parentCrfData',[crfFilter]));	
 	}	
+   queryArray.push(makeQuery('data','help','help'));
 
 	print('running getDataFromQueries');
 	getDataFromQueries(queryArray,fcontinue);
@@ -3393,8 +3564,8 @@ function afterDatasets(data,cb){
 		if ("containerPath" in field.lookup){
 			selectRows.containerPath=field.lookup.containerPath;
 		}
-		selectRows.columns=field.lookup.keyColumn+","+
-			field.lookup.displayColumn;
+		//selectRows.columns=field.lookup.keyColumn+","+field.lookup.displayColumn;
+      //get all, descriptions may be hidden in further variables
 		//wait for all lookups to return
 		selectRows.success=function(data){addLookup(data,qobject,f,cb);};
 		print("Sending query: ["+
@@ -3426,6 +3597,7 @@ function addLookup(data,qobject,f,cb){
 		lObject.LUT[data.rows[i][key]]=data.rows[i][val];
 		lObject.ValToKey[data.rows[i][val]]=data.rows[i][key];
 	}
+   lObject.rows=data.rows;
 	qobject.lookup[f]="DONE";
 	if (!dataLayoutSet()) return;
 	cb();