jQuery: clone elements AND events

28,516

Solution 1

.clone( true ) does the trick.

Documentation: http://api.jquery.com/clone/

Solution 2

Hi I'm having a bit similar use case, I have some dynamically generated content that contains a button, click event is responding to the original button but not the generated one, I've done before :

$('.someclass').on('click', function() {

but i resolved my problem by replacing the on by live like this :

$('.someclass').live('click', function() {
Share:
28,516

Related videos on Youtube

Omar
Author by

Omar

I use SQL, MySQL, Oracle, php, javascript, Apache's httpd.conf VARIABLES and jQuery

Updated on November 14, 2020

Comments

  • Omar
    Omar over 3 years

    Whenever I use ajax to dynamically create new content, .clone(), append() etc, the new element looses any triggers and events I programmed =(

    After making copy, simple things that WORK on other elements like adding a class to , on the copied elements no longer work. Any new ajax content does not work. Command buttons no longer work. What can I do?

    I am cloning this HTML, and the command buttons no longer work. Styling the span elements no longer work on the CLONED elements:

    <div name="shows" id="x"><br/> <!-- The ID depends on the database-->
        <div name="shows" id="x">
            ID: <input disabled="disabled" size="7" value="x" name="id" />
            Status: 
            <select name="status" >
              <option selected="selected" >Display</option>
              <option >Hide</option>
            </select>
            <br/><br/>
            <span class="required" id="date_txt">*Date: </span><input type="text" value="" name="date" />
            &nbsp;&nbsp;
            <span class="required" id="title_txt">*Title: </span><input type="text" size="65" value="" name="title" />
            <br/>
            <span class="required" id="venue_txt">*Venue: </span><input type="text" size="45" value="" name="venue" />
            Telephone: <input type="text" value="" name="tel" />
            <br/>
            URL: <input type="text" size="100" value="" name="url" />
            <br/><br/>
            Address: <input type="text" size="45" value="" name="address" />
            &nbsp;&nbsp;
            <span class="required" id="city_txt">*City: </span><input type="text" value="" name="city" />
            <br/>
            State: <input type="text" value="" name="state" />
            ZIP: <input type="text" value="" name="zip" />
            <span id="country_txt">*Country: </span><input type="text" value="United States" name="country" />
            <br/>
            <br/>Comments: <br/>
            <textarea cols="80" rows="8" name="comments" ></textarea>
        </div>
        <!-- START OF:commands  -->
        <div id="commands" >
            <button name="edit" id="edit" >Edit</button> 
            <button name="delete" id="delete" >Delete</button>
        <br />
        <hr />
        <br />
        </div>
        <!-- END OF:commands  -->
    </div>
    <!-- END OF:new -->
    

    New comments added, 11/03/2011:

    OK, I figured out the problem and I had an error on my jQuery. Now, when I add .clone( true ) ALMOST everything works.


    My new problem is the UI datepicker. After cloning the HTML, when I click on the newly cloned date field, the focus goes to the (old) datefield the data was cloned from. More over, if I select a date, the value goes to the old datefield -Not the newly cloned datefield.

    Here is my ajax code (After a successful submition):

    UI datepicker code:

    $("input[name='date']").datepicker({ dateFormat: 'yy-mm-dd', changeMonth: true, changeYear: true, numberOfMonths: 3, showButtonPanel: true});
    

    Ajax:

        ...ajax code...
    function(data)
    {
    var $msg = eval(data);
    if( $msg[0] == 1 )
        {
        //#var.new
            $id = '#'+$msg[1];
            $data = $("#new");
        $new = $data.clone(true);
        $new.find('input.datefield').datepicker();
    
    
            $new.attr("id", $id);
            $new.children('[name="id"]').val($id);
            $new.children('[name="id"]').attr("value", $id);
            $new.children(":input").each(function() { var $value = $(this).val(); $(this).attr("value", $value); });
            $new.prepend( "<br/>" );
    
            $commands = $("#blank").children("#commands").clone(true);
            $commands.children("#add").text("Update");
            $commands.children("#add").attr("pk", $id);
            $commands.children("#add").attr("name", "update");
            $commands.children("#add").attr("id", "update");
    
            $commands.children("#reset").text("Delete");
            $commands.children("#reset").attr("pk", $id);
            $commands.children("#reset").attr("name", "delete");
            $commands.children("#reset").attr("id", "delete");
    
            $new.append( $commands );
    
            //#animation
            //blank.slideUp
            $("#blank").slideUp(2500, function(){
            $("#ADDNEW").html("&#9658; New:");
            //$("#blank").clone().prependTo( $("#active") );
            //$("#blank").prependTo( "#active" );
    
            //active.slideUp
            $("#active").slideUp("slow", function(){
            $("#ON").html("&#9658; Active:");
            $("#active").prepend( $new );
            $('#reset').trigger('click');
    
            //active.slideDown
            $("#active").slideDown(8500, function(){
            $("#ON").html("&#9660; Active:");
    
            //blank.slideDown
            $("#blank").slideDown(3500, function(){
            $("#ADDNEW").html("&#9660; New:");
            load_bar(0);
    
            }); //end: anumation.#blank.slideDown
            }); //end: anumation.#active.slideDown
            }); //end: anumation.#blank.slideUp
            }); //end: anumation.#active.slideUp
    
            //$("#new").fadeOut(2000, function(){
            //START: blank
            //alert( $("#blank").html() );
            //$dad = $("#new");
            //$dad.children('input[name!="id"][name!="country"], textarea').val('');
            //$dad.children('[name="country"]').val("United States");
            //$dad.children('[name="date"]').focus();
            //END: blank
            //$("#new").fadeIn(2000, function(){
            //alert( $msg );
            //}); //end: anumation.fadeIn
            //}); //end: anumation.fadeOut
            } //end: if
        else
            {
            //var varMSG = data;
            //alert( "Hello" );
            alert( $msg );
    
            //$("#add").attr("disabled", false);
            //$("#reset").attr("disabled", false);
            load_bar(0);
            } //end: if.else
        }//end: $.post.function
    ); //END:$.post
    }); 
    //END:ajax
    
    • rossipedia
      rossipedia over 12 years
      Can you post some sample javascript?
    • nnnnnn
      nnnnnn over 12 years
      Does the HTML above replace content that was already on the page, or add to it? Because any JS that uses element IDs is not going to work properly if you are adding additional copies with the same IDs (e.g., id="edit" on your button). Please show your JS.
    • RobG
      RobG over 12 years
      What does "no longer work" mean?
  • Omar
    Omar over 12 years
    I used .clone( true ) but it still does not work. span elements are supposed to change color (toggle class .required) depending on the input's change. Yet, but they do not.
  • Šime Vidas
    Šime Vidas over 12 years
    @Omar Could you post the JavaScript code that clones and appends those elements?
  • Rohan Desai
    Rohan Desai over 12 years
    By the sound of his question it looks like he should have gone for clone(true, true) instead.
  • Šime Vidas
    Šime Vidas over 12 years
    @missingno true twice is not needed, since the value of the second parameter matches the value of the first argument by default...
  • FrankDraws
    FrankDraws over 8 years
    Brilliant! The .live method worked for me. I was trying .clone(true) but couldn't figure out how or where. Thanks!
  • UncaughtTypeError
    UncaughtTypeError over 6 years
    Heads up, .live() has been deprecated since jQuery ver 1.7. Ref: api.jquery.com/live