This is a custom code placeholder.
Switch to Preview or publish the page
to see how your code works.
Double-click to edit
<!-- Softinet – Formularz pobrania e-booka (345 px, walidacja dopiero przy submit) -->
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet">
<div id="softinet-form-wrapper">
<style>
#softinet-form-wrapper {
font-family: 'Poppins', system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
color: #000;
text-align: center;
}
#softinet-form {
width: 345px;
margin: 0 auto;
background: transparent;
border: none;
padding: 0;
text-align: left;
}
.field {
display: flex;
flex-direction: column;
gap: 6px;
margin-bottom: 14px;
}
.input-base {
width: 100%;
background: #f2f2f2;
border: 1px solid #e5e5e5;
border-radius: 8px;
padding: 10px 14px;
font-size: 16px;
color: #000;
outline: none;
transition: box-shadow .12s ease, border-color .12s ease;
}
.input-base::placeholder {
color: #000;
opacity: 0.7;
}
.input-base:focus {
border-color: #048fcc;
box-shadow: 0 0 0 3px rgba(4, 143, 204, .12);
background: #fff;
}
.consents {
display: flex;
flex-direction: column;
gap: 10px;
margin: 14px 0 10px;
}
.consent-item {
display: flex;
gap: 10px;
align-items: flex-start;
}
.consent-item input[type="checkbox"] {
width: 16px;
height: 16px;
margin-top: 3px;
}
.consent-text {
font-size: 12px;
line-height: 1.4;
color: #000;
}
.consent-text a {
color: #000;
text-decoration: underline;
}
.error {
color: #d40000;
font-size: 12px;
margin-top: 4px;
display: none;
}
.show-error { display: block; }
.actions { text-align: center; margin-top: 16px; }
.btn {
display: inline-block;
width: 100%;
max-width: 345px;
background: #048fcc;
color: #fff;
border: none;
border-radius: 8px;
padding: 12px 26px;
font-weight: 600;
font-size: 16px;
cursor: pointer;
font-family: 'Poppins', system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
}
.btn:hover { filter: brightness(1.05); }
.btn:active { transform: translateY(1px); }
</style>
<form id="softinet-form" action="https://app.getresponse.com/add_subscriber.html" method="post" novalidate>
<!-- GetResponse -->
<input type="hidden" name="campaign_token" value="XjWe7">
<input type="hidden" name="thankyou_url" value="https://noc.softinet.com.pl/thank_you.html">
<input type="hidden" name="start_day" value="0">
<input type="hidden" name="custom_source" value="Landing page">
<input type="hidden" id="name_full" name="name" value="">
<div class="field">
<input type="text" id="first_name" name="custom_imie" class="input-base" placeholder="Imię *" required>
<div class="error" data-error-for="first_name">Podaj imię.</div>
</div>
<div class="field">
<input type="text" id="last_name" name="custom_nazwisko" class="input-base" placeholder="Nazwisko *" required>
<div class="error" data-error-for="last_name">Podaj nazwisko.</div>
</div>
<div class="field">
<input type="email" id="email" name="email" class="input-base" placeholder="Adres e-mail *" required>
<div class="error" data-error-for="email">Podaj poprawny adres e-mail.</div>
</div>
<div class="field">
<input type="text" id="company" name="custom_company" class="input-base" placeholder="Nazwa firmy *" required>
<div class="error" data-error-for="company">Podaj nazwę firmy.</div>
</div>
<div class="field">
<input type="text" id="job_title" name="custom_job_title" class="input-base" placeholder="Stanowisko *" required>
<div class="error" data-error-for="job_title">Podaj stanowisko.</div>
</div>
<div class="field">
<input type="text" id="phone_number" name="phone_display" class="input-base" placeholder="Numer telefonu (+48...) *" inputmode="tel" autocomplete="tel" required>
<input type="hidden" id="phone_e164" name="custom_phone" value="">
<div class="error" data-error-for="phone">Podaj poprawny numer telefonu w formacie +48XXXXXXXXX.</div>
</div>
<div class="consents">
<p class="consent-text">
Chcę otrzymywać od Softinet Sp. z o.o. z siedzibą w Warszawie informacje o ofercie, nowościach i promocjach dotyczących tej spółki oraz I Know IT Szymański Bojar sp. k. z siedzibą w Warszawie:
</p>
<label class="consent-item">
<input type="checkbox" id="consent_channel_email" name="custom_consent_email_marketing" value="yes">
<span class="consent-text">Emailem</span>
</label>
<label class="consent-item">
<input type="checkbox" id="consent_channel_phone" name="custom_consent_phone_marketing" value="yes">
<span class="consent-text">Telefonicznie</span>
</label>
<div class="error" id="channels_error">Zaznacz oba kanały kontaktu.</div>
<p class="consent-text">
Jeżeli chcesz uzyskać dostęp do materiału bez zapisywania się do newslettera, skontaktuj się z nami:
<a href="mailto:softinet@softinet.com.pl">softinet@softinet.com.pl</a>.
</p>
<p class="consent-text">
Administratorem Twoich danych osobowych jest Softinet Sp. z o.o. z siedzibą w Warszawie. Przeczytaj w naszej
<a href="https://softinet.com.pl/polityka-prywatnosci/" target="_blank" rel="noopener">Polityce prywatności i cookies</a>
jak przetwarzamy Twoje dane.
</p>
</div>
<div class="actions">
<button type="submit" class="btn">Pobieram e-book</button>
</div>
</form>
<script>
(function () {
const form = document.getElementById('softinet-form');
const first = document.getElementById('first_name');
const last = document.getElementById('last_name');
const email = document.getElementById('email');
const company = document.getElementById('company');
const job = document.getElementById('job_title');
const phoneInput = document.getElementById('phone_number');
const phoneE164 = document.getElementById('phone_e164');
const nameFull = document.getElementById('name_full');
const chEmail = document.getElementById('consent_channel_email');
const chPhone = document.getElementById('consent_channel_phone');
const channelsError = document.getElementById('channels_error');
const emailRe = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i;
// flaga: czy użytkownik próbował wysłać formularz
let triedSubmit = false;
function showError(key, show) {
const el = form.querySelector(`.error[data-error-for="${key}"]`);
if (el) el.classList.toggle('show-error', !!show);
}
function toPL_E164(raw) {
if (!raw) return '';
let s = String(raw).replace(/[^\d+]/g, '');
if (s.startsWith('0048')) s = '+' + s.slice(2);
if (/^48\d{9}$/.test(s)) s = '+' + s;
if (/^\d{9}$/.test(s)) s = '+48' + s;
s = s.replace(/[^\d+]/g, '');
return /^\+48\d{9}$/.test(s) ? s : '';
}
function validateFieldset(showErrors) {
let ok = true;
const fnEmpty = !first.value.trim();
const lnEmpty = !last.value.trim();
const emBad = !emailRe.test(email.value.trim());
const coEmpty = !company.value.trim();
const jobEmpty= !job.value.trim();
const phoneNormalized = toPL_E164(phoneInput.value);
const phoneBad = !phoneNormalized;
const bothChecked = chEmail.checked && chPhone.checked;
if (showErrors) {
showError('first_name', fnEmpty);
showError('last_name', lnEmpty);
showError('email', emBad);
showError('company', coEmpty);
showError('job_title', jobEmpty);
showError('phone', phoneBad);
channelsError.classList.toggle('show-error', !bothChecked);
} else {
// przy wpisywaniu w pojedyncze pole pokazujemy tylko jego błąd
// (reszty nie ruszamy, żeby nie "rozpychać" formularza)
}
if (fnEmpty || lnEmpty || emBad || coEmpty || jobEmpty || phoneBad || !bothChecked) ok = false;
return { ok, phoneNormalized };
}
// walidacja pojedynczego pola dopiero po próbie submitu
[first, last, email, company, job, phoneInput, chEmail, chPhone].forEach(el => {
el.addEventListener('input', () => {
if (!triedSubmit) return;
const { phoneNormalized } = validateFieldset(true);
// jeśli poprawny telefon, aktualizujemy hidden
if (phoneNormalized) phoneE164.value = phoneNormalized;
});
el.addEventListener('change', () => {
if (!triedSubmit) return;
validateFieldset(true);
});
});
form.addEventListener('submit', function (e) {
e.preventDefault();
triedSubmit = true;
// scal imię i nazwisko
nameFull.value = [first.value.trim(), last.value.trim()].filter(Boolean).join(' ').trim();
const { ok, phoneNormalized } = validateFieldset(true);
phoneE164.value = phoneNormalized || '';
if (!ok) {
const firstErr = form.querySelector('.error.show-error');
if (firstErr && firstErr.scrollIntoView) {
firstErr.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
return false;
}
// wszystko ok → wysyłamy do GetResponse
form.submit();
});
})();
</script>
</div>