Не получается добавить весь список из объектов в json ответе , добавляется только самый первый объект
Не получается добавить весь список из объектов в json ответе , добавляется только самый первый объект , делаю что то типа конструктора анкеты с любым количеством вопросов и в них ответами, теста , и хочу отправить в контроллер JSON объект для дальнейшей обработки , отправляется один объект Survey , состоящий из названия и списка объектов Question , тот в свою очередь тоже состоит из названия и списка из объектов Ansver , а этот состоит из названия и булевого значения. Самое главное, что передаются все объекты Question в списке, но у самого Question в списке ответов добавляется только самый первый ответ , вот пример JSON
{"name":"опрос","questions":
[{"title":"вопрос1","answers":[{"title":"ответ1","isCorrect":false}]},
{"title":"вопрос2","answers":[{"title":"ответ1","isCorrect":true}]}]}
вот html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="view" content="width=device-width, initial-scale=1.0">
<title>Вопросы и ответы</title>
<link rel="stylesheet" type="text/css" href="/static/new.css">
</head>
<body>
<h1>Вопросы и ответы</h1>
<form th:action="@{/survey}" method="post" enctype="application/json">
<div class="button-container">
<button type="button" class="add-question-button">Добавить вопрос</button>
<input type="submit" class="save-button" value="Сохранить опрос">
</div>
<div class="survey-name-container">
<label for="survey-name">Название опроса:</label>
<input type="text" name="survey-name" id="survey-name">
</div>
<div class="question-container hidden">
<label for="question-title">Текст вопроса:</label>
<input type="text" name="question-title" id="question-title">
<div class="answer-container">
<label for="answer-title">Текст ответа:</label>
<input type="text" name="answer-title" id="answer-title">
<label for="is-correct">Является ли правильным:</label>
<input type="checkbox" name="is-correct" id="is-correct">
<input type="hidden" name="is-correct" value="">
<button type="button" class="add-answer-button">Добавить ответ</button>
</div>
</div>
<div class="dynamic-container">
<!-- Динамический контент -->
</div>
</form>
<script>
const addQuestionButton = document.querySelector('.add-question-button');
const questionContainers = document.querySelectorAll('.question-container');
const dynamicContainer = document.querySelector('.dynamic-container');
addQuestionButton.addEventListener('click', () => {
const lastQuestionContainer = questionContainers[questionContainers.length - 1];
// Клонируем последний контейнер с вопросом
const newQuestionContainer = lastQuestionContainer.cloneNode(true);
// Очищаем поля в новых вопросах
const questionTitleInput = newQuestionContainer.querySelector('#question-title');
questionTitleInput.value = '';
// Очищаем поля в новых ответах
const answerContainer = newQuestionContainer.querySelector('.answer-container');
const answerTitle = answerContainer.querySelectorAll('#answer-title');
answerTitle.forEach(input => {
input.value = '';
});
// Добавляем обработку событий для кнопки добавления ответа
const addAnswerButton = answerContainer.querySelector('.add-answer-button');
addAnswerButton.addEventListener('click', () => {
const newAnswer = document.createElement('div');
newAnswer.innerHTML = `
<label for="answer-title">Текст ответа:</label>
<input type="text" name="answer-title" id="answer-title">
<label for="is-correct">Является ли правильным:</label>
<input type="checkbox" name="is-correct" id="is-correct">
`;
answerContainer.appendChild(newAnswer);
});
// Добавляем новый вопрос в динамический контент
dynamicContainer.appendChild(newQuestionContainer);
});
questionContainers.forEach(container => {
const addAnswerButton = container.querySelector('.add-answer-button');
addAnswerButton.addEventListener('click', () => {
const newAnswer = document.createElement('div');
newAnswer.innerHTML = `
<label for="answer-title">Текст ответа:</label>
<input type="text" name="answer-title" id="answer-title">
<label for="is-correct">Является ли правильным:</label>
<input type="checkbox" name="is-correct" id="is-correct">
`;
container.querySelector('.answer-container').appendChild(newAnswer);
});
});
// Создаем объект опроса
const survey = {
name: '',
questions: []
};
// Создаем объект вопроса
const question = {
title: '',
answers: []
};
// Создаем объект ответа
const answer = {
title: '',
isCorrect: false
};
// Добавляем обработку события "submit" для формы
const form = document.querySelector('form');
form.addEventListener('submit', (event) => {
event.preventDefault();
// Получаем название опроса
const surveyName = document.querySelector('#survey-name').value;
// Устанавливаем название опроса
survey.name = surveyName;
// Получаем все контейнеры с вопросами
const questionContainers = document.querySelectorAll('.question-container');
// Итерируем по контейнерам с вопросами
questionContainers.forEach(container => {
// Получаем заголовок вопроса
const questionTitle = container.querySelector('#question-title').value;
// Создаем новый объект вопроса
const newQuestion = {
title: questionTitle,
answers: []
};
// Получаем все контейнеры с ответами
const answerContainers = container.querySelectorAll('.answer-container');
// Итерируем по контейнерам с ответами
answerContainers.forEach(answerContainer => {
// Получаем заголовок ответа
const answerTitle = answerContainer.querySelector('#answer-title').value;
// Получаем флаг правильности ответа
const isCorrect = answerContainer.querySelector('#is-correct').checked;
// Создаем новый объект ответа
const newAnswer = {
title: answerTitle,
isCorrect: isCorrect
};
// Добавляем новый объект ответа в массив ответов
newQuestion.answers.push(newAnswer);
});
// Добавляем новый объект вопроса в массив вопросов
survey.questions.push(newQuestion);
});
// Отправляем данные на сервер
const data = JSON.stringify(survey);
const xhr = new XMLHttpRequest();
console.log(JSON.stringify(data, null, 2));
xhr.open('POST', '/survey', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(data);
});
</script>
</body>
</html>
не понимаю что не так, со списком из Question работает, а Ansver не собирается , а добавляется только самый первый элемент...
Ответы (1 шт):
У Вас проблема с неправильной вложенностью элементов в div class="answer-container", первоначально добавлены элементы label, input, но когда добавляется следующий ответ, то вложенность становится неправильной. Это можно увидеть в консоли браузера на вкладке Elements (на скриншоте она есть), когда доберетесь до нужного элемента. Также неправильный поиск ответов через querySelectorAll.
<div class="answer-container">
<label .../> <input...>
<div name="новый ответ" > <label .../> <input...> </div>
</div>
Исправил вложенность для первого ответа, исправил получение всех ответов const answerContainers = container.querySelector('.answer-container').children и его перебор в цикле. Другие ошибки не исправлял.
const addQuestionButton = document.querySelector('.add-question-button');
const questionContainers = document.querySelectorAll('.question-container');
const dynamicContainer = document.querySelector('.dynamic-container');
addQuestionButton.addEventListener('click', () => {
const lastQuestionContainer = questionContainers[questionContainers.length - 1];
// Клонируем последний контейнер с вопросом
const newQuestionContainer = lastQuestionContainer.cloneNode(true);
// Очищаем поля в новых вопросах
const questionTitleInput = newQuestionContainer.querySelector('#question-title');
questionTitleInput.value = '';
// Очищаем поля в новых ответах
const answerContainer = newQuestionContainer.querySelector('.answer-container');
const answerTitle = answerContainer.querySelectorAll('#answer-title');
answerTitle.forEach(input => {
input.value = '';
});
// Добавляем обработку событий для кнопки добавления ответа
const addAnswerButton = answerContainer.querySelector('.add-answer-button');
addAnswerButton.addEventListener('click', () => {
const newAnswer = document.createElement('div');
newAnswer.innerHTML = `
<label for="answer-title">Текст ответа:</label>
<input type="text" name="answer-title" id="answer-title">
<label for="is-correct">Является ли правильным:</label>
<input type="checkbox" name="is-correct" id="is-correct">
`;
answerContainer.appendChild(newAnswer);
});
// Добавляем новый вопрос в динамический контент
dynamicContainer.appendChild(newQuestionContainer);
});
questionContainers.forEach(container => {
const addAnswerButton = container.querySelector('.add-answer-button');
addAnswerButton.addEventListener('click', () => {
const newAnswer = document.createElement('div');
newAnswer.innerHTML = `
<label for="answer-title">Текст ответа:</label>
<input type="text" name="answer-title" id="answer-title">
<label for="is-correct">Является ли правильным:</label>
<input type="checkbox" name="is-correct" id="is-correct">
`;
container.querySelector('.answer-container').appendChild(newAnswer);
});
});
// Создаем объект опроса
const survey = {
name: '',
questions: []
};
// Создаем объект вопроса
const question = {
title: '',
answers: []
};
// Создаем объект ответа
const answer = {
title: '',
isCorrect: false
};
// Добавляем обработку события "submit" для формы
const form = document.querySelector('form');
form.addEventListener('submit', (event) => {
event.preventDefault();
// Получаем название опроса
const surveyName = document.querySelector('#survey-name').value;
// Устанавливаем название опроса
survey.name = surveyName;
// Получаем все контейнеры с вопросами
const questionContainers = document.querySelectorAll('.question-container');
// Итерируем по контейнерам с вопросами
questionContainers.forEach(container => {
// Получаем заголовок вопроса
const questionTitle = container.querySelector('#question-title').value;
// Создаем новый объект вопроса
const newQuestion = {
title: questionTitle,
answers: []
};
// Получаем все контейнеры с ответами
const answerContainers = container.querySelector('.answer-container').children;
// Итерируем по контейнерам с ответами
for (var i = 0; i < answerContainers.length; i++) {
var answerContainer = answerContainers[i];
// Получаем заголовок ответа
const answerTitle = answerContainer.querySelector('#answer-title').value;
// Получаем флаг правильности ответа
const isCorrect = answerContainer.querySelector('#is-correct').checked;
// Создаем новый объект ответа
const newAnswer = {
title: answerTitle,
isCorrect: isCorrect
};
// Добавляем новый объект ответа в массив ответов
newQuestion.answers.push(newAnswer);
};
// Добавляем новый объект вопроса в массив вопросов
survey.questions.push(newQuestion);
});
// Отправляем данные на сервер
const data = JSON.stringify(survey);
const xhr = new XMLHttpRequest();
console.log(JSON.stringify(data, null, 2));
xhr.open('POST', '/survey', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(data);
});
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="view" content="width=device-width, initial-scale=1.0">
<title>Вопросы и ответы</title>
<link rel="stylesheet" type="text/css" href="/static/new.css">
</head>
<body>
<h1>Вопросы и ответы</h1>
<form th:action="@{/survey}" method="post" enctype="application/json">
<div class="button-container">
<button type="button" class="add-question-button">Добавить вопрос</button>
<input type="submit" class="save-button" value="Сохранить опрос">
</div>
<div class="survey-name-container">
<label for="survey-name">Название опроса:</label>
<input type="text" name="survey-name" id="survey-name">
</div>
<div class="question-container hidden">
<label for="question-title">Текст вопроса:</label>
<input type="text" name="question-title" id="question-title">
<div class="answer-container">
<div>
<label for="answer-title">Текст ответа:</label>
<input type="text" name="answer-title" id="answer-title">
<label for="is-correct">Является ли правильным:</label>
<input type="checkbox" name="is-correct" id="is-correct">
<input type="hidden" name="is-correct" value="">
<button type="button" class="add-answer-button">Добавить ответ</button>
</div>
</div>
</div>
<div class="dynamic-container">
<!-- Динамический контент -->
</div>
</form>
</body>
</html>
