Adding a required select field to a blueprint results in an error when saving an existing page

If I add a toggle to an existing blueprint with required: true and default: true. When I visit an existing page, that toggle will be active but the value “true” will only be added to the .txt file once the page is saved. No issues here :+1:

:point_right: Now to the select field:
If I add the following to a blueprint, once visiting an existing page, the select field will be marked as red. I wont be able to save the page until I’ve made a selection.
Worse, as you can see the field have a “when” condition. You can then get an error when saving a page but you don’t know where the field is because it might be hidden.

overlay:
  default: color
  label: Overlay
  options:
    color: Color
    gradient: Gradient
  required: true
  type: select
  when:
    type: media

It would be nice if the select field would have the default value selected on load (similar to how the toggle works) and then the value is added to the .txt file once the page is saved.

The required option doesn’t work with conditional fields at the moment. Defaults only work at page creation and the value is only validated when the page is saved and only when it is made public, not as long as the page is a draft.

Would it be possible to check if a required structure field doesn’t exist or is empty? And in that case assign the default value?

Edit: forget about this :slight_smile:

I’m actually curious about this. Would it be possible to write a hook or something that would change empty select fields and change their selection to the default value? Then when the page is saved those values would be added to the .txt file.

Or, when a page is saved, add the default value to empty select fields.

Yes, you can fill empty fields via a hook.

Cool! Will try and make a hook :smiley:

I also found the property empty: false that actually gets rid of the empty state of the select field. Why is this not in the documentation? Is it safe to use?

Does it? Could you post your example field definition?

columns:
  default: one
  empty: false
  label: Columns
  options:
    one: 1
    two: 2
  type: select
  when:
    type: master

It seems to work like a required field but you won’t get any errors. So this is really cool!

Doesn’t do anything for me. Are we still in a structure field context here? I only tested with a simple field.

Which Kirby version?

Ah yes sorry, this is within a structured field!

Hm, ok, but in a structure field context it doesn’t make any difference if I add the empty option or not, an option is always preselected when a default is given, whereas the –– is show if no default is given. In that way it behaves like when you create a new page (i.e. the default is preselected once you add a new item).

And I can’t find an empty option anywhere for fields in the source code. Where did you get that from?

The only way to get rid of the –– is to have required: true and a default value. Just having a default value won’t get rid of the ––.

(i.e. the default is preselected once you add a new item).

In my scenario there are existing items and when adding new functionalities to the structured field, those existing items run into issues.

If the editor opens an item, new required select fields are marked in red, others are marked in red but hidden because they’re conditional. And actually, those fields are only required to get rid of the ––.

If I replace required: true with empty: false then those new fields are no longer marked in red for existing items, and if you make a selection there is no ––. And if the editor doesn’t make a selection, it’s fine because in my template I make empty select fields fallback to the default value. For example a select field with options: one or two columns, one column would just be:

if ($block->columns()->value() !== 'two')

It’s a very specific scenario.

Using empty: false improves the experience for those existing items as there are no more errors. But I will look into adding a hook to add the default value to empty select fields.

And I can’t find an empty option anywhere for fields in the source code. Where did you get that from?

I tried and was surprised :sweat_smile: but now I’m confused if I should use it or not ^^

Yes, existing items don’t get the default, that’s right. I’ve seen your idea issue.

For structured fields not sure how to update the value because it’s one level down, .txt file:

Blocks:

- 
  columns: ""

Currently just doing some dirty testing but I guess I need to do foreach to go through all items.

'page.update:after' => function($page) {
  if ($page->blocks()->toStructure()->first()->columns()->isEmpty()) {
    $page->update([
      'columns' => 'one' // <- how do I do here to target the field name that is one level down?
    ]);
  }
}

Also, do you need to go through all individual fields one by one or can you check for empty select fields and if empty, fill with their default value? Not sure this is possible!

Edit: I will skip this, I’m overcomplicating things… again! Will use empty: false for now.