• I have created a Meta Box in my custom post types and added a code to create repeater (Add/remove dynamic fields) fields. Following is the code:

    function add_project_reward_meta_box( $post ) {
    
        add_meta_box(
    
            'project-reward-meta-box',
            __( 'Rewards' ),
            'project_reward_callback',
            'project',
            'normal',
            'high'
    
        );
    
    }
    
    add_action( 'add_meta_boxes_project', 'add_project_reward_meta_box' );
    
    function project_reward_callback( $post ) {
        wp_nonce_field( 'group_project_reward_nonce', 'project_reward_nonce' );
        $reward_value = get_post_meta( get_the_ID(), '_project_rewards', true );
    
    ?>
    
        <script type="text/javascript">
        jQuery(document).ready(function( $ ){
            $( '#add-row' ).on('click', function() {
                var row = $( '.empty-row.screen-reader-text' ).clone(true);
                row.removeClass( 'empty-row screen-reader-text' );
                row.insertBefore( '#repeatable-fieldset-one tbody>tr:last' );
                return false;
            });
    
            $( '.remove-row' ).on('click', function() {
                $(this).parents('tr').remove();
                return false;
            });
        });
        </script>
    
        <table id="repeatable-fieldset-one" width="100%">
    
        <thead>
            <tr>
                <th>Reward Amount</th>
                <th>Reward Title</th>
                <th>Reward Description</th>                             
            </tr>
        </thead>
    
        <tbody>
    
    <?php
    
        ( $reward_value );
    
        foreach ( $reward_value as $field ) {
    
    ?>
    
        <tr>
            <td><input type="text" class="widefat" name="reward[]" value="<?php if($field['reward'] != '') echo esc_attr( $field['reward'] ); ?>" /></td>
    
            <td><input type="text" class="widefat" name="reward_title[]" value="<?php if ($field['reward_title'] != '') echo esc_attr( $field['reward_title'] ); ?>" /></td>
    
            <td><input type="text" class="widefat" name="reward_description[]" value="<?php if($field['reward_description'] != '') echo esc_attr( $field['reward_description'] ); ?>" /></td>
    
            <td><a class="button remove-row" href="#">Remove</a></td>
        </tr>
    
    <?php } ?>
    
        <!-- empty hidden one for jQuery -->
        <tr class="empty-row screen-reader-text">
            <td><input type="text" class="widefat" name="reward[]" /></td>
    
            <td><input type="text" class="widefat" name="reward_title[]" /></td>
    
            <td><input type="text" class="widefat" name="reward_description[]" /></td>
    
            <td><a class="button remove-row" href="#">Remove</a></td>
        </tr>
    
        </tbody>
    
        </table>
    
        <p><a id="add-row" class="button" href="#">Add another</a></p>
    
    <?php   
    
    }
    
    function save_project_reward( $post_id ) {
    
        // Check if our nonce is set.
        if ( ! isset( $_POST['project_reward_nonce'] ) ) {
            return;
        }
    
        // Verify that the nonce is valid.
        if ( ! wp_verify_nonce( $_POST['project_reward_nonce'], 'group_project_reward_nonce' ) ) {
            return;
        }
    
        // If this is an autosave, our form has not been submitted, so we don't want to do anything.
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
            return;
        }
    
        // Check the user's permissions.
        if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) {
    
            if ( ! current_user_can( 'edit_page', $post_id ) ) {
                return;
            }
    
        }
        else {
    
            if ( ! current_user_can( 'edit_post', $post_id ) ) {
                return;
            }
        }
    
        $reward_data = array();
    
        $rewards = $_POST['reward'];
        $reward_titles = $_POST['reward_title'];
        $reward_descriptions = $_POST['reward_description'];
    
        $count = count( $rewards );
    
        for ( $i = 0; $i < $count; $i++ ) {
    
                $reward_data[$i]['reward'] = stripslashes( strip_tags( $rewards[$i] ) );
                $reward_data[$i]['reward_title'] = stripslashes( strip_tags( $reward_titles[$i] ) );
                $reward_data[$i]['reward_description'] = stripslashes( strip_tags( $reward_descriptions[$i] ) );
    
        }
    
                update_post_meta( $post_id, '_project_rewards', $reward_data );
    
    }
    
    add_action( 'save_post', 'save_project_reward' );

    Everything is working fine but the only problem I am facing is that once the post is published the repeater field is unnecessarily creating a blank record in the database and also displaying the blank fields of that record on post edit page. Plz help me out to get rid off the blank record.

    Also is the code is perfectly sanitized? If no, Plz suggest me the process.

    Thanks.

Viewing 7 replies - 1 through 7 (of 7 total)
  • The problem is that the empty field you’re cloning is still on the page and is getting posted with empty values.

    There’s a bunch of ways you could approach this (like making the empty row an Underscore.js template), but the way to go about it with the fewest changes to your code would be to hide the empty element with display: none;, rather than screen-reader-text (since elements hidden this way will not get posted), and then show the element after appending.

    So
    <tr class="empty-row screen-reader-text">

    Could become
    <tr class="empty-row" style="display: none;">

    And then

    var row = $( '.empty-row.screen-reader-text' ).clone(true);
    row.removeClass( 'empty-row screen-reader-text' );
    row.insertBefore( '#repeatable-fieldset-one tbody>tr:last' );
    

    Would become

    var row = $('.empty-row').clone(true);
    row.removeClass( 'empty-row' ).show();
    row.insertBefore( '#repeatable-fieldset-one tbody>tr:last' );
    
    Thread Starter Mineshrai

    (@mineshrai)

    Hi @jakept

    Thanks for answering but the problem still exist. No change

    @Minashrai

    Ah, sorry, looks like my info on display: none; was out of date. Next easiest thing to do is probably using the disabled attribute on the empty inputs.

    <td><input type="text" class="widefat" name="reward[]" disabled/></td>
    
    <td><input type="text" class="widefat" name="reward_title[]" disabled/></td>
    
    <td><input type="text" class="widefat" name="reward_description[]" disabled/></td>
    

    Then modify the script slightly to remove the disabled attribute.

    row.removeClass( 'empty-row' ).show().find('[disabled]').prop('disabled', false);
    
    Thread Starter Mineshrai

    (@mineshrai)

    @jakept

    It disables the field. No luck

    Did you also update the script to remove the disabled property when it’s appended?

    I’ve tested your code with those changes and it’s working fine.

    Thread Starter Mineshrai

    (@mineshrai)

    yes

    Thread Starter Mineshrai

    (@mineshrai)

    @jakept

    Thanks dear. Its now working.

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘How to get rid off blank record generated through Repeater Fields’ is closed to new replies.