frankish
frankish

Reputation: 6826

How to keep reference to another jQuery object in a jQuery object?

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>

Upvotes: 2

Views: 341

Answers (3)

Hitmands
Hitmands

Reputation: 14179

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>

Upvotes: 1

Satish Kumar sonker
Satish Kumar sonker

Reputation: 1288

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>');

Upvotes: 0

Satish Kumar sonker
Satish Kumar sonker

Reputation: 1288

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

Upvotes: 0

Related Questions