0

I have a custom metabox running that dynamically adds fields to the form
I'm stuck on the saving part.

This is how the fields are added:

<tr>
   <td valign="top">
     <label for="brands" class="prfx-row-title"><?php _e( 'Merken:', 'prfx-textdomain' )?></label>
   </td>
   <td>
        <script type="text/javascript">
            jQuery(document).ready(function($){
            var max_fields      = 10; //maximum input boxes allowed
            var wrapper         = $(".input_fields_brand"); //Fields wrapper
            var add_button      = $(".add_field_button_brand"); //Add button ID

            var x = 1; //initlal text box count
            $(add_button).click(function(e){ //on add input button click
                e.preventDefault();
                if(x < max_fields){ //max input box allowed
                x++; //text box increment
                $(wrapper).append('<div><input type="text" name="brand[]" id="brand[]"/><a href="#" class="remove_field_brand">Verwijderen</a></div>'); //add input box
                }
            });

            $(wrapper).on("click",".remove_field_brand", function(e){ //user click on remove text
                e.preventDefault(); $(this).parent('div').remove(); x--;
                })
            });
           </script>
    <div class="input_fields_brand">
       <button class="add_field_button_brand">Toevoegen</button>
       <div><input type="text" name="brand[]" id="brand[]"></div>
    </div>
  </td>
 </tr>

This works. I want to load all data in an array with brands[]

Now this is what I did in the saving part:

if( isset( $_POST[ 'brand[]' ] ) ) {
    update_post_meta( $post_id, 'brand[]', sanitize_text_field( $_POST[ 'brand[]' ] ) );
}

I use this for all my other fields and they are saved proper to the database. Don't see what I'm missing.

Hope someone else does.

EDIT

Ok so this works. I know have a follow up question :-)

I need to output the data to input fields. Users must be able to change the earlier filled fields. So I did the following:

<?php
$postid = get_the_ID();
$brands = get_post_meta( $postid, 'brand' );                                                        
    $arrlength = count($brands);
    echo '<div class="input_fields_brand">';
    echo '<button class="add_field_button_brand">Toevoegen</button>';
    for($x = 0; $x <= $arrlength; $x++)
    {
        echo '<div><input type="text" name="brand[]" id="brand[]" value="'.$brands[0][$x].'"></div>';
    }
    echo '</div>';
?>

This shows me the data in the database and let's me add new data with the following:

var x = 1; //initlal text box count
$(add_button).click(function(e){ //on add input button click
    e.preventDefault();
    if(x < max_fields){ //max input box allowed
        x++; //text box increment
        $(wrapper).append('<div><input type="text" name="brand[]" id="brand[]"/><a href="#" class="remove_field_brand">Verwijderen</a></div>'); //add input box
    }
});

This adds the field but doesn't save the value.

Any thoughts?

(Still have to work on the id fields)

2

In PHP, there is no need to use the square brackets that are required in an HTML form name to indicate an array, such as you get when using checkboxes.

In other words, this in HTML:

<label><input type="checkbox" name="brand[]" value="1"> Brand 1</label> <label><input type="checkbox" name="brand[]" value="2"> Brand 2</label> <label><input type="checkbox" name="brand[]" value="3"> Brand 3</label>

Will be set as $_POST['brand'] in PHP, the value of which is an array with a count of 3, indexed from 0 to 2, assuming that all three boxes are checked (only checked boxes will be part of the $_POST['brand'] array).

So we can't treat that post variable as a string, either, since it is an array and WordPress needs it to be an array to properly serialize its value when it's inserted into the database.

So, the correct code to set it as a metadata value is:

if( isset( $_POST[ 'brand' ] ) ) {
    update_post_meta( $post_id, 'brand', array_map( 'sanitize_text_field', $_POST[ 'brand' ] ) );
}

WordPress will automatically serialize the array for you, so when you retrieve that metadata key-value pair using get_post_meta, the value of brand will also be an array with a count of 3, indexed from 0 to 2 (again, if all three checkboxes were checked).

All that said, you might want to create a better callback function for array_map than just sanitize_text_field; that is, you may want to ensure that the values in $_POST['brand'] match your expected type and range.

For example, if you need integers and get letters, it doesn't do you any good to save that bad data.

  • Wow thank you so much. Nice explanation too. The data is now saved to the db like it is supposed to. I just realised that I need to add a value field to the input fields so I can get them back from the database. With a counting $i++ i guess. Once again Thank you. – Interactive Mar 17 '15 at 14:46
  • I needed to clarify that ONLY checked boxes will be part of $_POST['brand']. Answer edited to same effect. – user12479 Mar 17 '15 at 14:48
  • @Interactive Also, looking at your jQuery / HTML, you are using brand[] as an ID for all fields. HTML element IDs need to be unique. – user12479 Mar 17 '15 at 14:55
  • Thank you I need to update them as well but first the value field. Still not sure how to do this. – Interactive Mar 17 '15 at 15:11
  • 1
    Naild it. Thanks for all your help! I added: $arrlength = count($brands, COUNT_RECURSIVE) - count($brands); because the arrays I want are nested in another array – Interactive Mar 17 '15 at 16:40

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.