Fix: TomSelect для мультивыбора в modal
✅ <select multiple> вместо <div> для групп/пользователей ✅ plugins: ['remove_button'] для крестиков ✅ modalInitialized флаг для однократной инициализации ✅ Правильное получение getValue() для мультивыбора Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
c65da15feb
commit
5187c6f784
|
|
@ -87,12 +87,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label">Группа</label>
|
<label class="form-label">Группа</label>
|
||||||
<div id="element_group_ids"></div>
|
<select id="element_group_ids" multiple></select>
|
||||||
<small class="text-muted">И</small>
|
<small class="text-muted">И</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label">Пользователь</label>
|
<label class="form-label">Пользователь</label>
|
||||||
<div id="element_user_ids"></div>
|
<select id="element_user_ids" multiple></select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Строка 3: Даты -->
|
<!-- Строка 3: Даты -->
|
||||||
|
|
@ -124,18 +124,21 @@ let items = [];
|
||||||
let elementCounter = 0;
|
let elementCounter = 0;
|
||||||
|
|
||||||
// TomSelect экземпляры
|
// 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() {
|
document.getElementById('addElementModal').addEventListener('show.bs.modal', function() {
|
||||||
|
if (modalInitialized) return;
|
||||||
|
|
||||||
// Курсы
|
// Курсы
|
||||||
if (!courseSelect) {
|
|
||||||
courseSelect = new TomSelect('#element_course_id', {
|
courseSelect = new TomSelect('#element_course_id', {
|
||||||
valueField: 'id',
|
valueField: 'id',
|
||||||
labelField: 'text',
|
labelField: 'text',
|
||||||
searchField: 'text',
|
searchField: 'text',
|
||||||
placeholder: 'Выберите курс...',
|
placeholder: 'Выберите курс...',
|
||||||
preload: false,
|
preload: false,
|
||||||
|
maxOptions: null,
|
||||||
load: function(query, callback) {
|
load: function(query, callback) {
|
||||||
if (query.length < 2) return callback();
|
if (query.length < 2) return callback();
|
||||||
fetch('/api/courses/search?q=' + encodeURIComponent(query))
|
fetch('/api/courses/search?q=' + encodeURIComponent(query))
|
||||||
|
|
@ -144,16 +147,15 @@ document.getElementById('addElementModal').addEventListener('show.bs.modal', fun
|
||||||
.catch(() => callback());
|
.catch(() => callback());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// Организации
|
// Организации
|
||||||
if (!orgSelect) {
|
|
||||||
orgSelect = new TomSelect('#element_organization_id', {
|
orgSelect = new TomSelect('#element_organization_id', {
|
||||||
valueField: 'id',
|
valueField: 'id',
|
||||||
labelField: 'text',
|
labelField: 'text',
|
||||||
searchField: 'text',
|
searchField: 'text',
|
||||||
placeholder: 'Не выбрано',
|
placeholder: 'Не выбрано',
|
||||||
preload: false,
|
preload: false,
|
||||||
|
maxOptions: null,
|
||||||
load: function(query, callback) {
|
load: function(query, callback) {
|
||||||
if (query.length < 2) return callback();
|
if (query.length < 2) return callback();
|
||||||
fetch('/api/organizations/search?q=' + encodeURIComponent(query))
|
fetch('/api/organizations/search?q=' + encodeURIComponent(query))
|
||||||
|
|
@ -162,16 +164,16 @@ document.getElementById('addElementModal').addEventListener('show.bs.modal', fun
|
||||||
.catch(() => callback());
|
.catch(() => callback());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// Группы
|
// Группы (мультивыбор)
|
||||||
if (!groupTags) {
|
|
||||||
groupTags = new TomSelect('#element_group_ids', {
|
groupTags = new TomSelect('#element_group_ids', {
|
||||||
valueField: 'id',
|
valueField: 'id',
|
||||||
labelField: 'text',
|
labelField: 'text',
|
||||||
searchField: 'text',
|
searchField: 'text',
|
||||||
placeholder: 'Выберите группы...',
|
placeholder: 'Выберите группы...',
|
||||||
preload: false,
|
preload: false,
|
||||||
|
maxOptions: null,
|
||||||
|
plugins: ['remove_button'],
|
||||||
load: function(query, callback) {
|
load: function(query, callback) {
|
||||||
if (query.length < 2) return callback();
|
if (query.length < 2) return callback();
|
||||||
fetch('/api/groups/search?q=' + encodeURIComponent(query))
|
fetch('/api/groups/search?q=' + encodeURIComponent(query))
|
||||||
|
|
@ -180,16 +182,16 @@ document.getElementById('addElementModal').addEventListener('show.bs.modal', fun
|
||||||
.catch(() => callback());
|
.catch(() => callback());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// Пользователи
|
// Пользователи (мультивыбор)
|
||||||
if (!userTags) {
|
|
||||||
userTags = new TomSelect('#element_user_ids', {
|
userTags = new TomSelect('#element_user_ids', {
|
||||||
valueField: 'id',
|
valueField: 'id',
|
||||||
labelField: 'text',
|
labelField: 'text',
|
||||||
searchField: 'text',
|
searchField: 'text',
|
||||||
placeholder: 'Выберите пользователей...',
|
placeholder: 'Выберите пользователей...',
|
||||||
preload: false,
|
preload: false,
|
||||||
|
maxOptions: null,
|
||||||
|
plugins: ['remove_button'],
|
||||||
load: function(query, callback) {
|
load: function(query, callback) {
|
||||||
if (query.length < 2) return callback();
|
if (query.length < 2) return callback();
|
||||||
fetch('/api/users/search?q=' + encodeURIComponent(query))
|
fetch('/api/users/search?q=' + encodeURIComponent(query))
|
||||||
|
|
@ -198,7 +200,8 @@ document.getElementById('addElementModal').addEventListener('show.bs.modal', fun
|
||||||
.catch(() => callback());
|
.catch(() => callback());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
modalInitialized = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Сброс формы при закрытии modal
|
// Сброс формы при закрытии modal
|
||||||
|
|
@ -215,8 +218,8 @@ document.getElementById('addElementModal').addEventListener('hidden.bs.modal', f
|
||||||
document.getElementById('addElementBtn').addEventListener('click', function() {
|
document.getElementById('addElementBtn').addEventListener('click', function() {
|
||||||
const courseId = courseSelect.getValue();
|
const courseId = courseSelect.getValue();
|
||||||
const organizationId = orgSelect.getValue();
|
const organizationId = orgSelect.getValue();
|
||||||
const groupIds = groupTags.getValue();
|
const groupIds = groupTags.getValue() || [];
|
||||||
const userIds = userTags.getValue();
|
const userIds = userTags.getValue() || [];
|
||||||
const startDate = document.getElementById('element_start_date').value;
|
const startDate = document.getElementById('element_start_date').value;
|
||||||
const endDate = document.getElementById('element_end_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 || 'Курс',
|
course_name: courseSelect.options[courseId]?.text || 'Курс',
|
||||||
organization_id: organizationId || null,
|
organization_id: organizationId || null,
|
||||||
organization_name: organizationId ? orgSelect.options[organizationId]?.text : null,
|
organization_name: organizationId ? orgSelect.options[organizationId]?.text : null,
|
||||||
group_ids: Array.isArray(groupIds) ? groupIds : (groupIds ? [groupIds] : []),
|
group_ids: Array.isArray(groupIds) ? groupIds : [groupIds],
|
||||||
group_names: Array.isArray(groupIds) ? groupIds.map(id => groupTags.options[id]?.text) : (groupIds ? [groupTags.options[groupIds]?.text] : []),
|
group_names: (Array.isArray(groupIds) ? groupIds : [groupIds]).map(id => groupTags.options[id]?.text).filter(Boolean),
|
||||||
user_ids: Array.isArray(userIds) ? userIds : (userIds ? [userIds] : []),
|
user_ids: Array.isArray(userIds) ? userIds : [userIds],
|
||||||
user_names: Array.isArray(userIds) ? userIds.map(id => userTags.options[id]?.text) : (userIds ? [userTags.options[userIds]?.text] : []),
|
user_names: (Array.isArray(userIds) ? userIds : [userIds]).map(id => userTags.options[id]?.text).filter(Boolean),
|
||||||
start_date: startDate,
|
start_date: startDate,
|
||||||
end_date: endDate || null
|
end_date: endDate || null
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -74,12 +74,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label">Группа</label>
|
<label class="form-label">Группа</label>
|
||||||
<div id="element_group_ids"></div>
|
<select id="element_group_ids" multiple></select>
|
||||||
<small class="text-muted">И</small>
|
<small class="text-muted">И</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label">Пользователь</label>
|
<label class="form-label">Пользователь</label>
|
||||||
<div id="element_user_ids"></div>
|
<select id="element_user_ids" multiple></select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="form-label">Дата начала *</label>
|
<label class="form-label">Дата начала *</label>
|
||||||
|
|
@ -120,54 +120,56 @@ let items = @json($courseRequest->items->map(fn($item) => [
|
||||||
]) ?? []);
|
]) ?? []);
|
||||||
|
|
||||||
let elementCounter = items.length;
|
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() {
|
document.getElementById('addElementModal').addEventListener('show.bs.modal', function() {
|
||||||
if (!courseSelect) {
|
if (modalInitialized) return;
|
||||||
|
|
||||||
courseSelect = new TomSelect('#element_course_id', {
|
courseSelect = new TomSelect('#element_course_id', {
|
||||||
valueField: 'id', labelField: 'text', searchField: 'text',
|
valueField: 'id', labelField: 'text', searchField: 'text',
|
||||||
placeholder: 'Выберите курс...', preload: false,
|
placeholder: 'Выберите курс...', preload: false, maxOptions: null,
|
||||||
load: function(query, callback) {
|
load: function(query, callback) {
|
||||||
if (query.length < 2) return callback();
|
if (query.length < 2) return callback();
|
||||||
fetch('/api/courses/search?q=' + encodeURIComponent(query))
|
fetch('/api/courses/search?q=' + encodeURIComponent(query))
|
||||||
.then(response => response.json()).then(json => callback(json)).catch(() => callback());
|
.then(response => response.json()).then(json => callback(json)).catch(() => callback());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
if (!orgSelect) {
|
|
||||||
orgSelect = new TomSelect('#element_organization_id', {
|
orgSelect = new TomSelect('#element_organization_id', {
|
||||||
valueField: 'id', labelField: 'text', searchField: 'text',
|
valueField: 'id', labelField: 'text', searchField: 'text',
|
||||||
placeholder: 'Не выбрано', preload: false,
|
placeholder: 'Не выбрано', preload: false, maxOptions: null,
|
||||||
load: function(query, callback) {
|
load: function(query, callback) {
|
||||||
if (query.length < 2) return callback();
|
if (query.length < 2) return callback();
|
||||||
fetch('/api/organizations/search?q=' + encodeURIComponent(query))
|
fetch('/api/organizations/search?q=' + encodeURIComponent(query))
|
||||||
.then(response => response.json()).then(json => callback(json)).catch(() => callback());
|
.then(response => response.json()).then(json => callback(json)).catch(() => callback());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
if (!groupTags) {
|
|
||||||
groupTags = new TomSelect('#element_group_ids', {
|
groupTags = new TomSelect('#element_group_ids', {
|
||||||
valueField: 'id', labelField: 'text', searchField: 'text',
|
valueField: 'id', labelField: 'text', searchField: 'text',
|
||||||
placeholder: 'Выберите группы...', preload: false,
|
placeholder: 'Выберите группы...', preload: false, maxOptions: null,
|
||||||
|
plugins: ['remove_button'],
|
||||||
load: function(query, callback) {
|
load: function(query, callback) {
|
||||||
if (query.length < 2) return callback();
|
if (query.length < 2) return callback();
|
||||||
fetch('/api/groups/search?q=' + encodeURIComponent(query))
|
fetch('/api/groups/search?q=' + encodeURIComponent(query))
|
||||||
.then(response => response.json()).then(json => callback(json)).catch(() => callback());
|
.then(response => response.json()).then(json => callback(json)).catch(() => callback());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
if (!userTags) {
|
|
||||||
userTags = new TomSelect('#element_user_ids', {
|
userTags = new TomSelect('#element_user_ids', {
|
||||||
valueField: 'id', labelField: 'text', searchField: 'text',
|
valueField: 'id', labelField: 'text', searchField: 'text',
|
||||||
placeholder: 'Выберите пользователей...', preload: false,
|
placeholder: 'Выберите пользователей...', preload: false, maxOptions: null,
|
||||||
|
plugins: ['remove_button'],
|
||||||
load: function(query, callback) {
|
load: function(query, callback) {
|
||||||
if (query.length < 2) return callback();
|
if (query.length < 2) return callback();
|
||||||
fetch('/api/users/search?q=' + encodeURIComponent(query))
|
fetch('/api/users/search?q=' + encodeURIComponent(query))
|
||||||
.then(response => response.json()).then(json => callback(json)).catch(() => callback());
|
.then(response => response.json()).then(json => callback(json)).catch(() => callback());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
modalInitialized = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('addElementModal').addEventListener('hidden.bs.modal', function() {
|
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() {
|
document.getElementById('addElementBtn').addEventListener('click', function() {
|
||||||
const courseId = courseSelect.getValue();
|
const courseId = courseSelect.getValue();
|
||||||
const organizationId = orgSelect.getValue();
|
const organizationId = orgSelect.getValue();
|
||||||
const groupIds = groupTags.getValue();
|
const groupIds = groupTags.getValue() || [];
|
||||||
const userIds = userTags.getValue();
|
const userIds = userTags.getValue() || [];
|
||||||
const startDate = document.getElementById('element_start_date').value;
|
const startDate = document.getElementById('element_start_date').value;
|
||||||
const endDate = document.getElementById('element_end_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 || 'Курс',
|
course_name: courseSelect.options[courseId]?.text || 'Курс',
|
||||||
organization_id: organizationId || null,
|
organization_id: organizationId || null,
|
||||||
organization_name: organizationId ? orgSelect.options[organizationId]?.text : null,
|
organization_name: organizationId ? orgSelect.options[organizationId]?.text : null,
|
||||||
group_ids: Array.isArray(groupIds) ? groupIds : (groupIds ? [groupIds] : []),
|
group_ids: Array.isArray(groupIds) ? groupIds : [groupIds],
|
||||||
group_names: Array.isArray(groupIds) ? groupIds.map(id => groupTags.options[id]?.text) : (groupIds ? [groupTags.options[groupIds]?.text] : []),
|
group_names: (Array.isArray(groupIds) ? groupIds : [groupIds]).map(id => groupTags.options[id]?.text).filter(Boolean),
|
||||||
user_ids: Array.isArray(userIds) ? userIds : (userIds ? [userIds] : []),
|
user_ids: Array.isArray(userIds) ? userIds : [userIds],
|
||||||
user_names: Array.isArray(userIds) ? userIds.map(id => userTags.options[id]?.text) : (userIds ? [userTags.options[userIds]?.text] : []),
|
user_names: (Array.isArray(userIds) ? userIds : [userIds]).map(id => userTags.options[id]?.text).filter(Boolean),
|
||||||
start_date: startDate,
|
start_date: startDate,
|
||||||
end_date: endDate || null
|
end_date: endDate || null
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue