async function getDynamicJobTable(p) { //if one exists, render a dynamic table let params = p || ''; let m; let previewEnabled = false; let searchTag = ''; let output = ''; if(p.includes('{{job}}')) { searchTag = '{{job}}'; } else if (p.includes('{{invoice}}')) { searchTag = '{{invoice}}'; } if(searchTag=='') { return params; } const regex = new RegExp(searchTag, 'gm'); while ((m = regex.exec(params)) !== null) { // This is necessary to avoid infinite loops with zero-width matches if (m.index === regex.lastIndex) { regex.lastIndex++; } if(job != null) { let data = { rows:job }; let searchable = false; output = '
'; for (let row = 0;row0) { output +=''; if(data.rows[row].hasOwnProperty('pageBreak') && data.rows[row].pageBreak == true) { output +='
'; } } output += ''; } if(data.rows[row].hasOwnProperty('titles') && data.rows[row].titles != null ) { if(data.rows[row].hasOwnProperty('hideTitlesOnSearch') && data.rows[row].hideTitlesOnSearch == true) { output += ''; } else { output += ''; } for(let t=0;t' + data.rows[row].titles[t] + ''; } else { output += ''; } } output +=''; } if(!data.rows[row].hasOwnProperty('cols') || data.rows[row].cols == null) { data.rows[row].cols = [{"ordinal":1,"id":"dummy","fieldType":"display","dataType":"text","value":""}]; } let colCount = 0; if(data.rows[row].hasOwnProperty('cols') && data.rows[row].cols != null) { for(let col = 0;col' + data.rows[row].heading + ''; } if(data.rows[row].hasOwnProperty('subHeading') && data.rows[row].subHeading != null) { if(data.rows[row].hasOwnProperty('hideHeadingOnSearch') && data.rows[row].hideHeadingOnSearch == true) { output += ''; } else { output += ''; } output += ''; } output += ' '') { previewEnabled = true; classStr += 'previewRow '; output += ' data-previewfield="' + data.rows[row].previewField + '"'; } else { classStr += 'hideRowOnPreview '; } if(classStr!="") { output += ' class="' + classStr + '" '; } output += '>'; for(let col = 0;col'; } output +=''; } output += '
' + data.rows[row].subHeading + '
'; } else if(width!='' || align!='') { output += ''; } else { output += ''; } } let id = 'field_' + data.rows[row].cols[col].id + '(' + row.toString() + ')' ; switch(data.rows[row].cols[col].fieldType) { case 'hidden': output += ''; break; case 'markdown': output += marked.parse(data.rows[row].cols[col].value); break; case 'display': if(data.rows[row].cols[col].dataType == 'hidden') { output += ''; } else { if(data.rows[row].cols[col].value.includes('{{') && data.rows[row].cols[col].value.includes('}}')) { let align=""; if(data.rows[row].cols[col].dataType=='decimal') { align = 'style="text-align:right;" '; } else if(data.rows[row].cols[col].dataType == 'integer') { align = 'style="text-align:center;" '; } output += ''; } else { if(data.rows[row].cols[col].dataType=='decimal') { let precision = 2; if(data.rows[row].cols[col].hasOwnProperty('precision')) { precision = parseInt(data.rows[row].cols[col].precision); } output += '' + parseFloat(data.rows[row].cols[col].value).toFixed(precision) + ''; } else { output += '' + data.rows[row].cols[col].value + ''; } } } break; case 'input': let disabled =''; if(data.rows[row].cols[col].hasOwnProperty('disabled') && data.rows[row].cols[col].disabled==true) { disabled=' disabled'; } if(data.rows[row].cols[col].dataType=='list') { output += ''; } else if(data.rows[row].cols[col].dataType=='date') { let minDate = ''; if(data.rows[row].cols[col].hasOwnProperty('data')) { let minMax = data.rows[row].cols[col].data.split('|'); minDate = ' min="' + minMax[0] + '"'; if(minMax.length>1) { minDate += ' max="' + minMax[1] + '"'; } } output += ''; } else if(data.rows[row].cols[col].dataType=='text') { let maxLength = ''; if(data.rows[row].cols[col].hasOwnProperty('maxLength')) { maxLength=' maxlength="' + data.rows[row].cols[col].maxLength + '"'; } output += ''; } else if(data.rows[row].cols[col].dataType=='integer') { output += ''; } else if(data.rows[row].cols[col].dataType=='decimal') { let precision = 2; if(data.rows[row].cols[col].hasOwnProperty('precision')) { precision = parseInt(data.rows[row].cols[col].precision); } if(precision>0) { let v = data.rows[row].cols[col].value; if(v!='') { v = parseFloat(v).toFixed(precision); } output += ''; } else { output += ''; } } else if(data.rows[row].cols[col].dataType=='boolean') { output += ''; } break; } output += '
'; output = output.replaceAll("icon:star",""); if(searchable==true) { let search = ''; output = search + output; } if(jobrecord!=null) { if(jobrecord.hasOwnProperty('ShowButtons') && jobrecord.ShowButtons.S == "1") { output += ' '; output += ''; } } setTimeout(function(){refreshStoredData()},0); setTimeout(function(){ $("#searchFilter").on('keyup', function () { let value = $(this).val().toLowerCase(); if(value!='') { $(".hideRowOnSearch").hide(); $(".hideHeadingOnSearch").hide(); $(".hideTitlesOnSearch").hide(); } else { $(".hideRowOnSearch").show(); $(".hideHeadingOnSearch").show(); $(".hideTitlesOnSearch").show(); } $(".searchRow").each(function () { if ($(this).attr('data-search').toLowerCase().search(value) > -1) { $(this).show(); } else { $(this).hide(); } }); showAllJobTables(); hideTablesWithHiddenRows(); }); },0); if(jobType == 'receipt') { setTimeout(function(){ d_id('formPreview').style.display = 'none'; d_id('formSaveProgress').style.display = 'none'; d_id('formComplete').style.display = 'none'; d_id('formPayWithCard').style.display = 'none'; },500); } else if(jobType == 'invoice') { setTimeout(function(){ d_id('formPreview').style.display = 'none'; d_id('formSaveProgress').style.display = 'none'; d_id('formComplete').style.display = 'none'; d_id('formPayWithCard').style.display = 'inline-block'; },500); } else { if(jobrecord) { setTimeout(function(){ if(previewEnabled) { d_id('formPreview').style.display = 'inline-block' d_id('formComplete').style.display = 'none'; } else { d_id('formPreview').style.display = 'none' d_id('formComplete').style.display = 'inline-block'; } d_id('formSaveProgress').style.display = 'inline-block'; },500); } else { setTimeout(function(){ d_id('formPreview').style.display = 'none'; d_id('formSaveProgress').style.display = 'none'; d_id('formComplete').style.display = 'none'; },500); } setTimeout(function(){ d_id('formPayWithCard').style.display = 'none'; },500); } } else { if(jobtable!='') { output = jobtable; } else { if(searchTag=='{{job}}') { output = 'Form not found or already completed'; } else { output = 'Invoice not found'; } } //kill the complete button setTimeout(function(){ d_id('formSaveProgress').style.display = 'none'; d_id('formPreview').style.display = 'none'; d_id('formComplete').style.display = 'none'; d_id('formPayWithCard').style.display = 'none'; },500); } params = params.replace(m[0],output); } return params; } function refreshStoredData() { if(jobsaved) { for(let i=0;i') != d_id(id).innerHTML) { d_id(id).innerHTML = data.rows[row].cols[col].value.replaceAll('icon:star',''); } } else { if(data.rows[row].cols[col].value != d_id(id).value) { d_id(id).value = data.rows[row].cols[col].value; } } } break; case 'input': if(data.rows[row].cols[col].hasOwnProperty('validation') && data.rows[row].cols[col].validation !=null) { if(data.rows[row].cols[col].dataType=='integer' || data.rows[row].cols[col].dataType=='decimal' || data.rows[row].cols[col].dataType=='boolean') { let val = data.rows[row].cols[col].value.toString(); if(val == 'false' || val == '') { val = '0'; } else if(val == 'true') { val = '1'; } val = val.replace(/[^0-9.]/g,''); if(eval('(' + val + ')' + data.rows[row].cols[col].validation)) { data.rows[row].cols[col].valid=true; } else { data.rows[row].cols[col].valid=false; data.rows[row].valid=false; } } else if(data.rows[row].cols[col].dataType=='text') { //test regex in validation if(RegExp(data.rows[row].cols[col].validation, 'g').test(data.rows[row].cols[col].value)) { data.rows[row].cols[col].valid=true; } else { data.rows[row].cols[col].valid=false; data.rows[row].valid=false; } } else if(data.rows[row].cols[col].dataType=='date') { //test regex in validation if(RegExp(data.rows[row].cols[col].validation, 'g').test(data.rows[row].cols[col].value)) { data.rows[row].cols[col].valid=true; } else { data.rows[row].cols[col].valid=false; data.rows[row].valid=false; } } } break; } } } let valid=true; for (let row = 0;row0) { valid = true; } break; default: if(data.rows[row].cols[col].value!='') { valid = true; } } } } } } } } } } if(valid) { d_id('formComplete').disabled = ''; d_id('formSaveProgress').disabled = ''; d_id('formPreview').disabled = ''; } else { d_id('formComplete').disabled = 'disabled'; d_id('formSaveProgress').disabled = 'disabled'; d_id('formPreview').disabled = 'disabled'; } job = data.rows; } async function getJobAsCSV(csvortab) { let delim = '\t'; if(csvortab == 'csv') { delim = ','; } let csv = ''; let data = {rows:job}; for (let r= 0;r0) { output.rows.push(row); } } return JSON.stringify(output,null,2); } var freeze = ''; var freezeArray = []; function previewJob() { if(d_id('formPreview').innerHTML=='Edit') { d_id('formPreview').innerHTML='Preview >'; d_id('formPreview').setAttribute("class","btn btn-primary"); d_id('searchBar').style.display='flex'; document.getElementById('jobForm').innerHTML = freeze; let controls = document.getElementById('jobForm').querySelectorAll(".form-control,.form-select"); for(let i=0; i0) { flagShow = true; } } controlCollection[i].disabled = 'disabled'; } if(flagShow==true) { $(this).show(); } else { $(this).hide(); } }); hideTablesWithHiddenRows(); } } function showAllJobTables() { let controls = document.getElementById('jobForm').querySelectorAll("table"); for(let i=0;i