I'm having unexpected behavior for displaying this modal.
<% if @show_modal %>
<%= render 'modal' %>
<% end %>
<div id="scanQrCodeModal">
<h1>Scan QR Codes</h1>
<div class="section">
<div id="my-qr-reader"></div>
</div>
</div>
the instance variable @show_modal is generated from this method in attendances_controller.rb and everything works as expected apart from where if my_student_course.size > 1.
def mark_attendance
token = params[:encoded_token]
# Ensure the token is provided
if token.blank?
render json: { error: "Token is missing" }, status: :unprocessable_entity
return
end
begin
#decode jwt token
secret_key = Rails.application.credentials.secret_key_base
payload = JWT.decode(token, secret_key, true, algorithm: "HS256")[0]
lecturer_id = payload["lecturer_id"]
lecturer = Lecturer.find_by(id: lecturer_id)
if lecturer
my_student_course = lecturer.lecturer_units.flat_map(&:students_courses).uniq.select { |course| course.student_id == current_student.id }
if my_student_course.size > 1
@show_modal = true
@students_attendance_courses = my_student_course
puts @students_attendance_courses
# Render a pop-up page with a list of results and radio buttons for selection
else
# If there is only one result or none, proceed with the first result
@student_course = my_student_course
my_student_course_id = @student_course.first&.id
end
create_attendance(my_student_course_id)
else
render json: { error: "Lecturer not found for the given lecturer_id" }, status: :unprocessable_entity
end
rescue JWT::DecodeError => e
render json: { error: "Invalid token format" }, status: :unprocessable_entity
end
end
This is my bootsrap modal:
<!-- Button trigger modal -->
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<% if @show_modal %>
<div id="modal">
<!-- Use @students_attendance_courses to render the list -->
<% @students_attendance_courses.each do |course| %>
<!-- Rendering course details as needed -->
<%= course.id %>
<% end %>
</div>
<% else %>
<%= "No modal to show" %>
<% end %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
var myModal = new bootstrap.Modal(document.getElementById('exampleModal'));
myModal.show();
});
</script>
changed the condition rendering to render when false, the modal displayed on page load.
<% if !@show_modal %>
<%= render 'modal' %>
<% end %>
<div id="scanQrCodeModal">
<h1>Scan QR Codes</h1>
<div class="section">
<div id="my-qr-reader"></div>
</div>
</div>
This is how I trigger my mark attendance
function domReady(fn) {
if (
document.readyState === "complete" ||
document.readyState === "interactive"
) {
setTimeout(fn, 1000);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
function sendPostRequest(encodedToken, csrfToken) {
const currentUrl = window.location.href;
// Replace "/scan" with "/mark_attendance" in the URL
const newUrl = currentUrl.replace('/scan', '/mark_attendance');
fetch(newUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken,
},
body: JSON.stringify({ encoded_token: encodedToken }),
})
.then(response => {
if (response.redirected) {
// Handling redirect manually
window.location.href = response.url;
} else {
return response.json();
}
})
.catch(error => {
console.error('Error:', error);
});
}
domReady(function () {
// If found your QR code
function onScanSuccess(decodeText, decodeResult) {
alert("Your QR code is: " + decodeText, decodeResult);
// Fetch CSRF token from the meta tag
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
// Send a POST request to create attendance
sendPostRequest(decodeText, csrfToken);
}
let htmlscanner = new Html5QrcodeScanner(
"my-qr-reader",
{ fps: 10,
qrbox: { width: 250, height: 250 },
supportedScanTypes: [Html5QrcodeScanType.SCAN_TYPE_CAMERA, Html5QrcodeScanType.SCAN_TYPE_FILE] }
);
htmlscanner.render(onScanSuccess);
});

Try applying one of the solution from below
Soution-1
Solution-2