我在Thymeleaf表单中使用Select2进行多选选项。我有一个要求,即在单击提交后,当您返回到同一表单时,应保留先前的选择。只有单击清除按钮后,您才能清除选择。所有其他选项都按预期工作,除了项目名称。当我选择项目名称和其他值并单击提交时,它会生成一个图表。点击后退按钮后,我看到所有其他选项选择都与之前的选择相同,除了项目名称,它是重复的。下面是供参考的图像。
表格提交前
提交表单后,单击返回按钮
的数据
你看到连接是重复的,我不知道为什么这是下面发生的表单和js文件
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Defect Dashboard</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="defectdashboard.css">
<link href="custom_styles.css" rel="stylesheet" />
</head>
<body>
<!-- Header with company logo -->
<div class="header-bar">
<!-- Back to Form Button on the left -->
<a class="nav-link" href="/">
<span class="button-home">
<i class="fa fa-home" style="font-size:35px;" title="Home"></i>
</span>
</a>
<!-- Defect Dashboard in the middle -->
<h1 class="dashboard-defect">Defect Dashboard</h1>
<img src="pngLogo.png" id="nike-image" alt="Nike Logo" style="width: 50px; height: 50px; margin-right: 28px;display:none;">
<!-- Company Logo on the right -->
</div>
<!-- Form Section -->
<section class="container mt-3" id="form-section">
<div class="spinner" id="spinner" style="display: none;">
<i class="fas fa-spinner fa-spin fa-3x"></i>
</div>
<form action="submit" method="POST" th:object="${defectModel}">
<!-- Project Name Dropdown -->
<div class="form-group">
<label for="projectName">Project Name</label>
<select id="projectName" name="projectName" class="form-control" th:field="*{projectName}" multiple>
<option th:each="project : ${projectNames}" th:value="${project}" th:text="${project}"></option>
</select>
</div>
<!-- Squad Dropdown -->
<div class="form-group">
<label for="squad">Squad</label>
<select id="squad" name="squad" class="form-control" th:field="*{squad}" multiple>
<option th:each="squad : ${squads}" th:value="${squad}" th:text="${squad}"></option>
</select>
</div>
<div class="form-group">
<label for="label">Labels</label>
<select id="label" name="label" class="form-control" th:field="*{label}" multiple>
<option value="ALL">ALL</option>
<option th:each="label : ${labels}" th:value="${label}" th:text="${label}"></option>
</select>
</div>
<div class="form-group">
<label for="monthlyOption">Monthly</label>
<select id="monthlyOption" name="monthlyOption" class="form-control" th:field="*{monthlyOption}" multiple>
<option th:each="monthlyOption : ${monthlyOptions}" th:value="${monthlyOption}"
th:text="${monthlyOption}"></option>
</select>
</div>
<div class="form-group">
<label for="quarter">Quaterly</label>
<select id="quarter" name="quarter" class="form-control" th:field="*{quarter}" multiple>
<option value="ALL">ALL</option>
<option th:each="quaterlyData : ${quaterly}" th:value="${quaterlyData}"
th:text="${quaterlyData}"></option>
</select>
</div>
<div class="form-group">
<label for="yeartodate">Year To Date</label>
<select id="yeartodate" name="yeartodate" class="form-control" th:field="*{yeartodate}" multiple>
<option th:each="yto : ${yeartoDate}" th:value="${yto}" th:text="${yto}"></option>
</select>
</div>
<div class="form-group">
<label for="yearonyear">Year On Year</label>
<select id="yearonyear" name="yearonyear" class="form-control" th:field="*{yearonyear}" multiple>
<option th:each="yoy : ${yearOnYearList}" th:value="${yoy}" th:text="${yoy}"></option>
</select>
</div>
<!-- Multiselect Option -->
<!-- Submit and Cancel Buttons -->
<div class="form-group text-center">
<button type="submit" class="btn btn-primary">Submit</button>
<button type="button" id="clearSelection" class="btn btn-primary">Clear</button>
<button type="button" class="btn btn-secondary">Cancel</button>
</div>
</form>
</section>
<section class="container mt-3" id="chart-section" style="display:none">
<div th:replace="fragments :: chart-content"></div>
<div style="position:absolute; left:50%">
<a href="/defect?name=defectDashboard" class="btn btn-primary" id="backToFormBtn" style="display:none;margin-right:0.2rem">Back</a>
</div>
</section>
<div class="modal fade" id="errorModal" tabindex="-1" role="dialog" aria-labelledby="errorModalLabel"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-sm" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="errorModalLabel">Error</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Please Select Project Name Or Squad Or Label.
</div>
</div>
</div>
</div>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="dashboard.js"></script>
</body>
</html>
字符串
Js文件
$(document).ready(function () {
const multiselect = $('select[multiple]');
multiselect.each(function () {
const savedOptions = JSON.parse(localStorage.getItem(this.id));
if (savedOptions) {
const currentOptions = $(this).val() || [];
// Check if saved options include the first selected item
const firstSelectedItem = currentOptions.length > 0 ? currentOptions[0] : null;
const includeFirstItem = firstSelectedItem ? savedOptions.includes(firstSelectedItem) : false;
// Merge options only if the first selected item is not in the saved options
if (!includeFirstItem) {
const mergedOptions = [...currentOptions, ...savedOptions];
$(this).val(mergedOptions).trigger('change');
}
}
});
$('#label').select2();
$('#quarter').select2();
$('#projectName').select2({
placeholder: 'Select Projects...',
});
$('#label').select2({
placeholder: 'Select Label...',
});
$('#quarter').select2({
placeholder: 'Select Quareter...',
});
// Show/hide form and chart sections based on user interaction
$("#form-section").show();
$("#nike-image").show();
$("#chart-section").hide();
$("#backToFormBtn").hide();
// Handle form submission
$("form").submit(function (event) {
event.preventDefault();
multiselect.each(function () {
const selectedOptions = $(this).val();
localStorage.setItem(this.id, JSON.stringify(selectedOptions));
});
var projectName = $("#projectName").val();
var squad = $("#squad").val();
var label = $("#label").val();
if (projectName.length === 0 && squad.length === 0 && label.length === 0) {
$("#errorModal").modal('show');
} else {
$("#errorModal").modal('hide');
var montlyOption = $("#monthlyOption").val();
var quarterlyOption = $("#quarter").val();
var yearToYear = $("#yeartodate").val();
var yearToDate = $("#yearonyear").val();
if (montlyOption.length === 0 && quarterlyOption.length === 0 && yearToYear.length === 0 && yearToDate.length === 0) {
$("#monthlyOption option").prop("selected", true);
$("#quarter option").prop("selected", true);
$("#yeartodate option").prop("selected", true);
$("#yearonyear option").prop("selected", true);
}
$("#spinner").show();
$.ajax({
type: $(this).attr("method"),
url: $(this).attr("action"),
data: $(this).serialize(),
success: function (response) {
$("#spinner").hide();
// Hide the form and show the chart section
$("#form-section").hide();
$("#chart-section").show();
$("#backToFormBtn").show();
var chartData = JSON.parse(response);
google.charts.load('current', {
'packages': ['corechart']
});
google.charts.setOnLoadCallback(function () {
drawCharts(chartData);
});
}
});
}
});
// Handle "Back to Form" button click
$("#backToFormBtn").click(function () {
$("#chart-section").hide();
window.history.back();
});
function drawCharts(chartData) {
drawBarChart('monthly-chart', chartData['Monthly'], 'Monthly Data');
drawBarChart('quarterly-chart', chartData['Quarterly'], 'Quarterly Data');
drawBarChart('year-on-year-chart', chartData['YearOnYear'], 'Year-on-Year Data');
drawBarChart('year-to-date-chart', chartData['YearToDate'], 'Year-to-Date Data');
}
function drawBarChart(containerId, data, title) {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('string', 'Label');
dataTable.addColumn('number', 'Value');
for (var key in data) {
dataTable.addRow([key, parseInt(data[key])]);
}
var options = {
title: title,
legend: {
position: 'none'
},
chart: {
title: title,
subtitle: ''
}
};
var chart = new google.visualization.ColumnChart(document.getElementById(containerId));
chart.draw(dataTable, options);
}
$("#clearSelection").click(function () {
multiselect.val(null).trigger('change');
multiselect.each(function () {
localStorage.removeItem(this.id);
});
});
$('#label').on('select2:select select2:unselect', function (e) {
if (e.params.data.id === 'ALL') {
if (e.type === 'select2:select') {
// If "ALL" is selected, select all other options except "ALL"
$(this).find('option[value!="ALL"]').prop('selected', true);
$(this).trigger('change');
} else if (e.type === 'select2:unselect') {
// If "ALL" is deselected, unselect all options
$(this).val(null).trigger('change');
}
}
});
$('#quarter').on('select2:select select2:unselect', function (e) {
if (e.params.data.id === 'ALL') {
if (e.type === 'select2:select') {
// If "ALL" is selected, select all other options except "ALL"
$(this).find('option[value!="ALL"]').prop('selected', true);
$(this).trigger('change');
} else if (e.type === 'select2:unselect') {
// If "ALL" is deselected, unselect all options
$(this).val(null).trigger('change');
}
}
});
});
型
1条答案
按热度按时间5vf7fwbs1#
找到了一个答案,如果有人有同样的经验问题,因为其中select2多个选项的行为怪异,以解决这个问题,我把列表选项值小于150