2

I am writing a simple jQuery plugin for my purpose, which:

  1. creates a background div (for blocking purposes, like a modal dialog). (referenced with backDiv)
  2. shows that background.
  3. shows $(this).
  4. removes background and hides $(this) when background clicked.

I am able to do all of these except 4th one: As I can't save a reference to the background div, I cannot get it back and remove it.

I tried $(this).data('backDiv',backDiv); and $(this)[0].backDiv = backDiv;

I know that there are various plugins that does this including the jQuery's own dialog function, but I want to create my own version.

I cannot keep this variable globally, so, how can I keep a reference to backDiv in a jQuery object, (or DOM object?) if that's even possible at all?

update: I allow multiple of these elements show on top of each other: Nested modal dialogs.

update-2:

(function($) {

  $.fn.showModal = function() {
    var backDiv = $('<div style="width: 100%; height: 100%; background-color: rgba(55, 55, 55, 0.5); position:absolute;top:0px;left:0px;">This is backDiv</div>');
    $(this).data('backDiv', backDiv);
    $('body').append(backDiv);

    //TODO: bringToFront(backDiv);
    $(this).show();
    //TODO: bringToFront($(this);

    var thisRef = $(this);
    backDiv.click(function() {
      thisRef.closeModal();
    });

    return $(this);
  };
  $.fn.closeModal = function() {
    //PROBLEM (null): var backDiv = $(this).data('backDiv');
    //backDiv.remove();
    $(this).data('backDiv', '');
    $(this).hide();
  }
}(jQuery));

$(document).ready(function() {
  $('#a').showModal();

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="a" style="display:none;z-Index:2;background:red; width: 100px; height:50px;position:absolute"></div>

6
  • 1
    Using class/id selector ? Commented Mar 28, 2016 at 7:42
  • 2
    Share your plugin code - $(this).data('backDiv',backDiv); should work, then var backDiv = $(this).data('backDiv'); Commented Mar 28, 2016 at 7:44
  • can you please make a fiddle for better understanding?? Commented Mar 28, 2016 at 7:45
  • Rayon Dabre's answer is the simplest I believe.. else the reference can also be stored in a variable for later use, Commented Mar 28, 2016 at 7:47
  • I added the code here, $(this).data('backDiv') returns null Commented Mar 28, 2016 at 8:03

3 Answers 3

1

I suggest you to work in terms of complex dom objects, something similar angular directives, basically, you have to work with components that are represented in the dom as Group of Objects.

So, following what I'm saying, your modal component should be something like that:

var Modal = (function($) {
  var tpl = '<div style="display:none;" class="modal"><div class="modal-backdrop"></div><div class="modal-content"></div></div>';
  
  function Modal(container) {
    var self = this;

    this.container = $(container || 'body');
    this.tpl = $(tpl).appendTo(this.container);
    this.content = $('.modal-content', this.tpl);
    this.backdrop = $('.modal-backdrop', this.tpl);
    
    this.isOpened = false;
    
    this.ANIMATION_DURATION = 500;
    
    this.backdrop.click(function(e) { self.toggle(e) });
  }
  
  Modal.prototype.show = function(cb) {
    var self = this;
    cb = $.isFunction(cb) ? cb : $.noop;
  
    this.tpl.fadeIn(this.ANIMATION_DURATION, function() {
      self.isOpened = true;
      cb();
    });
    
    return this;
  };
  
  Modal.prototype.hide = function(cb) {
    var self = this;
    cb = $.isFunction(cb) ? cb : $.noop;
  
    this.tpl.fadeOut(this.ANIMATION_DURATION, function() {
      self.isOpened = false;
      cb();
    });
    
    return this;
  };
  
  Modal.prototype.toggle = function() {
    if(this.isOpened) {
      return this.hide();
    }
    
    return this.show();
  };
  
  Modal.prototype.setContent = function(content) {
    this.content.html($('<div />').append(content).html());
    
    return this;
  };
  
  
  return Modal;
})(window.jQuery);

function ExampleCtrl($) {
  var modal = new Modal();
  
  modal.setContent('<h1>Hello World</h1>');
  
  $('#test').click(function() {
    modal.show();
  });
}

window.jQuery(document).ready(ExampleCtrl);
.modal {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
}

.modal .modal-backdrop {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  
  background: rgba(0, 0, 0, .8);
}

.modal .modal-content {
  width: 300px;
  height: 150px;
  background: #fff;
  border: 1px solid yellow;
  position: absolute;
  
  left: 50%;
  top: 50%;
  margin-left: -150px;
  margin-top: -75px;
  
  line-height: 150px;
  text-align: center;
}

h1 {
  line-height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="test">Test Modal</button>

Sign up to request clarification or add additional context in comments.

3 Comments

This is a very very valuable post and it gave me new ideas, thank you very much! I didn't select this just because it is not a "direct" solution to my problem.
There's no problem, generally, what I prefer is doing things in as better way as possible :)
I am agree with you that this total solution seems cleaner and more scalable.
0

Add data-backDiv="" into you dynamic modal div

Change below

var backDiv = $('<div data-backDiv="" style="width: 100%; height: 100%; background-color: rgba(55, 55, 55, 0.5); position:absolute;top:0px;left:0px;">This is backDiv</div>');

1 Comment

As this is the direct solution to my problem I selected this answer. So, it seems like the variable for data must already exist for dynamic divs. If not, please share your experience.
0

In order to retrive data attribute value using JQuery use following code

Syntax

$('selector').data('data-KeyName');

Example

1. $(this).data('backDiv'); // use to retrive value    or
2. var temp=$(this).data('backDiv'); // use to retrive value and assign into variable

2 Comments

I added the code, unfortunately $(this).data('backDiv') returns null
Please make sure data must be assign before access the same. otherwise it's return null

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.