-->

Dynamically duplicated forms disappear on CodeIgni

2019-09-06 11:39发布

问题:

I have the following code that needs to be duplicated:

<form method="post">
<div id="field-row-container">
    <div id="field-row-1" class="field-row">
        <div class="field-element">
            <label for="Name[1]">Name</label>
            <input type="text" id="Name[1]" name="Name[]" />
        </div>
        <div class="field-element">
            <label for="Email[1]">Email</label>
            <input type="text" id="Email[1]" name="Email[]" />
        </div>
        <hr/>
    </div>
</div>
<div class="form-element">
    <input type="button" class="confirm add-field-row" value="Add" />
    <input type="button" class="danger delete-field-row" value="Delete" />
    <input type="submit" />
</div>

The duplicated / dynamically added elements will have the same names of Name[] and Email[] but their ID's will be incremented.

The JavaScript is below, based from Josiah Ruddell's form duplication script.

var template = $('#field-row-container #field-row-1').clone();
window.addForm = function () {
        var parent = $(this).closest('.dynamic-rows').attr('id');
    var fieldRowCount = countRows(parent) + 1;
    var newFieldRow = template.clone().find(':input').each(function () {
        var newId = this.id.substring(0, this.id.length - 3) + "[" + fieldRowCount + "]";

        $(this).prev().attr('for', newId); // update label for
        this.id = newId; // update id and name (assume the same)
        $(this).closest('.field-row').addClass('new-row');
    }).end()
        .attr('id', 'field-row-' + fieldRowCount)
        .appendTo('#field-row-container');
}
$('.add-field-row').click(addForm);

Whenever I submit the form to CodeIgniter and if there is a validation error, once the controller reloads the multi-part form, the dynamically added elements disappear as well as the values in the initial fields.

How do I go around this problem? I'm at a loss on how to solve this...

Other notes that might help:

  1. This is a component multi-part form with only one form controller
  2. I have multiple instances of this - Addresses, Education Degrees and such
  3. I use CodeIgniter's form_validation library to check server-side each array of posts

回答1:

When the page with the form on reloads after the controllers redirects back to it after failing validation, it will only reload the original page, with no DOM manipulations applied.

I would perform the POST request which submits the form via ajax, so you can handle the response without leaving the page. Something like this:

$.post('/locationOfController.php', $('#yourForm').serialize(), function(response){
  if(response.valid){
    window.location.href = '/somewhereAfterFormPosted.php';
  } else {
    $('#yourForm').append("<p>"+response.error+"</p>");
  }
}, 'json');

and change the controller to return a JSON object based on whether validation passed or not. To match up with my example above, you would return something like below when an error occurs:

{valid: false, error: 'Please fill out the whole form'}

Try something like that as a basic example. You could do much more, such as returning several errors if multiple fields are invalid.