.multi-step-form-container {
max-width: 600px;
margin: 20px auto;
background: #fff;
padding: 20px 30px;
border-radius: 10px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.form-title{
font-size: 26px;
margin: 0 0 18px 0;
text-align:center;
color:#053C5E;
font-weight: 500;
}
.step-indicators {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
background: #f2f2f2;
border-radius: 6px;
padding: 10px 10px;
}
.step-indicator {
flex: 1;
text-align: center;
padding: 6px 4px;
font-size: 18px;
color: #a0a0a0;
border-bottom: 2px solid transparent;
position: relative;
}
.step-indicator.active {
font-weight: bold;
color: #053C5E;
border-bottom-color: #053C5E;
}
.step-indicator::after {
content: attr(data-label);
display: inline-block;
font-size: 14px;
color: inherit;
margin-left: 8px;
}
.form-step { display: none; }
.form-step.active { display: block; }
.custom-form-row {
display: flex;
gap: 15px;
flex-wrap: wrap;
}
.custom-form-row > .custom-form-field {
flex: 1;
min-width: 200px;
}
label { color: #053C5E; font-weight: 600; display:block; margin-bottom: 10px; }
label input, label select, label textarea { margin-top: 6px; }
.helper-text{
display:block;
font-size: 12px;
color:#777;
margin-top: 6px;
font-weight: 400;
}
.form-navigation button,
.wpcf7-submit {
width: 100%;
padding: 12px;
background: #053C5E;
border: none;
border-radius: 5px;
color: #fff;
font-size: 18px;
text-align: center;
cursor: pointer;
display: block;
text-decoration: none;
transition: background 0.3s;
margin-top: 10px;
}
.form-navigation.nav-two{
display:flex;
gap: 12px;
}
.form-navigation.nav-two button,
.form-navigation.nav-two .wpcf7-submit{
width: 50%;
}
.form-navigation button:hover:not(:disabled),
.wpcf7-submit:hover:not(:disabled) {
background: #042f4b;
}
.form-navigation button:disabled,
.wpcf7-submit:disabled{
opacity: .55;
cursor: not-allowed;
}
.form-footnote{
margin-top: 18px;
font-size: 14px;
color:#053C5E;
text-align:center;
}
.consent-label{
display:flex;
gap: 10px;
align-items:flex-start;
font-weight: 500;
color:#053C5E;
margin-top: 12px;
line-height: 1.35;
}
.consent-label input[type="checkbox"]{
margin-top: 4px;
}
(function () {
function initMultiStep(container) {
if (!container || container.dataset.msInit === '1') return;
container.dataset.msInit = '1';
const steps = container.querySelectorAll('.form-step');
const indicators = container.querySelectorAll('.step-indicator');
const submitButton = container.querySelector('.wpcf7-submit');
// Inputs
const stateSelect = container.querySelector('[name="your-state"]');
const firstNameInput = container.querySelector('[name="your-name"]');
const lastNameInput = container.querySelector('[name="last-name"]');
const bestTimeSelect = container.querySelector('[name="best-time"]');
const phoneInput = container.querySelector('[name="your-phone"]');
const birthdateInput = container.querySelector('[name="birthdate"]');
const ufSelect = container.querySelector('[name="uf"]');
const addrInput = container.querySelector('[name="address-full"]');
const neighInput = container.querySelector('[name="neighborhood"]');
const cityInput = container.querySelector('[name="city"]');
const cepInput = container.querySelector('[name="cep"]');
const numberInput = container.querySelector('[name="house-number"]');
const complementInput = container.querySelector('[name="complement"]');
const consentInput = container.querySelector('[name="consent"]');
let loadingTimeout;
function showStep(index) {
steps.forEach((step, i) => step.classList.toggle('active', i === index));
indicators.forEach((ind, i) => ind.classList.toggle('active', i === index));
validateAll();
container.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
/* ===== Helpers ===== */
function isSelectChosen(selectEl){
if(!selectEl) return false;
const v = (selectEl.value || '').trim();
return v !== '' && v !== 'Selecione seu estado' && v !== 'Melhor horário para contato';
}
function isNameValid(v){
const nameRegex = /^[A-Za-zÀ-ÖØ-öø-ÿ\s]+$/;
return nameRegex.test((v || '').trim());
}
/* ===== Phone ===== */
function formatPhone(value) {
let digits = (value || '').replace(/\D/g, '');
if (digits.startsWith('55')) digits = digits.slice(2);
if (digits.length > 11) digits = digits.slice(0, 11);
if (digits.length >= 10) {
const ddd = digits.slice(0, 2);
const number = digits.slice(2);
if (number.length === 9) return `+55 (${ddd}) ${number.slice(0,5)}-${number.slice(5)}`;
if (number.length === 8) return `+55 (${ddd}) ${number.slice(0,4)}-${number.slice(4)}`;
}
return digits ? ('+55 ' + digits) : '';
}
function isPhoneValid(value) {
const clean = (value || '').replace(/\D/g, '');
return clean.length === 12 || clean.length === 13;
}
if (phoneInput) {
phoneInput.addEventListener('input', function () {
phoneInput.value = formatPhone(phoneInput.value);
validateAll();
});
}
/* ===== Birthdate DD-MM-AAAA + 18+ ===== */
function normalizeBirth(value){
return (value || '').trim().replace(/\//g,'-');
}
function parseBirthToDate(value){
const v = (value || '').trim();
// input[type="date"] retorna YYYY-MM-DD
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(v);
if(!m) return null;
const yyyy = parseInt(m[1],10);
const mm = parseInt(m[2],10);
const dd = parseInt(m[3],10);
const d = new Date(yyyy, mm - 1, dd);
if (d.getFullYear() !== yyyy || d.getMonth() !== (mm - 1) || d.getDate() !== dd) return null;
return d;
}
function isAdult18(value){
const d = parseBirthToDate(value);
if(!d) return false;
const now = new Date();
let age = now.getFullYear() - d.getFullYear();
const m = now.getMonth() - d.getMonth();
if (m < 0 || (m === 0 && now.getDate() = 18;
}
/* ===== CEP via ViaCEP ===== */
let cepTimeout;
function fetchCEP(cep) {
const clean = cep.replace(/\D/g, '');
if (clean.length !== 8) return;
fetch(`https://viacep.com.br/ws/${clean}/json/`)
.then(r => r.json())
.then(data => {
if (data.erro) return;
if (addrInput && !addrInput.value) addrInput.value = data.logradouro || '';
if (neighInput && !neighInput.value) neighInput.value = data.bairro || '';
if (cityInput && !cityInput.value) cityInput.value = data.localidade || '';
if (ufSelect) ufSelect.value = data.uf || '';
validateAll();
})
.catch(() => {});
}
if (cepInput) {
cepInput.addEventListener('input', function () {
let digits = cepInput.value.replace(/\D/g, '').slice(0, 8);
if (digits.length >= 6) {
cepInput.value = digits.slice(0, 5) + '-' + digits.slice(5);
} else {
cepInput.value = digits;
}
clearTimeout(cepTimeout);
cepTimeout = setTimeout(() => {
fetchCEP(cepInput.value);
}, 400);
validateAll();
});
}
function isCEPValid(value){
return (value || '').replace(/\D/g,'').length === 8;
}
/* ===== Validação por passos ===== */
function step0Valid(){ return isSelectChosen(stateSelect); }
function step1Valid(){
return (
isNameValid(firstNameInput?.value) &&
isNameValid(lastNameInput?.value) &&
isSelectChosen(bestTimeSelect) &&
isPhoneValid(phoneInput?.value || '') &&
isAdult18(birthdateInput?.value || '')
);
}
function step2Valid(){
return (
isCEPValid(cepInput?.value || '') &&
(addrInput?.value || '').trim().length >= 4 &&
(numberInput?.value || '').trim().length >= 1 &&
(neighInput?.value || '').trim().length >= 2 &&
(cityInput?.value || '').trim().length >= 2 &&
isSelectChosen(ufSelect) &&
!!(consentInput && consentInput.checked)
);
}
function validateAll(){
const activeStep = container.querySelector('.form-step.active');
const activeIndex = activeStep ? parseInt(activeStep.getAttribute('data-step'),10) : 0;
// habilita/desabilita botões do passo atual
const nextBtn0 = container.querySelector('.form-step[data-step="0"] .next-button');
const nextBtn1 = container.querySelector('.form-step[data-step="1"] .next-button');
if (nextBtn0) nextBtn0.disabled = !step0Valid();
if (nextBtn1) nextBtn1.disabled = !step1Valid();
// auto-ajuste: se Região = São Paulo, UF = SP
if (stateSelect && ufSelect && stateSelect.value === 'São Paulo') {
ufSelect.value = 'SP';
}
if (submitButton) {
submitButton.disabled = !(step0Valid() && step1Valid() && step2Valid());
}
}
// listeners gerais (input/change)
[
stateSelect, firstNameInput, lastNameInput, bestTimeSelect,
birthdateInput, ufSelect, addrInput, numberInput, complementInput,
neighInput, cityInput, cepInput, consentInput
].forEach(el => {
if (!el) return;
el.addEventListener('input', validateAll);
el.addEventListener('change', validateAll);
});
validateAll();
/* ===== CF7 (protege para este form) ===== */
function getOwnForm() {
return container.closest('form');
}
document.addEventListener('wpcf7beforesubmit', function (e) {
const ownForm = getOwnForm();
if (!ownForm || !e.target || e.target !== ownForm) return;
if (submitButton) {
submitButton.disabled = true;
submitButton.value = 'Enviando...';
}
clearTimeout(loadingTimeout);
loadingTimeout = setTimeout(() => {
if (submitButton) {
submitButton.disabled = false;
submitButton.value = '+ Quero receber! +';
}
}, 25000);
});
document.addEventListener('wpcf7mailsent', function (e) {
const ownForm = getOwnForm();
if (!ownForm || !e.target || e.target !== ownForm) return;
clearTimeout(loadingTimeout);
if (submitButton) {
submitButton.value = '✅ Enviado!';
submitButton.disabled = true;
}
});
document.addEventListener('wpcf7invalid', function (e) {
const ownForm = getOwnForm();
if (!ownForm || !e.target || e.target !== ownForm) return;
clearTimeout(loadingTimeout);
if (submitButton) {
submitButton.disabled = false;
submitButton.value = '+ Quero receber! +';
}
validateAll();
});
// Expor showStep local via dataset (pra delegação de clique)
container._msShowStep = showStep;
}
// Inicializa containers já existentes
function initAll() {
document.querySelectorAll('.multi-step-form-container').forEach(initMultiStep);
}
// Delegação de clique (resolve “não avança” mesmo quando CF7 re-renderiza)
document.addEventListener('click', function (e) {
const nextBtn = e.target.closest('.next-button');
const prevBtn = e.target.closest('.prev-button');
if (!nextBtn && !prevBtn) return;
const container = e.target.closest('.multi-step-form-container');
if (!container) return;
// garante init mesmo se CF7 inseriu agora
initMultiStep(container);
e.preventDefault();
if (nextBtn) {
const target = parseInt(nextBtn.getAttribute('data-next'), 10);
if (!isNaN(target) && typeof container._msShowStep === 'function') {
container._msShowStep(target);
}
}
if (prevBtn) {
const target = parseInt(prevBtn.getAttribute('data-prev'), 10);
if (!isNaN(target) && typeof container._msShowStep === 'function') {
container._msShowStep(target);
}
}
});
// DOM ready + fallback (caso CF7 injete depois)
document.addEventListener('DOMContentLoaded', initAll);
setTimeout(initAll, 300);
setTimeout(initAll, 1200);
// Observa inserções (caso o CF7 renderize depois via AJAX)
const obs = new MutationObserver(function(){
initAll();
});
obs.observe(document.documentElement, { childList: true, subtree: true });
})();