carbon-fields
carbon-fields copied to clipboard
Question: Is there a JavaScript method to repopulate select options?
I'm trying to work out if this is even possible: Essentially I'm trying to build a select control with dynamically defined options based on another field value.
->set_options(function(){ $foo = // value of my other meta field return [ // options based on $foo ] });
I assume this would need to be a JavaScript thing in order to pick up changes and re-populate the select. I can see the API has methods to detect field changes and getFieldValue/setFieldValue.
Is there a way to repopulate the select options?
Hello, did you happen to ever figure this out? I was trying to do something similar but couldn't quite get it figured out. I was trying to change a text field based on which select option was selected but got lost along the way.
As far as I was able to determine it wasn’t possible… or at least not practical in my case. Where I ended up was a bit hacktastic so the attempt was abandoned.
Thank you for the response!
I finally figured out a way to do it without trying to use React or Carbon Fields stuff since the docs seem to require some updating:
// Points to a function to enqueue the JS file only in the block editor
add_action( 'enqueue_block_editor_assets', 'my_block_editor_scripts' );
jQuery(function ($) {
function update_fields() {
const $textfield1 = $('input[name="myfield_text1"]');
const $textfield2 = $('input[name="myfield_text2"]');
const $select = $('select[name="myfield_select"]');
jQuery.ajax({
url: ajaxurl,
data: {
action: "admin_ajax",
data: $select.val(),
ajax_nonce: ajax_nonce
},
type: "POST",
dataType: "json",
success: function (response) {
if (response.success) {
$textfield2.val(response.data.value);
}
}
});
}
// When the select box is changed, update the fields.
$(document).on('change', 'select[name="myfield_select"]', function () {
update_fields();
});
// When the an input field is changed, wait a second, then update the fields.
let timer = null;
$(document).on('change', 'input[name="myfield_text1"]', function () {
clearTimeout(timer);
timer = setTimeout(function () {
update_fields();
}, 1000)
});
});
And basically using wp_send_json_success with an array of the data for those fields to be updated with from the PHP side:
check_ajax_referer( 'ajax_nonce', 'ajax_nonce' );
if ( isset( $_POST['data'] ) ) {
$value = 'something';
wp_send_json_success( [
'value' => $value,
] );
}
Something like that anyway. You would just have to adjust it a bit to update the select field instead. It doesn't really seem too hacky to me other than it's just using jQuery rather than React which seems perfectly ok to me since I don't think I'm a fan of it anyway.
In my previous code inside the ajax response replace this:
$textfield2.val(response.data.value);
With this:
const field_key = 'field-name';
block.attributes.data[field_key ] = response.data.value;
wp.data.dispatch('core/block-editor').updateBlock(block.clientId, {attributes: block.attributes});
And add this before the ajax request to get the block:
const block = wp.data.select('core/block-editor').getSelectedBlock();
I just wanted to follow up and post another solution that doesn't necessarily use blocks in case anyone was trying to do it that way too. For example when using a theme options page. Something like this will update the value of a field. In my case I submit an AJAX request and store the values directly that way as well since I'm doing some other things with them but I didn't include that in the example.
jQuery(document).ready(function ($) {
const {select, dispatch} = window.cf.vendor['@wordpress/data'];
const metaboxes = select('carbon-fields/metaboxes');
const {updateFieldValue} = dispatch('carbon-fields/metaboxes');
const fields = metaboxes.getFields();
let field = Object.values(fields).find(f => f.base_name === 'your-option-name');
updateFieldValue(field.id, 'your new value');
});