我正在开发一个项目,用户需要使用签名板签署表单。该表单需要三个单独的签名,我已经实现了三个按钮来打开签名板的模式。但是,我在使用第二个按钮时遇到了问题:
当我单击第二个按钮打开其模式时,第一次单击时它不会打开。仅在第二次单击后才打开。 一旦模式打开,它就无法正确关闭。 此问题仅发生在第二个按钮上,无论单击按钮的顺序如何。第一个和第三个按钮对于打开和关闭各自的模态效果非常好。
我怀疑我的代码中可能存在与事件处理或模式初始化相关的问题,但我不确定是什么导致了这种不一致。
这是我的按钮代码片段:
<tr>
<td>
<label for="candidate_sign">Tandatangan</label>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#signatureModal" data-user="candidate">Add Signature</button>
<input type="hidden" name="candidate_signature" id="candidate_signature" value="<?= htmlspecialchars($form_data['candidate_signature'] ?? '') ?>">
<div id="candidate-signature-container" class="signature-container">
<!-- The signature that been saved will be placed here -->
<?php if (!empty($form_data['candidate_signature'])): ?>
<img src="<?= htmlspecialchars($form_data['candidate_signature']); ?>" alt="Candidate Signature" class="signature-img">
<?php endif; ?>
</div>
</td>
<td>
<label for="hr_sign">Tandatangan</label>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#signatureModal" data-user="hr">Add Signature</button>
<input type="hidden" name="hr_signature" id="hr_signature" value="<?= htmlspecialchars($form_data['hr_signature'] ?? '') ?>">
<div id="hr-signature-container" class="signature-container">
<!-- HR signature will be displayed here -->
<?php if (!empty($form_data['hr_signature'])): ?>
<img src="<?= htmlspecialchars($form_data['hr_signature']); ?>" alt="HR Signature" class="signature-img">
<?php endif; ?>
</div>
</td>
<td>
<label for="comben_sign">Tandatangan</label>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#signatureModal" data-user="comben">Add Signature</button>
<input type="hidden" name="comben_signature" id="comben_signature" value="<?= htmlspecialchars($form_data['comben_signature'] ?? '') ?>">
<div id="comben-signature-container" class="signature-container">
<!-- Comben signature will be displayed here -->
<?php if (!empty($form_data['comben_signature'])): ?>
<img src="<?= htmlspecialchars($form_data['comben_signature']); ?>" alt="Comben Signature" class="signature-img">
<?php endif; ?>
</div>
</td>
</tr>
此片段适用于模态框:
<div class="modal" id="signatureModal" tabindex="-1" role="dialog" aria-labelledby="signature" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content" style="width: 100%; max-width:100%;">
<div class="modal-header">
<h4 class="modal-title" style="display: inline-block; vertical-align: middle;">Electronic Signature</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" style="float: right; margin-top: -5px;">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<!-- Tab navigation -->
<ul class="nav nav-tabs" id="signatureTab">
<li class="active">
<a href="#add-signature" data-toggle="tab">Add Signature</a>
</li>
</ul>
<!-- Tab contents -->
<div class="tab-content" id="signatureTabContent">
<!-- Add Signature Tab -->
<div class="tab-pane active" id="add-signature">
<canvas id="signature-pad" class="signature-pad border bg-white" style="width: 100%; height: 500px; border: 1px solid #ccc;"></canvas>
<p class="text-muted small">*Your signature will be saved in the database.</p>
</div>
</div>
<div class="modal-footer">
<div class="pull-left">
<button type="button" class="btn btn-info" id="undo">Undo</button>
<button type="button" class="btn btn-danger" id="clear">Clear</button>
<button type="button" class="btn btn-primary" id="done">Done</button>
</div>
</div>
</div>
</div>
</div>
</div>
这是函数的片段:
var $j = jQuery.noConflict();
document.addEventListener("DOMContentLoaded", () => {
const canvas = document.getElementById('signature-pad');
const clearButton = document.querySelector('#clear');
const undoButton = document.querySelector('#undo');
const doneButton = document.querySelector('#done');
let currentUserType = ''; // To track the current user type (candidate, hr, or comben)
// jQuery-specific logic
$j(() => {
// Initialize tabs
$j('.nav-tabs a').tab();
// Track which button triggered the modal
$j('button[data-target="#signatureModal"]').on("click", function () {
currentUserType = $j(this).data("user"); // Set current user type
updateSignatureButtonText(currentUserType); // Update button text for the specific user
$j('#signatureTab a[href="#add-signature"]').tab('show'); // Show the add signature tab
});
// Resize canvas when modal is shown
$j("#signatureModal").on("shown.bs.modal", resizeCanvas);
$j(window).on("resize", resizeCanvas);
});
const signaturePad = new SignaturePad(canvas, {
backgroundColor: null,
penColor: 'black',
lineWidth: 10
});
function resizeCanvas() {
const ratio = Math.max(window.devicePixelRatio || 1, 1);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
canvas.getContext("2d").scale(ratio, ratio);
signaturePad.clear();
}
function closeModal() {
$j('#signatureModal').on('shown.bs.modal', function() {
$j("#signatureModal").modal("hide");
});
}
clearButton.addEventListener('click', () => signaturePad.clear());
undoButton.addEventListener('click', () => {
const data = signaturePad.toData();
if (data.length > 0) {
data.pop();
signaturePad.fromData(data);
}
});
doneButton.addEventListener("click", function () {
if (signaturePad.isEmpty()) {
alert("Please provide a signature first.");
return;
}
const dataURL = signaturePad.toDataURL("image/svg+xml");
displayRecentSignature(dataURL, currentUserType);
closeModal();
});
// Function to display the signature
function displayRecentSignature(dataURL, userType) {
const containerId = `${userType}-signature-container`; // Dynamically determine the container
const recentSignatureContainer = document.getElementById(containerId);
if (!recentSignatureContainer) {
console.error(`Signature container for ${userType} not found`);
return; // Exit if the container doesn't exist
}
// Clear previous signature in the specific container
recentSignatureContainer.innerHTML = "";
const img = document.createElement("img");
img.src = dataURL;
img.alt = "Recent Signature";
img.classList.add("recent-signature");
img.style.width = "150px";
img.style.height = "auto";
recentSignatureContainer.appendChild(img);
const hiddenInput = document.getElementById(`${userType}_signature`);
hiddenInput.value = dataURL;
// Update button text to "Edit Signature" after signature is added
updateSignatureButtonText(userType);
}
// Function to update the signature button text
function updateSignatureButtonText(userType) {
const button = document.querySelector(`button[data-user="${userType}"]`);
if (!button) {
console.error(`Button for ${userType} not found`);
return; // Exit if the button doesn't exist
}
const signatureField = document.getElementById(`${userType}_signature`).value;
// Check if the signature field has a value and update the button text accordingly
if (signatureField && signatureField.trim() !== "") {
button.textContent = "Edit Signature"; // Change button text if signature exists
} else {
button.textContent = "Add Signature"; // Default button text if no signature
}
}
// Call the function on page load to set the initial button text
["candidate", "hr", "comben"].forEach(userType => {
updateSignatureButtonText(userType);
});
});
我尝试了以下方法来解决这个问题:
我的期望:
实际发生的事情:
在此处的代码中,您在
shown.bs.modal
事件上添加一个新的事件侦听器。
function closeModal() {
$j('#signatureModal').on('shown.bs.modal', function() {
$j("#signatureModal").modal("hide");
});
}
我认为然后监听模式显示(第二次单击),然后立即再次关闭它。也许将其更改为
function closeModal() {
$j("#signatureModal").modal("hide");
}