Support Forum
Support › MB Custom Table › Add Image To Advanced Select Option
Hey there! I've got something I have been struggling to figure out, and could use some guidance. The end goal for me, is simply just to be able display an image next to each of my advanced select options. I know it is possible using Select2s templating stuff, but I am struggling to get that to work using an actual select field through MetaBox. The only way I have been able to (sort of) achieve this so far, is with a Custom HTML field. The only problem with this, is that the value selected in this field is not being saved to the database. I wasn't sure if it would be better to try and convert what I have into an advanced select field, or just figure out how to save / display the values from a custom html field instead. Here is custom HTML field I currently have:
[
'name' => 'Alert Type',
'id' => $prefix . 'alert_type',
'type' => 'custom_html',
'std' => '<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/css/select2.css" />
</head>
<body>
<select id="alert_type" style="width: 100%">
<option value="Low" data-img_src="/wp-content/uploads/2022/12/Low.png">Low</option>
<option value="High" data-img_src="/wp-content/uploads/2022/12/High.png">High</option>
<option value="Usage" data-img_src="/wp-content/uploads/2022/12/Usage.png">Usage</option>
<option value="Non-Usage" data-img_src="/wp-content/uploads/2022/12/NonUsage.png">Non-Usage</option>
</select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.js"></script>
<script type="text/javascript">
function custom_template(obj){
var data = $(obj.element).data();
var text = $(obj.element).text();
if(data && data[\'img_src\']){
img_src = data[\'img_src\'];
template = $("<div><img src=\\"" + img_src + "\\" style=\\"vertical-align: middle; width: 25px; margin-right: 20px; \\">" + text + "</div>");
return template;
}
}
var options = {
\'templateSelection\': custom_template,
\'templateResult\': custom_template,
}
$(\'#alert_type\').select2(options);
$(\'.select2-container--default .select2-selection--single\').css({\'height\': \'100%\', \'padding\': \'10px 0px\'});
$(\'.select2-container--default .select2-selection--single .select2-selection__arrow\').css({\'height\': \'100%\'});
</script>
</body>',
'width' => '10px',
'admin_columns' => [
'sort' => true,
'searchable' => true,
'filterable' => true,
],
],
I would greatly appreciate any help I can get. Thanks in advance!
Hello Jeremy,
The field type custom_html does not save the field value so it does not work in your case. I think you can create a custom field type to accomplish the task. Please read more on the documentation
https://docs.metabox.io/creating-new-field-types/
I appreciate the quick response! I hadn't considered making my own field, so thanks for the suggestion! I'll play around with it a little and see what I am able to figure out. Thanks!
Hey Peter, another question for you. So I was able to get everything displaying correctly by using a custom field type like you suggested, but I am still having trouble getting the selected value to save. If you look, you will see that I have "value" properties set for each one of my options, which let me conditionally show / hide other fields in my form, which seem to be work. But after submitting, I noticed that the selected option is not being saved to the database, and when I go back into that model to "edit" that entry, the select menu just displays the first option in the list, instead of the actual choice that I had made. All of my other fields seem to saving correctly, while this custom field type remains blank. I am still very new to PHP, and MetaBox at that, so I would appreciate any help you'd be able to provide. Thanks!
/** Creating A Custom Field Type **/
add_action( 'init', 'prefix_load_alert_type' );
class RWMB_Alert_Type_Field extends RWMB_Field {
public static function html( $meta, $field ) {
return sprintf('
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/css/select2.css" />
<link rel="stylesheet" href="/wp-content/themes/Divi Child Theme/style.css" />
</head>
<body>
<select id="alert_type">
<option value="Low" data-img_src="/wp-content/uploads/2022/12/Low.png">Low</option>
<option value="High" data-img_src="/wp-content/uploads/2022/12/High.png">High</option>
<option value="Usage" data-img_src="/wp-content/uploads/2022/12/Usage.png">Usage</option>
<option value="Non-Usage" data-img_src="/wp-content/uploads/2022/12/NonUsage.png">Non-Usage</option>
</select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.js"></script>
<script type="text/javascript">
function custom_template(obj){
var data = $(obj.element).data();
var text = $(obj.element).text();
if(data && data[\'img_src\']){
img_src = data[\'img_src\'];
template = $("<div><img src=\" "+ img_src +" \"> <p> "+ text +" </p> </div>");
return template;
}
}
var options = {
\'templateSelection\': custom_template,
\'templateResult\': custom_template,
}
$(\'#alert_type\').select2(options);
</script>
</body>
',
$field['Alert Type'],
$field['alert_type'],
$meta
);
}
}
Model Code:
[
'name' => 'Alert Type',
'id' => 'alert_type',
'type' => 'alert_type',
'admin_columns' => [
'sort' => true,
'searchable' => true,
'filterable' => true,
],
],
[
'name' => 'Alert Value (%)',
//'id' => $prefix . 'alert_value_percent',
'id' => $prefix . 'trigger_value',
'type' => 'slider',
'suffix' => __( '%', 'alerts' ),
'js_options' => [
'min' => 0,
'max' => 100,
'step' => 5,
],
'admin_columns' => [
'sort' => true,
'searchable' => true,
'filterable' => true,
],
'visible' => [
'when' => [['alert_type', '=', 'Low'], ['alert_type', '=', 'High']],
'relation' => 'or',
],
],
[
'name' => 'Alert Value (Gallons)',
//'id' => $prefix . 'alert_value_gallons',
'id' => $prefix . 'trigger_value',
'type' => 'slider',
'suffix' => __( ' gal', 'alerts' ),
'js_options' => [
'min' => 0,
'max' => 500,
'step' => 5,
],
'admin_columns' => [
'sort' => true,
'searchable' => true,
'filterable' => true,
],
'visible' => [
'when' => [['alert_type', '=', 'Usage'], ['alert_type', '=', 'Non-Usage']],
'relation' => 'or',
],
],
Quick Update:
Looks like I was able to get this value saving to the database correctly by adding name="alert_type" in my custom field select definition. The only thing I am still having issues with now, is having the correct option display when viewing / editing a record. Even though the correct value is captured to the database on submission, the selection being displayed does not match its actual value, and seems to switch to the first available option once the page refreshes.
Does anyone know if it is possible to display the selected value when viewing / editing an existing record with this? The value is saving to the database correctly, it is just not displaying that way after I create the record, and go back into it. It seems to be just defaulting to the first option in the list, and not the correct value. Any help would be appreciated. Thanks!
Hello,
To display the selected value you can use the attribute selected
for the select option, please read more here https://www.w3schools.com/tags/att_option_selected.asp
and to get the saved field value, please use the variable $meta
, you can see the sample code in the documentation to know how it works https://docs.metabox.io/creating-new-field-types/#adding-a-method-to-output-the-field
I don't believe this is quite what I am looking for, so I'll try to explain my issue a a little better. I think I am running into issues because this is custom field type trying to piggyback off of the way a select field works, and not an actual select field itself. When I am on the "Add New" form for this model, the alert type defaults to the "Low" option, (I'm guessing because it is the first choice in the list). This default option doesn't matter for the "Add New" form, but the "Edit" form needs to display its actual saved value, not just the first option in the list again. While on the "Add New" form, if I were to try and change this field to "High" and click save, the "High" option is correctly saved to the database, but since the view changes to the "Edit" screen upon submission, the field immediately switches back to showing "Low" as the selected option, instead of its actual saved value. I am trying to figure out how to get this "Edit" screen to display the value it has saved in the database for each appropriate record. Hopefully that makes a little more sense? Thanks!
Hello,
Thanks, I understand that you need to display the saved value when editing the post. I already said you need to use the selected
attribute of the <option>
tag to display the saved value first instead of Low
value. You can read more on this topic https://wordpress.stackexchange.com/questions/105471/how-to-mark-an-option-as-selected
For example:
<?php
if( $meta == 'High' ) {
$select = 'selected';
}
?>
<select id="alert_type">
<option value="Low" data-img_src="/wp-content/uploads/2022/12/Low.png">Low</option>
<option value="High" <?php echo $select ?> data-img_src="/wp-content/uploads/2022/12/High.png">High</option>
<option value="Usage" <?php echo $select ?> data-img_src="/wp-content/uploads/2022/12/Usage.png">Usage</option>
<option value="Non-Usage" data-img_src="/wp-content/uploads/2022/12/NonUsage.png">Non-Usage</option>
</select>
Then you can select High
and Usage
value to see how it works.
Please note that, supporting customization code is beyond our scope of support, you can read more here https://support.metabox.io/topic/support-policy/.
If it still does not work, you can request a customization service by submitting here https://metabox.io/contact/
I appreciate the quick reply. I will play around with that a bit, and see if I can get it figured out. Thank you so much for all your help!