Skip to content

Instantly share code, notes, and snippets.

@kdmukai
Last active August 29, 2015 13:56
Show Gist options
  • Save kdmukai/8959215 to your computer and use it in GitHub Desktop.
Save kdmukai/8959215 to your computer and use it in GitHub Desktop.
Simple jQuery approach to a site-wide popup warning or action dialog with a page overlay to dim the background. This should eventually be packaged up as a plugin that can be loaded on a per-page basis rather than living in the __base_template.html
<html>
<body>
<style>
.page_overlay {
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0, 0.75);
text-align: center;
z-index: 2;
}
.page_overlay_popup {
display: none;
opacity: 0.0;
margin: 0 auto;
max-width: 450px;
text-align: center;
border-radius: 1.0em;
border: 0.25em solid yellow;
background-color: #f8f8f8;
padding: 1.0em;
z-index: 3;
}
</style>
<div class="page_overlay" id="page_overlay">
<div class="page_overlay_popup" id="page_overlay_popup">
<div id="page_overlay_popup_content"></div>
<div class="float-right"><input type="button" id="page_overlay_popup_cancel_button" class="stylized_button stylized_button_tiny" data-role="none" value="cancel"/></div>
<div class="clear-both"></div>
</div>
</div>
<div>
...Rest of page template...
</div>
<script>
function initPageOverlay(content_selector) {
// Transfer the content to a new hidden div
var $holder = $("<div/>").hide().appendTo("body");
$(content_selector).appendTo($holder);
}
function showPageOverlay(content_selector) {
// Transfer the content to the popup overlay div
$(content_selector).appendTo($("#page_overlay_popup_content"));
$("#page_overlay").show();
var top_position = (window.innerHeight/2) - $("#page_overlay_popup").height();
if (top_position < 20) { top_position = 20; }
$("#page_overlay_popup").css({
"position": "relative",
"display": "block",
"top": top_position,
});
window.scrollTo(0, 0);
$("#page_overlay_popup").animate({opacity:1.0}, 500);
}
function hidePageOverlay() {
// Transfer the content back into a holder div
initPageOverlay($("#page_overlay_popup_content").children());
$("#page_overlay").hide();
$("#page_overlay_popup").css({opacity:0.0});
}
$(document).ready(function(){
$("#page_overlay_popup_cancel_button").click(function(){
// Wire up the popup cancel button
hidePageOverlay();
});
$(document).keyup(function(e) {
// Dismiss popup with ESC button
if (e.keyCode == 27) {
if ($("#page_overlay").is(":visible")) {
hidePageOverlay();
}
}
});
$(document).mouseup(function (e) {
// Dismiss popup with click outside window
var container = $("#page_overlay_popup");
if (container.is(":visible") &&
!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
hidePageOverlay();
}
});
});
</script>
</body>
</html>
<div>
<!-- Create "archive" and "delete" action buttons for each Gymnast -->
{% for gymnast in gymnasts %}
<tr>
<td>
<input type="text" name="gymnast_{{ gymnast.uuid }}" id="gymnast_{{ gymnast.uuid }}" value="{{ gymnast.name }}" data-mini="true" autocapitalize="off" autocorrect="off" />
</td>
<td><input type="button" class="stylized_button stylized_button_tiny stylized_button_tight archive_button" data-role="none" id="archive_{{ gymnast.uuid }}" value="archive" /></td>
<td><input type="button" class="stylized_button stylized_button_tiny stylized_button_tight delete_button" data-role="none" id="delete_{{ gymnast.uuid }}" value="delete" /></td>
</tr>
{% endfor %}
</div>
<!-- Create the "archive" popup content -->
<div id="archive_gymnast_confirm_container">
<div class="popup_header">Archive Gymnast</div>
Remove <span class="archive_gymnast_name"></span> from your active roster. All data for this
gymnast will still be saved.
<form name="archive_gymnast_form" id="archive_gymnast_form" method="post">
{% csrf_token %}
<input type="hidden" name="archive_gymnast_uuid" id="archive_gymnast_uuid"/>
<label for="archive_gymnast_confirm_checkbox">
<input type="checkbox" name="archive_gymnast_confirm_checkbox" id="archive_gymnast_confirm_checkbox" />
&nbsp;Yes, archive <span class="archive_gymnast_name"></span>
</label>
<br/>
<input type="submit" id="archive_gymnast_submit_button" name="archive_gymnast_submit_button" class="stylized_button stylized_button_small" data-role="none" value="archive"/>
</form>
</div>
<!-- Create the "delete" popup content -->
<div id="delete_gymnast_confirm_container">
<div class="popup_header">Delete Gymnast</div>
All data for <span class="delete_gymnast_name"></span> will be permanently deleted. This cannot be undone.
<form name="delete_gymnast_form" id="delete_gymnast_form" method="post">
{% csrf_token %}
<input type="hidden" name="delete_gymnast_uuid" id="delete_gymnast_uuid"/>
<label for="delete_gymnast_confirm_checkbox">
<input type="checkbox" name="delete_gymnast_confirm_checkbox" id="delete_gymnast_confirm_checkbox" />
&nbsp;Yes, I'm sure I want to delete <span class="delete_gymnast_name"></span>
</label>
<br/>
<input type="submit" id="delete_gymnast_submit_button" name="delete_gymnast_submit_button" class="stylized_button stylized_button_small" data-role="none" value="delete"/>
</form>
</div>
<script>
$(document).ready(function(){
// Wire up the popup content to use the site-wide popup system
initPageOverlay($("#archive_gymnast_confirm_container"));
initPageOverlay($("#delete_gymnast_confirm_container"));
// Wire up the "archive" and "delete" buttons for each Gymnast
{% for gymnast in gymnasts %}
$("#archive_{{ gymnast.uuid }}").click(function(event){
event.preventDefault();
// Insert Gymnast-specific values into the popup content
$(".archive_gymnast_name").text("{{ gymnast.name }}");
$("#archive_gymnast_uuid").val("{{ gymnast.uuid }}");
// Reset the confirm checkbox (otherwise it will retain state)
$("#archive_gymnast_confirm_checkbox").removeAttr("checked").checkboxradio("refresh");
// Trigger the popup display for this content
showPageOverlay($("#archive_gymnast_confirm_container"));
});
// Same popup wiring but for the "delete" action...
$("#delete_{{ gymnast.uuid }}").click(function(event){
event.preventDefault();
$(".delete_gymnast_name").text("{{ gymnast.name }}");
$("#delete_gymnast_uuid").val("{{ gymnast.uuid }}");
$("#delete_gymnast_confirm_checkbox").removeAttr("checked").checkboxradio("refresh");
showPageOverlay($("#delete_gymnast_confirm_container"));
});
{% endfor %}
// Wire up the submit button within the "archive" popup content
$("#archive_gymnast_submit_button").click(function(event) {
event.preventDefault();
if ( !$("#archive_gymnast_confirm_checkbox").is(":checked") ) {
alert("You must check the confirm checkbox!");
} else {
$("#archive_gymnast_form").submit();
}
});
// Do the same for the "delete" popup content
$("#delete_gymnast_submit_button").click(function(event) {
event.preventDefault();
if ( !$("#delete_gymnast_confirm_checkbox").is(":checked") ) {
alert("You must check the confirm checkbox!");
} else {
$("#delete_gymnast_form").submit();
}
});
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment