I came to a solution on this problem, but it was more detailed than originally expected. Include the following JavaScript in your admin pages:
jQuery(document).ready(function($){
const form = $('form[name="adminForm"]');
const form_id = form.attr('id');
const initial_form_state = $('form[name="adminForm"]').serialize();
const obj_name = form_id.replace('-form', '');
let clicked_url = '';
/**
* Checks in the current form and then redirects to the URL selected by the user
*
* @return {void}
*/
function checkInThenRedirect(){
// Set the task to cancel
$(form).find('input[name="task"]').val(`${obj_name}.cancel`);
$.ajax({
cache: false,
contentType: false,
data: new FormData($('form')[0]),
method: 'POST',
processData: false,
url: $('form').attr('action')
}).done(function(data){
window.location = clicked_url;
});
}
// Listen for any changes to files
$('form :file').change(function(){
$('form').data('changed',true);
});
// Listen for clicks on links
$('#content a').not('[target="_blank"]').not('[href^="#"]').not('.modal').not('[class*="group-add"]').not('[class*="group-remove"]').not('[class*="button"]').click(function(event){
event.preventDefault();
clicked_url = $(this).attr('href');
// Get the current from state
const form_state = $(`#${form_id}`).serialize();
// If changes were made, prompt the user to see if they want to save
if(initial_form_state !== form_state || $('form').data('changed')){
event.preventDefault();
// Add a modal to the screen
$('body').append(`
<div class="modal" id="confirmLeaveModal" style="margin-left: -150px; text-align: center; width: 300px;">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3>Unsaved Changes</h3>
</div>
<div class="modal-body">
<p style="padding: 20px;">You have unsaved changes. Would you like to save them?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn" id="confirmLeaveNo">No</button>
<button type="button" class="btn btn-primary" id="confirmLeaveYes">Yes</button>
</div>
</div>`);
return;
}
checkInThenRedirect();
});
// Bootstrap's modal close doesn't work on dynamic modals. Fixing that
$('body').on('click', '#confirmLeaveModal .close', function(event){
$('#confirmLeaveModal').remove();
});
// If the user does not want to save changes
$('body').on('click', '#confirmLeaveNo', function(event){
event.preventDefault();
checkInThenRedirect();
});
// If the user agrees to save changes
$('body').on('click', '#confirmLeaveYes', function(event){
event.preventDefault();
// Get the form URL
let target = $('form').attr('action');
// Add a return with the clicked_url
target += '&return=' + encodeURI(window.btoa(clicked_url));
// Add the new target to the form
$('form').attr('action', target);
// Cause the form to be submitted
Joomla.submitform(`${obj_name}.save`, document.getElementById(form_id));
});
});
The above code will automatically check-in the resource that the user had locked when they navigate to a new admin screen. If they made changes to the current screen, it will prompt them for what to do first.