Q:

jQuery created fields not sending POST data to PHP

My code is not getting any post data from the jQuery created fields in my form. I commented out a lot of the code to see exactly what was happening, but my $_POST is only receiving the Fields that are set manually in html. 
The jQuery created fields on the page show up and allow me to enter data. So I can't understand why I am not receiving any post data after a submit in my php code. Is there a way to capture the data in those fields and save them before a submit? 
      <?php

    session_start();
    require_once "pdo.php";

    // Demand a GET parameter
    if ( ! isset($_SESSION['user_id']) || strlen($_SESSION['user_id']) < 1  ) {
        die('ACCESS DENIED');
    } else {
        $username = $_SESSION['who'];
        $user_id = $_SESSION['user_id'];
    }

    if ( isset($_POST['cancel'] ) ) {
        // Redirect the browser to game.php
        unset($_SESSION['first_name']);
        unset($_SESSION['last_name']);
        unset($_SESSION['email']);
        unset($_SESSION['headline']);
        unset($_SESSION['summary']);
        header("Location: index.php?name=".urlencode($_SESSION['who']));
        return;
    }

    if ( isset($_POST['clear']) ) {
        $first_name = '';
        $last_name = '';
        $email = '';
        $headline = '';
        $summary = '';
        unset($_POST);
    }

    if ( isset($_POST['headline']) && isset($_POST['summary']) && isset($_POST['email']) 
        && isset($_POST['first_name']) && isset($_POST['last_name'])) {
        //$first_name = $_POST['first_name'];
        $email = $_POST['email'];
        //$headline = $_POST['headline'];
        $findme = "@";
        $pos = strpos($email, $findme);

        if ( strlen($_POST['headline']) < 1 || strlen($_POST['last_name']) < 1 
                || strlen($_POST['first_name']) < 1 || strlen($_POST['email']) < 1
                || strlen($_POST['summary']) < 1){
            $_SESSION['error'] = "All Fields Are Required";
            header("Location: add.php?name=".urlencode($_SESSION['who']));
            return;
        } 
        elseif ( $pos === FALSE ) {
                $_SESSION['error'] = "Email must have an at-sign (@)";
                header("Location: add.php");
                return;
        }
        else {
            foreach ($_POST as $key => $value) {
                echo "POST Field ".htmlspecialchars($key)." is ".htmlspecialchars($value)."<br>";
            }

            foreach ($_GET as $key => $value) {
                echo "GET Field ".htmlspecialchars($key)." is ".htmlspecialchars($value)."<br>";
            }

            $_SESSION['first_name'] = $_POST['first_name'];
            $_SESSION['last_name'] = $_POST['last_name'];
            $_SESSION['email'] = $_POST['email'];
            $_SESSION['headline'] = $_POST['headline'];
            $_SESSION['summary'] = $_POST['summary'];
           // header("Location: add.php");
            //return;
        }
    }

    ?>
    <!DOCTYPE HTML>
</p>    
<form id="form" method="post">
<p>First Name:
<input type="text" name="first_name" size="60" value="<?= htmlentities($first_name) ?>"/></p>
<p>Last Name:
<input type="text" name="last_name" size="60" value="<?= htmlentities($last_name) ?>"/></p>
<p>Email:
<input type="text" name="email" value="<?= htmlentities($email) ?>"/></p>
<p>Headline:
<input type="text" name="headline" value="<?= htmlentities($headline) ?>"/></p>
<p>Summary:<br/>
<textarea name="summary" rows="8" cols="80" value="<?= htmlentities($summary) ?>"></textarea></p>
<p>Position: <input type="submit" name="addPos" id="addPos" value="+">
<div id="position_fields">
</div>
<input type="submit" id="add" value="Add">
<input type="submit" name="clear" value="Clear">
<input type="submit" name="cancel" value="Cancel">

</form>
<script>
countPos = 0;

// http://stackoverflow.com/questions/17650776/add-remove-html-inside-div-using-javascript
$(document).ready(function(){
    window.console && console.log('Document ready called');
    $('#addPos').click(function(event){
        // http://api.jquery.com/event.preventdefault/
        event.preventDefault();
        alert("Does this work?");
        if ( countPos >= 9 ) {
            alert("Maximum of nine position entries exceeded");
            return;
        }
        countPos++;
        window.console && console.log("Adding position "+countPos);
        $('#position_fields').append(
            '<div id="position'+countPos+'"> \
            <p>Year: <input type="text" name="year'+countPos+'" value="" /> \
            <input type="button" value="-" \
                onclick="$(\'#position'+countPos+'\').remove();return false;"></p> \
            <textarea name="desc'+countPos+'" rows="8" cols="80"></textarea>\
            </div>');
    });

    $('#add').click(function(event) {
    event.preventDefault();
    var form = $('#form');
    var year = form.find('input[name="year'+countPos+'"]').val();
    var desc = form.find('textarea[name="desc'+countPos+'"]').val();
    var test = $('#form').serialize();
    alert ('You a beast');
    alert(countPos);
    alert(test['summary']);
    //alert(desc);
    alert($('#form').serialize());
    //alert(form.find('textarea[name="desc1"]')).val();
    // Executes an AJAX's POST request
    $.post(

      // replace with the URL that will process the POST request
      'postdata.php',

      // here is where the magic happens
      // form.serialize get data from all fields
      // in your form object and submit them via AJAX
      { 'val': year,'val2': desc,'val3': countPos},

      // Here you process the server's response
      function(data) {
        // do something with your data
        window.console && console.log("Postdata "+data);
        //console.log(data);
       // console.log(postdata);
        //alert(console.log(data));
        //alert(console.log(postdata));
      }
    ).error( function() { 
      $('#form').css('background-color', 'red');
      window.console && console.log("No Post data "+data);
      alert("Didn't work! "+data);
    });
    });
});

</script>
</div>
</html>

A:

The problem is that since you're adding fields on the fly, the DOM doesn't know that they exist.
All you have to do is to call form.serialize() so that you can get all data from your form fields.
I've created a small working example so that you can see what you should do:

$(document).ready(function() {
  var form = $('form');
  var fields = $('#fields');
  
  var add_button = $('#add');
  add_button.click(function(event) {
    console.log('Add a new field');
    
    // Notice I'm using backtick instead of quotes
    // It's easier to read and add data dinamically
    fields.append(`
      <div>
        <label for="field_${count}">Field #${count}</label><br />
        <input type="text" name="field_${count}" id="field_${count}" />
      </div>
    `);
    
    count++;
  });
  
  var count = 1;
  var submit_button = $('#submit');
  submit_button.click(function(event) {
    event.preventDefault();
    
    // Executes an AJAX's POST request
    $.post(
    
      // replace with the URL that will process the POST request
      'https://jsonplaceholder.typicode.com/posts',
      
      // here is where the magic happens
      // form.serialize get data from all fields
      // in your form object and submit them via AJAX
      form.serialize(),
      
      // Here you process the server's response
      function(data) {
        // do something with your data
        console.log(data);
      }
    );
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form" method="post">
  <div>
    <input type="button" id="add" value="Add" />
  </div>
  <div id="fields">
    <div>
      <label for="first_name">First Name</label><br />
      <input type="text" name="first_name" id="first_name" />
    </div>
    <div>
      <label for="first_name">Last Name</label><br />
      <input type="text" name="last_name" id="last_name" />
    </div>
  </div>
  <div>
    <input type="submit" name="submit" id="submit" value="Submit" />
  </div>
</form>

