2

Hi Im trying to trying to track down a good modern Vanilla Javascript modal/lytebox with iFrame support, essentially I have I number of links like below:

<a class="edit-html" href="/iframe.html?para=123"></a>

That I want to trigger the modal with iframe content, without having to embed anything other than JS/CSS in the page (i.e. no modal markup)

HighslideJS (http://highslide.com/examples/iframe.html) meets the main requirements(although it doesn't have a modern look and isn't open source) does anyone know of any alternatives?

I've had a look at this link http://planetozh.com/projects/lightbox-clones/ although the list looks quite old and only HighSlideJS meets my requirements on that list

So my main requirements are:

  1. Vanilla JS (No dependencies)
  2. Iframe Content determined by href tag
  3. Actively Maintained, ideally on Github
  4. Modal markup does not need to be manually embedded on page
sjm
  • 5,378
  • 1
  • 26
  • 37
  • `looks old`... css is customizable – charlietfl Sep 23 '15 at 01:21
  • Yes if need be I could modernize the look oh Highslide via its CSS, but was hoping to not get involved in that – sjm Sep 23 '15 at 01:29
  • Highslide JS is completely open source. In theory you need a license for commercial use, but the script is almost "abandonware" at this point. As far as a "modern look" is concerned, it's very customizable (with very little effort), so I'm not sure what you mean. – MisterNeutron Sep 24 '15 at 21:10

1 Answers1

1

Interesting to try to see how we could accomplish your iframe manipulation in a way that would degrade gracefully without script. The anchor tag attributes can do most of the heavy lifting.

<a href="https://jsfiddle.net/rtoal/wvp4scLL/" target="iframe1" onclick="modal.show()">Link</a>
<a href="https://jsfiddle.net/exdev/sxGN3/" target="iframe1" onclick="modal.show()">Link</a>

<iframe name="iframe1" src="about:blank""></iframe>

Personally I think the best lightweight approach to dialogs is to use something sparse like the code below. They aren't often required to do much and therefore don't really require much in the way of being "maintained".

Fiddle here.

var Dialog = function(content, config){
  /*
  content: selector, element, or text to wrap into dialog body
  config object parameters:
    modal: boolean,
    dialogClass: text,
    createCallBack, renderCallBack, showCallBack, hideCallBack, toggleCallBack: functions
  */

  var self = this;

  this.config = config || {};

  this.init = function(){
    //check for an element passed as content or a selector corresponding to an element
    self.content = content.tagName ? content : document.querySelector(content);
    if( ! self.content){
      //otherwise content is text to be appended to the dialog body
      self.content = document.createElement("div");
      self.content.innerText = content;
    }
    self.container = self.create();
    self.body.appendChild(self.content);
    if(document.body){
      self.render();
    }else{
      document.body.addEventListener("load", self.render);
    }

    window.addEventListener("resize", function(){
      self.size();
    })

    return self;
  }

  this.create=function create(){
    self.container = document.createElement("div");
    self.dialog = document.createElement("div");
    self.head = document.createElement("h2");
    self.closeButton = document.createElement("button");
    self.body = document.createElement("div");
    self.head.innerText = self.config.headerText || "";
    self.dialog.appendChild(self.head);
    self.dialog.appendChild(self.closeButton);
    self.container.appendChild(self.dialog);
    self.dialog.appendChild(self.body);
    self.body.appendChild(self.content);
    self.container.className = "dialog-container" + (self.config.modal ? " modal" : "");
    self.dialog.className = "dialog " + self.config.dialogClass || "";
    self.head.className = "dialog-head";
    self.body.className = "dialog-body";
    self.closeButton.className = "dialog-close";
    self.closeButton.innerText = self.config.closeButtonText || "close";
   self.closeButton.title = self.config.closeButtonText || "close"; self.closeButton.addEventListener("click", self.hide);
    self.closeButton.setAttribute("type","button");
    self.checkCallBack();
    return self.container;
  }

  this.render = function render(){
    document.body.appendChild(self.container);
    self.checkCallBack(arguments);
    return self.dialog;
  }

  this.show = function(){
    setTimeout(function(){
      self.container.classList.add("visible");
      self.closeButton.focus();
      self.checkCallBack(arguments); 
      return self.container;
    },0);
  }

  this.hide = function hide(){
    var iframe = self.dialog.querySelector("iframe");
    if(iframe){
      iframe.setAttribute("src","about:blank");
    }
    self.container.classList.remove("visible");
    self.checkCallBack(arguments);
    return self.container;
  }

  this.toggle = function(){
    if(self.dialog.classList.contains("visible")){
      self.hide();
    }else{
      self.show();
    }
    self.checkCallBack(arguments);
    return self.container;
  }

  this.size = function(){
    var padding = 80;
    self.body.style.maxHeight = window.innerHeight - self.head.offsetHeight - padding + "px";
    console.log(self.body.style.maxHeight);
    return self.body.style.maxHeight;
  }

  this.checkCallBack = function(args){
    var action = arguments.callee.caller.name,
        callBackName = action + "CallBack",
      args = Array.prototype.slice.call(args || []),
      fn = self.config[callBackName];

    if(fn){
      args.unshift(action);
      fn.apply(self, args);
    }

    return !!fn;
  }

  this.init();
}

//sample usage
var.modal = new Dialog("iframe", {modal: true});
cage rattler
  • 1,587
  • 10
  • 16