Form does not submit jQuery added input fields

Hi,

I have a form with a few input fields. I then have jQuery append a few checkbox input fields. I can see the checkboxes appear and behave fine. Now, when I click on the button to submit my form, all input fields are posted to my php controller except for those which have been added by jQuery.

Here is how I add a checkbox input field:

        $('#checkboxes').append(
          $(document.createElement("div")).html(firstname + ' ' + lastname).append(
            $(document.createElement("input")).attr('name', 'subscriptionId_' + elearningSubscriptionId).attr('value', 1).attr('type', 'checkbox').attr('checked', true)
          )
        )

The form lookis like:

<form action='/dev/php/learnintouch/www/learnintouch.com/engine/modules/elearning/assignment/add.php' method='post' name='edit' id='edit'  target='_self'>

The checkboxes elements is sitting within the form opening and closing tags and looks like:

<div id='checkboxes' />

I retrieve the posted input field values in the PHP controller with a:

foreach ($_POST as $inputName => $inputValue) {
}

My log shows:

[02-Feb-2013 11:16:04 Europe/London] elearningExerciseId : 55
[02-Feb-2013 11:16:04 Europe/London] elearningSubscriptionId :
[02-Feb-2013 11:16:04 Europe/London] participantName :
[02-Feb-2013 11:16:04 Europe/London] elearningClassId : 7
[02-Feb-2013 11:16:04 Europe/London] openingDate :
[02-Feb-2013 11:16:04 Europe/London] closingDate :
[02-Feb-2013 11:16:04 Europe/London] okButton_x : 19
[02-Feb-2013 11:16:04 Europe/London] okButton_y : 14
[02-Feb-2013 11:16:04 Europe/London] formSubmitted : 1

If I append the checkbox input fields not onto the checkboxes div element but on the form itself, with a:
$(‘#edit’).append(
instead of the
$(‘#checkboxes’).append(
then the checkbox input field values are posted fine to the PHP controller. The side effect is that I cannot position my checkboxes where I want on the page.

Any clue ?

Kind Regards,

The same problem happens if I build the checkbox input field as an html content string:

$('#checkboxes').append("<div>" + firstname + " " + lastname + " <input type='checkbox' value='1' checked='checked' name='subscriptionId_" + elearningSubscriptionId+ "'></div>");

I tried not using a div as in:

$('#checkboxes').append(firstname + " " + lastname + " <input type='checkbox' value='1' checked='checked' name='subscriptionId_" + elearningSubscriptionId+ "'><br/>");

but the issue remained the same.

The full page source:

<!doctype html public '-//w3c//dtd html 4.01 transitional//en'>
<html>
<head>
<title> A little web platform for your language school</title>
<meta http-equiv='content-type' content='text/html; charset=iso-8859-1'>
<link rel='stylesheet' type='text/css' href='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/system/panel/css/default.css' />
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/popup.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/ajax.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/utilities.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/cookies.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/adddomloadevent-compressed.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/jquery-1.7.1.min.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/datepicker/language/jquery.ui.datepicker-da.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/datepicker/language/jquery.ui.datepicker-de.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/datepicker/language/jquery.ui.datepicker-en-GB.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/datepicker/language/jquery.ui.datepicker-es.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/datepicker/language/jquery.ui.datepicker-fi.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/datepicker/language/jquery.ui.datepicker-fr.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/datepicker/language/jquery.ui.datepicker-it.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/datepicker/language/jquery.ui.datepicker-nl.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/datepicker/language/jquery.ui.datepicker-no.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/datepicker/language/jquery.ui.datepicker-ru.js'></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/datepicker/language/jquery.ui.datepicker-sv.js'></script>
<link rel='stylesheet' type='text/css' href='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/ui/css/smoothness/jquery-ui-1.8.17.custom.css' />
<script type="text/javascript" src="http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/ui/jquery-ui-1.8.17.custom.min.js"></script>
<script type="text/javascript" src="http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/jquery-ui-autocomplete-extension/scottgonzalez-jquery-ui-extensions-e34c945/autocomplete/jquery.ui.autocomplete.html.js"></script>
<script type='text/javascript' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/wtooltip.min.js'></script>
<script type="text/javascript" src="http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/js/jquery/cycle/jquery.cycle.all.min.2.99.js"></script>

<script type="text/javascript">
$(document).ready(function() {
  $(".tooltip").wTooltip({
    follow: false,
    fadeIn: 300,
    fadeOut: 500,
    delay: 500,
    style: {
      width: "500px", // Required to avoid the tooltip being displayed off the right
      background: "#ffffff",
      color: "#000",
      fontSize: 14
    }
  });
});
</script>

<script type="text/javascript">
function setPageTitle() {
  parent.document.title = " A little web platform for your language school";
}
</script>
</head>
<body onLoad="setPageTitle(); formFocus(); ">

<table border='0' id='bodyTable' class='admin' style='width:100%; height:94%;'><tbody><tr><td class='no_style_body'>
<table border='0' width='100%' cellpadding='2' cellspacing='2'><tr>
<td align='left' width='25%'>
<a href='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/modules/elearning/assignment/admin.php' onmouseover="(window.status=''); return(true);">
<img src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/system/panel/image/common/parent_menu.png' border='0' title='Back to the upper level'></a>
</td>
<td align='center'>
<div class='header'>Give an assignment</div>
</td>
<td align='right' width='25%'><span class='tooltip' title='<span class="system_tooltip">It is possible to give an assignment to one or more participants.<br /><br />All the participants will then be able to do the assignment.<br /><br />For example, it is possible to give an assignment to all the participants of a class.</span>'><img src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/system/panel/image/common/help.png' style='border-width:0px; vertical-align:middle;' title='' alt='' /></span>
</td>
</tr></table>
<br/><table class='list_lines' border='0' width='100%' cellpadding='4' cellspacing='0'><tbody>
<tr class=''>
<td style='' width='10%'  colspan=2>
&nbsp;
</td>
</tr>
<form action='/dev/php/learnintouch/www/learnintouch.com/engine/modules/elearning/assignment/add.php' method='post' name='edit' id='edit'  target='_self'>
<script type='text/javascript'>
$(document).ready(function() {

  $("#elearningExerciseName").keyup(function() {
    if (!this.value) {
      $("#elearningExerciseId").attr("value", '-1');
      $("#elearningExerciseId").change();
      $("#elearningExerciseName").attr("value", '');
      $("#elearningExerciseName").change();
    }
  });

  $("#elearningExerciseName").autocomplete({
    source: "http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/modules/elearning/exercise/suggestExercises.php",
    minLength: 2,
    html: true,
    select: function(event, ui) {
      if (ui.item) {
        $("#elearningExerciseId").attr("value", ui.item.id);
        $("#elearningExerciseId").change();
      }
    }
  });

});
</script>
<input type='hidden' name='elearningExerciseId' id='elearningExerciseId' value=''>
<tr class=''>
<td style=' font-weight:bold;' width='10%'  align='right' nowrap valign='top'>
Exercise:
</td>
<td style='' width='10%' >
<input type='text' id='elearningExerciseName' value='' size='40' />
</td>
</tr>
<tr class=''>
<td style='' width='10%'  colspan=2>
&nbsp;
</td>
</tr>
<script type='text/javascript'>
$(document).ready(function() {

  $("#participantName").keyup(function() {
    if (!this.value) {
      $("#elearningSubscriptionId").attr("value", '-1');
      $("#elearningSubscriptionId").change();
      $("#participantName").attr("value", '');
      $("#participantName").change();
    }
  });

  $("#participantName").autocomplete({
    source: "http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/modules/elearning/subscription/suggest.php",
    minLength: 2,
    html: true,
    select: function(event, ui) {
      if (ui.item) {
        $("#elearningSubscriptionId").attr("value", ui.item.id);
        $("#elearningSubscriptionId").change();
      }
    }
  });

});
</script>
<input type='hidden' name='elearningSubscriptionId' id='elearningSubscriptionId' value=''>
<tr class=''>
<td style=' font-weight:bold;' width='10%'  align='right' nowrap valign='top'>
Participant:
</td>
<td style='' width='10%' >
<input type='text' id='participantName' name='participantName' value='' />
</td>
</tr>
<tr class=''>
<td style='' width='10%'  colspan=2>
&nbsp;
</td>
</tr>
<script type='text/javascript'>
$(document).ready(function() {

  $("#className").keyup(function() {
    if (!this.value) {
      $("#elearningClassId").attr("value", '-1');
      $("#elearningClassId").change();
      $("#className").attr("value", '');
      $("#className").change();
    }
  });

  $("#className").autocomplete({
    source: "http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/modules/elearning/class/suggest.php",
    minLength: 2,
    html: true,
    select: function(event, ui) {
      if (ui.item) {
        $("#elearningClassId").attr("value", ui.item.id);
        $("#elearningClassId").change();
      }
    }
  });

});
</script>
<input type='hidden' name='elearningClassId' id='elearningClassId' value=''>
<tr class=''>
<td style=' font-weight:bold;' width='10%'  align='right' nowrap valign='top'>
Class:
</td>
<td style='' width='10%' >
<input type='text' id='className' value='' />
</td>
</tr>
<tr class=''>
<td style='' width='10%'  colspan=2>
&nbsp;
</td>
</tr>
<tr class=''>
<td style=' font-weight:bold;' width='10%'  align='right' nowrap valign='top'>
To the participants:
</td>
<td style='' width='10%' >
<p id='checkboxes' />
</td>
</tr>
<tr class=''>
<td style='' width='10%'  colspan=2>
&nbsp;
</td>
</tr>
<tr class=''>
<td style=' font-weight:bold;' width='10%'  align='right' nowrap valign='top'>
<span class='tooltip' title='<span class="system_tooltip">By default, a participant can do an assignment several times over.<br /><br />But it is possible to only allow him to do the assignment once.<br /><br />In that case, the participant will not be able to do the assignment a second time.</span>' style='margin-right:4px;'>Only once <img src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/system/panel/image/common/question.png' style='border-width:0px; vertical-align:middle; margin-bottom:2px;' alt='' /></span>
</td>
<td style='' width='10%' >
<input type='checkbox' name='onlyOnce' value='1'>
</td>
</tr>
<tr class=''>
<td style='' width='10%'  colspan=2>
&nbsp;
</td>
</tr>
<tr class=''>
<td style=' font-weight:bold;' width='10%'  align='right' nowrap valign='top'>
<span class='tooltip' title='<span class="system_tooltip">If an opening date is specified then the assignment will not be available before the opening date.</span>' style='margin-right:4px;'>Opening date: <img src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/system/panel/image/common/question.png' style='border-width:0px; vertical-align:middle; margin-bottom:2px;' alt='' /></span>
</td>
<td style='' width='10%' >
<input type='text' name='openingDate' id='openingDate' value='' size='12' maxlength='10'> (JJ-MM-AAAA)
</td>
</tr>
<tr class=''>
<td style='' width='10%'  colspan=2>
&nbsp;
</td>
</tr>
<tr class=''>
<td style=' font-weight:bold;' width='10%'  align='right' nowrap valign='top'>
<span class='tooltip' title='<span class="system_tooltip">If a closing date is specified then the assignment will not be available after the opening date.</span>' style='margin-right:4px;'>Closing date: <img src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/system/panel/image/common/question.png' style='border-width:0px; vertical-align:middle; margin-bottom:2px;' alt='' /></span>
</td>
<td style='' width='10%' >
<input type='text' name='closingDate' id='closingDate' value='' size='12' maxlength='10'> (JJ-MM-AAAA)
</td>
</tr>
<tr class=''>
<td style='' width='10%'  colspan=2>
&nbsp;
</td>
</tr>
<tr class=''>
<td style='' width='10%' >
&nbsp;
</td>
<td style='' width='10%' >
<input type='image' border='0' name='okButton' id='okButton' src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/system/panel/image/common/green_tick_large.png' title=''>
</td>
</tr>
<input type='hidden' name='formSubmitted' id='formSubmitted' value='1'>
</form>
<script type='text/javascript'>
$(document).ready(function() {

  function getSubscriptions() {
    var elearningSubscriptionId = $('#elearningSubscriptionId').val();
    var elearningClassId = $('#elearningClassId').val();
    var url = 'http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/modules/elearning/subscription/get_list.php?elearningSubscriptionId='+elearningSubscriptionId+'&elearningClassId='+elearningClassId;
    ajaxAsynchronousRequest(url, renderSubscriptions);
  }

  $('#elearningSubscriptionId').change(function() {
    getSubscriptions();
  });

  $('#elearningClassId').change(function() {
    getSubscriptions();
  });

function renderSubscriptions(responseText) {
  var response = eval('(' + responseText + ')');
  var subscriptions = response.subscriptions;
  $('#checkboxes').empty();
  if (subscriptions.length > 0) {
    for (var i in subscriptions) {
      var elearningSubscriptionId = subscriptions[i].elearningSubscriptionId;
      var elearningSubscriptionId = subscriptions[i].elearningSubscriptionId;
      var firstname = subscriptions[i].firstname;
      var lastname = subscriptions[i].lastname;
      var elearningSubscriptionId = subscriptions[i].elearningSubscriptionId;
      if (elearningSubscriptionId > 0) {
//        $('#checkboxes').append(
//          $(document.createElement("div")).html(firstname + ' ' + lastname).append(
//            $(document.createElement("input")).attr('name', 'subscriptionId_' + elearningSubscriptionId).attr('value', 1).attr('type', 'checkbox').attr('checked', true)
//          )
//        )
        $('#checkboxes').append(firstname + " " + lastname + " <input type='checkbox' value='1' checked='checked' name='subscriptionId_" + elearningSubscriptionId+ "'><br/>");
      }
    }
  }
}

});
</script>
<script type='text/javascript'>
$(function() {
  $("#openingDate").datepicker({ dateFormat:'dd-mm-yy' });
  $("#closingDate").datepicker({ dateFormat:'dd-mm-yy' });
});
</script><script type='text/javascript'>
$(function() {
    $.datepicker.setDefaults($.datepicker.regional['en-GB']);
});
</script>
</tbody></table>
</td></tr></tbody></table><div style='width:100%; text-align:center;'><a onclick="window.open(this.href, '_blank'); return(false);" href='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/modules/language/translate.php?toLanguageCode=se&filePath=%2Fhome%2Fstephane%2Fdev%2Fphp%2Flearnintouch%2Fwww%2Flearnintouch.com%2Fengine%2Fmodules%2Felearning%2Fassignment%2Fadd.php' onmouseover="(window.status=''); return(true);">
<span class='language_item'><img src='http://localhost/dev/php/learnintouch/www/learnintouch.com/engine/modules/language/image/flag_se.gif' class='language_item_img' title='Svenska' alt='' /></span></a> <a href='http://8fub189.copyrightfrance.com' onmouseover="(window.status=''); return(true);" target='_blank' title='The name LearnInTouch and the software are registered at Copyright France.'>Copyright</a> 2010 <a href='http://www.thalasoft.com' onmouseover="(window.status=''); return(true);" target='_blank' title='The name LearnInTouch and the software are registered at Copyright France.'>Thalasoft</a> All Rights Reserved.</div> &nbsp;
</body>
</html>

Hi there,

I’ve just been playing around with this and it should work, that is to say, dynamically created inputs should definitely submit with your form.
However, there are a lot of variables involved in your case, so what we need to do is to make a stripped down example and remove as many of the things that might be causing an error as possible.
For example, here is the code I used to ensure that what you are asking actually works and we’re not missing anything simple:

index.html

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Survey</title>
    <script src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
    <style>
    #checkboxes{
      margin-bottom:10px;
    }
    </style>
  </head>
  
  <body>
    <form action="checkbox.php" method="post">
      <p>Please select some numbers:</p>
      <div id="checkboxes">
        <div>
          <label for="1">1</label>
          <input type="checkbox" name="numbers[]" value="1" id="1" />
        </div>
        <div>
          <label for="2">2</label>
          <input type="checkbox" name="numbers[]" value="2" id="2" />
        </div>
        <div>
          <label for="3">3</label>
          <input type="checkbox" name="numbers[]" value="3" id="3" />
        </div>
      </div>
      
      <a id="more" href="">Another checkbox</button></a><br>
      <input type="submit" name="formSubmit" value="Submit" />
    </form>
    
    <script>
     $("#more").click(function(){
       l = $("#checkboxes div input").last();
       v = Number(l.val()) + 1;
       c = '<div>\
<label for="' + v + '">' + v + '</label>\
<input type="checkbox" name="numbers[]" value="' + v + '" id="' + v + '" /></div>';
       $('#checkboxes').append(c);
       return false;
     });
    </script>
  </body>
</html>

checkbox.php

<?php
print_r($_POST['numbers']);
?>

If you can get somewhere close to this, then
a) there’s a very good chance that you will discover the problem yourself along the way
b) I’ll be in a much better position to help you.

In the mean time if there is anybody else listening who has an idea why this isn’t working as expected, please chime in.

Thanks Pullo for the code example. I will try to get to the core of it. Also note that my code works fine if I append to the form and not to the div.

As I wrote above:

If I append the checkbox input fields not onto the checkboxes div element but on the form itself, with a:
$(‘#edit’).append(
instead of the
$(‘#checkboxes’).append(
then the checkbox input field values are posted fine to the PHP controller. The side effect is that I cannot position my checkboxes where I want on the page.

So it looks like an issue with the DOM of my page.

To work around the issue, I added a function that moves the checkboxes from the div element and append then to the form element.

  $("#okButton").click(function() {
    $('#checkboxes').find(".subscriptionId").each(function() {
      $('#edit').append($(this));
    });
    $('#checkboxes').empty();
  });

And it now works, the checkbox values are posted fine.

I admit, I have not really solved the issue and still don’t understand why it didn’t work in the first place.

Hi there,

While I’m glad that you have found a way to get this working, it would still be better to get to the heart of the issue.

These are the current things I see in your code that could be improved:

  • The mark-up is invalid.
    For example, you have a closing </tbody> tag at the end of your page which you never opened.
    Invalid mark-up can easily confuse jQuery when it comes to appending things to things.
  • You have inline CSS and JavaScript. Although not a cardinal sin, this makes your code harder to read and maintain.
  • You are using (nested) tables for layout purposes. This is an accessibility issue and also makes your code harder to read and maintain.
  • You have JavaScript peppered at random intervals throughout your document and you have lots of calls to $(document).ready() (which could be moved into one).

If I was you, I would work at improving all of these things.
It might seem like a lot of effort now, but it will be worth it in the long run.
Coding your forms in the right way will make your site a lot more accessible for your users.
Separating your JavaScript from your mark-up will make your code a lot more maintainable and considerably easier to debug.

If you would like a hand doing any of this, or even just a pointer in the right direction, just let me know.

Hi,

Thanks for all these remarks. I agree with you on all accounts, including the “a lot of effort now” :slight_smile:

I shall try to improve the situation and post here if I can solve the issue.

Kind Regards,