Advanced Concrete Calculator: Estimate Volume, Bags & Total Cost Concrete Calculator - Slabs, Walls, Columns, Stairs & Curbs
Slabs Calculator
Walls & Footings
Columns & Holes
Stairs Calculator
Curbs & Gutters
Cost Calculator
Material Density Optional: You can enter wet concrete density to get a more accurate weight estimate. All other results like volume, bags, mix breakdown, and cost remain unchanged.
Concrete Slab Calculator How to Use Concrete Slab Estimator To use the concrete slab calculator, first select the slab shape: square/rectangular, tube, or round. Enter the slab dimensions, such as length, width, thickness, or diameter, and choose your unit like meters, feet, or yards. You can optionally select a concrete grade and add a wastage allowance of 3–8% to account for small losses. If desired, enter the concrete price to see the total cost. Click calculate, and the concrete slab estimator will show the concrete volume in cubic meters, cubic feet, and cubic yards, weight in kilograms, tons, and pounds, the number of concrete bags needed, and the estimated amount of materials like cement, sand, gravel, and water.
Floor Slab Measurement Example You want a rectangular floor slab 5 meters long, 4 meters wide, and 0.15 meters thick. Select square/rectangular, enter the dimensions, and add 5% wastage. After calculation, the tool shows the volume as 3.15 m³, the required weight, total concrete bags, estimated material amounts for cement, sand, gravel, and water, and the total cost if a price is entered. This gives a complete overview of everything you need before starting the project.
Square / Rectangle
Round
Tube
Concrete Walls & Footings Calculator How to Use Concrete Footing Calculator To use the wall and concrete footing calculator, start by selecting whether you are calculating for a wall or a footing. Enter the dimensions required for your structure: length, height, and thickness for a wall, or length, width, and depth for a footing, and choose your preferred unit like meters, feet, or yards. Optionally, select the concrete grade and add a wastage percentage between 3% and 8% to ensure enough material is available.
You can also provide the concrete price to estimate total cost. Click calculate, and the figuring concrete tool will display the concrete volume in cubic meters, cubic feet, and cubic yards, the weight in kilograms, tons, and pounds, the number of concrete bags required, and the estimated quantities of cement, sand, gravel, and water.
Footing Calculator Usage Example You are building a footing 10 meters long, 0.6 meters wide, and 0.4 meters deep. Select footing, enter the dimensions, and include 5% wastage. After calculation, the tool shows the total concrete needed, the corresponding weight, required bags, material breakdown for cement, sand, gravel, and water, and the estimated cost. This helps you plan all materials efficiently before starting construction.
Concrete Column & Hole Calculator How to Use Concrete Column Calculator To use the column and hole calculator, first choose the shape you need, such as a round column or a circular hole. Enter the measurements like height and diameter, and select your preferred unit: meters, feet, or yards. You can optionally select a concrete grade and add a wastage allowance of 3%-8% for extra safety. If you want, enter the concrete price to get the total cost. Click calculate, and the tool will provide the concrete volume in cubic meters, cubic feet, and cubic yards, the weight in kilograms, tons, and pounds, the number of concrete bags required, and estimated amounts of cement, sand, gravel, and water.
Example of Using the Hole Calculator You need to fill 20 round columns, each 3 meters tall with a diameter of 0.3 meters. Select a round column, enter the height and diameter, and add 5% wastage. After calculation, the tool shows the concrete volume for one column, total volume for 20 columns, the corresponding weight, number of bags, material breakdown for cement, sand, gravel, and water, and total cost. This ensures you know exactly how much material is needed for all columns or circular holes before starting the project.
Round Column
Square Column
Concrete Stairs Calculator How to Concrete Steps Calculator The concrete stairs calculator helps you determine exactly how much material is needed for staircases of any shape. Start by entering the total width, height, and depth of the stairs, along with the number of steps, and select your preferred unit such as meters, feet, or yards. You can optionally choose a concrete grade and add a wastage allowance of 3–8% to cover minor losses during pouring. If you want, enter the concrete price to get an estimated cost. Click calculate, and the tool will display the concrete volume in cubic meters, cubic feet, and cubic yards, the weight in kilograms, tons, and pounds, required concrete bags, and the estimated amounts of cement, sand, gravel, and water.
Stairs Calculator Usage Example You are building a staircase 4 meters wide, 3 meters high, and 0.2 meters deep with 15 steps. Enter the dimensions, number of steps, and a 5% wastage allowance. After calculation, the tool provides the total concrete volume for the stairs, weight, number of bags, material breakdown for cement, sand, gravel, and water, and total cost. This allows you to plan and order materials accurately before starting the stair construction.
Concrete Curbs & Gutter Barrier Calculator How to Use Concrete Curb Calculator The concrete curbs and gutters calculator helps you quickly determine how much material is needed for road edges, sidewalks, or drainage channels. Enter the total length, width, and height (or depth) of the curb or gutter and select your preferred unit, such as meters, feet, or yards. Optionally, you can choose a concrete grade and add a wastage allowance between 3–8% to account for small losses during pouring. If desired, enter the concrete price to calculate the total cost. Click calculate, and the tool shows the concrete volume in cubic meters, cubic feet, and cubic yards, the weight in kilograms, tons, and pounds, required concrete bags, and estimated amounts of cement, sand, gravel, and water.
Gutter Calculator Usage Example You are building a gutter 50 meters long, 0.3 meters wide, and 0.2 meters deep. Enter these dimensions and add a 5% wastage allowance. After calculation, the tool provides the total concrete volume, weight, number of bags, material breakdown for cement, sand, gravel, and water, and total cost. This ensures accurate material planning before starting the curb or gutter project.
Concrete Cost Calculator To estimate the cost of concrete, you first need to calculate the total volume required, which can be done easily using the concrete calculator.
After that, choose your country and enter the local prices of cement, sand, aggregate, and water into the provided fields. Once all values are added, click the Calculate Cost button.
The tool will instantly provide an estimate of the total material cost required for your concrete mix.
Simply copy and paste this code into your website HTML.
');
}function exportText(containerId) {
const el = document.getElementById(containerId);
const data = el.dataset.resultData ? JSON.parse(el.dataset.resultData) : null;
if (!data) return;
const txt = `${data.calcName} - Concrete Calculator Results\n${'='.repeat(50)}\nVolume: ${formatNum(data.volWithWaste)} ft³ (${formatNum(data.volYd3)} yd³)\nWeight: ${formatNum(data.weightLb)} lb (${formatNum(data.weightTons)} tons)\nBags: 40lb: ${data.bags[40]}, 60lb: ${data.bags[60]}, 80lb: ${data.bags[80]}\n${data.cost ? `Total Cost: $${formatNum(data.cost)} USD\n` : ''}`;
const a = document.createElement('a');
a.href = 'data:text/plain;charset=utf-8,' + encodeURIComponent(txt);
a.download = 'concrete-results.txt';
a.click();
}function exportPDF(containerId) {
window.print();
}// Tab switching
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.addEventListener('click', () => {
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
btn.classList.add('active');
document.getElementById(btn.dataset.tab).classList.add('active');
});
});// Slabs shape selector + diagram and Width-required logic
let slabsShape = 'rectangle';
const slabsWidthGroup = document.getElementById('slabs-width-group');
const slabsWidthInput = document.getElementById('slabs-width');
const slabsWidthLabel = document.getElementById('slabs-width-label');
const slabsLengthLabel = document.getElementById('slabs-length-label');
const slabsThicknessLabel = document.getElementById('slabs-thickness-label');
const slabsRebarSection = document.getElementById('slabs-rebar-section');function updateSlabsDiagram() {
const diagramRect = document.getElementById('slabs-diagram-rectangle');
const diagramRound = document.getElementById('slabs-diagram-round');
const diagramTube = document.getElementById('slabs-diagram-tube');
if (!diagramRect || !diagramRound || !diagramTube) return;
diagramRect.classList.toggle('hidden', slabsShape !== 'rectangle');
diagramRound.classList.toggle('hidden', slabsShape !== 'round');
diagramTube.classList.toggle('hidden', slabsShape !== 'tube');
}function updateSlabsLabelsAndRequirements() {
if (slabsShape === 'rectangle') {
slabsLengthLabel.innerHTML = ' Length';
slabsWidthLabel.innerHTML = ' Width';
slabsThicknessLabel.innerHTML = ' Thickness';
slabsWidthGroup.classList.remove('hidden');
slabsWidthInput.required = true;
if (slabsRebarSection) slabsRebarSection.classList.remove('hidden');
} else if (slabsShape === 'round') {
slabsLengthLabel.innerHTML = ' Diameter';
slabsThicknessLabel.innerHTML = ' Depth (Thickness)';
slabsWidthGroup.classList.add('hidden');
slabsWidthInput.required = false;
if (slabsRebarSection) slabsRebarSection.classList.add('hidden');
} else if (slabsShape === 'tube') {
slabsLengthLabel.innerHTML = ' Outer Diameter';
slabsWidthLabel.innerHTML = ' Inner Diameter';
slabsThicknessLabel.innerHTML = ' Depth (Height)';
slabsWidthGroup.classList.remove('hidden');
slabsWidthInput.required = true;
if (slabsRebarSection) slabsRebarSection.classList.add('hidden');
}
}document.querySelectorAll('#slabs .shape-option').forEach(opt => {
opt.addEventListener('click', () => {
document.querySelectorAll('#slabs .shape-option').forEach(o => o.classList.remove('selected'));
opt.classList.add('selected');
slabsShape = opt.dataset.shape;
updateSlabsLabelsAndRequirements();
updateSlabsDiagram();
});
});
updateSlabsLabelsAndRequirements();
updateSlabsDiagram();// Slabs form (correct square, round and tube logic)
document.getElementById('slabs-form').addEventListener('submit', e => {
e.preventDefault();
const len = toFeet(parseFloat(document.getElementById('slabs-length').value) || 0, document.getElementById('slabs-length-unit').value);
const w = toFeet(parseFloat(document.getElementById('slabs-width').value) || 0, document.getElementById('slabs-width-unit').value);
const thick = toFeet(parseFloat(document.getElementById('slabs-thickness').value) || 0, document.getElementById('slabs-thickness-unit').value);
const qty = parseInt(document.getElementById('slabs-qty').value) || 1;let volFt3 = 0;
if (slabsShape === 'rectangle') {
volFt3 = len * w * thick * qty;
} else if (slabsShape === 'round') {
const d = len;
const depth = thick;
volFt3 = Math.PI * (d / 2) ** 2 * depth * qty;
} else if (slabsShape === 'tube') {
const outerD = len;
const innerD = w;
const depth = thick;
const outerR = outerD / 2;
const innerR = innerD / 2;
volFt3 = Math.PI * (outerR * outerR - innerR * innerR) * depth * qty;
}let rebarEstimate = null;
if (slabsShape === 'rectangle') {
const spVal = parseFloat(document.getElementById('slabs-rebar-spacing').value) || 0;
const spUnit = document.getElementById('slabs-rebar-spacing-unit').value;
const spacingFt = spUnit === 'in' ? spVal / 12 : toFeet(spVal, 'cm');
const lbPerFt = parseFloat(document.getElementById('slabs-rebar-size').value) || 0.668;
rebarEstimate = computeRebarGridEstimate({
lengthFt: len,
widthFt: w,
spacingFt,
lbPerFt,
slabQty: qty
});
}renderResults('slabs-results', {
volFt3,
wastage: parseFloat(document.getElementById('slabs-wastage').value) || 0,
price: parseFloat(document.getElementById('slabs-price').value) || 0,
priceUnit: document.getElementById('slabs-price-unit').value,
calcName: 'Concrete Slabs',
grade: document.getElementById('slabs-grade').value || null,
rebarEstimate
});
});// Walls form
document.getElementById('walls-form').addEventListener('submit', e => {
e.preventDefault();
const len = toFeet(parseFloat(document.getElementById('walls-length').value) || 0, document.getElementById('walls-length-unit').value);
const h = toFeet(parseFloat(document.getElementById('walls-height').value) || 0, document.getElementById('walls-height-unit').value);
const thick = toFeet(parseFloat(document.getElementById('walls-thickness').value) || 0, document.getElementById('walls-thickness-unit').value);
const qty = parseInt(document.getElementById('walls-qty').value) || 1;
const volFt3 = len * h * thick * qty;
renderResults('walls-results', {
volFt3,
wastage: parseFloat(document.getElementById('walls-wastage').value) || 0,
price: parseFloat(document.getElementById('walls-price').value) || 0,
priceUnit: document.getElementById('walls-price-unit').value,
calcName: 'Concrete Walls & Footings',
grade: document.getElementById('walls-grade').value || null
});
});// Column sub-tabs switching
document.querySelectorAll('#columns-subtabs .subtab-btn').forEach(btn => {
btn.addEventListener('click', () => {
document.querySelectorAll('#columns-subtabs .subtab-btn').forEach(b => b.classList.remove('active'));
document.querySelectorAll('#columns .subtab-content').forEach(c => c.classList.remove('active'));
document.getElementById('columns-diagram-round').classList.add('hidden');
document.getElementById('columns-diagram-square').classList.add('hidden');btn.classList.add('active');
const targetId = btn.dataset.subtab;
document.getElementById(targetId).classList.add('active');
if (targetId === 'columns-round') {
document.getElementById('columns-diagram-round').classList.remove('hidden');
} else {
document.getElementById('columns-diagram-square').classList.remove('hidden');
}
});
});// Columns - Round Column form
document.getElementById('columns-round-form').addEventListener('submit', e => {
e.preventDefault();
const d = toFeet(parseFloat(document.getElementById('columns-round-diameter').value) || 0, document.getElementById('columns-round-diameter-unit').value);
const h = toFeet(parseFloat(document.getElementById('columns-round-height').value) || 0, document.getElementById('columns-round-height-unit').value);
const qty = parseInt(document.getElementById('columns-round-qty').value) || 1;
const volFt3 = Math.PI * (d / 2) ** 2 * h * qty;
renderResults('columns-round-results', {
volFt3,
wastage: parseFloat(document.getElementById('columns-round-wastage').value) || 0,
price: parseFloat(document.getElementById('columns-round-price').value) || 0,
priceUnit: document.getElementById('columns-round-price-unit').value,
calcName: 'Round Concrete Columns',
grade: document.getElementById('columns-round-grade').value || null
});
});// Columns - Square Column form
document.getElementById('columns-square-form').addEventListener('submit', e => {
e.preventDefault();
const side = toFeet(parseFloat(document.getElementById('columns-square-side').value) || 0, document.getElementById('columns-square-side-unit').value);
const width = toFeet(parseFloat(document.getElementById('columns-square-width').value) || 0, document.getElementById('columns-square-width-unit').value);
const h = toFeet(parseFloat(document.getElementById('columns-square-height').value) || 0, document.getElementById('columns-square-height-unit').value);
const qty = parseInt(document.getElementById('columns-square-qty').value) || 1;
const volFt3 = side * width * h * qty;
renderResults('columns-square-results', {
volFt3,
wastage: parseFloat(document.getElementById('columns-square-wastage').value) || 0,
price: parseFloat(document.getElementById('columns-square-price').value) || 0,
priceUnit: document.getElementById('columns-square-price-unit').value,
calcName: 'Square Concrete Columns',
grade: document.getElementById('columns-square-grade').value || null
});
});// Stairs form – standard triangular flight + rectangular platform
document.getElementById('stairs-form').addEventListener('submit', e => {
e.preventDefault();
const risePerStep = toFeet(parseFloat(document.getElementById('stairs-rise').value) || 0, document.getElementById('stairs-rise-unit').value);
const runPerStep = toFeet(parseFloat(document.getElementById('stairs-run').value) || 0, document.getElementById('stairs-run-unit').value);
const width = toFeet(parseFloat(document.getElementById('stairs-width').value) || 0, document.getElementById('stairs-width-unit').value);
const platform = toFeet(parseFloat(document.getElementById('stairs-platform').value) || 0, document.getElementById('stairs-platform-unit').value);
const steps = parseInt(document.getElementById('stairs-steps').value) || 1;
const qty = parseInt(document.getElementById('stairs-qty').value) || 1;const totalRise = risePerStep * steps;
const totalRun = runPerStep * steps;// Flight as right triangular prism: 0.5 * totalRise * totalRun * width
const flightVol = 0.5 * totalRise * totalRun * width;
// Platform as rectangular slab: platform depth * width * totalRise (approximate thickness)
const platformVol = platform * width * totalRise;const volFt3 = (flightVol + platformVol) * qty;renderResults('stairs-results', {
volFt3,
wastage: parseFloat(document.getElementById('stairs-wastage').value) || 0,
price: parseFloat(document.getElementById('stairs-price').value) || 0,
priceUnit: document.getElementById('stairs-price-unit').value,
calcName: 'Concrete Stairs',
grade: document.getElementById('stairs-grade').value || null
});
});// Curbs form – curb block + flag slab
document.getElementById('curbs-form').addEventListener('submit', e => {
e.preventDefault();
const h = toFeet(parseFloat(document.getElementById('curbs-height').value) || 0, document.getElementById('curbs-height-unit').value);
const w = toFeet(parseFloat(document.getElementById('curbs-width').value) || 0, document.getElementById('curbs-width-unit').value);
const d = toFeet(parseFloat(document.getElementById('curbs-depth').value) || 0, document.getElementById('curbs-depth-unit').value);
const flag = toFeet(parseFloat(document.getElementById('curbs-flag').value) || 0, document.getElementById('curbs-flag-unit').value);
const len = toFeet(parseFloat(document.getElementById('curbs-length').value) || 0, document.getElementById('curbs-length-unit').value);
const qty = parseInt(document.getElementById('curbs-qty').value) || 1;const curbVol = len * h * d; // vertical curb block
const flagVol = len * flag * w; // horizontal flag/slabconst volFt3 = (curbVol + flagVol) * qty;renderResults('curbs-results', {
volFt3,
wastage: parseFloat(document.getElementById('curbs-wastage').value) || 0,
price: parseFloat(document.getElementById('curbs-price').value) || 0,
priceUnit: document.getElementById('curbs-price-unit').value,
calcName: 'Concrete Curbs & Gutters',
grade: document.getElementById('curbs-grade').value || null
});
});// Grade info modal
const gradeModalWrapper = document.getElementById('grade-modal-wrapper');
const gradeModalBody = document.getElementById('grade-modal-body');
const gradeModalClose = document.getElementById('grade-modal-close');
const gradeModalBackdrop = document.getElementById('grade-modal-backdrop');function openGradeModal(selectId) {
const select = document.getElementById(selectId);
if (!select) return;
const grade = select.value;
if (!grade || !GRADE_DATA[grade]) {
gradeModalBody.innerHTML = '
Please select a concrete grade from the dropdown first to view detailed information.
';
} else {
const g = GRADE_DATA[grade];
gradeModalBody.innerHTML = `
Grade ${grade} concrete:
Strength: ${g.strength}Mix Ratio: ${g.mixRatio} (Cement : Sand : Aggregate)Water–Cement Ratio: ${g.waterCement}Cement Content: ${g.cementContent}Typical Uses: ${g.suitable}
`;
}
gradeModalWrapper.classList.remove('hidden');
}gradeModalClose.addEventListener('click', () => {
gradeModalWrapper.classList.add('hidden');
});gradeModalBackdrop.addEventListener('click', e => {
if (e.target === gradeModalBackdrop) {
gradeModalWrapper.classList.add('hidden');
}
});document.querySelectorAll('.grade-info-trigger').forEach(btn => {
btn.addEventListener('click', () => {
const selectId = btn.dataset.gradeSelect;
openGradeModal(selectId);
});
});// Cost Calculator form – grade only changes mix if selected, prices all required
document.getElementById('cost-form').addEventListener('submit', e => {
e.preventDefault();const volumeUnit = document.getElementById('cost-volume-unit').value;
const volume = parseFloat(document.getElementById('cost-volume').value) || 0;
const grade = document.getElementById('cost-grade').value || null;let volFt3 = 0;
if (volumeUnit === 'yd') volFt3 = volume * 27;
else if (volumeUnit === 'm') volFt3 = volume * 35.3147;
else if (volumeUnit === 'ft') volFt3 = volume;const materials = calcMaterials(volFt3, grade, 0);const cementPrice = parseFloat(document.getElementById('cost-cement').value) || 0;
const cementUnit = document.getElementById('cost-cement-unit').value;
const sandPrice = parseFloat(document.getElementById('cost-sand').value) || 0;
const sandUnit = document.getElementById('cost-sand-unit').value;
const gravelPrice = parseFloat(document.getElementById('cost-gravel').value) || 0;
const gravelUnit = document.getElementById('cost-gravel-unit').value;
const waterPrice = parseFloat(document.getElementById('cost-water').value) || 0;
const waterUnit = document.getElementById('cost-water-unit').value;let cementCost = 0;
if (cementUnit === 'kg') cementCost = materials.cement.kg * cementPrice;
else if (cementUnit === 'lb') cementCost = materials.cement.lb * cementPrice;let sandCost = 0;
if (sandUnit === 'yd') sandCost = materials.sand.yd3 * sandPrice;
else if (sandUnit === 'm') sandCost = materials.sand.m3 * sandPrice;
else if (sandUnit === 'ft') sandCost = (materials.sand.yd3 * 27) * sandPrice;let gravelCost = 0;
if (gravelUnit === 'yd') gravelCost = materials.aggregate.yd3 * gravelPrice;
else if (gravelUnit === 'm') gravelCost = materials.aggregate.m3 * gravelPrice;
else if (gravelUnit === 'ft') gravelCost = (materials.aggregate.yd3 * 27) * gravelPrice;let waterCost = 0;
if (waterUnit === 'gal') waterCost = materials.water.gallons * waterPrice;
else if (waterUnit === 'L') waterCost = materials.water.liters * waterPrice;const totalCost = cementCost + sandCost + gravelCost + waterCost;const costHtml = `
Cost Breakdown Total Project Cost
$${formatNum(totalCost)} USD
Cement Cost
$${formatNum(cementCost)}
Sand Cost
$${formatNum(sandCost)}
Aggregate Cost
$${formatNum(gravelCost)}
Water Cost
$${formatNum(waterCost)}
Material Quantities Cement
${formatNum(materials.cement.lb)} lb (${formatNum(materials.cement.kg)} kg)
40lb: ${materials.cement.bags40} | 60lb: ${materials.cement.bags60} | 80lb: ${materials.cement.bags80}
Sand
${formatNum(materials.sand.yd3)} yd³ (${formatNum(materials.sand.m3)} m³)
Aggregate
${formatNum(materials.aggregate.yd3)} yd³ (${formatNum(materials.aggregate.m3)} m³)
Water
${formatNum(materials.water.gallons)} gal (${formatNum(materials.water.liters)} L)
${buildExtendedAnalysisHtml({ volM3WithWaste: toCubicMeters(volFt3), materials, rebarEstimate: null })}
`;const el = document.getElementById('cost-results');
el.innerHTML = costHtml;
el.classList.add('visible');
el.dataset.resultData = JSON.stringify({
calcName: 'Concrete Cost Calculator',
volFt3,
volWithWaste: volFt3,
volM3WithWaste: toCubicMeters(volFt3),
materials,
rebarEstimate: null
});
});document.getElementById('extended-material-density')?.addEventListener('change', refreshExtendedAnalysisPanels);// Reset buttons
document.querySelectorAll('[data-reset]').forEach(btn => {
btn.addEventListener('click', () => {
const tab = btn.dataset.reset;
if (tab === 'columns-round') {
const form = document.getElementById('columns-round-form');
form.reset();
document.getElementById('columns-round-qty').value = 1;
const res = document.getElementById('columns-round-results');
res.innerHTML = '';
res.classList.remove('visible');
} else if (tab === 'columns-square') {
const form = document.getElementById('columns-square-form');
form.reset();
document.getElementById('columns-square-qty').value = 1;
const res = document.getElementById('columns-square-results');
res.innerHTML = '';
res.classList.remove('visible');
} else {
const form = document.getElementById(tab + '-form');
if (form) {
form.reset();
if (document.getElementById(tab + '-qty')) document.getElementById(tab + '-qty').value = 1;
if (tab === 'slabs') {
document.getElementById('slabs-width').value = '';
slabsShape = 'rectangle';
document.querySelectorAll('#slabs .shape-option').forEach(o => o.classList.remove('selected'));
document.querySelector('#slabs .shape-option[data-shape="rectangle"]').classList.add('selected');
updateSlabsLabelsAndRequirements();
updateSlabsDiagram();
}
const res = document.getElementById(tab + '-results');
if (res) {
res.innerHTML = '';
res.classList.remove('visible');
delete res.dataset.resultData;
}
if (tab === 'cost') {
const costRes = document.getElementById('cost-results');
costRes.innerHTML = '';
costRes.classList.remove('visible');
delete costRes.dataset.resultData;
}
}
}
});
});// Select1 Script
document.querySelectorAll(".input-row select").forEach(select => {const row = select.closest(".input-row");select.addEventListener("mousedown", () => {
row.classList.add("open");
});select.addEventListener("blur", () => {
row.classList.remove("open");
});select.addEventListener("change", () => {
row.classList.remove("open");
});});// Select2 Script
document.querySelectorAll(".select-wrap select").forEach(select => {const wrap = select.closest(".select-wrap");select.addEventListener("mousedown", () => {
wrap.classList.add("open");
});select.addEventListener("blur", () => {
wrap.classList.remove("open");
});select.addEventListener("change", () => {
wrap.classList.remove("open");
});});// Embed tool modal and code generation
const embedModalWrapper = document.getElementById('embed-modal-wrapper');
const embedModalBackdrop = document.getElementById('embed-modal-backdrop');
const openEmbedModalBtn = document.getElementById('open-embed-modal');
const embedModalCloseBtn = document.getElementById('embed-modal-close');
const embedCodeOutput = document.getElementById('embed-code-output');
const copyEmbedCodeBtn = document.getElementById('copy-embed-code-btn');
const embedCopyStatus = document.getElementById('embed-copy-status');const fallbackEmbedUrl = 'https://your-domain.com/concrete-calculator';const getEmbedSourceUrl = () => {
const currentUrl = window.location.href;
if (!currentUrl || !/^https?:\/\//i.test(currentUrl)) return fallbackEmbedUrl;
return currentUrl;
};const buildResponsiveEmbedCode = () => {
const src = getEmbedSourceUrl();
return `
`;
};const openEmbedModal = () => {
embedCodeOutput.value = buildResponsiveEmbedCode();
embedCopyStatus.textContent = '';
embedModalWrapper.classList.remove('hidden');
};const closeEmbedModal = () => {
embedModalWrapper.classList.add('hidden');
};if (openEmbedModalBtn) {
openEmbedModalBtn.addEventListener('click', openEmbedModal);
}if (embedModalCloseBtn) {
embedModalCloseBtn.addEventListener('click', closeEmbedModal);
}if (embedModalBackdrop) {
embedModalBackdrop.addEventListener('click', event => {
if (event.target === embedModalBackdrop) closeEmbedModal();
});
}document.addEventListener('keydown', event => {
if (event.key === 'Escape' && embedModalWrapper && !embedModalWrapper.classList.contains('hidden')) {
closeEmbedModal();
}
});if (copyEmbedCodeBtn) {
copyEmbedCodeBtn.addEventListener('click', async () => {
try {
await navigator.clipboard.writeText(embedCodeOutput.value);
embedCopyStatus.textContent = 'Embed code copied successfully.';
} catch (error) {
embedCodeOutput.select();
document.execCommand('copy');
embedCopyStatus.textContent = 'Embed code copied successfully.';
}
});
}