Support Forum
Support › Meta Box Group › How to create a unique identifier for each group when using clonable/sortableResolved
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.
Hi there,
I think there is a way to help you achieve this goal.
foreach
if it's cloneable)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.
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
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;
}
Hi Long
Brilliant, thanks for explaining that - I should have realised that everything is at the gropup level for a group of fields!
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
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.
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.