Egyszerű, dinamikus kérdőív JavaScript-tel

Ebben a példában bemutatjuk, hogyan hozhatsz létre egy egyszerű, dinamikus kérdőívet JavaScript segítségével. A kérdőív alapja egy HTML <form> elem, amelyben egy konténerben jelenítjük meg a kérdéseket, valamint egy gombbal indítjuk a kérdőív generálását vagy elküldését. A JavaScript feladata, hogy egy adatszerkezet (pl. tömb) alapján felépítse a kérdéseket és válaszlehetőségeket, majd a felhasználó válaszait összegyűjtse és feldolgozza.

Alap HTML váz:

<form id="quizForm">
  <div id="questionsContainer"></div>
  <button type="button" id="submitBtn">Eredmény elküldése</button>
</form>
<div id="result"></div>

A questionsContainer div-be fogjuk JavaScript-tel beszúrni a kérdéseket és input mezőket. A submitBtn gombhoz eseménykezelőt kapcsolunk, amely a válaszok összegyűjtését és feldolgozását végzi. A result div-ben jeleníthetjük meg az eredményt vagy visszajelzést.

A kérdéseket érdemes egy JavaScript tömbben tárolni:

const questions = [
  {
    text: "Melyik a kedvenc programozási nyelved?",
    type: "radio",
    name: "favLang",
    options: ["JavaScript", "Python", "Java", "C#"]
  },
  {
    text: "Hány éve programozol?",
    type: "select",
    name: "experience",
    options: ["0-1", "2-3", "4-5", "5+"]
  },
  {
    text: "Miért szeretnél kérdőívet készíteni?",
    type: "textarea",
    name: "reason"
  }
];

Ezután egy függvénnyel dinamikusan felépítjük a HTML-t:

function renderQuestions() {
  const container = document.getElementById('questionsContainer');
  container.innerHTML = '';

  questions.forEach((q, index) => {
    const wrapper = document.createElement('div');
    wrapper.className = 'question';

    const label = document.createElement('label');
    label.textContent = (index + 1) + '. ' + q.text;
    wrapper.appendChild(label);

    if (q.type === 'radio') {
      q.options.forEach(option => {
        const optWrapper = document.createElement('div');
        const input = document.createElement('input');
        input.type = 'radio';
        input.name = q.name;
        input.value = option;

        const span = document.createElement('span');
        span.textContent = option;

        optWrapper.appendChild(input);
        optWrapper.appendChild(span);
        wrapper.appendChild(optWrapper);
      });
    } else if (q.type === 'select') {
      const select = document.createElement('select');
      select.name = q.name;
      q.options.forEach(option => {
        const opt = document.createElement('option');
        opt.value = option;
        opt.textContent = option;
        select.appendChild(opt);
      });
      wrapper.appendChild(select);
    } else if (q.type === 'textarea') {
      const textarea = document.createElement('textarea');
      textarea.name = q.name;
      wrapper.appendChild(textarea);
    } else {
      const input = document.createElement('input');
      input.type = q.type;
      input.name = q.name;
      wrapper.appendChild(input);
    }

    container.appendChild(wrapper);
  });
}

document.addEventListener('DOMContentLoaded', renderQuestions);

A fenti kód a questions tömb alapján hozza létre a megfelelő HTML elemeket: rádiógombokat, legördülő listát, szövegterületet vagy egyszerű input mezőt. A name attribútum kulcsfontosságú, mert ezen keresztül tudjuk később az értékeket kiolvasni.

A válaszok összegyűjtéséhez a beküldés gombhoz eseménykezelőt adunk:

document.getElementById('submitBtn').addEventListener('click', function () {
  const form = document.getElementById('quizForm');
  const formData = new FormData(form);

  const answers = {};
  questions.forEach(q => {
    answers[q.name] = formData.getAll(q.name).length > 1
      ? formData.getAll(q.name)
      : formData.get(q.name);
  });

  // Eredmény kiírása a képernyőre
  const resultDiv = document.getElementById('result');
  resultDiv.innerHTML = '<h3>Válaszaid:</h3><pre>' +
    JSON.stringify(answers, null, 2) + '</pre>';

  // Elküldés a szervernek (példa fetch-csel)
  /*
  fetch('/save-quiz', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(answers)
  })
  .then(res => res.json())
  .then(data => {
    console.log('Szerver válasza:', data);
  })
  .catch(err => console.error(err));
  */
});

Itt a FormData objektum segítségével gyűjtjük össze az űrlap mezőinek értékeit. A get és getAll metódusokkal egyszerűen kiolvashatjuk az egyes kérdésekhez tartozó válaszokat. Az eredményt kiírhatjuk a képernyőre (pl. JSON formában), vagy elküldhetjük a szervernek fetch hívással. A szerver oldalon tetszőleges módon feldolgozhatjuk és eltárolhatjuk az adatokat.

Összefoglalva: szükségünk van egy <form> elemre, benne egy konténerre a kérdéseknek, egy gombra a beküldéshez, valamint egy JavaScript adatszerkezetre, amely leírja a kérdéseket és válaszlehetőségeket. A JavaScript dinamikusan építi fel a HTML-t, eseménykezelőkkel reagál a gombnyomásra, és a válaszokat vagy a felhasználónak jeleníti meg, vagy a szervernek küldi tovább.

JavaScript kérdőív kérdéstípusok és dinamikus űrlapkezelés

Az alábbiakban gyakorlati példákat látsz különböző kérdéstípusokra, amelyeket JavaScript-tel hozhatsz létre és dinamikusan adhatsz hozzá egy kérdőívhez. A példák egyszerű, mégis jól bővíthető minták.

1. Feleletválasztós kérdések (radio, checkbox)

Radio (egy válasz):

const form = document.getElementById('quiz');

function addRadioQuestion(id, label, options, required = false) {
  const wrapper = document.createElement('div');
  wrapper.dataset.required = required;
  wrapper.dataset.questionId = id;

  const title = document.createElement('p');
  title.textContent = label + (required ? ' *' : '');
  wrapper.appendChild(title);

  options.forEach((opt, i) => {
    const input = document.createElement('input');
    input.type = 'radio';
    input.name = id;
    input.value = opt;

    const span = document.createElement('span');
    span.textContent = opt;

    const labelEl = document.createElement('label');
    labelEl.appendChild(input);
    labelEl.appendChild(span);

    wrapper.appendChild(labelEl);
  });

  form.appendChild(wrapper);
}

addRadioQuestion('q1', 'Melyik a kedvenc nyelved?', ['JavaScript', 'Python', 'Java'], true);

Checkbox (több válasz):

function addCheckboxQuestion(id, label, options, required = false) {
  const wrapper = document.createElement('div');
  wrapper.dataset.required = required;
  wrapper.dataset.questionId = id;

  const title = document.createElement('p');
  title.textContent = label + (required ? ' *' : '');
  wrapper.appendChild(title);

  options.forEach(opt => {
    const input = document.createElement('input');
    input.type = 'checkbox';
    input.name = id;
    input.value = opt;

    const span = document.createElement('span');
    span.textContent = opt;

    const labelEl = document.createElement('label');
    labelEl.appendChild(input);
    labelEl.appendChild(span);

    wrapper.appendChild(labelEl);
  });

  form.appendChild(wrapper);
}

addCheckboxQuestion('q2', 'Mely technológiákat használod?', ['HTML', 'CSS', 'JavaScript'], true);

2. Szöveges válasz (input, textarea)

function addTextQuestion(id, label, multiline = false, required = false) {
  const wrapper = document.createElement('div');
  wrapper.dataset.required = required;
  wrapper.dataset.questionId = id;

  const title = document.createElement('label');
  title.textContent = label + (required ? ' *' : '');
  title.htmlFor = id;
  wrapper.appendChild(title);

  let input;
  if (multiline) {
    input = document.createElement('textarea');
  } else {
    input = document.createElement('input');
    input.type = 'text';
  }
  input.id = id;
  input.name = id;

  wrapper.appendChild(input);
  form.appendChild(wrapper);
}

addTextQuestion('q3', 'Miért szeretsz programozni?', true, true);

3. Értékelő skála (1–5)

function addScaleQuestion(id, label, min = 1, max = 5, required = false) {
  const wrapper = document.createElement('div');
  wrapper.dataset.required = required;
  wrapper.dataset.questionId = id;

  const title = document.createElement('p');
  title.textContent = label + ` (${min}-${max})` + (required ? ' *' : '');
  wrapper.appendChild(title);

  for (let i = min; i <= max; i++) {
    const input = document.createElement('input');
    input.type = 'radio';
    input.name = id;
    input.value = i;

    const span = document.createElement('span');
    span.textContent = i;

    const labelEl = document.createElement('label');
    labelEl.appendChild(input);
    labelEl.appendChild(span);

    wrapper.appendChild(labelEl);
  }

  form.appendChild(wrapper);
}

addScaleQuestion('q4', 'Mennyire érzed magad magabiztosnak JS-ben?', 1, 5, true);

4. Legördülő lista (select)

function addSelectQuestion(id, label, options, required = false) {
  const wrapper = document.createElement('div');
  wrapper.dataset.required = required;
  wrapper.dataset.questionId = id;

  const title = document.createElement('label');
  title.textContent = label + (required ? ' *' : '');
  title.htmlFor = id;
  wrapper.appendChild(title);

  const select = document.createElement('select');
  select.id = id;
  select.name = id;

  const placeholder = document.createElement('option');
  placeholder.value = '';
  placeholder.textContent = 'Válassz...';
  select.appendChild(placeholder);

  options.forEach(opt => {
    const optionEl = document.createElement('option');
    optionEl.value = opt;
    optionEl.textContent = opt;
    select.appendChild(optionEl);
  });

  wrapper.appendChild(select);
  form.appendChild(wrapper);
}

addSelectQuestion('q5', 'Milyen szinten vagy?', ['Kezdő', 'Középhaladó', 'Haladó'], true);

5. Dinamikus hozzáadás és kötelező kérdések ellenőrzése

Űrlap létrehozása és eseménykezelés:

document.addEventListener('DOMContentLoaded', () => {
  const form = document.getElementById('quiz');

  // Itt hívod meg a fenti add*Question függvényeket

  form.onsubmit = function (event) {
    event.preventDefault();
    const isValid = validateRequiredQuestions(form);
    if (!isValid) {
      alert('Kérlek, válaszolj minden kötelező kérdésre!');
      return;
    }
    alert('Köszönjük a kitöltést!');
  };
});

Kötelező kérdések ellenőrzése:

function validateRequiredQuestions(form) {
  let valid = true;

  const questions = form.querySelectorAll('div[data-required="true"]');

  questions.forEach(q => {
    const name = q.dataset.questionId;
    let answered = false;

    const inputs = q.querySelectorAll('input, textarea, select');

    inputs.forEach(input => {
      if (input.type === 'radio' || input.type === 'checkbox') {
        const group = form.querySelectorAll(`input[name="${input.name}"]`);
        answered = Array.from(group).some(i => i.checked);
      } else if (input.tagName === 'SELECT') {
        answered = input.value !== '';
      } else {
        answered = input.value.trim() !== '';
      }
    });

    if (!answered) {
      valid = false;
      q.classList.add('error');
    } else {
      q.classList.remove('error');
    }
  });

  return valid;
}

6. Eseménykezelés (onclick, onsubmit) és hibakezelés

onclick: gombokhoz, például új kérdés dinamikus hozzáadásához:

document.getElementById('add-question-btn').onclick = function () {
  addTextQuestion('q_new', 'Új dinamikus kérdés', false, false);
};

onsubmit: az űrlap elküldésekor fut le, itt végzed az ellenőrzést és a hibakezelést (pl. alert, hibaüzenet kiírása a DOM-ba).

Alap hibakezelés: ha a validáció hibát talál, jelezd a felhasználónak:

  • globális üzenet: alert('Hibaüzenet') vagy egy hiba <div> frissítése,
  • mezőszintű jelzés: CSS osztály (.error) hozzáadása a hibás kérdéshez, piros keret, kis szöveges figyelmeztetés.

Ezekkel az alapokkal rugalmas, dinamikusan bővíthető kérdőívet tudsz készíteni JavaScript segítségével.

Teszteld JavaScript-alapú kérdőívünket most, valós időben!