Field preview not working

I followed the guide to create a field preview in a structure.

Following code does however not show a preview. What am I doing wrong?

site/plugins/demo/index.js

panel.plugin('demo/field', {
    fields: {
        myfield: {
            template: '<p>Demo field</p>'
        }
    },
    components: {
        'k-myfield-field-preview': {
            props: {
                value: String,
                column: Object,
                field: Object
            },
            template: '<p>Demo field preview</p>'
        }
    }
});

blueprint

fields:
  test:
    type: myfield
  codes:
    type: structure
    translate: false
    sortable: false
    fields:
      myfield:
        type: myfield

Hm, just tested your example and works for me.

What’s your Kirby version?

Kirby: 9.2.4
PHP 8.2.0

sorry, . it’s Kirby 3.9.4, of course :roll_eyes:

will I have to register the props in PHP, as well?

I only have this:

index.php

<?php

use Kirby\Cms\App;

Kirby::plugin('demo/field', [
    'fields' => [
        'myfield' => []
    ]
]);

Should be suffcient for the test, since you are not using any props in your field; but if you add props to the demo field, they need to be registered in the php file, yes.

then I’m puzzled.
Are you using different versions? I updated Kirby to the main branch but without success.
Will try PHP 8.1 later. I will have to upload it to another server for that.

Haha, me too. Hm, can’t remember what I did, but turns out that the preview is empty when the field to preview has no value.

OK, cool. Sorry, it’s not clear to me how to provide a (fake) value.
Would you mind pasting you working example?

Thanks :slight_smile:

What I really want is to add a button so the user can download a generated QR-code.

When I tested this, I added a value in the content file. You can automate this by setting a default value. I don’t know if there is a way to fake a value.

I have the same issue. The field has a value and props are used, but the field works without registering them in index.php and the guide doesn’t mention that part: My first Panel field | Kirby CMS

Summary: I save the milliseconds since epoch, convert them to ISO and display only the time part (00:00:00). The field has a computed value for that, now I need a corresponding structure preview.

Any feedback on how to improve the plugin (besides structure preview) is very welcome. :slight_smile:

index.php

<?php

Kirby::plugin('ca/timer', [
    'fields' => [
        'timer' => [],
    ],
]);

index.js

panel.plugin('ca/timer', {
    fields: {
        timer: {
            template: `
                <div class="k-ca-timer-field">
                    <k-field :label="label">
                        <k-input theme="field" type="text" name="textfield" :value="timeValue" @input="onInput">
                    </k-field>
                    <div class="ca-timer" @click="trackTime">
                        <k-icon type="clock">
                    </div>
                </div>
            `,
            computed: {
                timeValue() {
                    // Convert milliseconds since epoch to ISO and display the 00:00:00 part only.
                    return new Date(Math.floor(this.value / 1000) * 1000).toISOString().slice(11, 19);
                },
            },
            props: {
                label: String,
                value: {
                    type: Number,
                    default: 0,
                },
            },
            data() {
                return {
                    interval: 0,
                };
            },
            methods: {
                onInput(value) {
                    this.$emit('input', value);
                },
                trackTime() {
                    if (this.interval === 0) {
                        const start = this.value === 0 ? Date.now() : Date.now() - this.value;

                        this.interval = setInterval(() => {
                            this.value = Date.now() - start;
                            this.$emit('input', this.value);
                        }, 1000);
                    } else {
                        clearInterval(this.interval);
                        this.interval = 0;
                    }
                },
            },
            components: {
                'k-timer-field-preview': {
                    props: {
                        value: String,
                        column: Object,
                        field: Object
                    },
                    template: '<p>test</p>',
                }
            },
        },
    },
});

Edit: Replaced JS-code with final logic.

I ended up doing, what @texnixe suggested and provided some value in a hook.
Here is the snippet from my plugins index.php:

[...]

'hooks' => [
    'site.update:after' => function (Site $newSite, Site $oldSite) {
        $codes = $newSite->codes()->yaml();

        foreach ($codes as &$code) {
            // save a value, otherwise the field preview is not shown in the panel
            $code["qr"] = true;
        }

        $newSite->update([
            'Codes' => Data::encode($codes, "yaml")
        ]);
    }
]

[...]

Not very elegant but I ran out of time so I accepted it for now :wink:

Thank you for the heads up.

Unfortunately, my field already has a value and the preview should work with a default value too. Maybe I am missing something in my code above?

Bildschirm­foto 2023-06-13 um 12.22.36
Bildschirm­foto 2023-06-13 um 12.22.31

Yes, I missed something. The components key was inside fields.timer. :man_facepalming: