Quick JS Modal with callback

by Miega

HTML

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="col-md-12">
  <button id="default" class="btn btn-primary">Default Modal</button>
  <button id="callback" class="btn btn-primary">Modal with custom callback</button>
</div>
<script>
"use strict";

$(document).ready(function() {

	$("#default").on("click", function(){
		var defaultModal = new raModal({
			content: '<div>You clicked on the default button.</div>',
			closeButton: false
		});
		defaultModal.open();
	});
	$("#callback").on("click", function(){
		var callbackModal = new raModal({
			content: "<div>You clicked on the Callback button. This shows the popup, but has a custom callback function, called when the user clicks OK and/or Close.</div>",
			onOK: function(){
					okCallback('4');
			},
			onClose: closeCallback,
			closeButtonText: "Close"
		});
		callbackModal.open();
	});

});

function closeCallback(){
	console.log("Successfully triggered the CLOSE callback.");
}

function okCallback(num){
	console.log("Successfully triggered the OK callback with the number: " + num);
}

</script>

CSS

/* raModal Base CSS */
@import url(https://fonts.googleapis.com/css?family=Open+Sans);

.ra-overlay
{
    position: fixed;
    z-index: 9998;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0,0,0,.33);
}

.ra-modal
{
    font-family: "Open Sans", sans-serif;
    position: absolute;
    z-index: 9999;
    top: 50%;
    left: 50%;
    width: 94%;
    padding: 24px 20px;

    /*Keeps modal always centered regardless of screen size on all broswers*/
    -webkit-transform: translate(-50%, -50%);
       -moz-transform: translate(-50%, -50%);
        -ms-transform: translate(-50%, -50%);
         -o-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);

    border-radius: 5px;
    background: #fff;
    box-shadow: 8px 8px 10px #888888;
}

.ra-title{
    font-family: "Open Sans", sans-serif;
    font-size: 18px;
    font-weight: 600;
    margin-top: 1px;
    margin-bottom: 10px;
    background-color: #cccccc;
    text-align: center;
    border-radius: 8px;
}

.ra-content{
    font-family: "Open Sans", sans-serif;
    margin-bottom: 20px;
}

.ra-modal.ra-open.ra-anchored
{
    top: 20px;

    /*Keeps modal always centered regardless of screen size on all broswers*/
    -webkit-transform: translate(-50%, 0);
       -moz-transform: translate(-50%, 0);
        -ms-transform: translate(-50%, 0);
         -o-transform: translate(-50%, 0);
            transform: translate(-50%, 0);
}

/* OK Button */
.ra-ok
{
    font-family: "Open Sans", sans-serif;
    font-size: 16px;
    font-weight: 500;
    line-height: 13px;

    position: relative;

    padding: 5px 7px 7px 7px;
    margin-right: 3px;
    float: right;

    cursor: pointer;

    color: #fff;
    border: 0;
    outline: none;
    background: #8c8c8c;  
}
.ra-ok:hover
{
    background: #505050;
}

/* Close Button */
.ra-close
{
    font-family: "Open Sans", sans-serif;
    font-size: 16px;
    font-weight: 500;
    line-height: 13px;

    position: relative;

   ...

JavaScript

"use strict";
(function() {

  // Make the constructor
  window.raModal = function() {

    // Create global element references
    this.closeButton = null;
    this.modal = null;
    this.overlay = null;

    // Define option defaults
    var defaults = {
      autoOpen: false,
      className: "modalClass",
      modalTitle: "Button Clicked!",
      okButton: true,
      closeButton: true,
      closeButtonText: "Close",
      content: "",
      maxWidth: 500,
      minWidth: 280,
      minHeight: 200,
      maxHeight: 800,
      overlay: true,
      onOK: null,
      onClose: null
    }

    // Create options by extending defaults with the passed in arugments
    if (arguments[0] && typeof arguments[0] === "object") {
      this.options = extendDefaults(defaults, arguments[0]);
    }
    if(this.options.autoOpen === true) this.open();

  }

  //Public Methods
  raModal.prototype.open = function(){
    // Build out raModal
    buildOut.call(this);

    // Initialize event listeners
    initializeEvents.call(this);

    //force recalcuation of modal height using the window's height
    window.getComputedStyle(this.modal).height;
  }

raModal.prototype.close = function() {
  
    var modalCollect = document.getElementsByClassName("ra-modal");
    var overlayCollect = document.getElementsByClassName("ra-overlay");
    while (modalCollect.length > 0){
      //Remove the nodes from the DOM (will cease to exist)
      modalCollect[0].parentNode.removeChild(modalCollect[0]);
      overlayCollect[0].parentNode.removeChild(overlayCollect[0]);
    }

}

  //Private Methods (only called by the plugin itself)

  function buildOut() {

    var content, title, contentHolder, titleHolder, docFrag;
    
    //If content is an HTML string, append the HTML string.
    //Otherwise, append its content.
    if (typeof this.options.content === "string") {
      title = this.options.modalTitle;
      content = this.options.content;
    } else {
      title =...