2

I'm trying to create a form that allows user to edit the input through new window. PHP will process the input then append the new input with the new values. Apparently, when I try to edit the appended input, the JavaScript just won't fire. Please enlighten me on what I did wrong. This is my html code:

<html>
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script>
      $(document).ready(function(){
        $('.races').click(function(e){
          console.log("Inside Testing");
          e.preventDefault();
          var currID = this.id;
          var content = '<form id="theForm" action="ct.php" method="post"> Race: <input type="text" id="race" name="race"><button type="submit" onClick="OKClicked()">Click this!</button></form>';              
          childWin = window.open('', "_blank", "height=400, width=550, status=yes, toolbar=no, menubar=no, location=no,addressbar=no");
          toBeAdded = $(this).closest('div');
          childWin.document.close();
          childWin.document.write(content);
          popupRace = childWin.document.getElementById("race");
          parentRace = document.getElementById(currID);
          transferValues();
        })
      });
      function transferValues()
      {
          popupRace.value = parentRace.value;
      }
      function setValue(text)
      {
        childWin.close();
        toBeAdded.parent().append(text);
        toBeAdded.remove();
      }
    </script>

  </head>
  <body>
    <div>
      Name: <input type="text" name="name">
    </div>  
    <div>
      <div>
        <input type="hidden" name="race-0" value="Human" id="race-0">
        <span>race: Human</span>
        <a href="javascript:void(0)" class="races" id="race-0">Edit</a>
      </div>
    </div>
    <div>
      Name: <input type="text" name="name">
    </div>
    <div>  
      <div>
        <input type="hidden" name="race-1" value="God" id="race-1">
        <span>race: God</span>
        <a href="javascript:void(0)" class="races" id="race-1">Edit</a>
      </div> 
    </div>         
  </body>
 </html>

And this is my php code:

<?php
    $postDataKey = array_keys($_POST);
    $text = "";
    foreach ( $postDataKey as $currPostKey ) 
    {
        $currValue = $_POST[$currPostKey];
        $text .= '<div><input type="hidden" name="'.$currPostKey.'-1" value="'.$currValue.'" id="'.$currPostKey.'-1"><span>'.$currPostKey.': '.$currValue.'</span> <a href="javascript:void(0)" class="races" id="race-1">Edit</a></div>';
    }
    echo 
    '
    <html>
      <head>
        <script>
          window.opener.setValue(\''.$text.'\');
        </script>  
      </head>
    </html>
    '
    ;   
?>
Lisa
  • 21
  • 1

3 Answers3

7

jQuery is only aware of the elements in the page at the time that it runs, so new elements added to the DOM are unrecognized by jQuery. To combat that use event delegation, bubbling events from newly added items up to a point in the DOM that was there when jQuery ran on page load. Many people use document as the place to catch the bubbled event, but it isn't necessary to go that high up the DOM tree. Ideally you should delegate to the nearest parent that exists at the time of page load.

You will likely want to change event handlers so they use the on() method.

Community
  • 1
  • 1
Jay Blanchard
  • 34,243
  • 16
  • 77
  • 119
2

This was solved in older versions of jQuery with the live function, opposed to the bindfunction.

  • The bind function attached an event to all the matching elements, as long as they existed in the moment of execution. Any element appended afterwards would be excluded.
  • The livefunciton would attach the event on any matching element, even if the element was created after the execution of the instruction.

On the present version of jQuery, bind and live has been replaced by on. The default behavior of on()is like bind. Fortunately there is a way to use on so that it works like live.

I wrote an article about it, which it may help you understand how.

To sum it up...

// This behaves like `bind`
$(".clickable").on("click", function(){...});

// This behaves like `live`
$(".parent-element").on("click", ".clickable", function(){...});

So just search the common parent element that all possible elements could possibly have (you could use $(document) if you do not want to think too hard) and you are golden.

Enrique Moreno Tent
  • 24,127
  • 34
  • 104
  • 189
0

jQuery on Method is what you're looking for; click the link and look for delegated events.

"Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. "

ajacian81
  • 7,419
  • 9
  • 51
  • 64