Hello Drupal Code Land,
I have created a custom admin form in a custom module as a class extending ConfigFormBase. I use this form as an admin config form to set pricing options for different variables used with a custom content type (called estimates) where the form settings are used having been passed in from drupalSettings and are used in a js file containing several custom Drupal.behaviors to calculate pricing interactively when creating a new estimate.
This all works 100% beautifully.
The problem (which isn't a huge problem) that I'm facing, is I've started going back through things cleaning up code and in a couple cases I have changed the names of several of the custom admin form fields. This appears to be causing the old named form fields with their set value to remain in drupalSettings in addition to the new form fields (modified fields) and their values.
Upon viewing the config form where I can change the form field values to update the form settings the old form fields aren't there (which they shouldn't be) so why are they still present in drupalSettings? I would have assumed they would be removed from drupalSettings once the form is resaved with any updated values, yet they are not...they remain!
I've cleared all caches in a browser on the site, and I've used drush cashe:rebuild several times which doesn't have any affect.
So I'm fairly certain I'm missing something probably in modules config form, but haven't been able to find any specific documentation regarding removal of "no-longer in existence" form field settings from drupalSettings. I've found how to override but not remove...
Here is the a snippet of the submit form function:
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$this->config('newlooks.pricesettings')
->set('estimate_gutter_install_base_price', $form_state->getValue('estimate_gutter_install_base_price'))
// a lot more of ->set()'s for form fields
->save();
}
Thinking about it now a little more - Do I need some kind of rebuild form within the submit? Or something in the buildForm function to get drupalSettings or Drupal to remove the fields and data no-longer present in buildForm or submit functions?
Here is a snip of the buildForm function as well:
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('newlooks.pricesettings');
// Lots and lots of $form[estimate_something_base_price] = []
// fields to display...
return parent::buildForm($form, $form_state);
}
I'm also trying to avoid dumping it directly from the DB which would be a quick fix (and not overly difficult) but really wouldn't solve this issue in the future as I will probably make more changes to the form over time.
Oh, and I'm currently working with Drupal 9.4.8
Thank You!
Update Edit:
using:
function newlooks_update_9101() {
\Drupal::configFactory()->getEditable('newlooks.settings')->clear('estimate_gutter_cover_size_five');
}
- did not clear the key in question
tried:
function newlooks_update_9102() {
\Drupal::configFactory()->getEditable('newlooks.settings')->delete('estimate_gutter_cover_size_five');
}
- and it deleted all the settings not the keyed one
This for my particular use case is not ideal having to run an update hook each time a configuration/settings form is edited. Seeing that if I add new form elements to the buildForm function and they become available instantly there has to be a better method.
I feel this over time could lead to a huge .module file with endless update hooks (as your not supposed to remove them once added).
Don't get me wrong hook_update_N() will work it just seams drastic.
Is there not some way to rebuild the settings or purge settings in another manor where I could actually use the existing form key:values to check against removing key:value pairs that no-longer exist?
I really feel there should be something that can handle that, another hook perhaps that runs anytime cache is cleared (just shooting in the dark on that) but something!
I definitely thank you Jaypan, I will need to use hook_update_N() else where at some point - it's just if I can avoid it in this use case it would be ideal.
Update Edit: I'll try to add a little clarity!
So in my buildForm function for example I started with this:
$form['estimate_gutter_cover_size_five'] = [
'#type' => 'number',
'#group' => 'cover_sizes',
'#step' => '.01',
'#prefix' => '<div class="gutters gtcovers gtcovers-size estimate-form-item">',
'#title' => $this->t('5 inch Covers'),
'#description' => $this->t('This is the base price for a standard gutter cover size <em>and is multiplied by quantity in feet for a total cost.</em>'),
'#min' => '0.00',
'#max' => '999.99',
'#placeholder' => '0.00',
'#default_value' => $config->get('estimate_gutter_cover_size_five_base_price'),
'#suffix' => '</div>',
'#required' => TRUE,
];
But later I went back and changed that to:
$form['estimate_gutter_cover_size_five_base_price'] = [
'#type' => 'number',
'#group' => 'cover_sizes',
'#step' => '.01',
'#prefix' => '<div class="gutters gtcovers gtcovers-size estimate-form-item">',
'#title' => $this->t('5 inch Covers'),
'#description' => $this->t('This is the base price for a standard gutter cover size <em>and is multiplied by quantity in feet for a total cost.</em>'),
'#min' => '0.00',
'#max' => '999.99',
'#placeholder' => '0.00',
'#default_value' => $config->get('estimate_gutter_cover_size_five_base_price'),
'#suffix' => '</div>',
'#required' => TRUE,
];
I open the form in a web browser and replace the placeholder with a value as it is now seen as a new element. Does exactly what I want aside from leaving garbage in the settings that aren't readily visible. Only reason I noticed it was I wanted to check variables on page load so in my js file I added:
console.log(window);
While inspecting them via browser console I saw drupalSettings and figured what the heck I'll take a peak.
Upon viewing I saw both:
- estimate_gutter_cover_size_five: "2.37"
- estimate_gutter_cover_size_five_base_price: "2.37"
Having changed estimate_gutter_cover_size_five to estimate_gutter_cover_size_five_base_price I would have expected that estimate_gutter_cover_size_five would have been removed but was not. Considering I had to open the form for settings in a browser and set/add the new/changed elements value (where the old element and value is no longer displayed, in my mind it was "should be" gone).
Now that is just one element/field on a form with probably about 70 now and it will be growing and changing as I build everything moving forward.
That in combination with the fact I do a lot of quick testing sometimes/many times not properly naming things in reference to everything else it is or needs to be associated with, using hook_update_N() isn't going to be very helpful.
->clear()
will delete the key. So the question is why it didn't work for you. Did you run the database update script? Was your implementation of hook_update_n() executed? What was the output of the update script? And how did you determine that this did not work - after running the update script, what did you do to check this value?drush cdel
on all environments that the key needs to be deleted from, if you have access to them all. But the stable way to do it is to use hook_update_N().drupalSettings
refers to a JavaScript object, which has nothing to do with your code. I believe you are referring to 'active configuration'.drush config:edit newlooks.settings
I can delete directly or output that to a file in tmp dir and use it to do diff compare to get a list of what needs to be removed and maybe throw a little script on it to then take that list and usedrush config:delete key_name
which is drush cdel. That was most helpful, thank you..