Bladeren bron

Major overhauld constricting functions to file based classes and providing namespaced like control over functions to avoid name collisions and simplify debugging, use console to output debug messages (ctrl-shift-c to view in Firefox)

Andrej Studen 2 jaren geleden
bovenliggende
commit
f2daa535f5

+ 11 - 5
views/approvedPortal.html

@@ -35,15 +35,21 @@ height:120px;
 </div>
 
 <script type "text/javascript">
-window.onload=init;
+window.onload=loadScripts;
+
+function loadScripts(){
+  LABKEY.requiresScript(["crfTecant/formPortal.js","crfTecant/debug.js"],init);
+}
+
 function init(){
+   let config=formPortal.config;
 	config.document=document;
-	config.reviewMode="APPROVED";
+	//config.reviewMode="APPROVED";
 	config.role="crfSponsor";
 	config.div="formDiv";
 	config.debugArea="formStatus";
-	clear();
-	print("XStarting");
-	generateFormArray();
+	formPortal.clear();
+	formPortal.print("XStarting");
+	formPortal.generateFormArray();
 }
 </script>

+ 2 - 2
views/approvedPortal.view.xml

@@ -1,7 +1,7 @@
 <view xmlns="http://labkey.org/data/xml/view" title="Approved CRF Portal (Tecant)">
 	<dependencies>
-			<dependency path="crfTecant/formPortal.js"/>
-			<dependency path="crfTecant/formGenerator.js"/>
+      <!--<dependency path="crfTecant/formPortal.js"/>-->
+      <!--<dependency path="crfTecant/formGenerator.js"/>-->
 		</dependencies>
 	<permissions>
 		<permission name="login"/>

+ 10 - 5
views/completedPortal.html

@@ -38,14 +38,19 @@ table.t2 td {border:1px solid black; text-align:center}
 </div>
 
 <script type "text/javascript">
-window.onload=init;
+window.onload=loadScripts;
+function loadScripts(){
+  LABKEY.requiresScript(["crfTecant/formPortal.js","crfTecant/debug.js"],init);
+}
+
+
 function init(){
+   let config=formPortal.config;
 	config.document=document;
 	config.role="crfManager";
 	config.div="formDiv";
-	config.debugArea="formStatus";
-	clear();
-	print("XStarting");
-	generateFormArray();
+	formPortal.clear();
+	formPortal.print("XStarting");
+	formPortal.generateFormArray();
 }
 </script>

+ 2 - 2
views/completedPortal.view.xml

@@ -1,7 +1,7 @@
 <view xmlns="http://labkey.org/data/xml/view" title="Completed CRF Portal (Tecant)">
 	<dependencies>
-			<dependency path="crfTecant/formGenerator.js"/>
-			<dependency path="crfTecant/formPortal.js"/>
+      <!--<dependency path="crfTecant/formGenerator.js"/>-->
+      <!--<dependency path="crfTecant/formPortal.js"/>-->
 		</dependencies>
 	<permissions>
 		<permission name="login"/>

+ 20 - 6
views/formPortal.html

@@ -27,7 +27,7 @@ height:120px;
 <div id="formDiv">
 </div>
 
-<div id="debugDiv" style="display:block">
+<div id="debugDiv" style="display:none">
 	<h3>Debug notes</h3>
 	<textarea cols="95" rows="5" id="formStatus">
 	</textarea>
@@ -35,15 +35,29 @@ height:120px;
 
 
 <script type "text/javascript">
-window.onload=init;
+window.onload=loadScripts;
+
+function loadScripts(){
+  LABKEY.requiresScript(["crfTecant/formPortal.js","crfTecant/debug.js"],init);
+}
+
 function init(){
+   console.log('Here');
+   let config=formPortal.config;
 	config.document=document;
 	config.div="formDiv";
-	config.debugArea="formStatus";
+   debug.document=document;
+	debug.debugArea="formStatus";
+   //set this to true to enable on-page debug display (otherwise, error messages appear in consloe)
+   if (false){
+      formPortal.setDebug(debug);
+      document.getElementById("debugDiv").style.display="block";
+   }
 	config.role="crfEditor";
-	clear();
-	print("Starting");
+	formPortal.clear();
+	formPortal.print("XStarting");
 	config.participantField="PatientId";
-	generateFormArray();
+	formPortal.generateFormArray();
+   //formPortal.scriptsLoaded();
 }
 </script>

+ 0 - 9
views/formPortal.view.xml

@@ -1,9 +0,0 @@
-<view xmlns="http://labkey.org/data/xml/view" title="FORM Portal (Tecant)" frame="portal">
-	<dependencies>
-			<dependency path="crfTecant/formGenerator.js"/>
-		<dependency path="crfTecant/formPortal.js"/>
-	</dependencies>
-	<permissions>
-		<permission name="login"/>
-	</permissions>
-</view>

+ 11 - 6
views/reviewPortal.html

@@ -35,15 +35,20 @@ height:120px;
 </div>
 
 <script type "text/javascript">
-window.onload=init;
+window.onload=loadScripts;
+function loadScripts(){
+  LABKEY.requiresScript(["crfTecant/formPortal.js","crfTecant/debug.js"],init);
+}
+
 function init(){
+   let config=formPortal.config;
 	config.document=document;
-	config.reviewMode="REVIEW";
+	//config.reviewMode="REVIEW";
 	config.role="crfMonitor";
 	config.div="formDiv";
-	config.debugArea="formStatus";
-	clear();
-	print("Starting");
-	generateFormArray();
+	debug.debugArea="formStatus";
+	formPortal.clear();
+	formPortal.print("Starting");
+	formPortal.generateFormArray();
 }
 </script>

+ 2 - 2
views/reviewPortal.view.xml

@@ -1,7 +1,7 @@
 <view xmlns="http://labkey.org/data/xml/view" title="Review Portal (Tecant)">
 	<dependencies>
-			<dependency path="crfTecant/formGenerator.js"/>
-			<dependency path="crfTecant/formPortal.js"/>
+      <!--<dependency path="crfTecant/formGenerator.js"/>-->
+      <!--<dependency path="crfTecant/formPortal.js"/>-->
 		</dependencies>
 	<permissions>
 		<permission name="login"/>

+ 7 - 5
views/visit.html

@@ -40,7 +40,11 @@ Loading
 
 <script type="text/javascript">
 
-window.onload = init();
+window.onload = loadScripts;
+
+function loadScripts(){
+   LABKEY.requiresScript(["crfTecant/crfVisit.js","crfTecant/debug.js"],init);
+}
 
 function init(){
 		
@@ -52,13 +56,13 @@ function init(){
 	document.getElementById("crfRefId").innerHTML=crfRef;
 
 
-	//let config=new Object();
 	//config is part of crfVisit.js
 	//will this change if we are in views?
 	//config.review=true;
 
 	//where to get ParticipantId
 	//pick this from study properties
+   let config=crfVisit.config;
 	config.masterForm="visitForm";
 	
 	config.document=document;
@@ -72,9 +76,7 @@ function init(){
 	config.formId=searchParams.get("formId");
 	config.role=searchParams.get('role');	
 	
-	clear();
-
-	generateMasterForm();
+	crfVisit.generateMasterForm();
 
 
 	

+ 84 - 57
web/crfTecant/crfPrint.js

@@ -1,48 +1,70 @@
+var crfPrint={};
+
 //printing section
+//
+crfPrint.set=
+function(parentClass){
+   this.parent=parentClass;
+}
 
-function checkBlob(){
-	print("checkBlob: "+config.blob);
-	if (config.blob) {
-		clearInterval(config.blobInterval);
-		config.a.href = config.window.URL.createObjectURL(config.blob);
-		print("HREF: "+config.a.href);
-		config.a.download = 'test.pdf';
-		config.a.click();
-		config.window.URL.revokeObjectURL(config.a.href);
+crfPrint.checkBlob=
+function(){
+	this.parent.print("checkBlob: "+this.blob);
+	if (this.blob) {
+		clearInterval(this.blobInterval);
+		this.a.href = this.parent.config.window.URL.createObjectURL(this.blob);
+		this.parent.print("HREF: "+this.a.href);
+		this.a.download = 'test.pdf';
+		this.a.click();
+		this.parent.config.window.URL.revokeObjectURL(this.a.href);
 	}
-	config.count=config.count+1;
-	print("Eval: "+config.count);
-	if (config.count>100){
-		clearInterval(config.blobInterval);
+	this.count=this.count+1;
+	this.parent.print("Eval: "+this.count);
+	if (this.count>100){
+		clearInterval(this.blobInterval);
 	}
 
 }
 
-function printForm(){
+crfPrint.printForm=
+function(){
+   let that=this;
+   let action=function(){that.afterScripts();};
+   LABKEY.Utils.requiresScript(["crfTecant/blob-stream.js","crfTecant/pdfkit.standalone.js"],action);
+}
 
-	config.doc=new PDFDocument();
+crfPrint.afterScripts=
+function(){
+   let config=this.parent.config;
+	this.doc=new PDFDocument();
+   let that=this;
 	//config.doc.end();
-	let stream = config.doc.pipe(blobStream()).on("finish",function(){
-			config.blob=stream.toBlob("application/pdf");});
+   let action=function(){that.blob=that.stream.toBlob("application/pdf");};
+	this.stream = this.doc.pipe(blobStream()).on("finish",action);
 	
-	print("BLob: "+config.blob);
-	config.a = config.document.createElement("a");
-	config.document.body.appendChild(config.a);
-	config.a.innerHTML="Download PDF";
-	config.a.style = "display: none";
-	config.count=0;
+	this.parent.print("BLob: "+this.blob);
+	this.a = this.parent.config.document.createElement("a");
+	this.parent.config.document.body.appendChild(this.a);
+	this.a.innerHTML="Download PDF";
+	this.a.style = "display: none";
+	this.count=0;
 	//run until blob is set
-	config.blobInterval=setInterval(checkBlob,1000);
+   let iAction=function(){that.checkBlob();}
+   this.blobInterval=setInterval(iAction,1000);
 
 	//pick data from crfForm list
-        print("Printing form");
-	printHeader();
-	setData(formatPrintData);
+   this.parent.print("Printing form");
+	this.printHeader();
+
+   let foo=function(){that.formatPrintData();};
+	this.parent.setData(foo);
 }
 
-function printHeader(){
-	config.doc.fontSize(25).text(config.formConfig.form['formName']);
-	config.doc.moveDown();
+crfPrint.printHeader=
+function(){
+   let config=this.parent.config;
+	this.doc.fontSize(25).text(config.formConfig.form['formName']);
+	this.doc.moveDown();
 	let crfEntry=config.formConfig.crfEntry;
 	let site=config.formConfig.currentSite;
 	let val=new Object();
@@ -55,44 +77,49 @@ function printHeader(){
 	val['F']={o:user,f:'DisplayName',t:'Investigator'};
 
 	for (let f in val){
-		print('Printing for '+f);
+		this.parent.print('Printing for '+f);
 		let e=val[f];
 		let entry=new Object();
 		entry[f]=e.o[e.f];
-		printPDF(entry,
+		this.printPDF(entry,
 			{name:f,caption:e.t,type:'string'},null);
 	}
-	config.doc.moveDown();
+	this.doc.moveDown();
 }
 
-function formatPrintData(){
-	qS=config.formConfig.dataQueries;
+crfPrint.formatPrintData=
+function(){
+   let config=this.parent.config;
+	qS=this.parent.getQueryList();
 	for (let q in qS){
-		print('Setting up '+q);
-		let qData=qS[q];
-		print('Number of rows: '+qData.rows.length);
+		this.parent.print('Setting up '+q);
+		let qData=this.parent.getQuerySnapshot(q);
+      let qLayout=this.parent.getQueryLayout(q);
+		this.parent.print('Number of rows: '+qData.rows.length);
 		if (qData.rows.length>0){
-			config.doc.fontSize(20).text(qData.title);
+			this.doc.fontSize(20).text(qLayout.title);
 		}
+      let fields=qLayout.fields;
 		for (let i=0;i<qData.rows.length;i++){
 			let entry=qData.rows[i];
-		       	for (let f in qData.fields){
-				let field=qData.fields[f];
+		   for (let f in fields){
+				let field=fields[f];
 				let lookup=null;
 				if (field.lookup){
-					lookup=config.formConfig.lookup[field.lookup.queryName];
+					lookup=this.parent.getLookup(field.lookup.queryName);
 				}
 				if (field.hidden) continue;
-				printPDF(entry,field,lookup);
+				this.printPDF(entry,field,lookup);
 			}
 		}
-		config.doc.moveDown();
+		this.doc.moveDown();
 	}
-	print("All done");
-	config.doc.end();
+	this.parent.print("All done");
+   this.doc.end();
 }
 
-function printPDF(entry,field,lookup){
+crfPrint.printPDF=
+function(entry,field,lookup){
 	//object field should have a name, type, caption
 	//entry should have field.name
 	//lookup is null or has a lookup table LUT 
@@ -107,12 +134,12 @@ function printPDF(entry,field,lookup){
 	let w1=(w-spacing)*0.5;
 	let fontSize=14;	
 	
-	print('printPDF: entry['+field.name+']='+entry[field.name]);
+	this.parent.print('printPDF: entry['+field.name+']='+entry[field.name]);
 	let v=entry[field.name];
 	if (lookup!=null){
 		v=lookup.LUT[v];
 	}
-	print('printPDF: field type:'+field.type);
+	this.parent.print('printPDF: field type:'+field.type);
 	if (field.type=="date"){
 		let d=new Date(v);
 		v=d.getDate()+'/'+(d.getMonth()+1)+'/'+d.getFullYear();
@@ -123,7 +150,7 @@ function printPDF(entry,field,lookup){
 	//measure text
 	let label=field.caption;
 	let opt={width:w1};
-	config.doc.fontSize(fontSize);
+	this.doc.fontSize(fontSize);
 	
 	//for more eloquent display the height of the text
 	//can be measured prior to output
@@ -133,22 +160,22 @@ function printPDF(entry,field,lookup){
 
 
 	//print label
-	config.doc.font('Courier').text(label,opt);
+	this.doc.font('Courier').text(label,opt);
 	
 	//align last row of description w/ first row of value
-	config.doc.moveUp();
+	this.doc.moveUp();
 
 	//store x value for later use
-	let tx=config.doc.x;
-	let ty=config.doc.y;
+	let tx=this.doc.x;
+	let ty=this.doc.y;
 
 	//shift for value output
-	config.doc.x+=w1+spacing;
+	this.doc.x+=w1+spacing;
 	
-	config.doc.font('Courier-Bold').text(v,opt);
+	this.doc.font('Courier-Bold').text(v,opt);
 
 	//restore x value
-	config.doc.x=tx;
+	this.doc.x=tx;
 	
 }
 

+ 143 - 81
web/crfTecant/crfReviewSection.js

@@ -1,6 +1,48 @@
-function generateReviewSection(listName,id,callback){
+//loadFile is in fileManager.js
+var crfReviewSection={};
+
+crfReviewSection.set=
+function(parentClass){
+   if ("parent" in this) 
+      return;
+   this.parent=parentClass;
+}
+
+crfReviewSection.generateErrorMessage=
+function (id,listName,msg){
+	this.parent.print('generateErrorMessage:');
+	let eid=listName+"_errorMsg";
+	let el=config.document.getElementById(eid);
+	if (el===null){
+		el=config.document.createElement("p");
+		config.document.getElementById(id).appendChild(el);
+	}
+	el.innerHTML=msg;
+}
+
+crfReviewSection.clearErrorMessage=
+function(listName){
+	let eid=listName+"_errorMsg";
+	let el=config.document.getElementById(eid);
+	if (el===null) return;
+	el.remove();
+}
+
+
+
+
+crfReviewSection.generateSection=
+function(listName,id,callback){
+   let that=this;
+   let action=function(){that.fcontinue(listName,id,callback);};
+   LABKEY.requiresScript(["crfTecant/fileManager.js"],action);
+}
+
+crfReviewSection.fcontinue=
+function(listName,id,callback){
 	//callback should be generateReviewSectionCB and it takes no arguments
-	print("generateReviewSection");
+	this.parent.print("generateReviewSection");
+   let config=this.parent.config;
 	//need base path
 
 
@@ -9,67 +51,77 @@ function generateReviewSection(listName,id,callback){
 	
 	config.loadFileConfig.cb=callback;
 	config.loadFileConfig.id=id;
-	config.loadFileConfig.url=getBasePath()+'/@files/reportSetup/'+listName+'.json';
-	loadFile();
+	config.loadFileConfig.url=fileManager.getBasePath()+'/@files/reportSetup/'+listName+'.json';
+	fileManager.loadFile();
 	//load file and continue in the next function
 }
 
-function getParticipantCode(pid){
+crfReviewSection.getParticipantCode=
+function(pid){
 
-	let filters=[LABKEY.Filter.create("crfRef",getCRFref())];
+	let filters=[LABKEY.Filter.create("crfRef",this.parent.getCRFref())];
+   let config=this.parent.config;
 	let mfId=config.formConfig.form['masterQuery'];
    let queryName=config.formConfig.queryMap[mfId];
-	pid.afterId=setParticipantCode;
+   let that=this;
+	pid.afterId=function(id){that.setParticipantCode(id);};
 	pid.participantField=config.formConfig.studyData["SubjectColumnName"];
-	let cb=function(data){afterRegistration(pid,data);}
+	let cb=function(data){that.afterRegistration(pid,data);}
    //untested
-   cvSelectRows('lists',queryName,filters,cb,getContainer('data'));
+   this.parent.selectRows('lists',queryName,filters,cb,this.parent.getContainer('data'));
 }
 
-function visitCodeFromVisitId(visitId){
+crfReviewSection.visitCodeFromVisitId=
+function(visitId){
 	if (visitId<0) return "NONE";
-	let project=getContainer('data');
-	print('visitCodeFromVisitId: '+project.search('retro'));
+	let project=this.parent.getContainer('data');
+this.parent.print('visitCodeFromVisitId: '+project.search('retro'));
 	if (project.search('retro')>-1)
 		visitId-=1;
 	return 'VISIT_'+visitId.toString();
 }
 
-function replaceSlash(x){
+crfReviewSection.replaceSlash=
+function(x){
 	return x.replace(/\//,'_');
 }
 
-function setParticipantCode(pid){
+crfReviewSection.setParticipantCode=
+function(pid){
 	let fName='[setParticipantCode]';
 	let rows=pid.registration.rows;
+   let config=this.parent.config;
 	//pick from study
 	let participantField=config.formConfig.studyData["SubjectColumnName"];
 	if (rows.length==1){
-		print(fName+': '+rows[0][participantField]+'/'+rows[0].visitId);
-		let visitCode=visitCodeFromVisitId(rows[0].visitId);
-		print('setParticipantCode: '+pid.participantId+'/'+visitCode);
-		pid.participantCode=replaceSlash(pid.participantId);
+		this.parent.print(fName+': '+rows[0][participantField]+'/'+rows[0].visitId);
+		let visitCode=this.visitCodeFromVisitId(rows[0].visitId);
+		this.parent.print('setParticipantCode: '+pid.participantId+'/'+visitCode);
+		pid.participantCode=this.replaceSlash(pid.participantId);
 		pid.visitCode=visitCode;
 	}
-	generateReviewSection2(pid);
+	this.generateReviewSection2(pid);
 }
 
-function generateReviewSectionCB(){
-
+crfReviewSection.CB=
+function(){
+   let config=this.parent.config;
 	let listName=config.loadFileConfig.listName;
 	let id=config.loadFileConfig.id;
 
-	clearErrorMessage(listName);
+	this.parent.clearErrorMessage(listName);
 
 	let pid=new Object();
 	pid.participantCode="NONE";
 	pid.visitCode="NONE";
-	getParticipantCode(pid);
-	print('Get participant code sent');
+	this.getParticipantCode(pid);
+	this.parent.print('Get participant code sent');
 	//involves database search, continue after callback
 }
 
-function getValueFromElement(id,defaultValue){
+crfReviewSection.getValueFromElement=
+function(id,defaultValue){
+   let config=this.parent.config;
 	let e=config.document.getElementById(id);
 	if (e!=null){
 		defaultValue=e.innerHTML;
@@ -77,14 +129,16 @@ function getValueFromElement(id,defaultValue){
 	return defaultValue;
 }
 
-function pickParticipantCodeFromPage(){
+crfReviewSection.pickParticipantCodeFromPage=
+function(){
 	let pid=new Object();
-	pid.participantCode=getValueFromElement("participantCode","NIX-LJU-D2002-IRAE-A000");
-	pid.visitCode=getValueFromElement("visitCode","VISIT_1");
-	generateReviewSection2(pid);
+	pid.participantCode=this.getValueFromElement("participantCode","NIX-LJU-D2002-IRAE-A000");
+	pid.visitCode=this.getValueFromElement("visitCode","VISIT_1");
+	this.generateReviewSection2(pid);
 }
 
-function patternReplace(src,replacements,values){
+crfReviewSection.patternReplace=
+function(src,replacements,values){
 
 	for (rep in replacements){
 		let txt1=src.replace(new RegExp(rep),values[replacements[rep]]);
@@ -94,9 +148,11 @@ function patternReplace(src,replacements,values){
 
 }
 
-function plotImage(cell,k,row,rowVariable,obj,pid){
-	let baseDir=patternReplace(obj.imageDir,obj.replacements,pid);
-	print('Base dir: '+pid.basePath);
+crfReviewSection.plotImage=
+function(cell,k,row,rowVariable,obj,pid){
+   let config=this.parent.config;
+	let baseDir=this.patternReplace(obj.imageDir,obj.replacements,pid);
+	this.parent.print('Base dir: '+pid.basePath);
 	pid[obj.variable]=obj.values[k];
 	cell.id=pid[obj.variable]+"_"+rowVariable+pid[rowVariable];
 	let img=null;
@@ -108,7 +164,7 @@ function plotImage(cell,k,row,rowVariable,obj,pid){
 		cell.appendChild(img);
 	}
 	let imgSrc=patternReplace(obj.file,obj.replacements,pid);
-	print('Image: '+imgSrc);
+   this.parent.print('Image: '+imgSrc);
 	let imagePath=pid.basePath+'/'+baseDir+'/'+imgSrc;
 			
 	img.src=imagePath;
@@ -117,7 +173,8 @@ function plotImage(cell,k,row,rowVariable,obj,pid){
 	
 }
 
-function showReport(cell,k,row,rowVariable,obj,pid){
+crfReviewSection.showReport=
+function(cell,k,row,rowVariable,obj,pid){
 
 	cell.width="300px";
 	cell.id='report_'+obj.values[k]+"_"+rowVariable+pid[rowVariable];
@@ -136,13 +193,13 @@ function showReport(cell,k,row,rowVariable,obj,pid){
 	}
 	reportConfig.partConfig.showSection="myscatterplot";
 	let reportWebPartRenderer = new LABKEY.WebPart(reportConfig);
-	print('Render to: '+reportConfig.renderTo);
+   this.parent.print('Render to: '+reportConfig.renderTo);
 	reportWebPartRenderer.render();
 }
 
-
-function showProbability(cell,k,row,rowSetup,j,obj,pid){
-	print('showProbability: '+rowSetup);
+crfReviewSection.showProbability=
+function(cell,k,row,rowSetup,j,obj,pid){
+   this.parent.print('showProbability: '+rowSetup);
 	let rowVariable=rowSetup.variable;	
 	cell.id='prob_'+obj.values[k]+"_"+rowVariable+pid[rowVariable];
 
@@ -150,7 +207,7 @@ function showProbability(cell,k,row,rowSetup,j,obj,pid){
 	probDensity.mean=rowSetup.mean[j];
 	probDensity.sigma=rowSetup.sigma[j];
 
-	print('showProbability: mean '+probDensity.mean+' sigma '+probDensity.sigma);
+   this.parent.print('showProbability: mean '+probDensity.mean+' sigma '+probDensity.sigma);
 
 
 	probDensity.func=obj.values[k];
@@ -165,14 +222,15 @@ function showProbability(cell,k,row,rowSetup,j,obj,pid){
 	for (let f in obj.filters){
 		selectRows.filterArray.push(
 				LABKEY.Filter.create(f,pid[obj.filters[f]]));
-		print('Filter ['+f+']: '+pid[obj.filters[f]]);
+	   this.parent.print('Filter ['+f+']: '+pid[obj.filters[f]]);
 	}
-	selectRows.success=function(data){
-		drawProbability(data,cell,obj,pid,probDensity);}
+	selectRows.success=function(data){ 
+		this.drawProbability(data,cell,obj,pid,probDensity);}
 	LABKEY.Query.selectRows(selectRows);
 }
 
-function erf(x){
+crfReviewSection.erf=
+function(x){
 	let fx=[0,0.02,0.04,0.06,0.08,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,
 		1,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2,
 		2.1,2.2,2.3,2.4,2.5,3,3.5];
@@ -200,13 +258,13 @@ function erf(x){
 		let x0=fx[i0];
 		fval=y0+(y1-y0)/(x1-x0)*(Math.abs(x)-x0);
 	}
-	print('Erf: '+fval);
+   this.parent.print('Erf: '+fval);
 	if (x<0) return -fval;
 	return fval;
 }
 
-
-function setLine(fbox,name,value,fontSize){
+crfReviewSection.setLine=
+function(fbox,name,value,fontSize){
 	let fpId=fbox.id+name;
 	let fp=config.document.getElementById(fpId);
 	if (fp===null){
@@ -220,10 +278,11 @@ function setLine(fbox,name,value,fontSize){
 	fp.innerText=value;
 }	
 
-function drawProbability(data,cell,obj,pid,probDensity){
-	print('drawProbability');
+crfReviewSection.drawProbability=
+function(data,cell,obj,pid,probDensity){
+this.parent.print('drawProbability');
 	if (data.rows.length!=1){
-		print("drawProbability row length mismatch: "+data.rows.length);
+	   this.parent.print("drawProbability row length mismatch: "+data.rows.length);
 		return;
 	}
 	//possible mismatch; I assume the dataset will have a field called value
@@ -238,7 +297,7 @@ function drawProbability(data,cell,obj,pid,probDensity){
 	}
 	let color="red";
 	let fzx=fz*Math.sqrt(2);
-	print('drawProbability '+fzx);
+   this.parent.print('drawProbability '+fzx);
 
 	for (let i=1;i<obj.intervals.n;i++){
 		if (fzx>obj.intervals.zlimits[i]) continue;
@@ -258,7 +317,7 @@ function drawProbability(data,cell,obj,pid,probDensity){
 	fbox.style.height="180px";
 	
 
-	print('organCode '+probDensity.organCode);
+   this.parent.print('organCode '+probDensity.organCode);
 	let organName="Lung";
 
 	if (probDensity.organCode==4){
@@ -268,36 +327,36 @@ function drawProbability(data,cell,obj,pid,probDensity){
 		organName="Bowel";
 	}
 
-	setLine(fbox,'_fp4_',organName,"16px");
-	setLine(fbox,'_fp_',val.toPrecision(3),"25px");
-	setLine(fbox,'_fp1_',"SUV("+probDensity.percentile+"%)","16px");
-	setLine(fbox,'_fp2_',fzx.toPrecision(3),"25px");
-	setLine(fbox,'_fp3_',"z-value","16px");
+	this.setLine(fbox,'_fp4_',organName,"16px");
+	this.setLine(fbox,'_fp_',val.toPrecision(3),"25px");
+	this.setLine(fbox,'_fp1_',"SUV("+probDensity.percentile+"%)","16px");
+	this.setLine(fbox,'_fp2_',fzx.toPrecision(3),"25px");
+	this.setLine(fbox,'_fp3_',"z-value","16px");
 
 
 }
-
-function generateReviewSection2(pid){ 
-	
+crfReviewSection.generateReviewSection2=
+function(pid){ 
+	let config=this.parent.config;
 	let listName=config.loadFileConfig.listName;
 	let id=config.loadFileConfig.id;
 	
-	print('generateReviewSection2: '+pid.participantCode+'/'+
+   this.parent.print('generateReviewSection2: '+pid.participantCode+'/'+
 		pid.visitCode);
 	if (pid.participantCode=="NONE" || pid.visitCode=="NONE"){
-		generateErrorMessage(id,listName,
+		this.generateErrorMessage(id,listName,
 			"ParticipantId/visitId not set");
 		return;
 	}
 	
 
-	print('JSON: '+config.loadFileConfig.json);
+   this.parent.print('JSON: '+config.loadFileConfig.json);
 
 	let json=config.loadFileConfig.json;
 	let nrows=json.rows.values.length;
 	let ncol=json.columns.length;
 
-	pid.basePath=getBasePath()+"/@files";
+	pid.basePath=fileManager.getBasePath()+"/@files";
 	
 	
 	let el=config.document.getElementById(id);
@@ -331,11 +390,11 @@ function generateReviewSection2(pid){
 				else
 					cell=row.insertCell();
 				if (obj.display=="image") 
-					plotImage(cell,k,row,json.rows.variable,obj,pid);
+					this.plotImage(cell,k,row,json.rows.variable,obj,pid);
 				if (obj.display=="report") 
-					showReport(cell,k,row,json.rows.variable,obj,pid);
+					this.showReport(cell,k,row,json.rows.variable,obj,pid);
 				if (obj.display=="probability"){ 
-					showProbability(cell,k,row,json.rows,i,obj,pid);
+					this.showProbability(cell,k,row,json.rows,i,obj,pid);
 				}	
 				ic++;
 			}
@@ -349,23 +408,24 @@ function generateReviewSection2(pid){
 
 ///>>>>>>>>>>>>>>end of reviewSection(REPORT)
 
-function afterRegistration(data,fc){
+crfReviewSection.afterRegistration=
+function(data,fc){
 	let fName='[afterRegistration/'+data.queryName+']';
-	print(fName+": rows:"+data.rows.length);
+   this.parent.print(fName+": rows:"+data.rows.length);
 	fc.registration=data;
 	let registrationData=fc.registration;
-	clearErr();
+	this.parent.clearErr();
 	if (registrationData.rows.length!=1){
 		let msg=fName+": ERROR: Found "+registrationData.rows.length;
-		msg+=" registration entries for crfrefid "+getCRFref();
-		print(msg);
+		msg+=" registration entries for crfrefid "+this.parent.getCRFref();
+	   this.parent.print(msg);
 		fc.afterId(fc);
 		return;
 	}
-	print(fName+'registration participant field: '+fc.participantField);
+   this.parent.print(fName+'registration participant field: '+fc.participantField);
 	fc.participantId=registrationData.rows[0][fc.participantField];
 	//could be a lookup field (particularly for studies)
-	print('ID: '+fc.participantId);	
+   this.parent.print('ID: '+fc.participantId);	
 	let fields=registrationData.metaData.fields;
 	let field="NONE";
 	for (f in fields){
@@ -374,14 +434,15 @@ function afterRegistration(data,fc){
 	}
 	if ("lookup" in field){
 		let pid=fc.participantId;
-		print("Using lookup for participantId: "+pid);
+	   this.parent.print("Using lookup for participantId: "+pid);
 		let lookup=field["lookup"];
-		print("Lookup: ["+lookup.schemaName+','+lookup.queryName+']');
+   	this.parent.print("Lookup: ["+lookup.schemaName+','+lookup.queryName+']');
 
       //load lookup
-		let cb=function(data){afterRegistrationLookup(data,lookup.displayColumn,fc)};
+      let that=this;
+		let cb=function(data){that.afterRegistrationLookup(data,lookup.displayColumn,fc)};
 		let filters=[LABKEY.Filter.create(lookup.keyColumn,pid)];
-      cvSelectRows(lookup.schemaName,lookup.queryName,filters,cb,lookup.containerPath);
+      this.parent.selectRows(lookup.schemaName,lookup.queryName,filters,cb,lookup.containerPath);
 
 	}
 	else{
@@ -390,11 +451,12 @@ function afterRegistration(data,fc){
 	}
 }
 
-function afterRegistrationLookup(data,displayColumn,fc){
-	print("afterRegistrationLookup");
+crfReviewSection.afterRegistrationLookup=
+function(data,displayColumn,fc){
+   this.parent.print("afterRegistrationLookup");
 	let entry=data.rows[0];
 	fc.participantId=entry[displayColumn];
-	print('Setting to '+fc.participantId);
+   this.parent.print('Setting to '+fc.participantId);
 	fc.afterId(fc);
 	//afterParticipantId(configUpload);
 }

File diff suppressed because it is too large
+ 301 - 305
web/crfTecant/crfVisit.js


+ 14 - 0
web/crfTecant/debug.js

@@ -0,0 +1,14 @@
+var debug={};
+
+
+debug.print=
+function(msg){
+	this.document.getElementById(this.debugArea).value+="\n"+msg;
+}
+
+debug.clear=
+function(){
+	this.document.getElementById(this.debugArea).value="";
+}
+
+

+ 27 - 0
web/crfTecant/fileManager.js

@@ -0,0 +1,27 @@
+function parseResponseXML(){
+	//print(config.config,'Status:' +this.status);
+	print('Status:'+this.status);
+	if (this.status!=200) return;
+	config.loadFileConfig.json=JSON.parse(this.responseText);
+	config.loadFileConfig.cb();
+}
+
+function loadFile(){
+	print('YY: '+config.loadFileConfig.url);
+
+	let connRequest=new XMLHttpRequest();
+	connRequest.addEventListener("loadend",parseResponseXML);
+		//function(e){parseResponseXML(e,config);});
+	connRequest.open("GET", config.loadFileConfig.url);
+	connRequest.send();
+}
+
+
+function getBasePath(){
+	let server=LABKEY.ActionURL.getBaseURL();
+	let basePath=server+"_webdav";
+	basePath+=LABKEY.ActionURL.getContainer();
+	return basePath;
+}
+
+

+ 107 - 69
web/crfTecant/formGenerator.js

@@ -1,37 +1,53 @@
-function addFormGenerator(){
+//namespace
+var formGenerator={};
+
+formGenerator.set=
+function(parentClass){
+   this.parent=parentClass;
+}
+
+formGenerator.addFormGenerator=
+function(){
+   //parentClass should provide config and print and getContainer
+   let config=this.parent.config;
       
    let fName='[addFormGenerator]';
-   print(fName);
+   this.parent.print(fName);
    //layout
    let table=config.document.createElement("table");
    table.className="t2";
    config.document.getElementById(config.div).appendChild(table);
-   let formGenerator=new Object();
-   formGenerator.formSelect=addInputRow(table,'Select form',"select");
-   formGenerator.crfSelect=addInputRow(table,'Select CRF',"select");
-   formGenerator.comment=addInputRow(table,'Enter comment','text');
-   formGenerator.details=addInputRow(table,'Details','label');
-   formGenerator.warnings=addInputRow(table,'Warnings','label');
-   formGenerator.warnings.innerHTML='formGenerator version 1.1.0';
-   addOption(formGenerator.formSelect,'<Select>',-1);
+   //this is a form manipulator
+   let fgForm=new Object();
+
+   fgForm.formSelect=this.addInputRow(table,'Select form',"select");
+   fgForm.crfSelect=this.addInputRow(table,'Select CRF',"select");
+   fgForm.comment=this.addInputRow(table,'Enter comment','text');
+   fgForm.details=this.addInputRow(table,'Details','label');
+   fgForm.warnings=this.addInputRow(table,'Warnings','label');
+   fgForm.warnings.innerHTML='formGenerator version 2.1.0';
+   this.addOption(fgForm.formSelect,'<Select>',-1);
    let formRows=config.formConfig.generateConfigData.rows;
    for (let i=0;i<formRows.length;i++){
       let formId=formRows[i]["formId"];
-      let formName=getFormName(formId);
-      print(fName+' '+formRows[i]["formId"]+'/'+formName);
-      addOption(formGenerator.formSelect,formName,formId);
+      let formName=this.getFormName(formId);
+      this.parent.print(fName+' '+formRows[i]["formId"]+'/'+formName);
+      this.addOption(fgForm.formSelect,formName,formId);
    }
-   formGenerator.formSelect.onchange=function(){updateIdList(formGenerator);};
-   formGenerator.crfSelect.onchange=function(){updateLabel(formGenerator);};
-   formGenerator.generateButton=addInputRow(table,'Generate Form','button');
-   formGenerator.generateButton.value="Generate Form";
-   formGenerator.generateButton.onclick=function(){createFormWithId(formGenerator);};
+   //callbacks should be called on copy of this
+   let that=this;
+   fgForm.formSelect.onchange=function(){that.updateIdList(fgForm);};
+   fgForm.crfSelect.onchange=function(){that.updateLabel(fgForm);};
+   fgForm.generateButton=this.addInputRow(table,'Generate Form','button');
+   fgForm.generateButton.value="Generate Form";
+   fgForm.generateButton.onclick=function(){that.createFormWithId(fgForm);};
       
 }
 
-function fgInsertRow(schemaName,queryName,row,cb=null,containerPath=null){
+formGenerator.insertRow=
+function(schemaName,queryName,row,cb=null,containerPath=null){
    let fName='[fgInsertRow]';
-   print(fName);
+   this.parent.print(fName);
    //cb=function(data){....}
 	let qconfig=new Object();
 	if (containerPath)
@@ -41,13 +57,15 @@ function fgInsertRow(schemaName,queryName,row,cb=null,containerPath=null){
 	qconfig.success=function(data){;};
    if (cb) qconfig.success=cb;
    qconfig.rows=[row];
-   print(fName+' qconfig '+qconfig);
+   this.parent.print(fName+' qconfig '+qconfig);
 	LABKEY.Query.insertRows(qconfig);
 }
 
-function addInputRow(table,header,type){
+formGenerator.addInputRow=
+function(table,header,type){
+   let config=this.parent.config;
    let fName='[addInputRow]';
-   print(fName);
+   this.parent.print(fName);
    let row=table.insertRow();
    let cell=config.document.createElement('th');
    let text=config.document.createTextNode(header);
@@ -74,8 +92,10 @@ function addInputRow(table,header,type){
    cell1.appendChild(input);
    return input;
 }
- 
-function getFormName(formId){
+
+formGenerator.getFormName=
+function(formId){
+   let config=this.parent.config;
    let rows=config.formConfig.dataForms.rows;
    for (let i=0;i<rows.length;i++){
       if (rows[i]['Key']==formId){
@@ -85,7 +105,9 @@ function getFormName(formId){
    return "NONE";
 }
 
-function getQueryName(queryId){
+formGenerator.getQueryName=
+function(queryId){
+   let config=this.parent.config;
    let rows=config.formConfig.inputLists.rows;
    for (let i=0;i<rows.length;i++){
       if (rows[i]['Key']==queryId){
@@ -95,7 +117,9 @@ function getQueryName(queryId){
    return "NONE";
 }
 
-function getGCRow(formId){
+formGenerator.getGCRow=
+function(formId){
+   let config=this.parent.config;
    let formRows=config.formConfig.generateConfigData.rows;
    for (let i=0;i<formRows.length;i++){
       if (formRows[i]['formId']==formId){
@@ -105,7 +129,9 @@ function getGCRow(formId){
    return Object();
 }
 
-function getCrfSelectRow(crfRef){
+formGenerator.getCrfSelectRow=
+function(crfRef){
+   let config=this.parent.config;
    let rows=config.formConfig.crfSelectRows;
    for (let i=0;i<rows.length;i++){
       if (rows[i]['crfRef']==crfRef)
@@ -116,31 +142,36 @@ function getCrfSelectRow(crfRef){
 }
 
 
-function addOption(input,name,value){
+formGenerator.addOption=
+function(input,name,value){
+   let config=this.parent.config;
    let opt=config.document.createElement("option");
    opt.text=name;
    opt.value=value;
    input.options[input.options.length]=opt;
 }
- 
-function clearOptions(input){
+
+formGenerator.clearOptions=
+function(input){
    for(let i = input.options.length; i >= 0; i--) {
 		input.remove(i);
    }
 }
-	
-function createFormWithId(formGenerator){
+
+formGenerator.createFormWithId=
+function(fgForm){
    //get form id and entry id from select and create form as above
    let fName='[createFormWithId]';
 
-   print(fName);
-   let formId=formGenerator.formSelect.options[formGenerator.formSelect.selectedIndex].value;
-   let crfRef=formGenerator.crfSelect.options[formGenerator.crfSelect.selectedIndex].text;
-   let configRow=getGCRow(formId);
-   let crfSelectRow=getCrfSelectRow(crfRef);
+   this.parent.print(fName);
+   let config=this.parent.config;
+   let formId=fgForm.formSelect.options[fgForm.formSelect.selectedIndex].value;
+   let crfRef=fgForm.crfSelect.options[fgForm.crfSelect.selectedIndex].text;
+   let configRow=this.getGCRow(formId);
+   let crfSelectRow=this.getCrfSelectRow(crfRef);
 	let formConfig=config.formConfig;
 
-	print("Create form w/id "+formId);
+	this.parent.print("Create form w/id "+formId);
 	
 	let crfEntry=new Object();
 	crfEntry.entryId=Date.now();
@@ -161,7 +192,7 @@ function createFormWithId(formGenerator){
    }
 	crfEntry.UserId=LABKEY.Security.currentUser.id;
 	crfEntry.Site=config.formConfig.currentSites[0].siteNumber;
-	print("Setting site to id="+crfEntry.Site);
+	this.parent.print("Setting site to id="+crfEntry.Site);
 	//from argument list
 	crfEntry.Form=formId;
    crfEntry.parentCrf=crfRef;
@@ -172,13 +203,13 @@ function createFormWithId(formGenerator){
    reviewComment['submissionDate']=crfEntry['Date'];
    reviewComment['crfRef']=crfRef;
    //comment length
-   let x=formGenerator.comment.value;
-   print(fName+' comment length '+x.length);
+   let x=fgForm.comment.value;
+   this.parent.print(fName+' comment length '+x.length);
    if (x.length==0){
-      formGenerator.warnings.innerHTML='Supply a comment';
+      fgForm.warnings.innerHTML='Supply a comment';
       return;
    }
-   reviewComment['reviewComment']=formGenerator.comment.value;
+   reviewComment['reviewComment']=fgForm.comment.value;
    reviewComment['queryName']=configRow['queryId'];
 
    let crfStatus=new Object();
@@ -190,53 +221,60 @@ function createFormWithId(formGenerator){
    crfStatus.operator=config.role;
    crfStatus.action='createFormWithId';
 
-
-   let rd=function(data){redirect();};
-   let pass1=function(data){fgInsertRow('lists','crfStatus',crfStatus,rd,getContainer('data'));}
-   let pass=function(data){fgInsertRow('lists','reviewComments',reviewComment,pass1,getContainer('data'));}
-   fgInsertRow('lists','crfEntry',crfEntry,pass,getContainer('data'));
+   let that=this;
+   let containerPath=this.parent.getContainer('data');
+   let rd=function(data){that.redirect();};
+   let pass1=function(data){that.insertRow('lists','crfStatus',crfStatus,rd,containerPath);};
+   let pass=function(data){that.insertRow('lists','reviewComments',reviewComment,pass1,containerPath);};
+   this.insertRow('lists','crfEntry',crfEntry,pass,this.parent.getContainer('data'));
 }
 
 
-function updateIdList(formGenerator){
+formGenerator.updateIdList=
+function(fgForm){
    let fName='[updateIdList]';
-   let formId=formGenerator.formSelect.options[formGenerator.formSelect.selectedIndex].value;
-   print(fName+' id '+formId);
+   let formId=fgForm.formSelect.options[fgForm.formSelect.selectedIndex].value;
+   this.parent.print(fName+' id '+formId);
    //remove old options
-   clearOptions(formGenerator.crfSelect);
-   print(fName+' options cleared');
+   this.clearOptions(fgForm.crfSelect);
+   this.parent.print(fName+' options cleared');
    //get query associated with form
-   let configRow=getGCRow(formId);
+   let configRow=this.getGCRow(formId);
    let queryId=configRow['queryId'];
-   print(fName+' queryId '+queryId);
+   this.parent.print(fName+' queryId '+queryId);
    if (!queryId || queryId<0)
       return;
 
    let qselect=new Object();
-   qselect.containerPath=getContainer('data');
+   qselect.containerPath=this.parent.getContainer('data');
    qselect.schemaName='lists';
-   qselect.queryName=getQueryName(queryId);
-   qselect.success=function(data){updateIdListWithData(formGenerator,data);};
+   qselect.queryName=this.getQueryName(queryId);
+   let that=this;
+   qselect.success=function(data){that.updateIdListWithData(fgForm,data);};
    LABKEY.Query.selectRows(qselect);
 }
 
-function updateIdListWithData(formGenerator,data){
+formGenerator.updateIdListWithData=
+function(fgForm,data){
+   let config=this.parent.config;
    let rows=data.rows;
    config.formConfig.crfSelectRows=data.rows;
    for (let i=0;i<rows.length;i++){
-      addOption(formGenerator.crfSelect,rows[i]['crfRef'],i);
+      this.addOption(fgForm.crfSelect,rows[i]['crfRef'],i);
    }
    let event=new Event('change');
-   formGenerator.crfSelect.dispatchEvent(event);
+   fgForm.crfSelect.dispatchEvent(event);
 }
 
-function updateLabel(formGenerator){
-   let crfRef=formGenerator.crfSelect.options[formGenerator.crfSelect.selectedIndex].text;
-   let crfSelectRow=getCrfSelectRow(crfRef);
-   formGenerator.details.innerHTML='Generating for Study:'+crfSelectRow['participantStudyId']+' / Local:'+crfSelectRow['participantLocalId'];
+formGenerator.updateLabel=
+function(fgForm){
+   let crfRef=fgForm.crfSelect.options[fgForm.crfSelect.selectedIndex].text;
+   let crfSelectRow=this.getCrfSelectRow(crfRef);
+   fgForm.details.innerHTML='Generating for Study:'+crfSelectRow['participantStudyId']+' / Local:'+crfSelectRow['participantLocalId'];
 }
 
-function redirect(){
+formGenerator.redirect=
+function(){
 
 	let debug=false;
 	let formUrl="begin";
@@ -245,14 +283,14 @@ function redirect(){
 	params.pageId="CRF";
 
 	//points to crf container
-	let containerPath=getContainer('data');
+	let containerPath=this.parent.getContainer('data');
         
 	// This changes the page after building the URL. 
 	//Note that the wiki page destination name is set in params.
         
 	var homeURL = LABKEY.ActionURL.buildURL(
 			"project", formUrl , containerPath, params);
-        print("Redirecting to "+homeURL);
+   this.parent.print("Redirecting to "+homeURL);
 	if (debug) return;	 
 	window.location = homeURL;
 

+ 152 - 151
web/crfTecant/formPortal.js

@@ -1,98 +1,49 @@
-//global config variable
-const config=new Object();
+var formPortal={};
 
-function print(msg){
-	config.document.getElementById(config.debugArea).value+="\n"+msg;
+//global config variable
+formPortal.config=new Object();
+
+formPortal.setDebug=
+function(debug=null){
+   if (debug){
+      this.print=function(msg){debug.print(msg);};
+      this.clear=function(){debug.clear();}
+      return;
+   }
+   //provide default functions if not debug object is available
+   this.print=function(msg){console.log(msg);}
+   this.clear=function(){;}
 }
 
-function clear(){
-	config.document.getElementById(config.debugArea).value="";
-}
 
-function getMode(){
-	if ("role" in config){
-		return config.role;
+formPortal.setDebug();
+
+formPortal.getMode=
+function(){
+	if ("role" in this.config){
+		return this.config.role;
 	}
 	return "crfEditor";
 }
 
-function doNothing(){
-	print('doNothing called');
-}
-
-function makeQuery(containerName,queryName,fieldName,filterArray){
-	//queryArray should contain elements with
-	//- fieldName to set the data variable
-	//- containerName to select container (data,config,CRF)
-	//- queryName to select query
-	//- filterArray to perform filtering, empty array works
-	//- callback cb to be called with no arguments
-	
-	let e=new Object();
-	e.containerName=containerName;
-	e.queryName=queryName;
-	e.fieldName=fieldName;
-	e.filterArray=filterArray;
-	return e;
-}
-
-function getDataFromQueries(queryArray,cb){
-	afterQuery(new Object(),-1,queryArray,cb);
+formPortal.doNothing=
+function(){
+	this.print('doNothing called');
 }
 
-function afterQuery(data,id,queryArray,cb){
+//load runQuery.js
 
-	print('afterQuery['+id+']: ');
-
-	if (id>-1){
-		let fieldName=queryArray[id].fieldName;
-		print('afterQuery['+fieldName+']: '+data.rows.length);
-		//uses config.formConfig
-		config.formConfig[fieldName]=data;
-	}
-	id+=1;
-	if (id==queryArray.length) {
-		cb();
-		return;
-	}
-
-
-	let e=queryArray[id];
-	let qconfig=new Object();
-	qconfig.containerPath=getContainer(e.containerName);
-	qconfig.schemaName="lists";
-	if ("schemaName" in e){
-		print('afterQuery: schemaName='+e.schemaName);
-		qconfig.schemaName=e.schemaName;
-	}
-
-	if ("columns" in e){
-		print('afterQuery: columns='+e.columns);
-		qconfig.columns=e.columns;
-	}
-	qconfig.queryName=e.queryName;
-	//this should point to configuration container
-	//don't filter -> so we can pick up other forms (say registration) later on
-	//qconfig.filterArray=[LABKEY.Filter.create('Key',config.formId)];
-	if ("filterArray" in e)
-		qconfig.filterArray=e.filterArray;
-	
-	//qconfig.filterArray=[LABKEY.Filter.create('formStatus',1)]
-	qconfig.success=function(data){afterQuery(data,id,queryArray,cb);};
-	qconfig.failure=doNothing;
-	LABKEY.Query.selectRows(qconfig);
-
-}
-
-
-function printMessage(msg){
-	let txt=config.document.createElement("p");
-	config.document.getElementById(config.div).appendChild(txt);
+formPortal.printMessage=
+function(msg){
+	let txt=this.config.document.createElement("p");
+	this.config.document.getElementById(this.config.div).appendChild(txt);
 	txt.innerText=msg;
 }
 
-function userName(id){
-	let formConfig=config.formConfig;
+
+formPortal.userName=
+function(id){
+	let formConfig=this.config.formConfig;
 	for (let i=0;i<formConfig.users.rows.length;i++){
 		if (formConfig.users.rows[i].UserId!=id)
 			continue;
@@ -101,43 +52,71 @@ function userName(id){
 	return "NONE";
 }
 
-function setContainer(label,container){
+formPortal.setContainer=
+function(label,container){
+   let config=this.config;
 	if (!(config.formConfig.hasOwnProperty('container'))){
 		config.formConfig.container=new Array();
 	}
 	config.formConfig.container[label]=container;
 }
 
-function getContainer(label){
-	return config.formConfig.container[label];
+
+formPortal.getContainer=
+function(label){
+	return this.config.formConfig.container[label];
 }
 
+formPortal.init=
+function(cb=null){
+   let that=this;
+   let action=function(){that.scriptsLoaded(cb);};
+   LABKEY.Utils.requiresScript(["crfTecant/runQuery.js","crfTecant/formGenerator.js"],action);
+}
+
+formPortal.scriptsLoaded=
+function(cb=null){
+   formGenerator.set(this);
+   if (cb) cb();
+}
 
-function generateFormArray(){
-	print("generateFormArray "+getMode());
+formPortal.generateFormArray=
+function(){
+   let that=this;
+   let action=function(){that.fcontinue0();};
+   this.init(action);
+}
+
+formPortal.fcontinue0=
+function(){
+	this.print("generateFormArray "+this.getMode());
+   let config=this.config;
 	
 	config.formConfig=new Object();
-	config.formConfig.softwareVersion='T.1.15';
+	config.formConfig.softwareVersion='T.2.01';	//report software version
 	//report software version
 	config.document.getElementById('version').innerText=config.formConfig.softwareVersion;	
 	
-	setContainer('data',LABKEY.ActionURL.getContainer());
-	setContainer('config',LABKEY.ActionURL.getContainer());
-	setContainer('CRF',LABKEY.ActionURL.getContainer());
+	this.setContainer('data',LABKEY.ActionURL.getContainer());
+	this.setContainer('config',LABKEY.ActionURL.getContainer());
+	this.setContainer('CRF',LABKEY.ActionURL.getContainer());
 
 	let selectRows=new Object();
 	//this is local data
-	selectRows.containerPath=getContainer('CRF');
+	selectRows.containerPath=this.getContainer('CRF');
 	selectRows.schemaName='lists';
 	selectRows.queryName='crfSettings';
 	//store form related data to this object
-	selectRows.success=afterSettings;
+   let that=this;
+	selectRows.success=function(data){that.afterSettings(data);};
 	LABKEY.Query.selectRows(selectRows);
 
 }
 
-function afterSettings(data){
-
+formPortal.afterSettings=
+function(data){
+   let fName="[afterSettings]";
+   let config=this.config;
 	config.formConfig.settings=new Array();
 	for (let i=0;i<data.rows.length;i++){
 		let n=data.rows[i]['name'];
@@ -146,9 +125,9 @@ function afterSettings(data){
 	}
 
 	let st=config.formConfig.settings;
-	print('afterSettings');
+	this.print(fName);
 	for (let k in st){
-		print('\t'+k+'='+st[k]);
+		this.print(fName+'\t'+k+'='+st[k]);
 	}
 
 	//if ('dataContainer' in st){
@@ -156,51 +135,59 @@ function afterSettings(data){
 	//}
 	let vname='configContainer';
 	if (vname in st){
-		setContainer('config',st[vname]);
+		this.setContainer('config',st[vname]);
 	}
-	print('Config: '+getContainer('config'));
-	print('Data: '+getContainer('data'));
+	this.print(fName+' config: '+this.getContainer('config'));
+	this.print(fName+' data: '+this.getContainer('data'));
 
 
 	//setup queryArray
 	let queryArray=new Array();
 
+   //targetObject
+   let targetObject=config.formConfig;
+
    //static variables
-	queryArray.push(makeQuery('data','crfStaticVariables','crfStaticVariables',[]));
+	queryArray.push(runQuery.makeQuery(targetObject,'data','crfStaticVariables','crfStaticVariables',[]));
 	//Forms
-	queryArray.push(makeQuery('config','Forms','dataForms',[]));
+	queryArray.push(runQuery.makeQuery(targetObject,'config','Forms','dataForms',[]));
 	//users
-	queryArray.push(makeQuery('data','users','users',[]));
+	queryArray.push(runQuery.makeQuery(targetObject,'data','users','users',[]));
 	queryArray[queryArray.length-1].schemaName='core';
 	//inputLists
-	queryArray.push(makeQuery('config','inputLists','inputLists',[]));
+	queryArray.push(runQuery.makeQuery(targetObject,'config','inputLists','inputLists',[]));
 	//crfEditors
-	queryArray.push(makeQuery('config','crfEditors','crfEditors',[]));
+	queryArray.push(runQuery.makeQuery(targetObject,'config','crfEditors','crfEditors',[]));
 	//crfMonitors
-	queryArray.push(makeQuery('config','crfMonitors','crfMonitors',[]));
+	queryArray.push(runQuery.makeQuery(targetObject,'config','crfMonitors','crfMonitors',[]));
 	//crfSponsors
-	queryArray.push(makeQuery('config','crfSponsors','crfSponsors',[]));
+	queryArray.push(runQuery.makeQuery(targetObject,'config','crfSponsors','crfSponsors',[]));
 	//crfManagers
-	queryArray.push(makeQuery('config','crfManagers','crfManagers',[]));
+	queryArray.push(runQuery.makeQuery(targetObject,'config','crfManagers','crfManagers',[]));
 	//FormStatus
-	queryArray.push(makeQuery('config','FormStatus','formStatusg',[]));
+	queryArray.push(runQuery.makeQuery(targetObject,'config','FormStatus','formStatusg',[]));
 	//site
-	queryArray.push(makeQuery('config','site','siteData',[]));
+	queryArray.push(runQuery.makeQuery(targetObject,'config','site','siteData',[]));
 	//crfEntry
-	queryArray.push(makeQuery('data','crfEntry','crfEntries',[]));
+	queryArray.push(runQuery.makeQuery(targetObject,'data','crfEntry','crfEntries',[]));
    
    queryArray.push(
-		makeQuery('config','generateConfig','generateConfigData',[]));	
-	
-	getDataFromQueries(queryArray,addStudyData);
+		runQuery.makeQuery(targetObject,'config','generateConfig','generateConfigData',[]));	
+	let that=this;
+
+   let action=function(){that.addStudyData();};
+	runQuery.getDataFromQueries(this,queryArray,action);
 	//getDataFromQueries(queryArray,fcontinue);
 }
 
-function addStudyData(){
-	//setup queryArray
+formPortal.addStudyData=
+function(){
+	let config=this.config;
+   //setup queryArray
 	let queryArray=new Array();
+   let targetObject=config.formConfig;
 	
-	queryArray.push(makeQuery('data','StudyProperties','studyData',[]));
+	queryArray.push(runQuery.makeQuery(targetObject,'data','StudyProperties','studyData',[]));
 	let e=queryArray[queryArray.length-1];
 	e.schemaName='study';
    let columnModel="";
@@ -210,12 +197,16 @@ function addStudyData(){
       columnModel+=varRows[i]['staticVariable'];
    }
 	e.columns=columnModel;
-   getDataFromQueries(queryArray,fcontinue);
+   let that=this;
+   let action=function(){that.fcontinue();};
+   runQuery.getDataFromQueries(this,queryArray,action);
 
 
 }
 
-function filterEntry(entry,filter,settings){
+formPortal.filterEntry=
+function(entry,filter,settings){
+   let fName="[filterEntry]";
 
    if (entry.Form!=filter.form)
       return false;
@@ -225,13 +216,13 @@ function filterEntry(entry,filter,settings){
       return false;
    }
 
-   print('Candidate '+entry.entryId);
+   this.print(fName+' candidate '+entry.entryId);
    //TODO: smart filter on user (now we get to see all)
    //
    //for editors
 
    if ("filterUser" in settings && filter.role=='crfEditor' && entry.UserId!=filter.userId){
-      print('Skipping identity mismatch: '+entry.UserId+'/'+filter.userId);  
+      this.print(fName+' skipping identity mismatch: '+entry.UserId+'/'+filter.userId);  
       return false;
    }
 
@@ -248,33 +239,35 @@ function filterEntry(entry,filter,settings){
    }
    potentialSiteNumbers+=']';
    if (matchingSite==-1){
-      print('Skipping wrong site: '+entry.Site+'/'+potentialSiteNumbers);
+      this.print(fName+' skipping wrong site: '+entry.Site+'/'+potentialSiteNumbers);
       return false;
    }
    return true;
 }
 
-function fcontinue(){
+formPortal.fcontinue=
+function(){
    let fName='[fcontinue]';
+   let config=this.config;
 	let formConfig=config.formConfig;
 
-	print("Number of study data entries: "+formConfig.studyData.rows.length);
-	print("ParticipantId: "+formConfig.studyData.rows[0].SubjectColumnName);
+	this.print(fName+" number of study data entries: "+formConfig.studyData.rows.length);
+	this.print(fName+" participantId: "+formConfig.studyData.rows[0].SubjectColumnName);
 
 	let dataForms=formConfig.dataForms.rows;
 
 	formConfig.table=config.document.createElement("table");
 	config.document.getElementById(config.div).appendChild(formConfig.table);
 
-	let accessModeColumn=getMode()+'Status';
-	print('accessModeColumn '+accessModeColumn);
+	let accessModeColumn=this.getMode()+'Status';
+	this.print(fName+' accessModeColumn '+accessModeColumn);
 	//cutting down on number of fields
    //let creatorModeColumn=getMode()+'Creator';
 
 
 	//switch from status based to form based access
-	print("Forms: "+dataForms.length);
-	print("Entries: "+formConfig.crfEntries.rows.length);
+	this.print(fName+" forms: "+dataForms.length);
+	this.print(fName+" entries: "+formConfig.crfEntries.rows.length);
 	let fEntries=formConfig.crfEntries.rows;
 	let users=formConfig.users.rows;
 	let currentUserId=LABKEY.Security.currentUser.id;
@@ -290,7 +283,7 @@ function fcontinue(){
    //check for users that fit the role, 
    //fRows lists all users for role
 	let fRows=config.formConfig[fList].rows;
-   print(fName+' candidates: '+fRows.length)
+   this.print(fName+' candidates: '+fRows.length)
 	//current user must be in the list
 	
 	let currentUserRoles=new Array();
@@ -312,7 +305,7 @@ function fcontinue(){
 
    //currentUser was not matched in fRows
 	if (currentUserRoles.length==0){
-		printMessage('User '+currentUser.DisplayName+" can't act as "+config.role);
+		this.printMessage('User '+currentUser.DisplayName+" can't act as "+config.role);
 		return;
 	}
 
@@ -333,7 +326,7 @@ function fcontinue(){
 		msg+=currentSites[i].siteName;
 	}
 	msg+=')';
-	printMessage(msg);
+	this.printMessage(msg);
 
    let filter=new Object();
    filter.role=config.role;
@@ -352,7 +345,7 @@ function fcontinue(){
 		//add row for each form
 		let row=formConfig.table.insertRow(i);
 		let formName=qForm.formName;
-		print("["+i+"/"+formKey+']: '+formName);
+		this.print(fName+" ["+i+"/"+formKey+']: '+formName);
 
       //column counter
 		let k=0;
@@ -360,12 +353,12 @@ function fcontinue(){
       //get the target status
 		let formStatus=qForm[accessModeColumn];
       filter.formStatus=qForm[accessModeColumn];
-		print('target formStatus '+formStatus);
+		this.print(fName+' target formStatus '+formStatus);
 
 
 		for (let j=0;j<fEntries.length;j++){
          let entry=fEntries[j];
-			if (!filterEntry(entry,filter,config.formConfig.settings))
+			if (!this.filterEntry(entry,filter,config.formConfig.settings))
             continue;
 
 			//insert form
@@ -422,19 +415,20 @@ function fcontinue(){
 
 			let button=config.document.createElement("button");
 			button.appendChild(fbox);
-			button.onclick=function(){openForm(entry)};
+         let that=this;
+			button.onclick=function(){that.openForm(entry)};
 
 			cell.appendChild(button);
 			k++;
 		}
-		print('finished checking existing forms');
+		this.print(fName+' finished checking existing forms');
 
 		//only those that are allowed to create forms
 		//print('Status: '+qForm[creatorModeColumn]);
 		
       let creator=qForm['creator'];
       if (!creator) continue;
-      if (creator!=getMode()) continue;
+      if (creator!=this.getMode()) continue;
       //if (qForm[creatorModeColumn]!='TRUE') continue;
 
 		let fbox=config.document.createElement("div");
@@ -456,27 +450,31 @@ function fcontinue(){
 
 		let button=config.document.createElement("button");
 		button.appendChild(fbox);
-		button.onclick=function(){createForm(formKey)};
+      let that=this;
+		button.onclick=function(){that.createForm(formKey)};
 
 		cell.appendChild(button);
 
 	}		  
    if (config.role=='crfManager')
       //need formGenerator.js
-      addFormGenerator();
+      formGenerator.addFormGenerator(this);
 
 }
 
-function openForm(crfEntry){
+formPortal.openForm=
+function(crfEntry){
+   let fName="[openForm]";
+   let config=this.config;
 	let formConfig=config.formConfig;
 	let crfRef=crfEntry.entryId;
 	
-	print("Clicked for "+crfRef);
+	this.print(fName+" clicked for "+crfRef);
 
 	let formId=crfEntry.Form;
 	for (let i=0;i<formConfig.dataForms.rows.length;i++){
 		if (formConfig.dataForms.rows[i].Key!=formId) continue;
-		print("Setting form "+formConfig.dataForms.rows[i].formName);
+		this.print(fName+" setting form "+formConfig.dataForms.rows[i].formName);
 		formEntry=formConfig.dataForms.rows[i];
 		break;
 	}
@@ -505,16 +503,19 @@ function openForm(crfEntry){
    // This changes the page after building the URL. 
 	//Note that the wiki page destination name is set in params.
    var wikiURL = LABKEY.ActionURL.buildURL("crf_tecant", formUrl , containerPath, params);
-   print("Redirecting to "+wikiURL);
+   this.print(fName+" redirecting to "+wikiURL);
 
 		 
 	window.location = wikiURL;
 }
 
-function createForm(formId){
+formPortal.createForm=
+function(formId){
+   let fName="[createForm]";
+   let config=this.config;
 	let formConfig=config.formConfig;
 
-	print("Create form w/id "+formId);
+	this.print(fName+" create form w/id "+formId);
 	
 	let crfEntry=new Object();
 	crfEntry.entryId=Date.now();
@@ -531,7 +532,7 @@ function createForm(formId){
    }
 	crfEntry.UserId=LABKEY.Security.currentUser.id;
 	crfEntry.Site=config.formConfig.currentSites[0].siteNumber;
-	print("Setting site to id="+crfEntry.Site);
+	this.print(fName+" setting site to id="+crfEntry.Site);
 	//from argument list
 	crfEntry.Form=formId;
 
@@ -543,10 +544,10 @@ function createForm(formId){
    crfStatus.Form=crfEntry.Form;
    crfStatus.operator=config.role;
    crfStatus.action='createForm';
-
-   let cb=function(data){openForm(crfEntry);};
-   let pass=function(data){fgInsertRow('lists','crfStatus',crfStatus,cb,getContainer('data'));};
-   fgInsertRow('lists','crfEntry',crfEntry,pass,getContainer('data'));
+   let that=this;
+   let cb=function(data){that.openForm(crfEntry);};
+   let containerPath=this.getContainer('data');
+   let pass=function(data){formGenerator.insertRow('lists','crfStatus',crfStatus,cb,containerPath);};
+   formGenerator.insertRow('lists','crfEntry',crfEntry,pass,this.getContainer('data'));
 }
 
-

+ 70 - 60
web/crfTecant/generateRegistration.js

@@ -1,94 +1,118 @@
-function grSelectRows(cb){
-   this.config.print(this.fName+": selectRows");
+let generateRegistration={};
+
+generateRegistration.fName="[generateRegistration]";
+
+generateRegistration.set=
+function(parentClass){
+   this.parent=parentClass;
+}
+
+generateRegistration.selectRows=
+function(gObj,cb){
+   this.parent.print(this.fName+": selectRows");
    let xRows=new Object();
-   let gObj=this;
-   xRows.schemaName=this.schemaName;
-   xRows.queryName=this.queryName;
+   let that=this;
+   xRows.schemaName=gObj.schemaName;
+   xRows.queryName=gObj.queryName;
    xRows.success=cb;
-   xRows.failure=function(errorInfo){gObj.fail(errorInfo);};
+   xRows.failure=function(errorInfo){that.fail(errorInfo);};
    LABKEY.Query.selectRows(xRows);
-   this.config.print(this.fName+": selectRows completed");
+   this.parent.print(this.fName+": selectRows completed");
 }
 
-function grInsertRows(rows){
-   this.config.print(this.fName+": insertRows");
+generateRegistration.insertRows=
+function(gObj,rows){
+   this.parent.print(this.fName+": insertRows");
    let iRows=new Object();
-   let gObj=this;
-   iRows.schemaName=this.schemaName;
-   iRows.queryName=this.queryName;
+   iRows.schemaName=gObj.schemaName;
+   iRows.queryName=gObj.queryName;
    iRows.rows=rows;
    iRows.success=function(data){gObj.callback(data);};
    LABKEY.Query.insertRows(iRows);
 }
  
-function zeroPad(val,strLength=3){
+generateRegistration.zeroPad=
+function(val,strLength=3){
    let strK=val.toString();
    return strK.padStart(strLength,'0');
 }
 
-function findFirstAvailableKey(rows){
+generateRegistration.findFirstAvailableKey=
+function(rows){
    let k=-1;
    for (let i=0;i<rows.length;i++){
       if (rows[i]['Key']>k){
          k=rows[i]['Key'];
       }
    }
-   this.config.print(this.fName+': Key candidate: '+(k+1));
+   this.parent.print(this.fName+': Key candidate: '+(k+1));
    return k+1;
 }
 
-function generateObjectAtKey(k){
-   let regCode=this.codeBase+this.zeroPad(k);
-   this.config.print(this.fName+": regCode "+regCode);
+generateRegistration.generateObjectAtKey=
+function(gObj,k){
+   let regCode=gObj.codeBase+this.zeroPad(k);
+   this.parent.print(this.fName+": regCode "+regCode);
    let row=new Object();
    row['Key']=k;
-   row[this.codeField]=regCode;
-   if ("addData" in this){
-      for (let q in this.addData){
-         row[q]=this.addData[q];
+   row[gObj.codeField]=regCode;
+   if ("addData" in gObj){
+      for (let q in gObj.addData){
+         row[q]=gObj.addData[q];
       }
    }
    return row;
 }
 
-function getCode(row){
-   return row[this.codeField];
+generateRegistration.getCode=
+function(gObj,row){
+   return row[gObj.codeField];
 }
 
-function updateField(text){
-   let el=this.config.document.getElementById(this.elementId);
+generateRegistration.updateField=
+function(gObj,text){
+   let el=this.parent.config.document.getElementById(gObj.elementId);
+   this.parent.print(this.fName+": updateField "+gObj.elementId+'/'+el);
    el.value=text;
 }
 
-function generateId(data){
-   this.config.print(this.fName+": generateId "+data.rows.length);
+generateRegistration.generateId=
+function(gObj,data){
+   this.parent.print(this.fName+": generateId "+data.rows.length);
    let k=this.findFirstAvailableKey(data.rows);
-   let row=this.generateObjectAtKey(k);
-   this.updateField(this.getCode(row));
+   let row=this.generateObjectAtKey(gObj,k);
+   this.updateField(gObj,this.getCode(gObj,row));
    let rows=new Array();
    rows.push(row);
-   this.insertRows(rows);
+   this.insertRows(gObj,rows);
 }
 
-function doNothing1(data){
-   this.config.print(this.fName+": doNothing() called");
+generateRegistration.doNothing=
+function(data){
+   this.parent.print(this.fName+": doNothing() called");
 }
 
-function fail(errorInfo){
-   this.config.print(this.fName+": error "+errorInfo.exception);
+generateRegistration.fail=
+function(errorInfo){
+   this.parent.print(this.fName+": error "+errorInfo.exception);
 }
 
-function execute(){
-   let gObj=this;
-   this.config.print(this.fName+": execute");
-   this.selectRows(function(data){gObj.generateId(data);});
+generateRegistration.execute=
+function(gObj){
+   let that=this;
+   //this.parent.print(this.fName+": execute "+gObj.elementId);
+   this.inspect(gObj);
+   this.selectRows(gObj,function(data){that.generateId(gObj,data);});
 }
 
-function inspect(){
-   this.config.print(this.fName);
-   this.config.print("query: "+this.schemaName+'/'+this.queryName);
-   this.config.print("codeBase "+this.codeBase+" codeField "+this.codeField);
-   this.config.print("version 25");
+generateRegistration.inspect=
+function(gObj){
+   this.parent.print(this.fName);
+   this.parent.print("query: "+gObj.schemaName+'/'+gObj.queryName);
+   this.parent.print("codeBase "+gObj.codeBase+" codeField "+gObj.codeField);
+   this.parent.print("elementId "+gObj.elementId);
+   this.parent.print("callback "+gObj.callback);
+   this.parent.print("version 1.01");
 }
 
 //generic function for all functors
@@ -105,28 +129,14 @@ function inspect(){
 //
 //object is initialized from a list in LabKey
 //
-function getGenerationObject(config,qPar,outputId){
+generateRegistration.getObject=
+function(qPar,outputId){
    let gObj=new Object();
-   gObj.config=config;
-   gObj.insertRows=grInsertRows;
-   gObj.selectRows=grSelectRows;
-   gObj.zeroPad=zeroPad;
-   gObj.findFirstAvailableKey=findFirstAvailableKey;
-   gObj.generateObjectAtKey=generateObjectAtKey;
-   gObj.getCode=getCode;
-   gObj.updateField=updateField;
-   gObj.generateId=generateId;
    gObj.codeBase=qPar["codeBase"];
    gObj.schemaName=qPar["schemaName"];
    gObj.queryName=qPar["queryName"];
    gObj.codeField=qPar["codeField"];
    gObj.elementId=outputId;
-   gObj.execute=execute;
-   gObj.inspect=inspect;
-   gObj.fName="[generateRegistration]";
-   gObj.fail=fail;
-   gObj.doNothing1=doNothing1;
-   gObj.callback=gObj.doNothing1;
    //should set codeBase and elementId after initialization
    return gObj;
 }

+ 166 - 173
web/crfTecant/participantIdManager.js

@@ -1,14 +1,20 @@
 //all functions are based off of participantManager (print, config, etc.)
+var participantIdManager={};
 
-function addSelectOptions(){
-   let pM=this;
+participantIdManager.set=
+function(parentClass){
+   this.parent=parentClass;
+}
+
+participantIdManager.addSelectOptions=
+function(pM){
    if (pM.mode=="LOCAL") return;
    
-   let input=pM.getInputElement();
-   let config=pM.config;
+   let input=this.getInputElement(pM);
+   let config=this.parent.config;
 
    let fName='addParticipantSelectOptions';
-   pM.print(fName+' input '+input);
+   this.parent.print(fName+' input '+input);
    let opt=config.document.createElement("option");
    opt.value=-1;
 
@@ -17,57 +23,57 @@ function addSelectOptions(){
 
    //here the lookup is being populated (registrationData)
    let demoRows=config.formConfig['registrationData'].rows;
-   pM.print(fName+" demoRows: "+demoRows.length);
+   this.parent.print(fName+" demoRows: "+demoRows.length);
    for (let i=0;i<demoRows.length;i++){
       let opt2=config.document.createElement("option");
       opt2.value=i+1;
-      let id=demoRows[i][pM.getCrfEntryFieldName()];
-      let loc=demoRows[i][pM.getCrfEntryFieldName('LOCAL')];
+      let id=demoRows[i][this.getCrfEntryFieldName(pM)];
+      let loc=demoRows[i][this.getCrfEntryFieldName(pM,'LOCAL')];
       opt2.text=id+' (Local: '+loc+')';
       input.options[input.options.length]=opt2;
-      pM.print(fName+' '+pM.participantField+' '+demoRows[i][pM.participantField]);
+      this.parent.print(fName+' '+pM.participantField+' '+demoRows[i][pM.participantField]);
    }
 
    input.selectedIndex=0;
 }
 
-function updateElements(){
-   let pM=this;
+participantIdManager.updateElements=
+function(pM){
    let fName='[updateElements]';
    //reset all values (some might be different depending on the call timing)
 
    //selector is with study
-   pM.cellSelector=config.document.getElementById(pM.cellSelectorId);
-   pM.inputSelector=config.document.getElementById(pM.inputSelectorId);
-   pM.textStudy=config.document.getElementById(pM.textStudyId);
+   pM.cellSelector=this.parent.getElement(pM.cellSelectorId);
+   pM.inputSelector=this.parent.getElement(pM.inputSelectorId);
+   pM.textStudy=this.parent.getElement(pM.textStudyId);
   
-   pM.print(fName+' selector '+pM.inputSelector+' id '+pM.inputSelectorId);
+   this.parent.print(fName+' selector '+pM.inputSelector+' id '+pM.inputSelectorId);
    //value is with local
-   pM.cellValue=config.document.getElementById(pM.cellValueId);
-   pM.inputValue=config.document.getElementById(pM.inputValueId);
-   pM.textLocal=config.document.getElementById(pM.textLocalId);
+   pM.cellValue=this.parent.getElement(pM.cellValueId);
+   pM.inputValue=this.parent.getElement(pM.inputValueId);
+   pM.textLocal=this.parent.getElement(pM.textLocalId);
    
-   //pM.inputManageLocal=config.document.getElementById(pM.inputManageLocalId);
-   //pM.inputManageStudy=config.document.getElementById(pM.inputManageStudyId);
+   //pM.inputManageLocal=this.parent.getElement(pM.inputManageLocalId);
+   //pM.inputManageStudy=this.parent.getElement(pM.inputManageStudyId);
 }
 
-function generateEntryField(){
-   let pM=this;
+
+participantIdManager.generateEntryField=
+function(pM){
    let fName='[generateParticipantEntryField]:';
-   pM.print(fName);
+   this.parent.print(fName);
 
    //this is HTML designator of area on page
-   let config=pM.config;
-	let formName=config.masterForm;
+	let formName=this.parent.config.masterForm;
 
     
-   pM.tb=config.document.createElement('table');
+   pM.tb=this.parent.config.document.createElement('table');
    let tb=pM.tb;
 	tb.className='t2';
 	let row=tb.insertRow();
 	
    //label for local ID
-   let cell=config.document.createElement('th');
+   let cell=this.parent.config.document.createElement('th');
 	row.appendChild(cell);	
 	cell.setAttribute("colspan","1");
 	cell.style.fontSize="20px";
@@ -87,7 +93,7 @@ function generateEntryField(){
    let rowStudy=tb.insertRow();
 
    //label for study ID
-   let cellStudy=config.document.createElement('th');
+   let cellStudy=this.parent.config.document.createElement('th');
 	rowStudy.appendChild(cellStudy);	
 	cellStudy.setAttribute("colspan","1");
 	cellStudy.style.fontSize="20px";
@@ -101,86 +107,87 @@ function generateEntryField(){
 
    //manage
    pM.cellManageStudy=rowStudy.insertCell();
-   config.document.getElementById(formName).appendChild(tb);
-   pM.print(fName+' done');
+   this.parent.getElement(formName).appendChild(tb);
+   this.parent.print(fName+' done');
 
 }
 
-function getMode(mode="NONE"){
-   let pM=this;
+
+participantIdManager.getMode=
+function(pM,mode="NONE"){
    if (mode=="NONE") return pM.mode;
    return mode;
 }
 
 //reslovers which operate depending on mode
-function getInputId(mode="NONE"){
-   let pM=this;
+participantIdManager.getInputId=
+function(pM,mode="NONE"){
    let fName='[getInputId]';
-   pM.print(fName);
-   if (pM.getMode(mode)=="LOCAL") return pM.inputValueId;
+   this.parent.print(fName);
+   if (this.getMode(pM,mode)=="LOCAL") return pM.inputValueId;
    return pM.inputSelectorId;
 }
 
 
-function getInputCell(mode="NONE"){
-   let pM=this;
+participantIdManager.getInputCell=
+function(pM,mode="NONE"){
    let fName='[getInputCell]';
-   pM.print(fName+' mode '+mode+' getMode '+pM.getMode(mode));
-   if (pM.getMode(mode)=="LOCAL") return pM.cellValue;
+   this.parent.print(fName+' mode '+mode+' getMode '+this.getMode(pM,mode));
+   if (this.getMode(pM,mode)=="LOCAL") return pM.cellValue;
    return pM.cellSelector;
 }
 
-function getInputElement(mode="NONE"){
-   let pM=this;
+participantIdManager.getInputElement=
+function(pM,mode="NONE"){
    let fName='[getInputElement]';
-   pM.print(fName);
-   let elementType=pM.getInputElementType(mode);
-   let id=pM.getInputId(mode);
-   let cell=pM.getInputCell(mode);
-   let el=pM.config.document.getElementById(id);
-   pM.print(fName+' mode '+pM.getMode(mode)+' type '+elementType+' id '+id+' cell '+cell+' el '+el);
+   this.parent.print(fName);
+   let elementType=this.getInputElementType(pM,mode);
+   let id=this.getInputId(pM,mode);
+   let cell=this.getInputCell(pM,mode);
+   let el=this.parent.getElement(id);
+   this.parent.print(fName+' mode '+this.getMode(pM,mode)+' type '+elementType+' id '+id+' cell '+cell+' el '+el);
    if (el) return el;
 
-   el=pM.config.document.createElement(elementType);
-   print(fName+' input '+el);
+   el=this.parent.config.document.createElement(elementType);
+   this.parent.print(fName+' input '+el);
    el.id=id;
 
    cell.replaceChildren(el);
-   pM.addSelectOptions();
+   this.addSelectOptions(pM);
  
    return el;
 }
 
-function getInputElementType(mode="NONE"){
-   let pM=this;
+participantIdManager.getInputElementType=
+function(pM,mode="NONE"){
    let fName='[getInputElementType]';
-   pM.print(fName);
-   if (pM.getMode(mode)=="LOCAL") return "input";
+   this.parent.print(fName);
+   if (this.getMode(pM,mode)=="LOCAL") return "input";
    return "select";
 }
 
 
-function getTextFieldId(mode="NONE"){
-   let pM=this;
+participantIdManager.getTextFieldId=
+function(pM,mode="NONE"){
    let fName='[getTextFieldId]';
-   pM.print(fName);
-   if (pM.getMode(mode)=="LOCAL") return pM.textLocalId;
+   this.parent.print(fName);
+   if (this.getMode(pM,mode)=="LOCAL") return pM.textLocalId;
    return pM.textStudyId;
 }
 
   
-function getTextElement(mode="NONE"){
-   let pM=this;
+participantIdManager.getTextElement=
+function(pM,mode="NONE"){
    let fName='[getTextElement]';
-   pM.print(fName+' mode '+mode);
-   let id=pM.getTextFieldId(mode);
-   pM.print(fName+' id '+id);
-   let el=pM.config.document.getElementById(id);
-   pM.print(fName+' el '+el);
+   this.parent.print(fName+' mode '+mode);
+   let id=this.getTextFieldId(pM,mode);
+   this.parent.print(fName+' id '+id);
+   let el=this.parent.getElement(id);
+   this.parent.print(fName+' el '+el);
    if (el) return el;
-   el=config.document.createElement("p");
+   el=this.parent.config.document.createElement("p");
    el.id=id;
-   let cell=pM.getInputCell(mode);
+   let cell=this.getInputCell(pM,mode);
    //let oldEl=pM.getInputElement(mode);
    cell.replaceChildren(el);
    return el;
@@ -188,54 +195,54 @@ function getTextElement(mode="NONE"){
 
 
 //get the button, create if not there yet
-function getInputManage(mode="NONE"){
-   let pM=this;
+participantIdManager.getInputManage=
+function(pM,mode="NONE"){
    let fName='[getInputManage]';
-   //pM.print(fName);
-   let config=pM.config;
+   //this.parent.print(fName);
    //this prevents from having two inputs; it is either local or global from the outset
    if ("inputManage" in pM) return pM.inputManage;
 
-   pM.inputManage=config.document.createElement("input");
+   pM.inputManage=this.parent.config.document.createElement("input");
    let inputManage=pM.inputManage;
    inputManage.type="button";
-   inputManage.onclick=function(){pM.manageId();};
+   let that=this;
+   inputManage.onclick=function(){that.manageId(pM);};
    //inputManageLocal.id=pM.inputManageLocalId;
    let cell=pM.cellManageStudy;
-   if (pM.getMode(mode)=="LOCAL") cell=pM.cellManageLocal;
-   //pM.print(fName+' inputManage '+pM.inputManage+' cell '+cell+' mode '+pM.mode);
+   if (this.getMode(pM,mode)=="LOCAL") cell=pM.cellManageLocal;
+   //this.parent.print(fName+' inputManage '+pM.inputManage+' cell '+cell+' mode '+pM.mode);
    cell.appendChild(inputManage);
    return inputManage;
 }
 
 //callback that splits to edit or set/label mode
-function manageId(){
-   let pM=this;
+
+participantIdManager.manageId=
+function(pM){
    let fName='[manageId]';
-   pM.print(fName);
+   this.parent.print(fName);
    //this can happen after object was created, so make sure current
    //elements are used
-   pM.updateElements();
-   let x=pM.getInputManage();
+   this.updateElements(pM);
+   let x=this.getInputManage(pM);
 
    if (x.value=="Set"){
-      pM.setId();
+      this.setId(pM);
       return;
    }
    if (x.value=="Edit"){
-      pM.editId();
+      this.editId(pM);
       return;
    }
 }
 
 //set mode
-function setId(){
-   let pM=this;
-   let fName='[setId]';
-   pM.print(fName);
-   let el=pM.getInputElement();
+participantIdManager.setId=
+function(pM){
+   this.parent.print(fName);
+   let el=this.getInputElement(pM);
 
-   pM.print(fName+" value: "+el.value);
+   this.parent.print(fName+" value: "+el.value);
    let pId=el.value;
    let label=pId;
    if (pM.mode!="LOCAL"){
@@ -246,34 +253,33 @@ function setId(){
       label=label.replace(/ \(Local: /,':');
       label=label.replace(/\)/,'');
    }
-   pM.setParticipantIdToCrfEntry(pId);//no argument (should come from mode)
-   pM.print(fName+" new value "+pId);
-   pM.setLabelMode(label);
+   this.setParticipantIdToCrfEntry(pM,pId);//no argument (should come from mode)
+   this.parent.print(fName+" new value "+pId);
+   this.setLabelMode(pM,label);
    pM.updateCrfEntry();
 }
 
-function setLabelMode(pId){
+participantIdManager.setLabelMode=
+function(pM,pId){
    let fName='[setLabelMode1]';
-   let pM=this;
-   let config=pM.config;
 
-   pM.print(fName+' id '+pId);
+   this.parent.print(fName+' id '+pId);
    ids=pId.split(':');
 
-   let textValue=pM.getTextElement();
-   pM.print(fName+' textElement '+textValue);
+   let textValue=this.getTextElement(pM);
+   this.parent.print(fName+' textElement '+textValue);
    textValue.innerText=ids[0];
 
    if (pM.mode=="STUDY"){
       let loc=ids[1];
       //pM.getParticipantIdFromCrfEntry('LOCAL');
-      pM.print(fName+' setting local id '+loc);
-      let tValLocal=pM.getTextElement('LOCAL');
+      this.parent.print(fName+' setting local id '+loc);
+      let tValLocal=this.getTextElement(pM,'LOCAL');
       tValLocal.innerText=loc;
-      pM.setParticipantIdToCrfEntry(loc,'LOCAL');
+      this.setParticipantIdToCrfEntry(pM,loc,'LOCAL');
    }
 
-   let x=pM.getInputManage();//getInputManage
+   let x=this.getInputManage(pM);//getInputManage
    if ("readOnly" in pM){
       x.style.display="none";
    }
@@ -283,70 +289,90 @@ function setLabelMode(pId){
 }
 
 //edit mode
-function editId(){
-   let pM=this;
-   pM.setEditMode();
+participantIdManager.editId=
+function(pM){
+   this.setEditMode(pM);
 }
 
-function setEditMode(){
-   let pM=this;
-   let config=pM.config;
+
+participantIdManager.setEditMode=
+function(pM){
 
    let fName='[setEditMode1]';
-   pM.print(fName+' pM '+pM+' mode '+pM.mode);
+   this.parent.print(fName+' pM '+pM+' mode '+pM.mode);
    //input
-   let el=pM.getInputElement();
+   let el=this.getInputElement(pM);
 
-   let x=pM.getInputManage();
+   let x=this.getInputManage(pM);
    x.value="Set";
 
 }
 
 //manage interaction to storage/CRF and study/LabKey
-function getParticipantField(config){
-   return config.formConfig['studyDataAll'].rows[0]['SubjectColumnName'];
+participantIdManager.getParticipantField=
+function(){
+   return this.parent.config.formConfig['studyDataAll'].rows[0]['SubjectColumnName'];
 }
 
-function getCrfEntryFieldName(mode="NONE"){
-   let pM=this;
+participantIdManager.getCrfEntryFieldName=
+function(pM,mode="NONE"){
    let variable="Study";
    if (mode=="NONE") mode=pM.mode;
    if (mode=="LOCAL") variable="Local";
    return 'participant'+variable+'Id';
 }
 
-function setParticipantIdToCrfEntry(pId,mode="NONE"){
-   let pM=this;
-   let config=pM.config;
-   config.formConfig.crfEntry[pM.getCrfEntryFieldName(mode)]=pId;
+participantIdManager.setParticipantIdToCrfEntry=
+function(pM,pId,mode="NONE"){
+   this.parent.config.formConfig.crfEntry[this.getCrfEntryFieldName(pM,mode)]=pId;
 }
 
-function getParticipantIdFromCrfEntry(mode="NONE"){
-   let pM=this;
-   let config=pM.config;
-   return config.formConfig.crfEntry[pM.getCrfEntryFieldName(mode)];
+participantIdManager.getParticipantIdFromCrfEntry=
+function(pM,mode="NONE"){
+   return this.parent.config.formConfig.crfEntry[this.getCrfEntryFieldName(pM,mode)];
+}
+
+participantIdManager.verifyCrfStudyId=
+function(pM){
+
+   //is studyId already set for the crf
+   let studyId=this.getParticipantIdFromCrfEntry(pM,'STUDY');
+   if (!studyId) return;
+   pM.mode="STUDY";
+   pM.readOnly="TRUE";
+}
+
+participantIdManager.verifyRegistration=
+function(pM, formConfig){
+   //if registration is in, 
+   //then local id should not be changed any longer
+   let idFieldName=this.getCrfEntryFieldName(pM,"STUDY");
+   //let fQuery=config.formConfig.registrationData;
+   let fQuery=formConfig.registrationData;
+   if (fQuery.rows.length==0) return; //registration is empty
+
+   let studyId=fQuery.rows[0][idFieldName];
+   if (!studyId) return; //study id not set
+   //set 
+   pM.mode="STUDY";
+   pM.readOnly="TRUE";
+   //set crf (this happens later, but probably before the form will be corrected)
+   this.setParticipantIdToCrfEntry(pM,studyId,"STUDY");
+   pM.updateCrfEntry();
 }
 
+
 //main interface. Use this to generate object and to refer to it later on
-function getParticipantManagerObject(config){
+participantIdManager.getObject=
+function(){
 
    let fName='[getParticipantManagerObject]';
-   config.print(fName);
-   if ("participantManager" in config) {
-      let pM=config.participantManager;
-      pM.updateElements();
-      return pM;
-   }
+   this.parent.print(fName);
 
    let pM=new Object();
-   //circular reference to traverse pM up and down
-   config.participantManager=pM;
-   pM.config=config;
-   //config should have a print routine
-   pM.print=config.print;
 
    //this never change
-   pM.participantField=getParticipantField(config);
+   pM.participantField=this.getParticipantField();
 
 
    pM.cellSelectorId=pM.participantField+"_cellSelect";
@@ -361,45 +387,12 @@ function getParticipantManagerObject(config){
    pM.inputManageStudyId=pM.participantField+"_ManageStudy";
 
    pM.mode="LOCAL";//or "STUDY"
-
-   //add methods
-   pM.getMode=getMode;
-
-   //global methods that are not subject to mode modifier
-   pM.updateElements=updateElements;
-   pM.addSelectOptions=addSelectOptions;
-   pM.generateEntryField=generateEntryField;
-
-   //getters subject to mode
-   pM.getInputId=getInputId;
-   pM.getInputCell=getInputCell;
-   pM.getInputElement=getInputElement;
-   pM.getInputElementType=getInputElementType;
-
-   pM.getTextFieldId=getTextFieldId;
-   pM.getTextElement=getTextElement;
-
-   pM.getInputManage=getInputManage;
-
-   //callback
-   pM.manageId=manageId;
    
-   //set/label mode
-   pM.setId=setId;
-   pM.setLabelMode=setLabelMode;
-
-   //edit mode
-   pM.editId=editId;
-   pM.setEditMode=setEditMode;
-   
-   //interact with storage/CRF and study/LabKey
-   pM.setParticipantIdToCrfEntry=setParticipantIdToCrfEntry;
-   pM.getParticipantIdFromCrfEntry=getParticipantIdFromCrfEntry;
-   pM.getCrfEntryFieldName=getCrfEntryFieldName;
-
+   //dummy function to be overloaded by calling class
+   pM.updateCrfEntry=function(){;}
 
    //init
-   pM.generateEntryField();
-   pM.updateElements();
+   this.generateEntryField(pM);
+   this.updateElements(pM);
    return pM;
 }

+ 21 - 14
web/crfTecant/runQuery.js

@@ -1,8 +1,11 @@
+var runQuery={};
+
 //external dependencies:
 //LABKEY.Query
 //print -> configObject.print
 
-function makeQuery(targetObject,containerName,queryName,fieldName,filterArray){
+runQuery.makeQuery=
+function(targetObject,containerName,queryName,fieldName,filterArray){
    //call with makeQuery(config.formConfig,getContainer(name),...
 	let e=new Object();
 	e.containerName=containerName;
@@ -13,7 +16,8 @@ function makeQuery(targetObject,containerName,queryName,fieldName,filterArray){
 	return e;
 }
 
-function getDataFromQueries(queryArray,cb){
+runQuery.getDataFromQueries=
+function(parentClass,queryArray,cb){
 	//queryArray should contain elements with
 	//- fieldName to set the data variable
 	//- containerName to select container (data,config,CRF)
@@ -21,10 +25,11 @@ function getDataFromQueries(queryArray,cb){
 	//- filterArray to perform filtering, empty array works
 	//- callback cb to be called with no arguments
 	//
-	afterQuery(new Object(),-1,queryArray,cb);
+	this.afterQuery(new Object(),-1,parentClass,queryArray,cb);
 }
 
-function afterQuery(data,id,queryArray,cb){
+runQuery.afterQuery=
+function(data,id,parentClass,queryArray,cb){
 	//queryArray should contain elements with
 	//- fieldName to set the data variable
 	//- containerName to select container (data,config,CRF)
@@ -40,7 +45,7 @@ function afterQuery(data,id,queryArray,cb){
 	if (id>-1){
 	   let e1=queryArray[id];
 		let fieldName=e1.fieldName;
-		e1.targetObject.print(fName+' ['+fieldName+']: '+data.rows.length);
+		parentClass.print(fName+' ['+fieldName+']: '+data.rows.length);
 		e1.targetObject[fieldName]=data;
 	}
 	id+=1;
@@ -52,23 +57,23 @@ function afterQuery(data,id,queryArray,cb){
 
 	let e=queryArray[id];
    for (v in e){
-      e.targetObject.print(fName+' value ['+v+'] '+e[v]);
+      parentClass.print(fName+' value ['+v+'] '+e[v]);
    }
 	let qconfig=new Object();
-	qconfig.containerPath=e.targetObject.getContainer(e.containerName);
+	qconfig.containerPath=parentClass.getContainer(e.containerName);
    if ("containerPath" in e){
-      e.targetObject.print(fName+' containerPath '+e.containerPath);
+      parentClass.print(fName+' containerPath '+e.containerPath);
       qconfig.containerPath=e.containerPath;
    }
 
 	qconfig.schemaName="lists";
 	if ("schemaName" in e){
-		e.targetObject.print(fName+' schemaName='+e.schemaName);
+		parentClass.print(fName+' schemaName='+e.schemaName);
 		qconfig.schemaName=e.schemaName;
 	}
 
 	if ("columns" in e){
-		e.targetObject.print(fName+' columns='+e.columns);
+		parentClass.print(fName+' columns='+e.columns);
 		qconfig.columns=e.columns;
 	}
 	qconfig.queryName=e.queryName;
@@ -79,15 +84,17 @@ function afterQuery(data,id,queryArray,cb){
 		qconfig.filterArray=e.filterArray;
 	
 	//qconfig.filterArray=[LABKEY.Filter.create('formStatus',1)]
-	qconfig.success=function(data){afterQuery(data,id,queryArray,cb);};
-	qconfig.failure=function(errorInfo,responseObj){onTAFailure(e.targetObject,errorInfo,responseObj);};
+   let that=this;
+	qconfig.success=function(data){that.afterQuery(data,id,parentClass,queryArray,cb);};
+	qconfig.failure=function(errorInfo,responseObj){that.onTAFailure(parentClass,errorInfo,responseObj);};
 	LABKEY.Query.selectRows(qconfig);
 
 }
 
-function onTAFailure(targetObj, errorInfo, responseObj){
+runQuery.onTAFailure=
+function(parentClass, errorInfo, responseObj){
    //don't have configObject to rely to
-   targetObj.print('[afterQuery]: Failure: '+errorInfo.exception);
+   parentClass.print('[afterQuery]: Failure: '+errorInfo.exception);
 
 }
 

+ 58 - 0
web/crfTecant/variableList.js

@@ -0,0 +1,58 @@
+var variableList={};
+
+variableList.parseVariables=
+function(pars){
+   let pA=pars.split(";");
+   let q=new Object();
+   for (let i=0;i<pA.length;i++){
+      let vA=pA[i].split('=');
+      q[vA[0]]=vA[vA.length-1];
+   }
+   return q;
+}
+
+variableList.printVariables=
+function(parentClass,q){
+	let fName="[printVariables]";
+	for (let x in q){
+		parentClass.print(fName+" ["+x+"] "+q[x]);
+	}
+}
+
+variableList.hasVariable=
+function(q,varName){
+   if (q && varName in q)
+      return true;
+
+   return false;
+}
+
+variableList.isFilterList=
+function(v){
+   if (typeof(v)!='string') return false;
+   if (v.search(';')==-1) return false;
+   return true;
+}
+
+variableList.convertToDictionary=
+function(rows){
+   let x=new Array();
+	for (let i=0;i<rows.length;i++){
+		let n=rows[i]['name'];
+		let v=rows[i]['value'];
+		x[n]=v;
+	}
+   return x;
+}
+ 
+variableList.convertToAssociatedArray=
+function(rows,fieldName="name"){
+   let x=new Object();
+	for (let i=0;i<rows.length;i++){
+		let n=rows[i][fieldName];
+		x[n]=rows[i];
+	}
+   return x;
+}
+
+

+ 98 - 0
web/crfTecant/webdav.js

@@ -0,0 +1,98 @@
+var webdav={};
+
+webdav.set=
+function(parentClass){
+   this.parent=parentClass;
+}
+   
+webdav.uploadFile=
+function(file,context){
+
+	let url=LABKEY.ActionURL.getBaseURL();
+	url+='_webdav';
+	url+=LABKEY.ActionURL.getContainer();
+	url+='/@files';
+   url+='/'+context['dirName'];
+
+	this.parent.print('uploadFile url: '+url);
+	let uploadConfig=new Object();
+	uploadConfig.file=file;
+	uploadConfig.context=context;
+	uploadConfig.url=url;
+   let that=this;
+	uploadConfig.success=function(cfg){that.afterBaseDir(cfg);};
+	uploadConfig.failure=function(cfg){that.tryMakeDir(cfg);};
+	this.webdavCheck(uploadConfig);
+}
+
+webdav.afterBaseDir=
+function(cfg){
+	this.parent.print('afterBaseDir');
+	cfg.url+='/'+cfg.context['ID'];
+   let that=this;
+	cfg.success=function(x){that.afterIDDir(x);};
+	cfg.failure=function(x){that.tryMakeDir(x);};
+	this.webdavCheck(cfg);
+}
+
+webdav.afterIDDir=
+function(cfg){
+	this.parent.print('afterIDDir');
+	this.parent.print('Uploading '+cfg.file.name);
+	let suf=cfg.file.name.split('.').pop();
+	cfg.url+='/'+cfg.context['ID']+'.'+suf;
+   cfg.data=cfg.file;
+   let that=this;
+	cfg.success=function(x){that.afterUpload(x);};
+	cfg.failure=function(x){that.onFailure(x);};
+	this.webdavPut(cfg);
+}
+
+webdav.afterUpload=
+function(cfg){
+	this.parent.print('afterUpload');
+}
+
+webdav.tryMakeDir=
+function(cfg){
+	this.parent.print('tryMakeDir '+cfg.url);
+   let that=this;
+	cfg.failure=function(x){that.onFailure(x);};
+	this.webdavMakeDir(cfg);
+}
+
+
+webdav.request=
+function (cfg,verb,data){
+	this.parent.print('request['+verb+'] '+cfg.url);
+	let connRequest=new XMLHttpRequest();
+   let that=this;
+   let action=function(connRequest,cfg){that.checkResponse(connRequest,cfg);};
+	connRequest.addEventListener("loadend",action);
+	connRequest.open(verb, cfg.url);
+	connRequest.send(data);
+	//this.print('request['+verb+'] sent');
+}
+
+webdav.checkResponse=
+function(xrq,cfg){
+	//this.print('checkResponse: readyState '+xrq.readyState);
+	//this.print('checkResponse: status '+xrq.status);
+	if (xrq.status<400) {
+		//client errors 400-499
+		//server errors 500-599
+		cfg.success(cfg);
+		return;
+	}
+	cfg.status=xrq.status;
+	cfg.failure(cfg);
+}
+
+webdav.webdavMakeDir=function(cfg){ this.request(cfg,'MKCOL',null);}
+webdav.webdavCheck=function(cfg) { this.request(cfg,'GET',null);}
+webdav.webdavPut=function(cfg) { this.request(cfg,'PUT',cfg.data);}
+
+
+webdav.onFailuer=function(cfg){
+	this.parent.print('request failed with status='+cfg.status);
+}

Some files were not shown because too many files changed in this diff