Custom Fields
Re-Envisioned
Support Meta Box Group How to create a unique identifier for each group when using clonable/sortable

  • Creator
    Topic
  • #19228
    Resolved realj42
    Participant

    Hi

    I need a way to add a unique ID to each group of fields so I can find that particular group even if the other values in the group are changed. To explain:
    I need to create a settings page where the admin user can create a list of video-urls and titles to be used in a dropdown on a page meta box so the page creator can just select a pre-approved video to insert into the page. OK so just create settings page, add a cloneable group of fields for video name and video url. In the Page metabox generate a select dropdown by getting the list of video names from settings, saving the video name as a Page meta, then when displaying the page, look up the videoname from the page meta, use that to find the matching video url in the settings, display video.
    OK so far so good. But there is a clear flaw – what if the name of the video is changed by the admin/ The page video name meta is out of date, and it can longer find the video-url. Saving the Videoname and the video URL with the page meta partially solves this but means the admin cannot change the video name, or even update the video url across the site.
    Ok another answer is to use a CPT to store video names and urls. The page meta then just stores the video CPT post id and looks that up on each page display. Works but is not as easy to use or as graceful as a settings page with a list of sortable clonable entries.
    So really what I want is a unique ID to store with each field group. This has to be generated for each new group the admin user creates and then is stored as an extra field with the group fields. This field value id is then used as the ‘value’ option in the select for the page meta, and can always be used to find the correct video name and url. Is this in any way possible?

    Thanks in advance for any replies.

Viewing 7 replies - 1 through 7 (of 7 total)
  • Author
    Replies
  • #19236
    Long Nguyen
    Moderator

    Hi there,

    I think there is a way to help you achieve this goal.

    In this way, the page meta always shows the current video name even the admin change the name on the settings page.

    You can follow this documentation and this topic to create a custom field type.

    #19296
    realj42
    Participant

    Hi Long

    Thanks for your reply. The problem is I am trying to create a pseudo index field I can use in the select vaule on the Page meta. So on the settings page with the list of videos I have added a ‘video id’ field which I need to automatically increment to create a unique Id for each row in the group. For a single, non cloned, field I can use the Rwmb_{field_id}_value filter to set the index value if it is empty or leave alone if it is already set. But for a cloneable group field that filter does not work.

    Here is my testing settings page definition with test code filters to test the ‘value’ filter.

    // Register meta boxes and fields for settings page
    add_filter( 'rwmb_meta_boxes', function ( $meta_boxes ) {
        $prefix = "settings_test_";
        $meta_boxes[] = array(
            'id'             => $prefix .'general',
            'title'          => 'General',
            'settings_pages' => 'settings_test',
            'tab'            => 'general',
            'fields' => array(
                array(
                    'type' => 'custom_html',
                    'std'  => 'General theme settings will be added here',
                ),
                array(
                    'name' => 'Single Id',
                    'id' => $prefix . 'single_id',
                    'type' => 'number',
                    'std' => 0,
                ),
            ),
        );
        $meta_boxes[] = array(
            'id'             => $prefix . 'videos',
            'title'          => 'Highlight Video Options',
            'settings_pages' => 'settings_test',
            'tab'            => 'highlights',
            'fields' => array(
                array(
                    'type' => 'custom_html',
                    'std'  => 'Here is the list of  highlight videos. Add videos here to be included in the highlight video list.',
                ),
    
                array(
                    'id'     => $prefix . 'video_list',
                    // Group field
                    'name' => "Videos",
                    'type'   => 'group',
                    // Clone whole group?
                    'clone'  => true,
                    // Drag and drop clones to reorder them?
                    'sort_clone' => true,
                    'collapsible' => true,
                    'group_title' => array( 'field' => $prefix .'video_name' ), // ID of the subfield
                    'save_state' => true,
                    // Sub-fields
                    'fields' => array(
                        array(
                            'name' => 'Video Name',
                            'id' => $prefix . 'video_name',
                            'description' => 'Name for dropdown list',
                            'type' => 'text'
                        ),
                        array(
                            'name' => 'Video URL',
                            'id' => $prefix . 'video_url',
                            'type' => 'url'
    
                        ),
                        array(
                            'name' => 'Id',
                            'id' => $prefix . 'video_id',
                            'type' => 'number',
                            'std' => 0,
                        )
                    ),
                ),
            ),
        );
        $meta_boxes[] = array(
            'id'             => 'info',
            'title'          => 'Theme Info',
            'settings_pages' => 'settings_test',
            'tab'            => 'faq',
            'fields'         => array(
                array(
                    'type' => 'custom_html',
                    'std'  => 'Having questions? Check out our documentation',
                ),
            ),
        );
        return $meta_boxes;
    } );
    
    add_filter('rwmb_settings_test_video_id_value', 'settings_test_autoinc_value', 10, 3 );
    function settings_test_autoinc_value($new, $field, $old) {
        global  $shsLog;
        $shsLog->trace("Entry - New - $new - old - $old");
        if (empty($new)) {
            $new = 4222;
        }else {
            $new = 21223;
        }
        return $new;
    }
    
    add_filter('rwmb_settings_test_single_id_value', 'settings_test_single_value', 10, 3 );
    function settings_test_single_value($new, $field, $old) {
        global  $shsLog;
        $shsLog->trace("Entry - New - $new - old - $old");
        if (empty($new)) {
            $new = 4222;
        }else {
            $new = 21223;
        }
        return $new;
    }
    

    In testing the filter ‘settings_test_single_value()’ is called as expected. However the filter for the cloned id field filter ‘settings_test_autoinc_value()’ is never called. I have tried creating a custom field type but the ::value() function is never called if the field is cloneable.

    Is there anyway round this?

    Cheers
    Hywel

    #19305
    Long Nguyen
    Moderator

    Hi,

    Because the field group saves as a meta key in the database and serializes the value of all the fields nested in, so you should use the filter rwmb_settings_test_video_list_value to modify the value of the field group and use foreach to loop through the array of the clone. The code would be

    add_filter('rwmb_settings_test_video_list_value', 'settings_test_autoinc_value', 10, 3 );
    function settings_test_autoinc_value($new, $field, $old) {
        // Loop through array of clone
        foreach ($new as $key => $value) {
            // check if the field video is empty
            if (empty($value['settings_test_video_id'])) {
                // set the ID for each field
                $new[$key]['settings_test_video_id'] = 4222;
            }else {
                $new[$key]['settings_test_video_id'] = 21223;
            }
        }
        
        return $new;
    }
    #19341
    realj42
    Participant

    Hi Long

    Brilliant, thanks for explaining that – I should have realised that everything is at the gropup level for a group of fields!

    #19371
    realj42
    Participant

    Hi Long

    Thanks again but just FYI when I am using the code above, when I try to retrieve the value with

    $video_options_list = rwmb_meta(‘settings_test_video_list’, [‘object_type’ => ‘setting’], ‘settings_test’ );

    then nothing is returned. Is that the correct way to get the field? I also cannot get the single field ‘settings_test_single_id’ using rwmb_meta().

    No worries though because ‘get_option()’ works fine –

    $settings_test = get_option('settings_test');
    $single = $settings_test['settings_test_single_id'];
    $video_options_list = $settings_test['settings_test_video_list'];

    All expected vallues/arrays returned fine

    #19378
    Long Nguyen
    Moderator

    Hi,

    Please take a look at my screen record https://www.loom.com/share/7264d770db2f40039f96777ebd73fdbc

    The code
    $video_options_list = rwmb_meta('settings_test_video_list', ['object_type' => 'setting'], 'settings_test' );
    to get the value of the group video_list works as well.

    #19381
    realj42
    Participant

    No worries – turns out I was invoking this code in my plugin startup code, straight after declaring the settings metabox, which is why it wasn’t working. Instead, using rwmb_meta() in a shortcode function it works fine for me.

    I could point out that getting option values during startup is pretty standard so I will allways use get_option() in that situation in future.

Viewing 7 replies - 1 through 7 (of 7 total)
  • You must be logged in to reply to this topic.
grid gear info copy caret-up caret-down trash