Need a quick way to quote snow plowing jobs or other snow removal services you offer? Use our calculator below to quote the price of your next snow removal and add on services like car-clearing, salting, walkway shoveling, and more!
input, select{border: 1px solid black; text-align: center;} select{background-color: #f0f0f0;}
Driveway Size (how many total car-spaces):
Price per car-space:
(in Dollars)
Add-on Services:
Add Service
Total Quote:
Total: $0.00
OPTIONAL: Brand your quote:
Company Name:
Contact Email:
Export Quote as TXT File
let customServices = [];
function addCustomService() {
const serviceDiv = document.createElement("div");
const serviceNameInput = document.createElement("input");
serviceNameInput.setAttribute("type", "text");
serviceNameInput.setAttribute("placeholder", "Service name");
const servicePriceInput = document.createElement("input");
servicePriceInput.setAttribute("type", "number");
servicePriceInput.setAttribute("placeholder", "Service price");
const priceTypeSelect = document.createElement("select");
priceTypeSelect.innerHTML = `Price per car-space
Flat rate`;
serviceDiv.appendChild(serviceNameInput);
serviceDiv.appendChild(servicePriceInput);
serviceDiv.appendChild(priceTypeSelect);
document.getElementById("customServices").appendChild(serviceDiv);
// Add event listener to update the total when a new service is added
serviceNameInput.addEventListener("input", updateTotal);
servicePriceInput.addEventListener("input", updateTotal);
priceTypeSelect.addEventListener("input", updateTotal);
}
function updateTotal() {
const lawnSize = parseFloat(document.getElementById("lawnSize").value) || 0;
const mowingPrice = parseFloat(document.getElementById("mowingPrice").value) || 0;
const customServiceTotal = Array.from(document.querySelectorAll("#customServices div")).reduce((total, serviceDiv) => {
const serviceName = serviceDiv.querySelector("input[type='text']").value;
const servicePrice = parseFloat(serviceDiv.querySelector("input[type='number']").value) || 0;
const priceType = serviceDiv.querySelector("select").value;
if (priceType === "sqft") {
total += lawnSize * servicePrice;
} else {
total += servicePrice;
}
return total;
}, 0);
const total = lawnSize * mowingPrice + customServiceTotal;
document.getElementById("totalQuote").textContent = `Total: $${total.toFixed(2)}`;
}
function exportQuote() {
const lawnSize = parseFloat(document.getElementById("lawnSize").value) || 0;
const mowingPrice = parseFloat(document.getElementById("mowingPrice").value) || 0;
const customServices = Array.from(document.querySelectorAll("#customServices div")).map(serviceDiv => {
const serviceName = serviceDiv.querySelector("input[type='text']").value;
const servicePrice = parseFloat(serviceDiv.querySelector("input[type='number']").value) || 0;
const priceType = serviceDiv.querySelector("select").value;
return `${serviceName} - $${servicePrice.toFixed(2)} (${priceType === "sqft" ? "per car-space" : "flat rate"})`;
});
const companyName = document.getElementById("companyName").value;
const contactEmail = document.getElementById("contactEmail").value;
// Calculate the total before appending it to quoteText
const total = lawnSize * mowingPrice + customServices.reduce((sum, service) => {
const servicePrice = parseFloat(service.split('$')[1]);
return sum + servicePrice;
}, 0);
let quoteText = `Approx. Driveway Size: ${lawnSize} car-spaces\nPlowing Rate: $${mowingPrice.toFixed(2)} per car-space\nPlowing Cost: $${(lawnSize * mowingPrice).toFixed(2)}\n\nAdditional Services:\n${customServices.join('\n')}\n\nTotal: $${total.toFixed(2)}\n\n`;
if (companyName) {
quoteText += `Quoted By: ${companyName}\n`;
}
if (contactEmail) {
quoteText += `Contact Email: ${contactEmail}\n`;
}
const blob = new Blob([quoteText], { type: "text/plain" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "SnowRemovalQuote.txt";
a.click();
}
document.getElementById("lawnSize").addEventListener("input", updateTotal);
document.getElementById("mowingPrice").addEventListener("input", updateTotal);