Below is a working example of a tool we coded – below that is the code so you can use it on your website as well or custom tailor it!
DTF Sizing & Pricing Calculator
Garment Details
| Size | Qty | Your Cost | Client Price |
|---|---|---|---|
| S | |||
| M | |||
| L | |||
| XL | |||
| 2XL | |||
| 3XL | |||
| 4XL | |||
| 5XL | |||
| 6XL |
⚠️ Advanced Cost Adjustments
Image / Job Name:
Print Breakdown by Location:
Garment Breakdown:
Height:
Width:
Area per Unit: sq ft
Total Print Area: sq ft
Total Print Cost: $
Total Print Charge: $
Total Garment Cost: $
Total Garment Charge: $
Total Garment Qty:
Total Order Cost (Print + Garment): $
Total Client Charge (Print + Garment): $
Estimated Profit: $
Below is the Code Snippet you can use to insert into your site via HTML blocks
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DTF Sizing & Pricing Calculator</title>
<style>
.attention {
color: red;
font-weight: bold;
}
body {
font-family: Arial, sans-serif;
background: #f4f4f4;
padding: 20px;
}
h2 {
text-align: center;
}
.calculator {
background: #fff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
label {
display: block;
margin-top: 15px;
}
input, select {
width: 100%;
padding: 8px;
margin-top: 5px;
border-radius: 4px;
border: 1px solid #ccc;
}
button {
margin-top: 20px;
width: 100%;
padding: 10px;
background-color: #0073aa;
color: #fff;
border: none;
border-radius: 4px;
font-weight: bold;
cursor: pointer;
}
.result {
margin-top: 20px;
padding: 15px;
background-color: #e6ffe6;
border-left: 4px solid #2e7d32;
display: none;
}
.result p {
margin: 6px 0;
}
.add-button-red {
background-color: #dc3545 !important; /* Bootstrap Red */
color: white;
border: none;
padding: 10px 16px;
margin-top: 10px;
font-weight: bold;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
.add-button-red:hover {
background-color: #c82333;
}
</style>
</head>
<body>
<h2>DTF Sizing & Pricing Calculator</h2>
<div class="calculator">
<label>
Image / Job Name:
<input type="text" id="jobName" placeholder="e.g. Window Decal Order">
</label>
<div id="printSections">
<div class="print-section" data-index="1">
<label>
Print Location:
<select class="printLocation">
<option value="Front">Front</option>
<option value="Left Chest">Left Chest</option>
<option value="Right Chest">Right Chest</option>
<option value="Back">Back</option>
<option value="Left Sleeve">Left Sleeve</option>
<option value="Right Sleeve">Right Sleeve</option>
<option value="Other">Other</option>
</select>
</label>
<label>
Width:
<input type="number" class="widthValue" step="0.01">
<select class="widthUnit">
<option value="inches">Inches</option>
<option value="feet">Feet</option>
<option value="yards">Yards</option>
<option value="cm">Centimeters</option>
<option value="meters">Meters</option>
</select>
</label>
<label>
Height:
<input type="number" class="heightValue" step="0.01">
<select class="heightUnit">
<option value="inches">Inches</option>
<option value="feet">Feet</option>
<option value="yards">Yards</option>
<option value="cm">Centimeters</option>
<option value="meters">Meters</option>
</select>
</label>
<label>
Print Cost (Your Supplier Rate):
<input type="number" class="costValue" step="0.01">
<select class="costUnit">
<option value="inches">Per Sq Inch</option>
<option value="feet" selected>Per Sq Foot</option>
<option value="yards">Per Sq Yard</option>
<option value="cm">Per Sq CM</option>
<option value="meters">Per Sq Meter</option>
</select>
</label>
<label>
Print Price (What You Charge Client):
<input type="number" class="priceValue" step="0.01">
<select class="priceUnit">
<option value="inches">Per Sq Inch</option>
<option value="feet" selected>Per Sq Foot</option>
<option value="yards">Per Sq Yard</option>
<option value="cm">Per Sq CM</option>
<option value="meters">Per Sq Meter</option>
</select>
</label>
<label>
Print QTY:
<input type="number" class="qtyValue" value="1" min="1">
</label>
<hr>
</div>
</div>
<!-- Add Button -->
<button type="button" class="add-button-red" onclick="addPrintSection()">Add Print Location</button>
<div id="garmentSections">
<div class="garment-section" data-index="1">
<h3>Garment Details</h3>
<label>
Garment Name / Style / Color:
<input type="text" class="garmentName" placeholder="e.g. Gildan 5000 - White Tee">
</label>
<div style="overflow-x:auto; margin-top: 10px;">
<table style="width:100%; border-collapse: collapse;">
<thead>
<tr>
<th style="text-align:left;">Size</th>
<th>Qty</th>
<th>Your Cost</th>
<th>Client Price</th>
</tr>
</thead>
<tbody>
<tr><td>S</td><td><input type="number" class="garmentQty" data-size="S" value="0" min="0"></td><td><input type="number" class="garmentCost" data-size="S" value="0" step="0.01"></td><td><input type="number" class="garmentPrice" data-size="S" value="0" step="0.01"></td></tr>
<tr><td>M</td><td><input type="number" class="garmentQty" data-size="M" value="0" min="0"></td><td><input type="number" class="garmentCost" data-size="M" value="0" step="0.01"></td><td><input type="number" class="garmentPrice" data-size="M" value="0" step="0.01"></td></tr>
<tr><td>L</td><td><input type="number" class="garmentQty" data-size="L" value="0" min="0"></td><td><input type="number" class="garmentCost" data-size="L" value="0" step="0.01"></td><td><input type="number" class="garmentPrice" data-size="L" value="0" step="0.01"></td></tr>
<tr><td>XL</td><td><input type="number" class="garmentQty" data-size="XL" value="0" min="0"></td><td><input type="number" class="garmentCost" data-size="XL" value="0" step="0.01"></td><td><input type="number" class="garmentPrice" data-size="XL" value="0" step="0.01"></td></tr>
<tr><td>2XL</td><td><input type="number" class="garmentQty" data-size="2XL" value="0" min="0"></td><td><input type="number" class="garmentCost" data-size="2XL" value="0" step="0.01"></td><td><input type="number" class="garmentPrice" data-size="2XL" value="0" step="0.01"></td></tr>
<tr><td>3XL</td><td><input type="number" class="garmentQty" data-size="3XL" value="0" min="0"></td><td><input type="number" class="garmentCost" data-size="3XL" value="0" step="0.01"></td><td><input type="number" class="garmentPrice" data-size="3XL" value="0" step="0.01"></td></tr>
<tr><td>4XL</td><td><input type="number" class="garmentQty" data-size="4XL" value="0" min="0"></td><td><input type="number" class="garmentCost" data-size="4XL" value="0" step="0.01"></td><td><input type="number" class="garmentPrice" data-size="4XL" value="0" step="0.01"></td></tr>
<tr><td>5XL</td><td><input type="number" class="garmentQty" data-size="5XL" value="0" min="0"></td><td><input type="number" class="garmentCost" data-size="5XL" value="0" step="0.01"></td><td><input type="number" class="garmentPrice" data-size="5XL" value="0" step="0.01"></td></tr>
<tr><td>6XL</td><td><input type="number" class="garmentQty" data-size="6XL" value="0" min="0"></td><td><input type="number" class="garmentCost" data-size="6XL" value="0" step="0.01"></td><td><input type="number" class="garmentPrice" data-size="6XL" value="0" step="0.01"></td></tr>
</tbody>
</table>
</div>
<hr>
</div>
</div>
<!-- Add Button -->
<button type="button" class="add-button-red" onclick="addGarmentSection()">Add Another Garment</button>
<div style="border: 2px dashed red; padding: 15px; margin-top: 20px;">
<h3 class="attention">⚠️ Advanced Cost Adjustments</h3>
<!-- Additional Print Supplier Costs -->
<label class="attention">Print Shipping (Your Cost)</label>
<input type="number" id="printShipping" value="0" step="0.01" placeholder="Flat $ amount">
<label class="attention">Print Tax % (Your Cost)</label>
<input type="number" id="printTax" value="0" step="0.1" placeholder="Percent (e.g. 8.5)">
<label class="attention">Transaction Fee Surcharge % (Print Supplier)</label>
<input type="number" id="printTransactionFee" value="0" step="0.1" placeholder="Percent (e.g. 3)">
<!-- Garment Supplier Costs -->
<label class="attention">Garment Shipping (Your Cost)</label>
<input type="number" id="garmentShipping" value="0" step="0.01" placeholder="Flat $ amount">
<label class="attention">Garment Tax % (Your Cost)</label>
<input type="number" id="garmentTax" value="0" step="0.1" placeholder="Percent (e.g. 8.5)">
<label class="attention">Garment Transaction Fee % (Your Cost)</label>
<input type="number" id="garmentTransactionFee" value="0" step="0.1" placeholder="Percent (e.g. 3)">
<!-- Client Charges -->
<label class="attention">Client Shipping Fee</label>
<input type="number" id="clientShippingFee" value="0" step="0.01" placeholder="Flat $ amount">
<label class="attention">Client Sales Tax %</label>
<input type="number" id="clientTax" value="0" step="0.1" placeholder="Percent (e.g. 6.75)">
<label class="attention">Client Transaction Fee % (Optional)</label>
<input type="number" id="clientSurcharge" value="0" step="0.1" placeholder="Percent (e.g. 3)">
</div>
<label class="attention">Actual Shipping to Client (UPS/FedEx/USPS)</label>
<input type="number" id="actualShippingToClient" value="0" step="0.01" placeholder="Flat $ amount">
<button onclick="calculate()">Calculate</button>
<div class="result" id="resultBox">
<p><strong>Image / Job Name:</strong> <span id="outJob"></span></p>
<p><strong>Print Breakdown by Location:</strong></p>
<pre id="printBreakdownText" style="background: #eef; padding: 10px; white-space: pre-wrap;"></pre>
<p><strong>Garment Breakdown:</strong></p>
<pre id="garmentBreakdownText" style="background: #ffe; padding: 10px; white-space: pre-wrap;"></pre>
<p><strong>Height:</strong> <span id="outHeight"></span></p>
<p><strong>Width:</strong> <span id="outWidth"></span></p>
<p><strong>Area per Unit:</strong> <span id="areaUnit"></span> sq ft</p>
<p><strong>Total Print Area:</strong> <span id="areaTotal"></span> sq ft</p>
<p><strong>Total Print Cost:</strong> $<span id="outPrintCost"></span></p>
<p><strong>Total Print Charge:</strong> $<span id="outPrintPrice"></span></p>
<hr>
<p><strong>Total Garment Cost:</strong> $<span id="outGarmentCost"></span></p>
<p><strong>Total Garment Charge:</strong> $<span id="outGarmentPrice"></span></p>
<p><strong>Total Garment Qty:</strong> <span id="outGarmentQty"></span></p>
<hr>
<p><strong>Total Order Cost (Print + Garment):</strong> $<span id="costTotal"></span></p>
<p><strong>Total Client Charge (Print + Garment):</strong> $<span id="priceTotal"></span></p>
<p><strong>Estimated Profit:</strong> $<span id="profit"></span></p>
<!-- Dynamically injected adjusted cost outputs go here -->
<div id="adjustedCostsBox"></div>
</div>
<script>
let printSectionIndex = 1;
function addPrintSection() {
printSectionIndex++;
const printSections = document.getElementById('printSections');
const firstSection = printSections.querySelector('.print-section');
const newSection = firstSection.cloneNode(true);
// Reset inputs inside clone
newSection.setAttribute('data-index', printSectionIndex);
newSection.querySelectorAll('input').forEach(input => input.value = input.type === "number" ? 0 : "");
newSection.querySelectorAll('select').forEach(select => {
if (select.classList.contains('priceUnit') || select.classList.contains('costUnit')) {
select.value = 'feet'; // default to Per Sq Ft
} else {
select.selectedIndex = 0;
}
});
printSections.appendChild(newSection);
}
function convertToSqFt(value, unit) {
const unitMap = {
inches: value => (value / 12),
feet: value => value,
yards: value => (value * 3),
cm: value => (value / 30.48),
meters: value => (value * 3.28084)
};
return unitMap[unit](value);
}
function convertRateToSqFt(rate, unit) {
const conversion = {
inches: 144,
feet: 1,
yards: 1/9,
cm: 929.03,
meters: 10.7639
};
return rate / conversion[unit];
}
//Garment Script
function addGarmentSection() {
const sections = document.querySelectorAll('.garment-section');
const last = sections[sections.length - 1];
const clone = last.cloneNode(true);
// Clear all inputs inside the clone
clone.querySelectorAll('input').forEach(input => {
if (input.type === "number") input.value = 0;
else input.value = "";
});
document.getElementById('garmentSections').appendChild(clone);
}
function calculate() {
const jobName = document.getElementById('jobName').value || 'Untitled Job';
let totalPrintCost = 0;
let totalPrintPrice = 0;
let printBreakdown = "";
const printSections = document.querySelectorAll('.print-section');
printSections.forEach((section, i) => {
const location = section.querySelector('.printLocation').value;
const hVal = parseFloat(section.querySelector('.heightValue').value);
const hUnit = section.querySelector('.heightUnit').value;
const wVal = parseFloat(section.querySelector('.widthValue').value);
const wUnit = section.querySelector('.widthUnit').value;
const printQty = parseInt(section.querySelector('.qtyValue').value);
const price = parseFloat(section.querySelector('.priceValue').value);
const priceUnit = section.querySelector('.priceUnit').value;
const cost = parseFloat(section.querySelector('.costValue').value);
const costUnit = section.querySelector('.costUnit').value;
if (isNaN(hVal) || isNaN(wVal) || isNaN(printQty) || isNaN(price) || isNaN(cost)) {
alert(`Please fill in all print fields for section ${i + 1}.`);
return;
}
const hFeet = convertToSqFt(hVal, hUnit);
const wFeet = convertToSqFt(wVal, wUnit);
const areaPerUnit = hFeet * wFeet;
const totalArea = areaPerUnit * printQty;
const pricePerSqFt = convertRateToSqFt(price, priceUnit);
const costPerSqFt = convertRateToSqFt(cost, costUnit);
const sectionPrintPrice = totalArea * pricePerSqFt;
const sectionPrintCost = totalArea * costPerSqFt;
totalPrintPrice += sectionPrintPrice;
totalPrintCost += sectionPrintCost;
printBreakdown += `➤ Location: ${location}\n`;
printBreakdown += `Area: ${totalArea.toFixed(2)} sq ft\n`;
printBreakdown += `Cost: $${sectionPrintCost.toFixed(2)}\n`;
printBreakdown += `Charge: $${sectionPrintPrice.toFixed(2)}\n\n`;
});
// Garment Breakdown Logic Section
let totalGarmentQty = 0;
let totalGarmentCost = 0;
let totalGarmentCharge = 0;
let garmentBreakdown = '';
const garmentSections = document.querySelectorAll('.garment-section');
garmentSections.forEach((section, index) => {
const name = section.querySelector('.garmentName').value || `Garment #${index + 1}`;
const sizeInputs = section.querySelectorAll('.garmentQty');
const costInputs = section.querySelectorAll('.garmentCost');
const chargeInputs = section.querySelectorAll('.garmentPrice');
let subQty = 0;
let subCost = 0;
let subCharge = 0;
garmentBreakdown += `► Garment: ${name}\n`;
sizeInputs.forEach((input, i) => {
const size = input.dataset.size;
const qty = parseInt(input.value) || 0;
const cost = parseFloat(costInputs[i].value) || 0;
const charge = parseFloat(chargeInputs[i].value) || 0;
if (qty > 0) {
garmentBreakdown += ` • ${size}: ${qty} @ $${cost.toFixed(2)} | $${charge.toFixed(2)}\n`;
subQty += qty;
subCost += qty * cost;
subCharge += qty * charge;
}
});
garmentBreakdown += ` Total Qty: ${subQty}\n`;
garmentBreakdown += ` Total Cost: $${subCost.toFixed(2)}\n`;
garmentBreakdown += ` Total Charge: $${subCharge.toFixed(2)}\n\n`;
// 👇 Add these 3 lines here
totalGarmentQty += subQty;
totalGarmentCost += subCost;
totalGarmentCharge += subCharge;
});
// --- Advanced Cost Adjustments ---
// PRINT SUPPLIER Cost Adjustments
const printShipping = parseFloat(document.getElementById('printShipping')?.value || 0);
const printTax = parseFloat(document.getElementById('printTax')?.value || 0);
const printTransactionFee = parseFloat(document.getElementById('printTransactionFee')?.value || 0);
const printTaxAmount = (totalPrintCost * printTax) / 100;
const printFeeAmount = (totalPrintCost * printTransactionFee) / 100;
const adjustedTotalPrintCost = totalPrintCost + printShipping + printTaxAmount + printFeeAmount;
// GARMENT SUPPLIER Cost Adjustments
const garmentShipping = parseFloat(document.getElementById('garmentShipping')?.value || 0);
const garmentTaxPercent = parseFloat(document.getElementById('garmentTax')?.value || 0);
const garmentFeePercent = parseFloat(document.getElementById('garmentTransactionFee')?.value || 0);
const garmentTaxAmount = (totalGarmentCost * garmentTaxPercent) / 100;
const transactionFeeAmountSupplier = ((totalGarmentCost + totalPrintCost) * garmentFeePercent) / 100;
const adjustedTotalGarmentCost = totalGarmentCost + garmentShipping + garmentTaxAmount + transactionFeeAmountSupplier;
// CLIENT-SIDE Adjustments
const clientShippingFee = parseFloat(document.getElementById('clientShippingFee')?.value || 0);
const clientTaxPercent = parseFloat(document.getElementById('clientTax')?.value || 0);
const clientSurchargePercent = parseFloat(document.getElementById('clientSurcharge')?.value || 0);
const subtotalForCustomer = totalPrintPrice + totalGarmentCharge;
const clientTaxAmount = (subtotalForCustomer * clientTaxPercent) / 100;
const clientSurchargeAmount = (subtotalForCustomer * clientSurchargePercent) / 100;
const adjustedTotalPrintPrice = totalPrintPrice; // currently unchanged
const adjustedTotalGarmentCharge = totalGarmentCharge + clientShippingFee + clientTaxAmount + clientSurchargeAmount;
// FINAL TOTALS (Unadjusted)
const totalCost = totalPrintCost + totalGarmentCost;
const totalCharge = totalPrintPrice + totalGarmentCharge;
const profit = totalCharge - totalCost;
// Get actual shipping to client value
const actualShippingToClient = parseFloat(document.getElementById('actualShippingToClient')?.value || 0);
// FINAL TOTALS (Adjusted)
const totalCostAdjusted = adjustedTotalPrintCost + adjustedTotalGarmentCost + actualShippingToClient;
const totalChargeAdjusted = adjustedTotalPrintPrice + adjustedTotalGarmentCharge;
const profitAdjusted = totalChargeAdjusted - totalCostAdjusted;
// Output
//copy breakdown style for each garment to match print location breakdowns
document.getElementById('outJob').innerText = jobName;
document.getElementById('garmentBreakdownText').innerHTML = garmentBreakdown
.split('\n\n')
.map(block => {
const lines = block.trim().split('\n');
const title = lines[0].replace('➤ ', '');
const body = lines.slice(1).join('\n');
return `<details><summary><strong>${title}</strong></summary><pre>${body}</pre></details>`;
})
.join('');
document.getElementById('outWidth').innerText = 'Multiple';
document.getElementById('outHeight').innerText = 'Multiple';
document.getElementById('areaUnit').innerText = 'N/A';
document.getElementById('areaTotal').innerText = totalPrintPrice > 0 ? totalPrintPrice.toFixed(2) : '-';
document.getElementById('outPrintCost').innerText = totalPrintCost.toFixed(2);
document.getElementById('outPrintPrice').innerText = totalPrintPrice.toFixed(2);
document.getElementById('outGarmentQty').innerText = totalGarmentQty;
document.getElementById('outGarmentCost').innerText = totalGarmentCost.toFixed(2);
document.getElementById('outGarmentPrice').innerText = totalGarmentCharge.toFixed(2);
document.getElementById('costTotal').innerText = totalCost.toFixed(2);
document.getElementById('priceTotal').innerText = totalCharge.toFixed(2);
document.getElementById('profit').innerText = profit.toFixed(2);
document.getElementById('printBreakdownText').innerText = printBreakdown.trim();
// Calculate adjusted totals
const trueTotalCost = totalCost + garmentShipping + garmentTaxAmount + transactionFeeAmountSupplier;
const trueTotalCharge = totalCharge + clientShippingFee + clientTaxAmount + clientSurchargeAmount;
const trueProfit = trueTotalCharge - trueTotalCost;
// Build updated Adjusted Cost Output in proper order
const supplierCostsHTML = `
<hr>
<h4>Supplier-Side Cost Adjustments:</h4>
<p><strong>Print Shipping:</strong> $${printShipping.toFixed(2)}</p>
<p><strong>Print Tax:</strong> $${printTaxAmount.toFixed(2)}</p>
<p><strong>Print Transaction Fee:</strong> $${printFeeAmount.toFixed(2)}</p>
<p><strong>Garment Shipping:</strong> $${garmentShipping.toFixed(2)}</p>
<p><strong>Garment Tax:</strong> $${garmentTaxAmount.toFixed(2)}</p>
<p><strong>Garment Transaction Fee:</strong> $${transactionFeeAmountSupplier.toFixed(2)}</p>
`;
const clientCostsHTML = `
<h4>Customer-Side Charge Adjustments:</h4>
<p><strong>Client Shipping Fee:</strong> $${clientShippingFee.toFixed(2)}</p>
<p><strong>Client Tax:</strong> $${clientTaxAmount.toFixed(2)}</p>
<p><strong>Client Surcharge:</strong> $${clientSurchargeAmount.toFixed(2)}</p>
`;
const adjustedTotalsHTML = `
<hr>
<p><strong>Adjusted Totals (Including Supplier & Client Adjustments):</strong></p>
<p><strong>Adjusted Order Cost (Print + Garment + Supplier Costs + Your Shipping):</strong> $${totalCostAdjusted.toFixed(2)}</p>
<p><strong>Adjusted Client Charge (Print + Garment + Client Costs):</strong> $${totalChargeAdjusted.toFixed(2)}</p>
<p><strong>Adjusted Profit:</strong> $${profitAdjusted.toFixed(2)}</p>
`;
// Append cleanly in correct order
document.getElementById('adjustedCostsBox').innerHTML = supplierCostsHTML + clientCostsHTML + adjustedTotalsHTML;
document.getElementById('resultBox').style.display = 'block';
// Optional: print breakdown to console or alert (add below if desired)
console.log(printBreakdown);
}
</script>
</body>
</html>JavaScript