diff --git a/resources/views/admin/course-requests/create.blade.php b/resources/views/admin/course-requests/create.blade.php
index e6bb960..4ba9eda 100644
--- a/resources/views/admin/course-requests/create.blade.php
+++ b/resources/views/admin/course-requests/create.blade.php
@@ -87,12 +87,12 @@
@@ -124,81 +124,84 @@ let items = [];
let elementCounter = 0;
// TomSelect экземпляры
-let courseSelect, orgSelect, groupTags, userTags;
+let courseSelect = null, orgSelect = null, groupTags = null, userTags = null;
+let modalInitialized = false;
-// Инициализация TomSelect при открытии modal
+// Инициализация TomSelect при ПЕРВОМ открытии modal
document.getElementById('addElementModal').addEventListener('show.bs.modal', function() {
+ if (modalInitialized) return;
+
// Курсы
- if (!courseSelect) {
- courseSelect = new TomSelect('#element_course_id', {
- valueField: 'id',
- labelField: 'text',
- searchField: 'text',
- placeholder: 'Выберите курс...',
- preload: false,
- load: function(query, callback) {
- if (query.length < 2) return callback();
- fetch('/api/courses/search?q=' + encodeURIComponent(query))
- .then(response => response.json())
- .then(json => callback(json))
- .catch(() => callback());
- }
- });
- }
+ courseSelect = new TomSelect('#element_course_id', {
+ valueField: 'id',
+ labelField: 'text',
+ searchField: 'text',
+ placeholder: 'Выберите курс...',
+ preload: false,
+ maxOptions: null,
+ load: function(query, callback) {
+ if (query.length < 2) return callback();
+ fetch('/api/courses/search?q=' + encodeURIComponent(query))
+ .then(response => response.json())
+ .then(json => callback(json))
+ .catch(() => callback());
+ }
+ });
// Организации
- if (!orgSelect) {
- orgSelect = new TomSelect('#element_organization_id', {
- valueField: 'id',
- labelField: 'text',
- searchField: 'text',
- placeholder: 'Не выбрано',
- preload: false,
- load: function(query, callback) {
- if (query.length < 2) return callback();
- fetch('/api/organizations/search?q=' + encodeURIComponent(query))
- .then(response => response.json())
- .then(json => callback(json))
- .catch(() => callback());
- }
- });
- }
+ orgSelect = new TomSelect('#element_organization_id', {
+ valueField: 'id',
+ labelField: 'text',
+ searchField: 'text',
+ placeholder: 'Не выбрано',
+ preload: false,
+ maxOptions: null,
+ load: function(query, callback) {
+ if (query.length < 2) return callback();
+ fetch('/api/organizations/search?q=' + encodeURIComponent(query))
+ .then(response => response.json())
+ .then(json => callback(json))
+ .catch(() => callback());
+ }
+ });
- // Группы
- if (!groupTags) {
- groupTags = new TomSelect('#element_group_ids', {
- valueField: 'id',
- labelField: 'text',
- searchField: 'text',
- placeholder: 'Выберите группы...',
- preload: false,
- load: function(query, callback) {
- if (query.length < 2) return callback();
- fetch('/api/groups/search?q=' + encodeURIComponent(query))
- .then(response => response.json())
- .then(json => callback(json))
- .catch(() => callback());
- }
- });
- }
+ // Группы (мультивыбор)
+ groupTags = new TomSelect('#element_group_ids', {
+ valueField: 'id',
+ labelField: 'text',
+ searchField: 'text',
+ placeholder: 'Выберите группы...',
+ preload: false,
+ maxOptions: null,
+ plugins: ['remove_button'],
+ load: function(query, callback) {
+ if (query.length < 2) return callback();
+ fetch('/api/groups/search?q=' + encodeURIComponent(query))
+ .then(response => response.json())
+ .then(json => callback(json))
+ .catch(() => callback());
+ }
+ });
- // Пользователи
- if (!userTags) {
- userTags = new TomSelect('#element_user_ids', {
- valueField: 'id',
- labelField: 'text',
- searchField: 'text',
- placeholder: 'Выберите пользователей...',
- preload: false,
- load: function(query, callback) {
- if (query.length < 2) return callback();
- fetch('/api/users/search?q=' + encodeURIComponent(query))
- .then(response => response.json())
- .then(json => callback(json))
- .catch(() => callback());
- }
- });
- }
+ // Пользователи (мультивыбор)
+ userTags = new TomSelect('#element_user_ids', {
+ valueField: 'id',
+ labelField: 'text',
+ searchField: 'text',
+ placeholder: 'Выберите пользователей...',
+ preload: false,
+ maxOptions: null,
+ plugins: ['remove_button'],
+ load: function(query, callback) {
+ if (query.length < 2) return callback();
+ fetch('/api/users/search?q=' + encodeURIComponent(query))
+ .then(response => response.json())
+ .then(json => callback(json))
+ .catch(() => callback());
+ }
+ });
+
+ modalInitialized = true;
});
// Сброс формы при закрытии modal
@@ -215,8 +218,8 @@ document.getElementById('addElementModal').addEventListener('hidden.bs.modal', f
document.getElementById('addElementBtn').addEventListener('click', function() {
const courseId = courseSelect.getValue();
const organizationId = orgSelect.getValue();
- const groupIds = groupTags.getValue();
- const userIds = userTags.getValue();
+ const groupIds = groupTags.getValue() || [];
+ const userIds = userTags.getValue() || [];
const startDate = document.getElementById('element_start_date').value;
const endDate = document.getElementById('element_end_date').value;
@@ -237,10 +240,10 @@ document.getElementById('addElementBtn').addEventListener('click', function() {
course_name: courseSelect.options[courseId]?.text || 'Курс',
organization_id: organizationId || null,
organization_name: organizationId ? orgSelect.options[organizationId]?.text : null,
- group_ids: Array.isArray(groupIds) ? groupIds : (groupIds ? [groupIds] : []),
- group_names: Array.isArray(groupIds) ? groupIds.map(id => groupTags.options[id]?.text) : (groupIds ? [groupTags.options[groupIds]?.text] : []),
- user_ids: Array.isArray(userIds) ? userIds : (userIds ? [userIds] : []),
- user_names: Array.isArray(userIds) ? userIds.map(id => userTags.options[id]?.text) : (userIds ? [userTags.options[userIds]?.text] : []),
+ group_ids: Array.isArray(groupIds) ? groupIds : [groupIds],
+ group_names: (Array.isArray(groupIds) ? groupIds : [groupIds]).map(id => groupTags.options[id]?.text).filter(Boolean),
+ user_ids: Array.isArray(userIds) ? userIds : [userIds],
+ user_names: (Array.isArray(userIds) ? userIds : [userIds]).map(id => userTags.options[id]?.text).filter(Boolean),
start_date: startDate,
end_date: endDate || null
});
diff --git a/resources/views/admin/course-requests/edit.blade.php b/resources/views/admin/course-requests/edit.blade.php
index 39dd712..3221ea7 100644
--- a/resources/views/admin/course-requests/edit.blade.php
+++ b/resources/views/admin/course-requests/edit.blade.php
@@ -74,12 +74,12 @@
@@ -120,54 +120,56 @@ let items = @json($courseRequest->items->map(fn($item) => [
]) ?? []);
let elementCounter = items.length;
-let courseSelect, orgSelect, groupTags, userTags;
+let courseSelect = null, orgSelect = null, groupTags = null, userTags = null;
+let modalInitialized = false;
-// Инициализация TomSelect при открытии modal
+// Инициализация TomSelect при ПЕРВОМ открытии modal
document.getElementById('addElementModal').addEventListener('show.bs.modal', function() {
- if (!courseSelect) {
- courseSelect = new TomSelect('#element_course_id', {
- valueField: 'id', labelField: 'text', searchField: 'text',
- placeholder: 'Выберите курс...', preload: false,
- load: function(query, callback) {
- if (query.length < 2) return callback();
- fetch('/api/courses/search?q=' + encodeURIComponent(query))
- .then(response => response.json()).then(json => callback(json)).catch(() => callback());
- }
- });
- }
- if (!orgSelect) {
- orgSelect = new TomSelect('#element_organization_id', {
- valueField: 'id', labelField: 'text', searchField: 'text',
- placeholder: 'Не выбрано', preload: false,
- load: function(query, callback) {
- if (query.length < 2) return callback();
- fetch('/api/organizations/search?q=' + encodeURIComponent(query))
- .then(response => response.json()).then(json => callback(json)).catch(() => callback());
- }
- });
- }
- if (!groupTags) {
- groupTags = new TomSelect('#element_group_ids', {
- valueField: 'id', labelField: 'text', searchField: 'text',
- placeholder: 'Выберите группы...', preload: false,
- load: function(query, callback) {
- if (query.length < 2) return callback();
- fetch('/api/groups/search?q=' + encodeURIComponent(query))
- .then(response => response.json()).then(json => callback(json)).catch(() => callback());
- }
- });
- }
- if (!userTags) {
- userTags = new TomSelect('#element_user_ids', {
- valueField: 'id', labelField: 'text', searchField: 'text',
- placeholder: 'Выберите пользователей...', preload: false,
- load: function(query, callback) {
- if (query.length < 2) return callback();
- fetch('/api/users/search?q=' + encodeURIComponent(query))
- .then(response => response.json()).then(json => callback(json)).catch(() => callback());
- }
- });
- }
+ if (modalInitialized) return;
+
+ courseSelect = new TomSelect('#element_course_id', {
+ valueField: 'id', labelField: 'text', searchField: 'text',
+ placeholder: 'Выберите курс...', preload: false, maxOptions: null,
+ load: function(query, callback) {
+ if (query.length < 2) return callback();
+ fetch('/api/courses/search?q=' + encodeURIComponent(query))
+ .then(response => response.json()).then(json => callback(json)).catch(() => callback());
+ }
+ });
+
+ orgSelect = new TomSelect('#element_organization_id', {
+ valueField: 'id', labelField: 'text', searchField: 'text',
+ placeholder: 'Не выбрано', preload: false, maxOptions: null,
+ load: function(query, callback) {
+ if (query.length < 2) return callback();
+ fetch('/api/organizations/search?q=' + encodeURIComponent(query))
+ .then(response => response.json()).then(json => callback(json)).catch(() => callback());
+ }
+ });
+
+ groupTags = new TomSelect('#element_group_ids', {
+ valueField: 'id', labelField: 'text', searchField: 'text',
+ placeholder: 'Выберите группы...', preload: false, maxOptions: null,
+ plugins: ['remove_button'],
+ load: function(query, callback) {
+ if (query.length < 2) return callback();
+ fetch('/api/groups/search?q=' + encodeURIComponent(query))
+ .then(response => response.json()).then(json => callback(json)).catch(() => callback());
+ }
+ });
+
+ userTags = new TomSelect('#element_user_ids', {
+ valueField: 'id', labelField: 'text', searchField: 'text',
+ placeholder: 'Выберите пользователей...', preload: false, maxOptions: null,
+ plugins: ['remove_button'],
+ load: function(query, callback) {
+ if (query.length < 2) return callback();
+ fetch('/api/users/search?q=' + encodeURIComponent(query))
+ .then(response => response.json()).then(json => callback(json)).catch(() => callback());
+ }
+ });
+
+ modalInitialized = true;
});
document.getElementById('addElementModal').addEventListener('hidden.bs.modal', function() {
@@ -182,8 +184,8 @@ document.getElementById('addElementModal').addEventListener('hidden.bs.modal', f
document.getElementById('addElementBtn').addEventListener('click', function() {
const courseId = courseSelect.getValue();
const organizationId = orgSelect.getValue();
- const groupIds = groupTags.getValue();
- const userIds = userTags.getValue();
+ const groupIds = groupTags.getValue() || [];
+ const userIds = userTags.getValue() || [];
const startDate = document.getElementById('element_start_date').value;
const endDate = document.getElementById('element_end_date').value;
@@ -196,10 +198,10 @@ document.getElementById('addElementBtn').addEventListener('click', function() {
course_name: courseSelect.options[courseId]?.text || 'Курс',
organization_id: organizationId || null,
organization_name: organizationId ? orgSelect.options[organizationId]?.text : null,
- group_ids: Array.isArray(groupIds) ? groupIds : (groupIds ? [groupIds] : []),
- group_names: Array.isArray(groupIds) ? groupIds.map(id => groupTags.options[id]?.text) : (groupIds ? [groupTags.options[groupIds]?.text] : []),
- user_ids: Array.isArray(userIds) ? userIds : (userIds ? [userIds] : []),
- user_names: Array.isArray(userIds) ? userIds.map(id => userTags.options[id]?.text) : (userIds ? [userTags.options[userIds]?.text] : []),
+ group_ids: Array.isArray(groupIds) ? groupIds : [groupIds],
+ group_names: (Array.isArray(groupIds) ? groupIds : [groupIds]).map(id => groupTags.options[id]?.text).filter(Boolean),
+ user_ids: Array.isArray(userIds) ? userIds : [userIds],
+ user_names: (Array.isArray(userIds) ? userIds : [userIds]).map(id => userTags.options[id]?.text).filter(Boolean),
start_date: startDate,
end_date: endDate || null
});