Custom field data not being submitted in Admin

In my plugin blueprint I have 3 fields - 2 of them are list type (plans and features) and the 3rd one is completely custom (table). When the form is rendered on the admin page, I can clearly see the input name attributes are correct on my custom field and matches the list fields

data[header][plancompare][plans][0][text]
data[header][plancompare][plans][1][text]
data[header][plancompare][features][0][text]
data[header][plancompare][features][1][text]
data[header][plancompare][table][slug1|slug2][text]
data[header][plancompare][table][slug1|slug3][text]

But when saving, data[header][plancompare][table] branch is never submitted. Or at least in onAdminSave() I get only plans and features, but table doesn’t even exist.

Custom field blueprint:

Custom field HTML:

Again can’t find what’s missing :frowning:

Add the following to your plan-compare.php and see if that works for you. No need to register the callback. See Advanced Blueprint Features | Grav Documentation

public function getFormFieldTypes(): array
{
    return [
        'plancompare' => [
            'input@' => false
        ],
    ];
}

Input:

Markdown page:

---
title: 'Plan Compare'
plancompare:
    features:
        -
            label: Feat1
            active: true
            divider: false
            description: 'This is feat1'
        -
            label: Feat2
            active: true
            divider: false
            description: 'This is feat2'
    plans:
        -
            label: Plan1
            active: true
            description: 'This is Plan1'
        -
            label: Plan2
            active: true
            description: 'This is Plan2'
    table:
        feat1|plan1:
            checkmark: '0'
            text: 'Feat1 x Plan1 cross'
        feat1|plan2:
            checkmark: '-1'
            text: 'Feat1 x Plan2 minus'
        feat2|plan1:
            checkmark: '1'
            text: 'Feat2 x Plan1 checked'
        feat2|plan2:
            checkmark: '1'
            text: 'Feat2 x Plan2 checked'
---

That’s so misleading IMO

above code makes display and spacer types to be virtual, meaning that they won’t exist in real data

My understanding is, if you add this 'input@' => false, data will not be submitted. That’s why I didn’t even try this. But it actually works the opposite way :confused:

Or am I misunderstanging this completely?

In the form plugin, in function getFormFieldTypes(), fields like columns, section, tabs etc. are also marked as 'input@' => false and yet, their children are seen as proper fields…

I interpreted it as “hm, container fields seem to be ignored, but not its containing fields”.
The container field becomes “virtual”, but not its containing fields.

So why not try if that holds also for plancompare?

I guess that makes sense. I didn’t consider my field as a container, but now I see it is. I still think this part of docs could be more clear, but I’m not sure how to properly phrase it

I removed the solution here, because this saves new entries first time only. It doesn’t save the edits. When form is submitted, page.header contains old data :confused:

Ok, try this…

public function getFormFieldTypes(): array
{
    return [
        'plancompare' => [
            'array' => true,
        ],
    ];
}

Uhh… please don’t ask…

This worked. I’m pretty sure I saw somewhere in the docs, that in order to save lists, you need to have

validate:
  type: array

Or something similar (can’t find it any more)… And I tried that, but didn’t work

P.S. TBH, I barely can find anything in the docs since they switched to Algolia :frowning: I just go page by page and just search in page - much more reliable and faster

I tried type: array, because when I replaced type: plancompare in the blueprint with array or list all worked fine, although the layout was off.