For HVAC & Plumbing

Stop Answering
"How Much to Fix This?"
Let a Calculator Do It

Free quote calculator for your HVAC or plumbing website. Homeowners get instant estimates. You get qualified leads. Setup in 5 minutes.

No credit card required
Free forever for calculators
Works on Wix, WordPress, any site
🔧 Service Quote Calculator
🔧 Service Type
 
❄️ HVAC Service
⏰ Timing
 
 
🏠 Property Info
💰 Estimate
$ 89.00
✓ Fixed price service
* Final price depends on diagnosis. Service call fee applies.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
export function hvacPlumbingForm(form: FormTs) {
form.setTitle(() => '🔧 Service Quote Calculator');
 
form.configureCompletionScreen({
type: 'text',
title: () => '📋 Quote Ready!',
message: () => 'Your service estimate is ready. We\'ll call you to schedule an appointment!'
});
 
const serviceSection = form.addSubform('service', {
title: () => '🔧 Service Type',
mobileBreakpoint: 0
});
 
serviceSection.addRow(row => {
row.addRadioButton('category', {
label: 'Category',
options: [
{ id: 'hvac', name: '❄️ HVAC/Heating & Cooling' },
{ id: 'plumbing', name: '🚿 Plumbing' },
{ id: 'electrical', name: '⚡ Electrical' }
],
defaultValue: 'hvac',
orientation: 'vertical',
isRequired: true
});
});
 
const hvacSection = form.addSubform('hvac', {
title: () => '❄️ HVAC Service',
isVisible: () => serviceSection.radioButton('category')?.value() === 'hvac',
mobileBreakpoint: 0
});
 
hvacSection.addRow(row => {
row.addDropdown('hvacService', {
label: 'Service Needed',
options: [
{ id: 'diagnostic', name: 'Diagnostic/Inspection ($89)' },
{ id: 'tune-up', name: 'Seasonal Tune-Up ($149)' },
{ id: 'repair', name: 'Repair ($150-$500)' },
{ id: 'replace-unit', name: 'Unit Replacement (Quote)' },
{ id: 'duct-cleaning', name: 'Duct Cleaning ($299+)' }
],
defaultValue: 'diagnostic'
}, '1fr');
});
 
const plumbingSection = form.addSubform('plumbing', {
title: () => '🚿 Plumbing Service',
isVisible: () => serviceSection.radioButton('category')?.value() === 'plumbing',
mobileBreakpoint: 0
});
 
plumbingSection.addRow(row => {
row.addDropdown('plumbingService', {
label: 'Service Needed',
options: [
{ id: 'diagnostic', name: 'Diagnostic ($79)' },
{ id: 'drain', name: 'Drain Cleaning ($125-$250)' },
{ id: 'leak', name: 'Leak Repair ($150-$400)' },
{ id: 'water-heater', name: 'Water Heater ($200-$1500)' },
{ id: 'toilet', name: 'Toilet Repair ($100-$300)' },
{ id: 'faucet', name: 'Faucet Install ($150-$250)' }
],
defaultValue: 'diagnostic'
}, '1fr');
});
 
const electricalSection = form.addSubform('electrical', {
title: () => '⚡ Electrical Service',
isVisible: () => serviceSection.radioButton('category')?.value() === 'electrical',
mobileBreakpoint: 0
});
 
electricalSection.addRow(row => {
row.addDropdown('electricalService', {
label: 'Service Needed',
options: [
{ id: 'diagnostic', name: 'Diagnostic ($89)' },
{ id: 'outlet', name: 'Outlet Install ($125-$200)' },
{ id: 'switch', name: 'Switch/Dimmer ($100-$175)' },
{ id: 'panel', name: 'Panel Upgrade (Quote)' },
{ id: 'lighting', name: 'Light Fixture ($100-$250)' }
],
defaultValue: 'diagnostic'
}, '1fr');
});
 
const timingSection = form.addSubform('timing', {
title: () => '⏰ Timing',
mobileBreakpoint: 0
});
 
timingSection.addRow(row => {
row.addRadioButton('urgency', {
label: 'When do you need service?',
options: [
{ id: 'standard', name: 'Standard (Next available)' },
{ id: 'same-day', name: 'Same Day (+$50)' },
{ id: 'emergency', name: '🚨 Emergency (+$150)' }
],
defaultValue: 'standard',
orientation: 'vertical'
}, '1fr');
 
row.addRadioButton('timing', {
label: 'Preferred Time',
options: [
{ id: 'regular', name: 'Weekday 8am-5pm' },
{ id: 'evening', name: 'Evening (+15%)' },
{ id: 'weekend', name: 'Weekend (+20%)' }
],
defaultValue: 'regular',
orientation: 'vertical'
}, '1fr');
});
 
const propertySection = form.addSubform('property', {
title: () => '🏠 Property Info',
mobileBreakpoint: 0
});
 
propertySection.addRow(row => {
row.addDropdown('propertyType', {
label: 'Property Type',
options: [
{ id: 'house', name: 'Single Family Home' },
{ id: 'condo', name: 'Condo/Townhouse' },
{ id: 'apartment', name: 'Apartment' },
{ id: 'commercial', name: 'Commercial (+25%)' }
],
defaultValue: 'house'
}, '1fr');
});
 
const calculateEstimate = () => {
const category = serviceSection.radioButton('category')?.value() || 'hvac';
const urgency = timingSection.radioButton('urgency')?.value() || 'standard';
const timing = timingSection.radioButton('timing')?.value() || 'regular';
const propertyType = propertySection.dropdown('propertyType')?.value() || 'house';
 
let minPrice = 0;
let maxPrice = 0;
 
if (category === 'hvac') {
const service = hvacSection.dropdown('hvacService')?.value() || 'diagnostic';
const hvacPrices: Record<string, [number, number]> = {
'diagnostic': [89, 89],
'tune-up': [149, 149],
'repair': [150, 500],
'replace-unit': [3000, 8000],
'duct-cleaning': [299, 599]
};
[minPrice, maxPrice] = hvacPrices[service] || [89, 89];
} else if (category === 'plumbing') {
const service = plumbingSection.dropdown('plumbingService')?.value() || 'diagnostic';
const plumbingPrices: Record<string, [number, number]> = {
'diagnostic': [79, 79],
'drain': [125, 250],
'leak': [150, 400],
'water-heater': [200, 1500],
'toilet': [100, 300],
'faucet': [150, 250]
};
[minPrice, maxPrice] = plumbingPrices[service] || [79, 79];
} else {
const service = electricalSection.dropdown('electricalService')?.value() || 'diagnostic';
const electricalPrices: Record<string, [number, number]> = {
'diagnostic': [89, 89],
'outlet': [125, 200],
'switch': [100, 175],
'panel': [1500, 4000],
'lighting': [100, 250]
};
[minPrice, maxPrice] = electricalPrices[service] || [89, 89];
}
 
const urgencyFees: Record<string, number> = { standard: 0, 'same-day': 50, emergency: 150 };
const urgencyFee = urgencyFees[urgency] || 0;
 
const timingMult: Record<string, number> = { regular: 1, evening: 1.15, weekend: 1.2 };
const timeMult = timingMult[timing] || 1;
 
const propertyMult = propertyType === 'commercial' ? 1.25 : 1;
 
minPrice = Math.round((minPrice * timeMult * propertyMult) + urgencyFee);
maxPrice = Math.round((maxPrice * timeMult * propertyMult) + urgencyFee);
 
return { min: minPrice, max: maxPrice };
};
 
const summary = form.addSubform('summary', {
title: () => '💰 Estimate',
isCollapsible: false
});
 
summary.addRow(row => {
row.addPriceDisplay('minEstimate', {
label: 'Starting At',
computedValue: () => calculateEstimate().min,
alignment: 'center',
variant: 'large'
});
});
 
summary.addRow(row => {
row.addTextPanel('range', {
computedValue: () => {
const { min, max } = calculateEstimate();
if (min === max) {
return '✓ Fixed price service';
}
return `📊 Typical range: $${min} - $${max}`;
},
customStyles: {
fontSize: '0.95rem',
color: '#059669',
textAlign: 'center',
fontWeight: '500'
}
});
});
 
summary.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => '* Final price depends on diagnosis. Service call fee applies.',
customStyles: {
fontSize: '0.85rem',
color: '#6b7280',
textAlign: 'center',
fontStyle: 'italic'
}
});
});
 
form.configureSubmitButton({
label: () => 'Request Service Call'
});
}
 

Why Contractors Love It

Stop wasting time on tire-kickers. Let homeowners see your pricing and call when they're ready to book.

Fewer Wasted Calls

No more 20-minute calls that end with "let me think about it." Pre-qualified leads only.

Higher Close Rates

Homeowners who submit already know your pricing. They're ready to commit.

Look Professional

Stand out from competitors with instant quotes. Builds trust before you even pick up the phone.

No Coding Required

Describe your services. Our AI builds your calculator in minutes.

Add a Quote Calculator in 3 Steps

1

Build Your Calculator

Use our AI assistant or pick a template. Set your service rates, call fees, and common repairs.

2

Customize Your Look

Match your brand colors and add your logo. Mobile-friendly by default. Looks great everywhere.

3

Embed Anywhere

Copy 2 lines of code. Works on WordPress, Wix, Squarespace, Shopify, or any custom site.

Add to your website
<script src="https://formts.com/widget.js"></script>
<formts-widget link-id="your-calculator"></formts-widget>

Everything You Need to Automate Quotes

Real-Time Calculations

Prices update instantly as homeowners describe their problem. No page reloads, no waiting.

Email Notifications

Get notified the moment someone requests a quote. Call them back while they're still at the computer.

Emergency Rates

Set different rates for after-hours, weekends, and holidays automatically.

Service Area Pricing

Charge more for distant service calls. The calculator adjusts based on zip code.

Works Everywhere

Embed on any website with 2 lines of code. WordPress, Wix, Squarespace, custom sites.

Mobile Optimized

Looks great on phones and tablets. Homeowners search on mobile when something breaks.

Frequently Asked Questions

Do I need to know how to code?

No. Our AI assistant builds the calculator from your description. Just tell it what services you offer and your rates. You can also start from a template and customize it - no coding required.

Will it work on my Wix/WordPress/Squarespace site?

Yes. FormTs works on any website that allows custom HTML. You just paste 2 lines of code where you want the calculator to appear. Works on WordPress, Wix, Squarespace, Shopify, and any custom site.

Is the calculator really free?

Yes. Calculators that don't collect submissions are completely free - no limits, no credit card. If you want to collect homeowner contact details, the Free plan includes 100 submissions/month. Need more? Pro gives you 1,000/month.

Can I set emergency and after-hours rates?

Absolutely. You can set different rates for regular hours, evenings, weekends, and holidays. The calculator automatically applies the right pricing based on when the service is needed.

How do I get notified when someone requests a quote?

All submissions appear in your dashboard instantly. Pro plan includes email notifications and webhooks to connect with Zapier, n8n, Make, or send data directly to your CRM or dispatch software.

Can the estimate include a disclaimer?

Yes! You can add text explaining that final pricing depends on the actual diagnosis. Most contractors use ranges ('$150-$300') and note that a service call is required for exact pricing.

Ready to Stop Wasting Time on Price Shoppers?

Join hundreds of HVAC and plumbing pros who automated their estimates. Start with a free template or let AI build your custom calculator.

No credit card required. Free plan available. Setup in under 10 minutes.