2

I am trying to add a new row and bind a click event when the row before is selected. The problem is that this create a recursive logic as the click function is bound in itself. So currently the first update works in terms of the click binding but the not the following new rows. Heres the code

$('.new').click(function ()
                {
                   var newrow =" <div class='controls controls-row'><div id='div_id_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"' class='control-group control span1 m-wrap input-icon' >"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"</div><div id='div_rules_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"' class='control-group control span5 m-wrap input-icon' ><input type='text' onchange='updateRecord(this)' id='rules_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"' name='rules_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"'  class='m-wrap span11 new' value=''/></div></div>";
                    var Parent = document.getElementById('tablediv');
                    var NewDiv = document.createElement("DIV");
                    NewDiv.innerHTML = newrow;
                    Parent.appendChild(NewDiv);
                    $('.new').click(function ()
                    {
                        var newrow =" <div class='controls controls-row'><div id='div_id_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"' class='control-group control span1 m-wrap input-icon' >"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"</div><div id='div_rules_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"' class='control-group control span5 m-wrap input-icon' ><input type='text' onchange='updateRecord(this)' id='rules_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"' name='rules_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"'  class='m-wrap span11 new' value=''/></div></div>";
                        var Parent = document.getElementById('tablediv');
                        var NewDiv = document.createElement("DIV");
                        NewDiv.innerHTML = newrow;
                        Parent.appendChild(NewDiv);

                    });

                });

How do I create it so that the click event creates a new row and adds the same function click event to the new row. Thanks

1
  • You might want to consider using something like jquery's clone instead of a massive string of html. Commented Sep 19, 2013 at 20:01

2 Answers 2

5

You can use event delegation using on() for jquery >=1.7 and live() for earlier versions.

$(document).on('click', '.new', function (){

var newrow =" <div class='controls controls-row'><div id='div_id_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"' class='control-group control span1 m-wrap input-icon' >"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"</div><div id='div_rules_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"' class='control-group control span5 m-wrap input-icon' ><input type='text' onchange='updateRecord(this)' id='rules_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"' name='rules_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"'  class='m-wrap span11 new' value=''/></div></div>";
                var Parent = document.getElementById('tablediv');
                var NewDiv = document.createElement("DIV");
                NewDiv.innerHTML = newrow;
                Parent.appendChild(NewDiv);

});

Instead of document bind the event to another parent container that exists in DOM at any given point in time. This makes use of event bubbling and in actuality you are binding the event to the parent element or document head as in my example when you click on the element it matches the selector and its parent as the event bubbles up to where event is bound to and triggers the event on that element

With the way you are binding the events internally with the generic selector .new it will bind the click event again on to the existing .new elements every time you click, so you end up having the events executed multiple times.

You can also do this as:

$(function(){
        $('.new').click(handleClick);
    });

    function handleClick(){
                       var newrow =" <div class='controls controls-row'><div id='div_id_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"' class='control-group control span1 m-wrap input-icon' >"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"</div><div id='div_rules_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"' class='control-group control span5 m-wrap input-icon' ><input type='text' onchange='updateRecord(this)' id='rules_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"' name='rules_"+this.id.split('_')[1]+'_'+new String(parseInt(this.id.split('_')[2])+1)+"'  class='m-wrap span11 new' value=''/></div></div>";
                        var Parent = document.getElementById('tablediv');
                        var NewDiv = document.createElement("DIV");
                        NewDiv.innerHTML = newrow;
                        $(Parent).append($(NewDiv).find('.new').click(handleClick).end());

    }

Also you can consider using templating to bind the data and clone the element instead of using string concatenation and creating the html dynamically in the click event.

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

1 Comment

Thanks for the solution and the underlying explanation!
4

use .on() instead. It auto-binds to newly created elements so you don't need the recursion.

Comments

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.