function print(config,msg){ config.document.getElementById(config.debugId).value+="\n"+msg; } function drawForm(par){ populateSourceTable(par); //populateSourceTableData let tableId="entryTable"; generateTable(par,"formDiv",tableId); generateRow(par,tableId,"User");//generateTableRow populateSelectTableEntry(par,"User");//populateTableRow , populateSelect generateRow(par, tableId,"Site"); generateRow(par, tableId, "FormStatus"); generateRow(par, tableId,"Crf"); populateSelectTableEntry(par,"Site"); populateSelectTableEntry(par,"FormStatus"); let formTableId="selectFormTable"; generateTable(par,"selectFormDiv",formTableId); generateRow(par,formTableId,"Form"); generateButtonRow(formTableId,"Add new CRF","Add", par, addNewEntry); } function generateQConfig(listName){ let qConfig=new Object(); qConfig.containerPath="TECANT/Data"; qConfig.schemaName="lists"; qConfig.queryName=listName; return qConfig; } function sourceVar(crfEntryName,elementId,sourceName){ let f=new Object(); f.masterSelectVarName=crfEntryName; f.selectId=elementId; f.inputType="innerHTML"; f.sourceSelectVarName=sourceName; return f; } function getField(config, data, varName){ let debug=false; if (debug) print(config, "getField"); let fields=data.metaData.fields; for (f in fields){ if (debug) print(config,"Checking "+f+": name "+fields[f].name+"/"+varName); if (fields[f].name!=varName) continue; return fields[f]; } return null; } function selectEntry(data,config, row){ let entry=data.rows[0]; let varName=row.masterSelectVarName; let el=config.document.getElementById(row.selectId); for (let i=0;i< el.options.length;i++){ print(config,"selectEntry: "+el.options[i].value+"/"+entry[varName]); if (el.options[i].value!=entry[varName]) continue; el.selectedIndex=i; return; } } function generateHead(config, headDivName,divName,title){ print(config,"generateHead"); let tb=config.document.createElement('table'); tb.className='t2'; let row=tb.insertRow(); let cell=config.document.createElement('th'); row.appendChild(cell); cell.setAttribute("colspan","4"); cell.style.fontSize="20px"; cell.style.textAlign="center"; let cellData=config.document.createTextNode(title); cell.appendChild(cellData); cell=row.insertCell(); cell.style.fontSize="20px"; let input=config.document.createElement("input"); input.type="button"; input.value="Show"; input.id="toggle"+divName+"VisbilityButton"; input.onclick=function(){toggleVisibility(config,divName,input.id)}; cell.appendChild(input); config.document.getElementById(headDivName).appendChild(tb); print(config,"generateHead: Done"); } function toggleVisibility(config,divName,buttonName){ let x = config.document.getElementById(divName); if (x.style.display === "none") { x.style.display = "block"; config.document.getElementById(buttonName).value="Hide"; } else { x.style.display = "none"; config.document.getElementById(buttonName).value="Show"; } } function selectRowsSuccess(config,data){ print(config,"Select rows on "+data.queryName+" got "+data.rows.length+" rows."); } function selectRowsFailure(config,errorObj){ print(config,"selectRowsFail: "+errorObj.exception) } function populateSourceTable(par){ let debug=true; if (debug){ print(par.config,"populateSourceTable: Starting"); } let config=generateQConfig(par.source.queryName); config.schemaName=par.source.schemaName; if (!("source" in par)) return; if (debug){ print(par.config,"populateSourceTable ["+par.source.queryName+"]"); } config.success=function(data){populateSourceTableData(data,par)}; //config.success=function(data){selectRowsSuccess(par.config,data)}; config.failure=function(errorObj){selectRowsFailure(par.config,errorObj)}; LABKEY.Query.selectRows(config); } function populateSourceTableData(data,par){ let debug=true; if (debug){ print(par.config, "populateSourceTableData: nrow: "+data.rows.length); } let entry=data.rows[0]; for (let i=0;i < par.source.vars.length;i++){ let srcVarName=par.source.vars[i]; if (debug){ print(par.config, "populateSourceTable ["+srcVarName+"]"); } let row=par.vars[srcVarName]; let el=par.config.document.getElementById(row.selectId); if (debug){ print(par.config, "Element: "+el); } el.innerHTML=entry[row.sourceSelectVarName]; } } function generateTable(par,divName,elementId){ let debug=true; if (debug) print(par.config,"generateTable"); let tb=par.config.document.createElement('table'); tb.className="t2"; tb.id=elementId; par.config.document.getElementById(divName).appendChild(tb); if (debug) print(par.config,"generateTable: Done"); } function generateRow(par, tableId, rowId){ let debug=true; if (debug) print(par.config,"generateRow: Start"); let config=generateQConfig(par.masterQuery); config.success=function(data){generateTableRow(data, par, tableId, rowId)}; LABKEY.Query.selectRows(config); if (debug) print(par.config,"generateRow: End"); return; } function generateTableRow(data, par, tableId, rowId){ let debug=true; if (debug) print(par.config,"generateTableRow: start"); let tb=par.config.document.getElementById(tableId); let row=par.vars[rowId]; if (debug) print(par.config,"getField for "+row.masterSelectVarName); let field=getField(par.config,data,row.masterSelectVarName); let trow=tb.insertRow(); let cell=par.config.document.createElement('th'); trow.appendChild(cell); let text = par.config.document.createTextNode(field.shortCaption); cell.appendChild(text); cell=trow.insertCell(); let input = par.config.document.createElement("select"); input.id = row.selectId; input.onchange=function(){row.callback(par,rowId)}; cell.appendChild(input); if (debug) print(par.config,"generateTableRow: end"); } function populateSelectTableEntry(par,rowId){ let debug=true; let row=par.vars[rowId]; if (debug) print(par.config,"populateSelectTableEntry:"+par.masterQuery+"/"+row.masterSelectVarName); let config=generateQConfig(par.masterQuery); if ("filter" in row){ //populateSelect on authorizationQuery with authSelectVarName let filter=row.filter; if (debug){ print(par.config,"Filter:"+filter.queryName); print(par.config,"FilterVar "+filter.filterVarName); } config.queryName=filter.queryName; config.filterArray=[]; for (f in filter.filters){ if (debug) print(par.config,"Adding filter: "+f+" val "+filter.filters[f]); config.filterArray.push(LABKEY.Filter.create(f,filter.filters[f])); } } else{ config.queryName=par.masterQuery; } config.success=function(data){populateTableRow(data,par,rowId)}; LABKEY.Query.selectRows(config); if (debug) print(par.config,"generateSelect: End"); return; } function populateTableRow(data,par,rowId){ //data is output of selectRows on either // * masterQuery looking at masterSelectVarName or // * authQuery looking at authSelectVarName //in both cases, query[varName] is a lookup variable, so do populateSelect with lookupData,queryData and par let debug=true; let row=par.vars[rowId]; let varName=row.masterSelectVarName; if ("filter" in row){ if (row.filter.queryName==data.queryName){ varName=row.filter.filterVarName; } } if (debug) print(par.config,"generateSelectVar: "+data.queryName+"/"+varName+" size "+data.rows.length); let field=getField(par.config,data,varName); if (!field) { print(par.config,"Field "+varName+" not found"); return; } if (debug) print(par.config,"Using field "+field.name); if (!("lookup" in field)){ let entry=data.rows[0]; print(par.config,"Field "+varName+" not a lookup"); //populateSelectNotLookup(data,par,rowId, entry); return; } let config=generateQConfig(field.lookup.queryName); config.schemaName=field.lookup.schemaName; config.success=function(lookupData){populateSelect(lookupData,data,par,rowId)}; //config.success=function(data){selectRowsSuccess(par.config,data)}; config.failure=function(errorObj){selectRowsFailure(par.config,errorObj)}; LABKEY.Query.selectRows(config); if (debug) print(par.config,"generateSelectVar: End"); } function populateSelect(data,selectedData, par, rowId){ //data is the set of lookup entries, selectedData is a subset of entries valued at lookup.keyColumn let debug=true; if (debug) print(par.config,"populateSelect Data: "+data.queryName+" selectedData:"+selectedData.queryName); let row=par.vars[rowId]; let selectId=row.selectId; let varName=row.masterSelectVarName; if ("filter" in row){ varName=row.filter.filterVarName; } let field=getField(par.config,selectedData,varName); let displayColumn=field.lookup.displayColumn; let keyColumn=field.lookup.keyColumn; if (debug){ print(par.config,"Query: "+data.queryName); print(par.config,"ElementId: "+selectId); print(par.config,"keyColumn: "+keyColumn); print(par.config,"displayColumn: "+displayColumn); } let el = document.getElementById(selectId); if (debug) print(par.config,"Element: "+el); for(i = el.options.length; i >= 0; i--) { el.remove(i); } if ("addSelect" in row){ let opt = par.config.document.createElement("option"); opt.text = "<Select>"; opt.value = -1; el.options[0] = opt; } if ("addNewFlag" in row){ let opt = par.config.document.createElement("option"); opt.text = "Add New" opt.value = row.addNewFlag; el.options[el.options.length] = opt; } for (var i = 0; i < data.rows.length; i++) { let key=data.rows[i][keyColumn]; let skip=true; if (row.selectAll){ skip=false; } else{ if (debug) print(par.config,"Selecting from: "+selectedData.rows.length); for (let j=0; j< selectedData.rows.length; j++){ let entry=selectedData.rows[j]; if (debug) print(par.config,"Comparing: "+entry[varName]+"/"+key); if (key!=entry[varName]) continue; skip=false; break; } } if (skip) continue; let opt = par.config.document.createElement("option"); opt.text = data.rows[i][displayColumn]; opt.value = data.rows[i][keyColumn]; if (debug) print(par.config,"Adding: "+opt.value+" : "+opt.text); el.options[el.options.length] = opt; if ("selectedKey" in row){ if (debug) print(par.config,"Comparing: " + opt.value + "/" + row["selectedKey"]); if (opt.value==row["selectedKey"]){ el.selectedIndex=el.options.length-1; if (debug) print(par.config,"Equal; "+el.selectedIndex); } } } if (debug) print(par.config,"Running callback"); row.callback(par,rowId); } function generateListAndPopulateDaughterSelect(par,rowId){ let debug=true; if (debug){ print(par.config,"generateListAndPopulateDaughter"); } generateList(par,rowId); let row=par.vars[rowId]; if ("daughterSelect" in row){ populateDaughterSelect(par,rowId,row["daughterSelect"],null); } } function populateDaughterSelect(par,rowId,daughterRowId,entry){//populateSelectNotLookup let debug=true; if (debug) print(par.config,"populateDaughterSelect: "+rowId+" "+daughterRowId); let row=par.vars[rowId]; if (debug) print(par.config,"row["+rowId+"]:"+row); let daughterRow=par.vars[daughterRowId]; if (debug) print(par.config,"daughterRow["+daughterRowId+"]:"+daughterRow); let el=par.config.document.getElementById(row.selectId); if (debug) print(par.config,"\n Element:"+el); let varValue=el.options[el.selectedIndex].value; if (debug) print(par.config,"\nAdding filter ["+row.masterSelectVarName+"]:"+varValue); let config=generateQConfig(par.masterQuery) config.filterArray=[]; for (let i=0;i < par.filters.length;i++){ let filterRowId=par.filters[i]; let filterRow=par.vars[filterRowId]; let filterValue=par.config.document.getElementById(filterRow.selectId).value; config.filterArray.push(LABKEY.Filter.create(filterRow.masterSelectVarName,filterValue)); } config.success=function(data){populateSelectNotLookup(data,par,daughterRowId,entry)}; LABKEY.Query.selectRows(config); } function populateSelectNotLookup(data,par,rowId, entry){ //selectId //masterSelectVarName let debug=true; if (debug) print(par.config,"populateSelectNonLookup on "+data.queryName); let row=par.vars[rowId]; let varName=row.masterSelectVarName; if (debug) print(par.config,"var "+varName+" rows "+data.rows.length); if (debug) print(par.config,"Getting element "+row.selectId); let el=par.config.document.getElementById(row.selectId); if (!el) { print(par.config,"Element not found"); return; } if (debug) print(par.config,"Element "+el); if (debug) print(par.config,"Clearing entries"); //remove previous options for(i = el.options.length; i >= 0; i--) { el.remove(i); } if (debug) print(par.config,"Adding entries"); if ("addSelect" in row){ if (debug) print(par.config,"adding <Select>"); let opt = par.config.document.createElement("option"); opt.text = "<Select>"; opt.value = -2; el.options[0] = opt; } if ("addNewFlag" in row){ if (debug) print(par.config,"adding Add new"); let opt = par.config.document.createElement("option"); opt.text = "Add New"; opt.value = row.addNewFlag; el.options[el.options.length] = opt; } for (let i=0;i< data.rows.length;i++){ let valEntry=data.rows[i]; if (debug) print(par.config,"adding "+valEntry[varName]); let opt = par.config.document.createElement("option"); opt.text = valEntry[varName]; opt.value = valEntry[varName]; if (entry){ if (opt.value==entry[varName]) el.selectedIndex=el.options.length-1; } el.options[el.options.length] = opt; } if (entry) row.callback(par,rowId); } function generateList(par,rowId){ let row=par.vars[rowId]; let debug=true; if (debug) print(par.config,"generateList: "+par.masterQuery); //ignore authorization, just select on select variable let el=par.config.document.getElementById(row.selectId); let varValue=el.options[el.selectedIndex].value; if (debug) print(par.config,"Using value "+varValue+" from "+row.selectId); let iValue=parseInt(varValue); let div=par.config.document.getElementById(par.addDiv); div.style.display="none"; //add new crf entry if ("addNewFlag" in row){ if (debug) print(par.config,"Comparing " + iValue + "/" + row.addNewFlag); if (iValue==row.addNewFlag) { addNew(par); return; } } //do filtering let filterArray=[]; for (let i=0;i < par.filters.length;i++){ let filterRowId=par.filters[i]; let filterRow=par.vars[filterRowId]; let filterValue=par.config.document.getElementById(filterRow.selectId).value; filterArray.push(LABKEY.Filter.create(filterRow.masterSelectVarName,filterValue)); } //show all for system entries (Select, Add New) if (debug) print(par.config,"Using iValue "+iValue); if (iValue<0) { if (debug) print(par.config,"Ignoring ["+row.masterSelectVarName+ "]: "+varValue); } else{ if (debug) print(par.config,"Filtering ["+row.masterSelectVarName+"]: "+varValue); if (rowId==="Crf"){ filterArray.push(LABKEY.Filter.create(row.masterSelectVarName,varValue)); if (debug) print(par.config,"Filtering ["+row.masterSelectVarName+"]: "+varValue); } } var config=generateQConfig(par.masterQuery); config.renderTo=par.dataDiv; config.buttonBarPosition='top'; config.filters=filterArray; config.viewName="sparseView"; config.success=function(data){updateSuccess(data,par)}; config.failure=function(json){updateFailure(json,par)}; LABKEY.QueryWebPart(config); } function updateSuccess(data,par){ print(par.config,"Update success"); } function updateFailure(json,par){ print(par.config,"Update failed"); } function addNew(par){ print(par.config,"Show Add new"); let div=par.config.document.getElementById(par.addDiv); div.style.display="block"; } function generateButtonRow(tableId,caption,label,par,callback){ let tb=par.config.document.getElementById(tableId); let trow=tb.insertRow(); let cell=par.config.document.createElement('th'); trow.appendChild(cell); let text = par.config.document.createTextNode(caption); cell.appendChild(text); cell=trow.insertCell(); let input = par.config.document.createElement("input"); input.type="button"; input.value=label; input.onclick=function(){callback(par)}; cell.appendChild(input); } //callback candidate function addNewEntry(par){ print(par.config,"Add new, npar "); let entry=new Object(); for (vv in par.vars){ let f=par.vars[vv]; print(par.config,"New: Adding "+f.masterSelectVarName); setValue(entry,f); } for (f in entry){ print(par.config,"entry ["+f+"]="+entry[f]); } entry.entryId=Date.now(); entry.Date=new Date(); entry.formStatus=1;//In Progress let config=generateQConfig(par.masterQuery); config.rows=[entry]; config.success=function(data){ populateDaughterSelect(par,"Site","Crf",data.rows[0]); selectEntry(par.config,data,par.vars["Crf"]); generateList(par,"Crf");}; LABKEY.Query.insertRows(config); }