Federal Acquisition Regulation (FAR) Clause Matrix

Federal Acquisition Regulation (FAR) Clause Matrix

Contract X-2025-A Clause Matrix

Clause No. Title/Subject Applicable? Flow-Down Required Special Requirements/Notes

Project Information

Add New FAR Clause

Current Clauses

No FAR clauses added yet.

"; } appState.clauses.forEach(function(clause) { var item = document.createElement("div"); item.className = "far-clause-item"; item.innerHTML = ` ${clause.no}: ${clause.title.substring(0, 50)}... `; clauseList.appendChild(item); }); } function renderDashboardTab() { projectTitleDisplay.textContent = appState.projectName; // Filters var flowdownFilter = filterFlowdownSelect.value; var statusFilter = filterStatusSelect.value; var filteredClauses = appState.clauses.filter(function(clause) { var flowdownMatch = flowdownFilter === 'all' || clause.flowdown === flowdownFilter; var statusMatch = statusFilter === 'all' || clause.special === statusFilter; return flowdownMatch && statusMatch; }); // Render Table tableBody.innerHTML = ""; if (filteredClauses.length === 0) { tableBody.innerHTML = "No clauses match the current filters."; return; } filteredClauses.forEach(function(clause) { var tr = document.createElement("tr"); var applicableClass = clause.applicable === 'Yes' ? 'far-yes' : 'far-no'; var flowdownClass = clause.flowdown === 'Yes' ? 'far-yes' : 'far-no'; var specialClass = clause.notes.trim() ? 'far-yes' : 'far-no'; tr.innerHTML = ` ${clause.no} ${clause.title} ${clause.applicable} ${clause.flowdown} ${clause.notes} `; tableBody.appendChild(tr); }); } // --- Event Handlers --- // Update Dashboard Button updateBtn.addEventListener("click", function() { appState.projectName = projectNameInput.value || "Untitled Contract Matrix"; saveState(); renderDashboardTab(); showTab(0); }); // Add Clause addClauseForm.addEventListener("click", function(e) { if (e.target.id === 'far-add-clause-btn') { var no = clauseNoInput.value.trim(); var title = clauseTitleInput.value.trim(); var applicable = applicableSelect.value; var flowdown = flowdownSelect.value; var notes = notesInput.value.trim(); if (!no || !title) { alert("Please enter both the Clause Number and Title."); return; } var newId = appState.clauses.length > 0 ? appState.clauses[appState.clauses.length - 1].id + 1 : 1; var newClause = { id: newId, no: no, title: title, applicable: applicable, flowdown: flowdown, notes: notes, special: notes ? "Yes" : "No" }; appState.clauses.push(newClause); saveState(); renderConfigTab(); // Clear form (except selects) clauseNoInput.value = ""; clauseTitleInput.value = ""; notesInput.value = ""; } }); // Remove Clause (Event Delegation) toolContainer.addEventListener("click", function(e) { if (e.target.classList.contains("far-remove-btn")) { var id = parseInt(e.target.dataset.id); appState.clauses = appState.clauses.filter(function(clause) { return clause.id !== id; }); saveState(); renderConfigTab(); } }); // Filters Change filterFlowdownSelect.addEventListener("change", renderDashboardTab); filterStatusSelect.addEventListener("change", renderDashboardTab); // --- PDF Download --- pdfBtn.addEventListener("click", function() { var jsPDF = window.jspdf.jsPDF; var titleSlug = projectNameInput.value.replace(/[^a-zA-Z0-9\s]/g, '').replace(/\s/g, '_').substring(0, 30) || 'FAR_Matrix'; var fileName = `${titleSlug}.pdf`; // Temporarily adjust minimum table width for PDF quality var table = document.getElementById('far-matrix-table'); var originalMinWidth = table.style.minWidth; table.style.minWidth = '1200px'; // Hide filters for PDF var filtersDiv = toolContainer.querySelector('.far-filters'); var filtersDisplayStyle = filtersDiv.style.display; filtersDiv.style.display = 'none'; html2canvas(exportArea, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }).then(function(canvas) { // Restore styles table.style.minWidth = originalMinWidth; filtersDiv.style.display = filtersDisplayStyle; var imgData = canvas.toDataURL('image/png'); var doc = new jsPDF({ orientation: 'l', // Landscape is better for wide tables unit: 'pt', format: 'a3' // Use A3 for maximum table fit }); var pdfWidth = doc.internal.pageSize.getWidth(); var pdfHeight = doc.internal.pageSize.getHeight(); var imgProps = doc.getImageProperties(imgData); var imgWidth = imgProps.width; var imgHeight = imgProps.height; var margin = 40; var usableWidth = pdfWidth - (2 * margin); var ratio = usableWidth / imgWidth; var scaledHeight = imgHeight * ratio; // Handle multi-page if content exceeds page height if (scaledHeight > pdfHeight - (2 * margin)) { var pageHeight = pdfHeight - (2 * margin); var heightLeft = scaledHeight; var position = 0; while (heightLeft > 0) { doc.addImage(imgData, 'PNG', margin, position + margin, usableWidth, scaledHeight); heightLeft -= pageHeight; position -= pageHeight; if (heightLeft > 0) { doc.addPage(); } } } else { // Single page doc.addImage(imgData, 'PNG', margin, margin, usableWidth, scaledHeight); } doc.save(fileName); }).catch(function(err) { // Restore styles even if PDF fails table.style.minWidth = originalMinWidth; filtersDiv.style.display = filtersDisplayStyle; console.error("FAR PDF Error:", err); // alert("An error occurred while generating the PDF."); // Per spec }); }); // --- Local Storage --- function saveState() { try { localStorage.setItem("farAppState", JSON.stringify(appState)); } catch (e) { console.warn("FAR: Could not save state."); } } function loadState() { try { var storedState = localStorage.getItem("farAppState"); if (storedState) appState = JSON.parse(storedState); } catch (e) { console.warn("FAR: Could not load state."); } } // --- Initial Load --- loadState(); renderConfigTab(); renderDashboardTab(); showTab(0); });
Scroll to Top