Votre devis gratuit
Un projet ? Une question ? Parlons-en ensemble.
Construisons ensemble votre projet digital
Merci de prendre quelques minutes pour remplir ce cahier des charges.
Ne complétez que les champs qui vous concernent : plus vos réponses seront précises, plus nous pourrons vous proposer une solution adaptée à vos besoins.
Ce formulaire ne vous engage à rien, il sert uniquement à mieux comprendre votre projet (site internet + SEO):
#dzignweb-form-wrap{max-width:900px;margin:0 auto;padding:0 15px;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif}
#dzignweb-form h2{margin:26px 0 12px;font-size:1.25rem}
#dzignweb-form .row{margin-bottom:16px}
#dzignweb-form label{display:block;font-weight:600;margin:6px 0}
#dzignweb-form input[type=text],
#dzignweb-form input[type=email],
#dzignweb-form input[type=tel],
#dzignweb-form input[type=url],
#dzignweb-form select,
#dzignweb-form textarea{width:100%;padding:12px;border:1px solid #d0d7de;border-radius:6px;font-size:1rem;box-sizing:border-box}
#dzignweb-form textarea{min-height:100px}
#dzignweb-form fieldset{border:1px solid #e5e7eb;padding:12px;border-radius:8px;margin:12px 0}
#dzignweb-form fieldset legend{font-weight:700}
#dzignweb-form button{background:#0ea5e9;color:#fff;border:0;border-radius:8px;padding:14px 22px;font-weight:700;cursor:pointer;width:100%;max-width:260px}
#dzignweb-form .success{background:#ecfdf5;color:#065f46;border:1px solid #a7f3d0;padding:12px;border-radius:8px;margin-top:12px}
#dzignweb-form .error{background:#fef2f2;color:#991b1b;border:1px solid #fecaca;padding:12px;border-radius:8px;margin-top:12px}
#dzignweb-form .error-field{border-color:#dc2626 !important;background-color:#fef2f2}
#dzignweb-form .error-check{outline:2px solid #dc2626; outline-offset:2px; background:#fef2f2; border-radius:6px}
.hidden{display:none}
@media(max-width:768px){
#dzignweb-form h2{font-size:1.1rem}
#dzignweb-form button{width:100%}
}
(function(){
const $ = (s,root=document)=>root.querySelector(s);
const $$ = (s,root=document)=>Array.from(root.querySelectorAll(s));
const form = document.getElementById('dzignweb-form');
const msg = document.getElementById('dzignweb-msg');
// Radios logiques
const mlRadios = $$('.js-ml', form);
const mlDetails = document.getElementById('ml-details');
const ecomRadios = $$('.js-ecom', form);
const ecomDetails = document.getElementById('ecom-details');
const intranetRadios = $$('.js-intranet', form);
const intranetDetails = document.getElementById('intranet-details');
mlRadios.forEach(r=>r.addEventListener('change', ()=> mlDetails.classList.toggle('hidden', form.multilang.value !== 'Oui')));
ecomRadios.forEach(r=>r.addEventListener('change', ()=> ecomDetails.classList.toggle('hidden', form.ecom.value !== 'Oui')));
intranetRadios.forEach(r=>r.addEventListener('change', ()=> intranetDetails.classList.toggle('hidden', form.intranet.value !== 'Oui')));
// Validation en temps réel (text/email/textarea/select requis)
form.querySelectorAll('[required]').forEach(el=>{
if (el.type !== 'checkbox') {
el.addEventListener('blur', ()=>{ if(!(el.value || '').toString().trim()) el.classList.add('error-field'); });
el.addEventListener('input', ()=>{ if((el.value || '').toString().trim()) el.classList.remove('error-field'); });
el.addEventListener('change', ()=>{ if((el.value || '').toString().trim()) el.classList.remove('error-field'); });
}
});
// Consentement RGPD
const consent = form.querySelector('input[name="consent"]');
const consentLabel = consent ? consent.closest('label') : null;
if (consent && consentLabel) {
consent.addEventListener('change', ()=>{ if (consent.checked) consentLabel.classList.remove('error-check'); });
}
// >>> Validation budget (au moins 1 case dans chaque groupe) << 0;
}
function markFieldsetError(fieldsetId, on){
const fs = document.getElementById(fieldsetId);
if(!fs) return;
if(on){ fs.classList.add('error-check'); } else { fs.classList.remove('error-check'); }
}
['budget_range[]','budget_monthly[]'].forEach(name => {
form.querySelectorAll('input[name="'+name+'"]').forEach(cb => {
cb.addEventListener('change', ()=>{
const fsId = name.includes('range') ? 'budget-range-fieldset' : 'budget-monthly-fieldset';
markFieldsetError(fsId, !hasAtLeastOneChecked(name));
});
});
});
form.addEventListener('submit', function(ev){
ev.preventDefault();
msg.innerHTML = '';
// Reset erreurs
form.querySelectorAll('.error-field').forEach(el=>el.classList.remove('error-field'));
if (consentLabel) consentLabel.classList.remove('error-check');
markFieldsetError('budget-range-fieldset', false);
markFieldsetError('budget-monthly-fieldset', false);
// Vérif champs requis (hors checkbox)
let valid = true;
form.querySelectorAll('[required]').forEach(el=>{
if (el.type === 'checkbox') return;
if(!(el.value || '').toString().trim()){ el.classList.add('error-field'); valid = false; }
});
// RGPD
if (consent && !consent.checked) {
if (consentLabel) consentLabel.classList.add('error-check');
msg.innerHTML = '1) Informations générales
— Sélectionner —
0–1011–100Plus de 100
2) Contexte & enjeux
3) Objectifs & public visé
4) Ressources disponibles
5) Charte graphique
6) Arborescence & navigation
7) Fonctions à développer
8) Renseignements techniques
9) Promotion & SEO
9 bis) Budget du projet
10) Pilotage du projet
Consentement & RGPD
Merci d’accepter le RGPD pour continuer.
'; alert('Veuillez accepter le RGPD pour envoyer le formulaire.'); consent.focus(); return; } // Budget checkboxes required const rangeOk = hasAtLeastOneChecked('budget_range[]'); const monthlyOk = hasAtLeastOneChecked('budget_monthly[]'); if (!rangeOk || !monthlyOk) { if (!rangeOk) markFieldsetError('budget-range-fieldset', true); if (!monthlyOk) markFieldsetError('budget-monthly-fieldset', true); msg.innerHTML = 'Merci de sélectionner au moins une option dans chaque section Budget.
'; return; } if(!valid){ msg.innerHTML = 'Merci de remplir tous les champs obligatoires.
'; return; } // Envoi AJAX const data = new FormData(form); fetch('https://www.dzignweb.fr/wp-admin/admin-ajax.php', { method:'POST', credentials:'same-origin', body:data }) .then(r=>r.json()) .then(res=>{ if(res && res.success){ msg.innerHTML = 'Merci ! Votre demande a été envoyée.
'; form.reset(); } else { throw new Error(res && res.data ? res.data : 'Une erreur est survenue.'); } }) .catch(err=>{ msg.innerHTML = ''+ (err.message||'Erreur réseau') +'
'; }); }); })();