• I have a custom cmb2 field called as pb_info, which is consist of 4 different field abbreviation (select), course code(text), pe point( number), pe hour (number). and i want to use it inside a repeatable group as a group field. my code is work fine until i am inserting 2 rows of data, but it miss after 2nd row that means from 3rd row it missing data. and when i inspect it i saw from 3rd row the id of input field is not changing.

    Here is my code :

    registering field behaviour :

     function cmb2_render_pb_info_field_callback( $field, $value, $object_id, $object_type, $field_type ) {
        $value = wp_parse_args( $value, array(
        'pb_abbreviation' => '',
        'pb_crs_cd' => '',
        'pe_pnt'  => '',
        'pe_hr'     => '',
        ) );
    
    ?>
    <div class="alignleft"><p><label for="<?php echo $field_type->_id( '_pb_abbreviation' ); ?>'">PB Abbreviation</label></p>
        <?php 
            echo $field_type->select( array(
            'name'    => $field_type->_name( '[pb_abbreviation]' ),
            'id'      => $field_type->_id( '_pb_abbreviation' ),
            'options' => cmb2_get_abbr_options( $value['pb_abbreviation'] ),
            'desc'    => '',
    
            ) ); 
        ?>
    </div>
    <div class="alignleft use_maxlength_validator"><p><label for="<?php echo $field_type->_id( '_pb_crs_cd' ); ?>'">PB Course Code</label></p>
        <?php echo $field_type->input( array(
            'class' => 'cmb_text_small',
            'name'  => $field_type->_name( '[pb_crs_cd]' ),
            'id'    => $field_type->_id( '_pb_crs_cd' ),
            'value' => $value['pb_crs_cd'],
            'maxlength' => 20,
            'desc'  => '',
        ) ); ?>
    </div>
    <div class="alignleft pb_credit"><p><label for="<?php echo $field_type->_id( '_pe_pnt' ); ?>'">PE Point</label></p>
        <?php echo $field_type->input( array(
            'class' => 'cmb_text_small',
            'name'  => $field_type->_name( '[pe_pnt]' ),
            'id'    => $field_type->_id( '_pe_pnt' ),
            'value' => $value['pe_pnt'],
            'desc'  => '',
        ) ); ?>
    </div>
    <div class="alignleft pb_hour"><p><label for="<?php echo $field_type->_id( '_pe_hr' ); ?>'">PE Hour</label></p>
        <?php echo $field_type->input( array(
            'class' => 'cmb_text_small',
            'name'  => $field_type->_name( '[pe_hr]' ),
            'id'    => $field_type->_id( '_pe_hr' ),
            'value' => $value['pe_hr'],
            'desc'  => '',
        ) ); ?>
    </div>
    <br class="clear">
    <?php
        echo $field_type->_desc( true );
    
    }
    add_filter( 'cmb2_render_pb_info', 'cmb2_render_pb_info_field_callback', 10, 5 );
    add_filter( 'cmb2_sanitize_pb_info', 'maybe_save_split_pb_values', 12, 4 );
    /**
        * The following snippets are required for allowing the pb_info field
        * to work as a repeatable field, or in a repeatable group
    */
    add_filter( 'cmb2_sanitize_pb_info','pb_sanitize', 10, 5 );
    add_filter( 'cmb2_types_esc_pb_info', 'pb_escape', 10, 4 );
    
    /**
        * Optionally save the Pb Info values into separate fields
    */
    
    function pb_sanitize( $check, $meta_value, $object_id, $field_args, $sanitize_object ) {
        if ( ! is_array( $meta_value ) || ! $field_args['repeatable'] ) { return $check;  }
        foreach ( $meta_value as $key => $val ) {
            $meta_value[ $key ] = array_filter( array_map( 'sanitize_text_field', $val ) );
        }
        return array_filter($meta_value);
    }
    
    function maybe_save_split_pb_values( $override_value, $value, $object_id, $field_args ) {
    
        foreach ($override_value as $key => $data) {
            if($data['pb_crs_cd'] == '' && $data['pe_hr'] == '' && $data['pe_pnt'] == '' ){
                unset($override_value[$key]);
            }
        }
        if ( ! isset( $field_args['split_values'] ) || ! $field_args['split_values'] ) {
            // Don't do the override
            return $override_value;
        }
        foreach ($value as $key => $data) {
            if($data['pb_crs_cd'] == '' && $data['pe_hr'] == '' && $data['pe_pnt'] == '' ){
                unset($value[$key]);
            }
        }
        $pb_info_keys = array( 'pb_abbreviation', 'pb_crs_cd', 'pe_pnt', 'pe_hr' );
        foreach ( $pb_info_keys as $key ) {
            if ( ! empty( $value[ $key ] ) ) {
                update_post_meta( $object_id, $field_args['id'] . 'addr_'. $key, sanitize_text_field( $value[ $key ] ) );
            }
        }
        remove_filter( 'cmb2_sanitize__pb_info', 'pb_sanitize', 10, 5 );
        return true;
    }
    
    function pb_escape( $check, $meta_value, $field_args, $field_object ) {
        if ( ! is_array( $meta_value ) || ! $field_args['repeatable'] ) { return $check;  }
        foreach ( $meta_value as $key => $val ) { $meta_value[ $key ] = array_filter( array_map( 'esc_attr', $val ) );  }
        return array_filter($meta_value);
    }
    
    function cmb2_get_abbr_options( $value = false ) {
        $terms = get_terms( 'professional-body', array( 'hide_empty' => false, ) );
        $pb_abbreviation = '';
        $meta_key = "abbreviation";
        foreach ( $terms  as $term ) {
            $pb_abbreviation .= '<option value="'.  $term->term_id .'" '. selected( $value, $term->term_id, false ) .'>'. get_pb_meta( $term->term_id, $meta_key) .'</option>';
        }
        return $pb_abbreviation;
    }
    
    And the field initialization is:
    

    $lu = new_cmb2_box( array(
    ‘id’ => $prefix.’mcptr{#}’,
    ‘title’ => _(‘Round Informations’),
    ‘object_types’ => array(‘mcpt’),
    ‘context’ => ‘normal’,
    ‘priority’ => ‘high’,
    ‘show_names’ => true,
    ));
    $group_field_id = $lu->add_field( array(
    ‘id’ => $prefix.’mcptre’,
    ‘class’ => $prefix.’mcptgrp’,
    ‘type’ => ‘group’,
    ‘repeatable’ => true,
    ‘options’ => array(
    ‘group_title’ => __( ‘Rounds {#}’, ‘cmb2’ ),
    ‘closed’ => false,
    ‘add_button’ => __( ‘Another Round’, ‘cmb2’ ),
    ‘remove_button’ => __( ‘Remove Round’, ‘cmb2’ ),
    ‘sortable’ => true,
    ),
    ) );

    $lu->add_group_field( $group_field_id, array(
    ‘name’ => ‘PB Info’,
    ‘id’ => $prefix.’pb_info_field’,
    ‘type’ => ‘pb_info’,
    ‘repeatable’ => true,
    ‘classes’ => ‘pb_lu_info’
    ) );
    `
    So how can i fix the problem, i have never mention to do something special at row number 2 or 3, but somehow it take 2 rows of value and after 3rd row it stops changing id.

Viewing 10 replies - 1 through 10 (of 10 total)
  • Plugin Contributor Michael Beckwith

    (@tw2113)

    The BenchPresser

    Is the issue showing up when editing the post in the admin? or is it more around the display on the frontend?

    Thread Starter Mustafa Kamal hossain

    (@nisan92)

    In both cases, actually that data is not found when i am trying to sanitizing data using cmb2_sanitize_pb_info hook, so that data never inserted into database.

    Thread Starter Mustafa Kamal hossain

    (@nisan92)

    Actually in both cases, actually data already missing when i sanitizing it using cmb2_sanitize_pb_info hook , so that data never been inserted into database.

    Plugin Contributor Michael Beckwith

    (@tw2113)

    The BenchPresser

    What’s the purpose of the custom field rendering? the ability to provide taxonomy term information as select options? Just checking because if so, it is possible to do that without having to create your own fields.

    Thread Starter Mustafa Kamal hossain

    (@nisan92)

    The purpose is to have 4 different field as a single repeatable field, here i have 1 select, 2 text field (pb_abbreviation, pb_crs_cd, pe_pnt, pe_hr) actually i wanted to add 1 number field also, so that i can have 4 datas repeatable at the same time.

    I am building a LMS plugin where courses available for different professions like doctor, engineer, developer etc. Now in this fields i will define which professions students with specific course code have to have how much credit or how many hours for completing this course. For example first row could be web developer wdev 130 credit and 2nd row could be frontend developer fwdev 100hr and so on.

    Plugin Contributor Michael Beckwith

    (@tw2113)

    The BenchPresser

    Something tells me the issue is in the implemenation and trying to successfully create he markup intended with incrementers for the field as you gain more.

    A question I have is if the data itself saves properly, despite how it ends up rendering. If it’s not saving properly either, then there’s more debugging to work out, but if it’s just rendering after the fact, then that’s not quite as much.

    Thread Starter Mustafa Kamal hossain

    (@nisan92)

    What i found is the data-iterator attribute of empty row not incrementing after 2nd row created so that in cmb.js at ajaxRow function the it number is same as previous one. so that the name and id property of my input fields are overwrite each other. And i cannot save them. and the main thing i am following all the rules of cmb2 of rendering fields, so how come it becomes problem of implementation?

    Plugin Contributor Michael Beckwith

    (@tw2113)

    The BenchPresser

    Well, it *may* be a missed detail on many fronts, both user-side, as well as documentation side. Something may be missing from the custom field creation here that helps get the data-iterator accurate.

    Just out of curiosity, have you looked over the core code for repeater-based fields to see if there’s anything obvious missed on your side?

    Please note, I’m not placing blame on anyone, just trying to help the best I can, as someone who hasn’t done much in this specific area of CMB2.

    Thread Starter Mustafa Kamal hossain

    (@nisan92)

    Might be my mistake in rendering custom field type but this problem is not for only my custom render field what i found https://github.com/CMB2/CMB2/issues/348 is the real issue here.
    Let me describe more clearly,
    The scenario is:
    i have a repeatable group field inside that i have a repeatable text field, Now for the first group it works fine, but after clicking add group button inside second instance of the repeatable group the first input field id is grp_1_field_0 and iterator: 1, second field it becomes id: grp_1_field_1 and iterator: 1, for third field it is id: grp_2_field_1 and iterator = 2 which means this data is for 3rd group which i haven’t create. And this happens because cmb only use 1 data attribute (iterator) for counting all the id and number of both normal fields and groups, and this could be lot more easier if cmb count the number of rows and groups. I think cmb2 doesn’t support repeatable field inside repeatable group, but it never mentioned.

    Another there is nothing such blaming, mistake could be happen by any side, and that very usual. And i am here to get a solution, so as an author of cmb2 you can highlight my mistakes so that i can solve it.

    Thanks

    Plugin Contributor Michael Beckwith

    (@tw2113)

    The BenchPresser

    For what it’s worth, I’m not technically the author of CMB2 by any means. It’s a plugin that has been built and evolved by many smarter people over the years. My primarily involvement/role is the front-lines of support. I do what I can to help those who have issues, but sometimes, it is a legitimate bug/issue that I don’t have an answer for. This may be one of those moments, especially if it’s similar to a different open bug.

Viewing 10 replies - 1 through 10 (of 10 total)

The topic ‘Custom repeatable field type missing data when update’ is closed to new replies.