0

I have html grid table consisting of comment link in each row.Clicking on any one opens a bootstrap modal with textbox and save button.So I wrote a library consisting of functions related to that comment system.Below is basic code.

HTML :

        <td><a class="addComment"  data-notedate="somevalue" data-toggle='modal'  href='#addnotesdiv' data-oprid="somevalue" data-soid="somevalue"  data-type="1"><i class="fa fa-comments-o fa-2"></i></a></td> ..... n

JS :

    var Inventory={};

Inventory.notes={
defaults:{
                        type:'1',
                        soid:0,
                        operator_id:0,
                        date:'',
                        target:'div#addnotesdiv',
                  },
init:function()
{
   var self=this;

   $('div#addnotesdiv').on('show.bs.modal',function(e){
            self.getandsetdefaults(e);
            self.setmodalelements(e);
            self.getNotes();
            self.addnote();
            self.activaterefresh();
   });


},
getandsetdefaults:function(e)
{
     this.defaults.soid = $(e.relatedTarget).data('soid');
     this.defaults.operator_id=$(e.relatedTarget).data('oprid');
     this.defaults.type=$(e.relatedTarget).data('type');
     this.defaults.date=$(e.relatedTarget).data('notedate');

},
setmodalelements:function(e)
{
    $(e.currentTarget).find('#notesthread').empty();
    $(e.currentTarget).find('input#inpnotesoid').val(this.defaults.soid);
    $(e.currentTarget).find('input#inpnoteoprid').val(this.defaults.operator_id);
    $(e.currentTarget).find('input#inpnotetype').val(this.defaults.type);
},
addnote:function()
{
         var self=this;

        $('button#btnaddnote').on('click',function(){

            var message=$(self.defaults.target).find('textarea#addnotemsg').val();
            var soid=$(self.defaults.target).find('input[type=hidden][id=inpnotesoid]').val();
            var note_date=$(self.defaults.target).find('input#addnotedate').val();
            var oprid=$(self.defaults.target).find('input[type=hidden][id=inpnoteoprid]').val();
            var type=$(self.defaults.target).find('input[type=hidden][id=inpnotetype]').val();


               if(message=="" || soid=="" || note_date=="")
                    {
                        alert("Fill all details");
                        return;
                    }

              var savenote=$.post(HOST+'notes/save',{message:message,soid:soid,note_date:note_date,type:type,operator_id:oprid});

                savenote.done(function(res){

                res=$.parseJSON(res);

                if(res.status && res.error){
                    alert(res.message);
                    return;
                }
                if(res.status && res.type)
                {
                  $('div#addnotemsg').showSuccess("Done").done(function(){self.getNotes();});
                  $('div#addnotesdiv').find('textarea#addnotemsg').val('');
                }
                else
                {
                $('div#addnotemsg').showFailure("Error");
                }
                });

        });


},
getNotes:function()
{
      $('button#btnrefreshcomments i').addClass('glyphicon-refresh-animate');

       var getnotes=$.getJSON(HOST,{soid:this.defaults.soid,type:this.defaults.type,note_date:this.defaults.date,operator_id:this.defaults.operator_id});

        getnotes.done(function(res){
          if(res.status && res.data.length)
          {
             --somecode---
          }
       });
},
activaterefresh:function(){

      var self=this;

     $(document).on('click','#btnrefreshcomments',function(){
               $('#notesthread').empty();
                self.getNotes();
            return false;
        });

        return false;
}

}

In Order to activate this functionality on that page I wrote

     Inventory.notes.init();

Above code works perfectly when I open modal once but when I close that same modal and open it again but by clicking on different link all events are fired twice,thrice and so on.Number of events fired is equal to number of times modal opened on that page. Is there any thing wrong in code Or any other way to perform this same task.

I know this is not a plugin all I wanted was to store all functionality related to comment system under one roof as library.

Vibhas
  • 241
  • 5
  • 20
  • I can't see a data-target in the html. How do you open the modal? I guess the multiple opening issue could be something to with the code opening the modal. Not sure where or how you define #addnotesdiv either, perhaps the bootstrap modal.js doesn't like how you've set it - take a look at [link](http://stackoverflow.com/questions/18995461/how-can-i-show-data-using-a-modal-when-clicking-a-table-row-using-bootstrap), Also the Inventory.notes.init('a.addComment') param doesn't appear to be being used. – Anthony Jan 26 '16 at 17:48
  • @anthony data-target not required href attribute does that for me.I am opening modal using boostrap attributes instead of jquery code.#addnotesdiv is my id of modal html.Also removed a.addComment . Still same ... – Vibhas Jan 27 '16 at 04:04

2 Answers2

0

every time you open the modal box, it triggered show.bs.modal event, then all methods was exec again, including the event bindings. e.g. event bind in [addnote]

$('div#addnotesdiv').on('show.bs.modal',function(e){
    self.getandsetdefaults(e);
    self.setmodalelements(e);
    self.getNotes();
    self.addnote();
    self.activaterefresh();
});
SONGLIN.WU
  • 76
  • 3
  • Executing all methods again is ok since I want them to when modal opens again on same page but by clicking on different link.But when I insert any comment OR press refresh button all those are fired twice and so on there are multiple inserts & selections.I know its something related to show.bs.modal event cant figure out how to get it fixed . – Vibhas Jan 27 '16 at 04:11
  • every time you open the model box, `addnote()` method is called and `$('button#btnaddnote').on('click',function(){})` is executed once. So when you open modal at second time, it bind twice click event callback on button#btnaddnote. At this time, comment creation will be duplicated. @Vibhas – SONGLIN.WU Jan 27 '16 at 19:24
0

Problem was whenever modal was shown getNotes,addnote,activatereferesh functions were called but when the modal was reopened again this functions are called again so thats twice and so on.Putting it in more simpler way is there were multiple listeners attached to single element without destroying previous one because my init function was called many times.

At last there were two solutions in both I need to unbind events or attach them only once.Got idea from here

1) Modified Init function with below code and added one unbind listener function

init:function(selector)
{
   var self=this;

   $(self.defaults.target).on('show.bs.modal',function(e){
            self.getandsetdefaults(e);
            self.setmodalelements(e);
            self.getNotes();
            self.addnote();
            self.activaterefresh();

   });

   $(self.defaults.target).on('hide.bs.modal',function(e){
           self.unbindlistners();
   });
}
   unbindlistners:function()
{
      var self=this;
     $('#btnrefreshcomments').unbind('click');
     $('button#btnaddnote').unbind('click');

      return false;
}

}

2) Place event binding function outside show.bs.modal

 init:function(selector)
{
   var self=this;

   $(self.defaults.target).on('show.bs.modal',function(e){
            self.getandsetdefaults(e);
            self.setmodalelements(e);
   });
  self.getNotes();
  self.addnote();
  self.activaterefresh();
}

There is small catch in second solution that is when first time my DOM is loaded function getNotes function is called with default values.

Community
  • 1
  • 1
Vibhas
  • 241
  • 5
  • 20