multy-stub/server/routers/questioneer/public/static/js/edit.js

356 lines
14 KiB
JavaScript
Raw Normal View History

2025-03-11 23:50:50 +03:00
/* global $, window, document, showAlert, showConfirm, showQRCodeModal */
$(document).ready(function() {
const form = $('#edit-questionnaire-form');
const questionsList = $('#questions-list');
const addQuestionBtn = $('#add-question');
const adminLink = window.location.pathname.split('/').pop();
let questionCount = 0;
let questionnaireData = null;
2025-03-12 00:09:36 +03:00
// Функция для получения базового пути API
2025-03-11 23:50:50 +03:00
const getApiPath = () => {
2025-03-12 00:09:36 +03:00
// Проверяем, содержит ли путь /ms/ (продакшн на dev.bro-js.ru)
const pathname = window.location.pathname;
const isMsPath = pathname.includes('/ms/questioneer');
if (isMsPath) {
// Для продакшна: если в пути есть /ms/, то API доступно по /ms/questioneer/api
return '/ms/questioneer/api';
} else {
// Для локальной разработки: используем обычный путь
// Извлекаем базовый путь из URL страницы
const pathParts = pathname.split('/');
// Если последний сегмент пустой (из-за /) - удаляем его
if (pathParts[pathParts.length - 1] === '') {
pathParts.pop();
}
// Путь до корня приложения
return pathParts.join('/') + '/api';
}
2025-03-11 23:50:50 +03:00
};
// Загрузка данных опроса
const loadQuestionnaire = () => {
$.ajax({
url: `${getApiPath()}/questionnaires/admin/${adminLink}`,
method: 'GET',
success: function(result) {
if (result.success) {
questionnaireData = result.data;
fillFormData();
$('#loading').hide();
$('#edit-form-container').show();
} else {
$('#loading').text(`Ошибка: ${result.error}`);
}
},
error: function(error) {
console.error('Error loading questionnaire:', error);
$('#loading').text('Не удалось загрузить опрос. Пожалуйста, попробуйте позже.');
}
});
};
// Заполнение формы данными опроса
const fillFormData = () => {
// Заполняем основные данные
$('#title').val(questionnaireData.title);
$('#description').val(questionnaireData.description || '');
$('#display-type').val(questionnaireData.displayType);
// Формируем ссылки
const baseUrl = window.location.origin;
const baseQuestionnairePath = window.location.pathname.split('/edit')[0];
const publicUrl = `${baseUrl}${baseQuestionnairePath}/poll/${questionnaireData.publicLink}`;
const adminUrl = `${baseUrl}${baseQuestionnairePath}/admin/${questionnaireData.adminLink}`;
$('#public-link').val(publicUrl);
$('#admin-link').val(adminUrl);
// Добавляем вопросы
questionsList.empty();
if (questionnaireData.questions && questionnaireData.questions.length > 0) {
questionnaireData.questions.forEach((question, index) => {
addQuestion(question);
});
} else {
// Если нет вопросов, добавляем пустой
addQuestion();
}
renumberQuestions();
};
// Добавление нового вопроса
addQuestionBtn.on('click', function() {
addQuestion();
renumberQuestions();
});
// Обработка отправки формы
form.on('submit', function(e) {
e.preventDefault();
saveQuestionnaire();
});
// Делегирование событий для динамических элементов
questionsList.on('click', '.delete-question', function() {
// Удаление вопроса
const questionItem = $(this).closest('.question-item');
questionItem.remove();
renumberQuestions();
});
questionsList.on('click', '.add-option', function() {
// Добавление варианта ответа
const questionIndex = $(this).data('question-index');
addOption(questionIndex);
});
questionsList.on('click', '.delete-option', function() {
// Удаление варианта ответа
$(this).closest('.option-item').remove();
});
// Делегирование для изменения типа вопроса
questionsList.on('change', '.question-type-select', function() {
const questionItem = $(this).closest('.question-item');
const questionIndex = questionItem.data('index');
const optionsContainer = $(`#options-container-${questionIndex}`);
const scaleContainer = $(`#scale-container-${questionIndex}`);
// Показываем/скрываем контейнеры в зависимости от типа вопроса
const questionType = $(this).val();
if (['single_choice', 'multiple_choice', 'tag_cloud'].includes(questionType)) {
optionsContainer.show();
scaleContainer.hide();
// Если нет вариантов, добавляем два
const optionsList = $(`#options-list-${questionIndex}`);
if (optionsList.children().length === 0) {
addOption(questionIndex);
addOption(questionIndex);
}
// Включаем required для полей ввода вариантов
optionsList.find('input[type="text"]').prop('required', true);
} else if (questionType === 'scale') {
optionsContainer.hide();
scaleContainer.show();
// Отключаем required для скрытых полей
$(`#options-list-${questionIndex}`).find('input[type="text"]').prop('required', false);
} else {
optionsContainer.hide();
scaleContainer.hide();
// Отключаем required для скрытых полей
$(`#options-list-${questionIndex}`).find('input[type="text"]').prop('required', false);
}
});
// Копирование ссылок
$('#copy-public-link').on('click', function() {
$('#public-link').select();
document.execCommand('copy');
showAlert('Ссылка для голосования скопирована в буфер обмена', 'Копирование');
});
$('#copy-admin-link').on('click', function() {
$('#admin-link').select();
document.execCommand('copy');
showAlert('Административная ссылка скопирована в буфер обмена', 'Копирование');
});
// Отображение QR-кода
$('#show-qr-code').on('click', function() {
const publicUrl = $('#public-link').val();
showQRCodeModal(publicUrl, 'QR-код для голосования');
});
// Возврат к админке
$('#back-to-admin').on('click', function(e) {
e.preventDefault();
const basePath = window.location.pathname.split('/edit')[0];
window.location.href = `${basePath}/admin/${adminLink}`;
});
// Функция для добавления нового вопроса
function addQuestion(questionData) {
const template = $('#question-template').html();
const index = questionCount++;
// Заменяем плейсхолдеры в шаблоне
let questionHtml = template
.replace(/\{\{index\}\}/g, index)
.replace(/\{\{number\}\}/g, index + 1);
questionsList.append(questionHtml);
// Если есть данные вопроса - заполняем поля
if (questionData) {
$(`#question-text-${index}`).val(questionData.text);
$(`#question-type-${index}`).val(questionData.type);
if (questionData.required) {
$(`input[name="questions[${index}][required]"]`).prop('checked', true);
}
// Добавляем варианты ответа если они есть
if (questionData.options && questionData.options.length > 0) {
questionData.options.forEach(option => {
addOption(index, option.text);
});
}
// Заполняем настройки шкалы если нужно
if (questionData.scaleMax) {
$(`#scale-max-${index}`).val(questionData.scaleMax);
}
}
// Показываем/скрываем контейнеры в зависимости от типа вопроса
const questionType = $(`#question-type-${index}`).val();
if (['single_choice', 'multiple_choice', 'tag_cloud'].includes(questionType)) {
$(`#options-container-${index}`).show();
$(`#scale-container-${index}`).hide();
// Если нет вариантов и не загружены данные, добавляем два
if (!questionData && $(`#options-list-${index}`).children().length === 0) {
addOption(index);
addOption(index);
}
} else if (questionType === 'scale') {
$(`#options-container-${index}`).hide();
$(`#scale-container-${index}`).show();
} else {
$(`#options-container-${index}`).hide();
$(`#scale-container-${index}`).hide();
}
}
// Функция для добавления варианта ответа
function addOption(questionIndex, optionText) {
const optionsList = $(`#options-list-${questionIndex}`);
const template = $('#option-template').html();
const optionIndex = optionsList.children().length;
// Заменяем плейсхолдеры в шаблоне
let optionHtml = template
.replace(/\{\{questionIndex\}\}/g, questionIndex)
.replace(/\{\{optionIndex\}\}/g, optionIndex);
optionsList.append(optionHtml);
// Если есть текст варианта - устанавливаем его
if (optionText) {
optionsList.children().last().find('input[type="text"]').val(optionText);
}
// Проверяем, видим ли контейнер опций
const optionsContainer = $(`#options-container-${questionIndex}`);
if (optionsContainer.is(':hidden')) {
// Если контейнер скрыт, отключаем required у полей ввода
optionsList.find('input[type="text"]').prop('required', false);
}
}
// Перенумерация вопросов
function renumberQuestions() {
$('.question-item').each(function(index) {
$(this).find('h3').text(`Вопрос ${index + 1}`);
});
}
// Сохранение опроса
function saveQuestionnaire() {
const questionnaire = {
title: $('#title').val(),
description: $('#description').val(),
displayType: $('#display-type').val(),
questions: []
};
// Собираем данные о вопросах
$('.question-item').each(function() {
const index = $(this).data('index');
const questionType = $(`#question-type-${index}`).val();
const question = {
text: $(`#question-text-${index}`).val(),
type: questionType,
required: $(`input[name="questions[${index}][required]"]`).is(':checked'),
options: []
};
// Добавляем настройки шкалы если нужно
if (questionType === 'scale') {
question.scaleMax = parseInt($(`#scale-max-${index}`).val());
}
// Собираем варианты ответа если это не текстовый вопрос или оценка
if (['single_choice', 'multiple_choice', 'tag_cloud'].includes(questionType)) {
$(`#options-list-${index} .option-item`).each(function() {
const optionText = $(this).find('input[type="text"]').val();
if (optionText) {
// Сохраняем количество голосов из старых данных
let count = 0;
const optionIndex = $(this).data('index');
if (questionnaireData &&
questionnaireData.questions[index] &&
questionnaireData.questions[index].options &&
questionnaireData.questions[index].options[optionIndex]) {
count = questionnaireData.questions[index].options[optionIndex].count || 0;
}
question.options.push({
text: optionText,
count: count
});
}
});
}
questionnaire.questions.push(question);
});
// Отправка на сервер
$.ajax({
url: `${getApiPath()}/questionnaires/${adminLink}`,
method: 'PUT',
contentType: 'application/json',
data: JSON.stringify(questionnaire),
success: function(result) {
if (result.success) {
2025-03-12 00:09:36 +03:00
showAlert('Опрос успешно сохранен!', 'Успех', { autoClose: true });
// Перенаправляем на страницу администратора
const isMsPath = window.location.pathname.includes('/ms/questioneer');
let basePath;
if (isMsPath) {
// Для продакшна: используем /ms/questioneer
basePath = '/ms/questioneer';
} else {
// Для локальной разработки: используем текущий путь
basePath = window.location.pathname.split('/edit')[0];
}
window.location.href = `${basePath}/admin/${adminLink}`;
2025-03-11 23:50:50 +03:00
} else {
showAlert(`Ошибка при обновлении опроса: ${result.error}`, 'Ошибка');
}
},
error: function(error) {
console.error('Error updating questionnaire:', error);
showAlert('Не удалось обновить опрос. Пожалуйста, попробуйте позже.', 'Ошибка');
}
});
}
// Инициализация
loadQuestionnaire();
});