0

I'm attempting to create a form with duplicatable sections for a listing site. It should work like this:

  1. Start with one listing form -> Fill out the form
  2. Click "add another" and another duplicate set of form fields appears (via jQuery).
  3. Complete the 2nd form, then click "add another".
  4. Fill in the third form. Then click "Submit".
  5. Each field set becomes a draft post, which will later be published upon successful WooCommerce checkout (I'll figure that out later).

I'm duplicating the DOM elements with jQuery similar to this demo by Tristan Denyer.

I'm using this basic proof-of-concept test code to see how I can loop through the DOM elements with either a sequential or non-sequential ID. Note: I'm aware there is no security or validation, just trying to get this loop to work.

This is with a sequential ID:

<form action="" id="testForm" method="POST">


<input type="text" id="testField_1" name="testField_1">
<input type="text" id="testField_2" name="testField_2">
<button type="submit">Submit!</button>


</form>


<?php 

   $testArray = array( $_POST['testField_1'], $_POST['testField_2'] );

    foreach( $testArray as $value ) {

    $post_information = array(
    'post_title' =>  $value,
    'post_status'=>'draft',
    'post_type' => 'apu' );

wp_insert_post( $post_information );


    }

Results: It works, there are two posts created, each with a post title as completed in the form, however, if I have 10 duplicated sections, each with their own set of about 20 meta fields, $testArray will quickly get to be a giant array just to accompany the sequenced ID. I feel like a foreach loop shouldn't need sequenced IDs, so I'll just create an array of one set of inputs, then cycle through each set.

Here's my attempt without sequenced IDs

        <form action="" id="testForm" method="POST">


    <input type="text" id="testField" name="testField">
    <input type="text" id="testField" name="testField">
    <button type="submit">Submit!</button>


    </form>


    <?php 

       $testArray = array( $_POST['testField'] );

        foreach( $testArray as $value ) {

        $post_information = array(
        'post_title' =>  $value,
        'post_status'=>'draft',
        'post_type' => 'apu' );

    wp_insert_post( $post_information );


        }

Results: This only creates one post, and the title of the post is always the 2nd field's data. The first post is not created.

  1. How can I create a post per field set without an array full of every possibility of IDs?
  2. I need to incorporate add_post_meta from the ID returned by wp_insert_post. Is this done in the foreach loop?
  3. Do the meta fields (not added yet) need to be in their own array & for each loop inside the original foreach?

Basically.. what am I doing wrong?

0

In the second scenario you're getting the only second title, because you need to have unique field names for each field, or one will override the other(s) in $_POST.

One way to resolve this is to have a single hidden field called perhaps max_id in which you store the highest id number that you've used on the form - so it starts at 1, and is incremented by jquery every time you load another set of form fields.

Then, your php reads that field, and does a basic for loop, starting at 1 up to the max_id that was submitted and reading the form data from $_POST. It would look something like this:

$max = $_POST['max_id'];

for ($i=1; $i <= $max; $i++) { 
    $field_key = 'testfield_' . $i;
    // process the form data here...
    // you can add suffix to $field_key if you're working with more than just a title field
    // i.e. $some_field = $_POST[$field_key . '_some_field']
    // which would correspond to $_POST['testfield_1_some_field'], $_POST['testfield_2_some_field'], etc
}

Second scenario

As mentioned in the comments, you need to allow for non-sequential form field IDs. In this case I'd use a different approach. Set up a hidden field and use it store the form field ID (just the numbers is fine), and update this appropriately via jQuery when new sets of fields are added/removed. For example, you may end up with something like this when the form is submitted and processed by PHP: <input type="hidden" name="field_ids" value="1,2,3,5,7" />

Then, your PHP needs to take this hidden field's value and loop through the fields appropriately:

$field_ids = explode(',', $_POST['field_ids']);
foreach ($field_ids as $id) { 
    $field_key = 'testfield_' . $i;
    // use the fieldkey to access values in $_POST as need be.
}
  • That's a pretty clever workaround, although maybe counting the elements with jquery instead of incrementing them would be better, because the form does have the ability to delete sections out of order, so I could create 4, delete the second, add another under that, etc... Would that present a challenge? – CA_ Oct 23 '15 at 15:11
  • In that case I think I'd go with a slightly different approach - instead a hidden variable will store a comma-delimited list of input field ids. I'll edit my answer with more information. – Aric Watson Oct 23 '15 at 15:47
  • I can see how the hidden field would work in the above example, but how would that play into a scenario with a form with 15-25 fields each duplicated section? – CA_ Oct 25 '15 at 19:35
  • Just remember that each input field needs to have a unique name - i.e. post_title_1, post_status_1, post_title2, post_status2 - so each time your jQuery code grabs and displays another set of fields, it needs to update the hidden field with the new number being used, as well as update each form field with the same number. – Aric Watson Oct 26 '15 at 12:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.