misterManSam
misterManSam

Reputation: 24692

Post Dynamic Inputs that are Appended with jQuery

I have found multiple questions that are the same, these include:

Most problems are caused by opening the form within a table / div or some other problem with the HTML. I don't believe I have either of these problems; I suspect my javascript needs to be tweaked.

I am using jQuery as so:

<head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
</head>
  1. When the add link is clicked a new table row is appended to tbody.newRow

  2. When clicking .remove, you are asked for confirmation. Upon confirmation the row is removed.

  3. The form is submitted via ajax when input.Value loses focus.

jQuery:

$(document).ready(function() {
  $(".add").on('click', function() {
    $("tbody.newRow").append(
      '<tr><td><input type="text" name="NewJobLeviesId[]" class="JobLeviesId" /><input type="text" name="NewValue[]" class="Value" /><input type="text" name="MasterId[]" class="Values" /><input type="text" name="LUPChoiceId[]" class="Values" /><input type="text" name="SortOrder[]" class="Values" /></td><td class="removeSelection"><a href="#" class="remove">Remove</a></td></tr>'
    );
  });
  $("tbody").on('click', '.remove', function() {
    $(this).parent().append($(
      '<div class="confirmation"><a href="#" class="removeConfirm">Yes</a><a href="#" class="removeCancel">No</a></div>'
    ))
    $(this).remove();
  });
  $("tbody").on('click', '.removeConfirm', function() {
    $(this).parent().parent().parent().remove();
  });
  $("tbody").on('click', '.removeCancel', function() {
    $(this).parent().parent().append(
      '<a href="#" class="remove">Remove</a>');
    $(this).parent().remove();
  });
  var formTwo = $('.ajaxTwo'); // contact form
  // form submit event
  $(".Value").blur(function() {
    $.ajax({
      type: 'POST', // form submit method get/post
      dataType: 'html', // request type html/json/xml
      data: formTwo.serialize(), // serialize form data 
      success: function(data) {
        url: 'functions.php'; // form action url
      },
      error: function(e) {
        console.log(e)
      }
    });
  });
});

The html form. The ajax works wonderfully with the existing row that is not added dynamically. The add row is located in the table footer looking pretty. The form is posted as an array.

<form class="ajaxTwo" method="post">
    <table>
    <tbody class="newRow">
        <tr>
          <td>
              <input type="text" name="NewJobLeviesId[]" class="JobLeviesId" />
              <input type="text" name="NewValue[]" class="Value" />
              <input type="text" name="MasterId[]" class="Values" />
              <input type="text" name="LUPChoiceId[]" class="Values" />
              <input type="text" name="SortOrder[]" class="Values" />
          </td>
          <td class="removeSelection">
              <a href="#" class="remove">Remove</a>
          </td>
        </tr>
    </tbody>
   <tfoot>
        <tr>
           <td>
               <a href="#" class="add">Add Row</a>
           </td>
        </tr>
    </tfoot>
    </table>
</form>

Finally the php. Each row is inserted into my database table with a PDO prepared statement.

if(isset($_SERVER['HTTP_X_REQUESTED_WITH'])){
    if(isset($_POST['NewJobLeviesId'])) {
        for($i=0; $i<count($_POST['NewJobLeviesId']); $i++) {
          $NewJobLeviesId = $_POST['NewJobLeviesId'][$i];
          $NewValue = $_POST['NewValue'][$i];
          $MasterId = $_POST['MasterId'][$i];
          $LUPChoiceId = $_POST['LUPChoiceId'][$i];
          $SortOrder = $_POST['SortOrder'][$i];
          $sql = "INSERT INTO joblevies (JobLeviesId,Value,MasterId,LUPChoiceId,SortOrder) VALUES (:JobLeviesId,:Value,:MasterId,:LUPChoiceId,:SortOrder)";
        $q = $db->prepare($sql);
        $q->execute(array(':JobLeviesId'=>($NewJobLeviesId),':Value'=>($NewValue),':MasterId'=>($MasterId),':LUPChoiceId'=>($LUPChoiceId),':SortOrder'=>($SortOrder)));
        }
    }
}

Again, this works wonderfully well. Only the dynamically added inputs have a problem. What am I missing?

Upvotes: 1

Views: 4122

Answers (2)

chiliNUT
chiliNUT

Reputation: 19573

The dynamically created dom elements don't have any of the events that you attach on $(document).ready(... because they didn't yet exist when you were attaching events. So the $('.Value').blur(... stuff is only attached to the first form, and not any future ones. So attach the event every time you create a new row, so maybe something like this:

First, delegate the binding action to its own function

function attachSubmitEvent() {
    // form submit event
    //remove old events first
    $(".Value").off();
    $(".Value").blur(function () {
        var formTwo = $('.ajaxTwo'); // contact form
        $.ajax({
            type: 'POST', // form submit method get/post
            dataType: 'html', // request type html/json/xml
            data: formTwo.serialize(), // serialize form data 
            success: function (data) {
                url: 'functions.php'; // form action url
            },
            error: function (e) {
                console.log(e)
            }
        });
    });
}

then in your document.ready, call that function

attachSubmitEvent();

then, to make sure they are also attached to the new elements, call it again when creating new elements

$(".add").on('click', function () {
$("tbody.newRow").append('<tr><td><input type="text" name="NewJobLeviesId[]" class="JobLeviesId" /><input type="text" name="NewValue[]" class="Value" /><input type="text" name="MasterId[]" class="Values" /><input type="text" name="LUPChoiceId[]" class="Values" /><input type="text" name="SortOrder[]" class="Values" /></td><td class="removeSelection"><a href="#" class="remove">Remove</a></td></tr>');
attachSubmitEvent(); //now everyone has the event attached.
});

Upvotes: 1

VLS
VLS

Reputation: 2346

For your form submit event, try:

$("tbody").on('focusout', '.Value', function() {
    ...
});

You could also use blur in this event handler, but the documentation recommends using focusout for clarity (See 'Additional Notes' section of jQuery on() method documentation: http://api.jquery.com/on/)

Upvotes: 1

Related Questions