Home / Widgets / Kitchen Renovation Estimator Edmonton
Duplicate Snippet

Embed Snippet on Your Site

Kitchen Renovation Estimator Edmonton

Lance Landiak
<10
Code Preview
php
<?php
(function(){
/* ===== Gravity Forms settings: replace the numbers with your form and field IDs ===== */
var JKR_GF={
formId: 0,                      /* e.g. 7 */
fields:{                        /* Hidden field IDs from the form editor */
home:0, scope:0, budget:0, contingency:0, total:0,
roi:0, added:0, after:0, pm:0, summary:0
},
FALLBACK_URL:'/contact/'        /* used only if the form isn't on this page */
};
/* ===================================================================================== */
var root=document.getElementById('jkr'); if(!root) return;
root.classList.add('jkr-js');
function $(id){return document.getElementById(id);}
var cad=new Intl.NumberFormat('en-CA',{style:'currency',currency:'CAD',maximumFractionDigits:0});
function money(v){return cad.format(Math.round(v/100)*100);}
var parts=[
{n:'Cabinetry and hardware',p:29,c:'top',d:'Your single largest line item. Door style, box construction, storage inserts and hardware set the look and the daily function of the whole room.'},
{n:'Project management',p:0,pm:true,c:'pm',d:'One point of contact for your whole renovation. Jostar manages it from first concept and design through construction: scheduling trades, coordinating suppliers and keeping design and budget on track.'},
{n:'Installation',p:17,c:'labour',d:'The labour to remove, build and fit everything. Expect this share to rise if walls are moving or the layout is being reconfigured.'},
{n:'Appliances and ventilation',p:14,c:'',d:'Range, fridge, dishwasher and hood fan. Energy-efficient models can lower running costs; check provincial and municipal rebate programs.'},
{n:'Countertops',p:10,c:'top',d:'A working surface and a focal point. With cabinetry, this is where most of the materials budget lands.'},
{n:'Flooring',p:7,c:'',d:'Durable, easy-to-clean flooring that ties the kitchen into the rest of the main floor.'},
{n:'Walls and ceilings',p:5,c:'',d:'Drywall repair, paint and backsplash surfaces that finish the space.'},
{n:'Lighting',p:5,c:'',d:'Layered task, ambient and accent lighting: pot lights, pendants and under-cabinet lighting.'},
{n:'Doors and windows',p:4,c:'',d:'New or relocated windows and doors that bring in light and connect the kitchen to the rest of the home.'},
{n:'Design fees',p:4,c:'',d:'An interior designer coordinates layout, finishes and details so the finished kitchen feels cohesive, which is what protects your return.'},
{n:'Faucets and plumbing',p:4,c:'',d:'Sink, faucet and the plumbing work behind them, especially if the sink is moving.'},
{n:'Other',p:1,c:'',d:'Small items that round out the project.'}
];
var max=29, active=0, revealed=false;
var list=$('jkr-bars');
parts.forEach(function(it,i){
var li=document.createElement('li');
li.className='jkr-bar '+it.c;
li.innerHTML='<button type="button"><span class="jkr-bname">'+it.n+'</span>'+
'<span><span class="jkr-bfill" data-fill></span></span>'+
'<span class="jkr-bamt"><span data-amt></span><small data-pct></small></span></button>';
li.querySelector('button').addEventListener('click',function(){active=i;update();});
list.appendChild(li);
});
var DEFAULTS={'jkr-home':500000,'jkr-pct':17.5,'jkr-cont':15,'jkr-roi':85};
var reduceMotion=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches;
/* Step bar starts at zero. A step's value appears once the visitor engages it
(moves its slider or continues past it). Steps 2-4 stay hidden until the visitor continues. */
var reached=1, current=1, unlocked=1;
var engaged={1:false,2:false,3:false,4:false};
var chips=root.querySelectorAll('.jkr-chip');
function touch(n){ if(n>reached) reached=n; paintProgress(); }
function engage(n){ if(!engaged[n]){ engaged[n]=true; update(); } }
function unlock(n){
while(unlocked<n){
unlocked++;
var el=root.querySelector('.jkr-step[data-step="'+unlocked+'"]');
if(el){ el.classList.remove('jkr-locked'); el.classList.add('jkr-unlock'); }
if(unlocked===4){ var r=$('jkr-reveal'); r.classList.remove('jkr-locked'); r.classList.add('jkr-unlock'); }
}
paintProgress();
}
function paintProgress(){
for(var i=0;i<chips.length;i++){
var n=+chips[i].getAttribute('data-chip');
chips[i].classList.toggle('done', engaged[n]);
chips[i].classList.toggle('empty', !engaged[n]);
chips[i].classList.toggle('active', n===current);
if(n>unlocked) chips[i].setAttribute('aria-disabled','true'); else chips[i].removeAttribute('aria-disabled');
if(n===current) chips[i].setAttribute('aria-current','step'); else chips[i].removeAttribute('aria-current');
}
}
function stepEl(n){
if(n===4 && !$('jkr-plan').hidden && reached>=4 && current===4) return $('jkr-plan');
return root.querySelector('.jkr-step[data-step="'+n+'"]');
}
function go(n){
var el=stepEl(n); if(!el || n>unlocked) return;
current=n; paintProgress();
requestAnimationFrame(function(){ el.scrollIntoView({behavior:reduceMotion?'auto':'smooth',block:'start'}); });
}
for(var c=0;c<chips.length;c++){
chips[c].addEventListener('click',function(){ go(+this.getAttribute('data-go')); });
}
/* Continue buttons: accept the current step's values, open the next step and move there */
var nexts=root.querySelectorAll('[data-next]');
for(var x=0;x<nexts.length;x++){
nexts[x].addEventListener('click',function(){
var n=+this.getAttribute('data-next');
engage(n-1); unlock(n); if(n===4) engage(4);
touch(n); go(n);
});
}
/* highlight the step currently in view */
if('IntersectionObserver' in window){
var io=new IntersectionObserver(function(entries){
entries.forEach(function(en){
if(en.isIntersecting){ current=+en.target.getAttribute('data-step'); paintProgress(); }
});
},{rootMargin:'-35% 0px -55% 0px'});
root.querySelectorAll('[data-step]').forEach(function(el){ io.observe(el); });
}
/* live values in the step bar, with a brief highlight when they change */
function setChip(id,text){
var el=$(id); if(el.textContent===text) return;
var first=el.textContent==='' || /^\$?0%?$/.test(text);
el.textContent=text;
if(!first && !reduceMotion){ el.classList.remove('bump'); void el.offsetWidth; el.classList.add('bump'); }
}
function fillTrack(el){
var pct=(el.value-el.min)/(el.max-el.min)*100;
el.style.background='linear-gradient(to right,#8EC3C1 0%,#8EC3C1 '+pct+'%,#DAD8D5 '+pct+'%,#DAD8D5 100%)';
}
var plan={};
function pmRateFor(budget){ return budget>100000?15:20; }
function fmtPct(v){ var r=Math.round(v*10)/10; return (r%1===0?r.toFixed(0):r.toFixed(1))+'%'; }
function scopeName(pct){return pct>=19?'Full-scale remodel':pct<=16?'Kitchen refresh':'Mid-range renovation';}
/* Gravity Forms: fill hidden fields (re-run after AJAX re-renders) */
function fillForm(){
if(!JKR_GF.formId) return;
Object.keys(JKR_GF.fields).forEach(function(k){
var fid=JKR_GF.fields[k]; if(!fid) return;
var el=document.getElementById('input_'+JKR_GF.formId+'_'+fid);
if(el && plan[k]!==undefined){ el.value=plan[k]; }
});
}
function formWrapper(){
return JKR_GF.formId ? document.getElementById('gform_wrapper_'+JKR_GF.formId) : null;
}
function placeForm(){
var w=formWrapper(), slot=$('jkr-form-slot');
if(w){
/* move the form's block container so confirmations and AJAX keep working */
var box=w.parentNode && w.parentNode!==document.body && !w.parentNode.contains(root) ? w.parentNode : w;
if(!slot.contains(w)) slot.appendChild(box);
$('jkr-fallback').hidden=true;
} else {
$('jkr-fallback').hidden=false;
$('jkr-send').querySelector('p').textContent='Your numbers are ready to go. Continue to send them to Jostar and book a 15-minute discovery call. No commitments.';
}
fillForm();
}
if(window.jQuery){ window.jQuery(document).on('gform_post_render',function(e,formId){ if(+formId===+JKR_GF.formId) fillForm(); }); }
function verdict(home,budget,added,roi,pct){
var cents=roi;
var scope=scopeName(pct).toLowerCase();
var s='For a '+money(home)+' home, a '+scope+' of about '+money(budget)+' could add '+money(added)+' back to your home\u2019s value. That\u2019s '+cents+' cents of every dollar returned at resale';
if(roi>=95) s+=', with a kitchen you get to enjoy every day until then. At this level, a well-designed, well-built kitchen nearly pays for itself.';
else if(roi>=85) s+=', plus a kitchen you get to enjoy every day until then. Coordinated design and quality finishes are what keep you at the top of the range.';
else s+='. Most of your investment comes back, and a coordinated design with quality finishes is what moves that number toward 100%.';
return s;
}
function update(){
var home=+$('jkr-home').value, pct=+$('jkr-pct').value, cont=+$('jkr-cont').value, roi=+$('jkr-roi').value;
var budget=home*pct/100, contAmt=budget*cont/100, added=budget*roi/100;
$('jkr-home-out').textContent=money(home);
$('jkr-pct-out').textContent=pct+'% of home value';
$('jkr-cont-out').textContent=cont+'%';
$('jkr-roi-out').textContent=roi+'%';
$('jkr-range').textContent=money(home*.15)+' to '+money(home*.20);
$('jkr-budget').textContent=money(budget);
$('jkr-contamt').textContent=money(contAmt);
$('jkr-total').textContent=money(budget+contAmt);
$('jkr-added').textContent=money(added);
$('jkr-net').textContent=money(budget-added);
$('jkr-after').textContent=money(home+added);
$('jkr-roifill').style.width=roi+'%';
$('jkr-roil').textContent=money(added)+' back';
$('jkr-roir').textContent=roi<100?money(budget-added)+' net':'Full cost recovered';
var pmRate=pmRateFor(budget), rest=(100-pmRate)/100;
var shares=parts.map(function(it){ return it.pm?pmRate:it.p*rest; });
var maxShare=Math.max.apply(null,shares);
$('jkr-cc').textContent=money(budget*.39*rest);
$('jkr-ccpct').textContent=fmtPct(39*rest);
$('jkr-pmline').textContent=pmRate+'% ('+money(budget*pmRate/100)+')';
setChip('jkr-c1',engaged[1]?money(home):'$0');
setChip('jkr-c2',engaged[2]?pct+'%':'0%');
setChip('jkr-c3',engaged[3]?roi+'%':'0%');
setChip('jkr-c4',engaged[4]?money(budget):'$0');
$('jkr-c3s').textContent=engaged[3]?money(added)+' back':'';
paintProgress();
var items=list.children;
for(var i=0;i<items.length;i++){
items[i].querySelector('[data-amt]').textContent=money(budget*shares[i]/100);
items[i].querySelector('[data-pct]').textContent=fmtPct(shares[i]);
items[i].querySelector('[data-fill]').style.width=(shares[i]/maxShare*100)+'%';
items[i].setAttribute('aria-current',i===active?'true':'false');
}
var a=parts[active];
var extra=a.pm?' At your budget of '+money(budget)+', project management is '+pmRate+'%. It\u2019s 20% of budgets under $100,000 and 15% of budgets over $100,000.':'';
$('jkr-detail').innerHTML='<h4>'+a.n+': '+money(budget*shares[active]/100)+' ('+fmtPct(shares[active])+')</h4><p>'+a.d+extra+'</p>';
/* plan */
$('jkr-verdict').textContent=verdict(home,budget,added,roi,pct);
$('jkr-p-budget').textContent=money(budget);
$('jkr-p-total').textContent=money(budget+contAmt);
$('jkr-p-added').textContent=money(added);
$('jkr-p-after').textContent=money(home+added);
plan={
home:money(home),
scope:scopeName(pct)+' ('+pct+'% of home value)',
budget:money(budget),
contingency:money(contAmt)+' ('+cont+'%)',
total:money(budget+contAmt),
roi:roi+'%',
added:money(added),
after:money(home+added),
pm:money(budget*pmRate/100)+' ('+pmRate+'%)'
};
plan.summary='Home value '+plan.home+' | '+plan.scope+' | Budget '+plan.budget+' | Contingency '+plan.contingency+
' | Total to set aside '+plan.total+' | Project management '+plan.pm+' | Return '+plan.roi+' | Value added '+plan.added+' | Home value after '+plan.after;
fillForm();
var q=Object.keys(plan).map(function(k){return 'jkr_'+k+'='+encodeURIComponent(plan[k]);}).join('&');
var base=JKR_GF.FALLBACK_URL; $('jkr-fallback-link').href=base+(base.indexOf('?')>-1?'&':'?')+q;
['jkr-home','jkr-pct','jkr-cont','jkr-roi'].forEach(function(id){fillTrack($(id));});
}
[['jkr-home',1],['jkr-pct',2],['jkr-cont',2],['jkr-roi',3]].forEach(function(p){
$(p[0]).addEventListener('input',function(){ engaged[p[1]]=true; touch(p[1]); update(); });
});
$('jkr-show').addEventListener('click',function(){
var plan=$('jkr-plan');
plan.hidden=false; plan.classList.add('show');
$('jkr-reveal').style.display='none';
touch(4); current=4; revealed=true; paintProgress();
plan.scrollIntoView({behavior:reduceMotion?'auto':'smooth',block:'start'});
plan.focus({preventScroll:true});
});
/* Clear all: back to defaults, plan hidden, form cleared, visitor returned to step 1 */
$('jkr-clear').addEventListener('click',function(){
Object.keys(DEFAULTS).forEach(function(id){ $(id).value=DEFAULTS[id]; });
active=0; reached=1; current=1; revealed=false; unlocked=1;
engaged={1:false,2:false,3:false,4:false};
root.querySelectorAll('.jkr-step[data-step]').forEach(function(el){
if(+el.getAttribute('data-step')>1){ el.classList.add('jkr-locked'); el.classList.remove('jkr-unlock'); }
});
$('jkr-reveal').classList.add('jkr-locked'); $('jkr-reveal').classList.remove('jkr-unlock');
var plan=$('jkr-plan'); plan.hidden=true; plan.classList.remove('show');
$('jkr-reveal').style.display='';
if(JKR_GF.formId){ var f=document.getElementById('gform_'+JKR_GF.formId); if(f && f.reset) f.reset(); }
update(); paintProgress();
$('jkr-announce').textContent='All selections cleared. Back to step 1.';
go(1);
$('jkr-home').focus({preventScroll:true});
});
paintProgress();
update();
if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded',placeForm); } else { placeForm(); }
})();

Comments

Add a Comment