outl1ne/nova-translatable

Field does not save when used from inline form

Opened this issue · 7 comments

miagg commented

In Nova4 Inline HasOne Creation has been introduced that allows to create/update a HasOne/MorphOne relation from the parent resource.

However it seems MorphOne it is not compatible with Nova-Translatable.
I can see the field and the language selectors but when I update the model, the values do not get stored.

bug.mov

There are no errors on laravel.log or browser console.

Also, validation does work but with no visual indicator on the field or error message.

If I edit the relation outside the parent resource, everything works as expected.

Same problem here can't figure out what's wrong

This is not a fix but a turnaround

            MorphOne::make('Seo')
                ->hideWhenUpdating()
                ->hideWhenCreating(),

The fields don't save when created inline, still we'll be able to develop until a solution is found

jaap commented

Tried debugging this issue, but no cigar unfortunately.

I think the problems lies in the Vue component.

When editing the Model from it's own resource (not trough the relation) you can see the request having the language attributes within the field.

CleanShot 2023-03-06 at 08h49

When doing the same update, but now trough the parent model and by using the Morph relationship you can see the attributes are missing from the request.

CleanShot 2023-03-06 at 08h54

Hopefully these steps help a bit in reproducing the issue. I'll give debugging the Vue components a shot. Will update here on any findings.

jaap commented

Did some more debugging and found a difference when the fill() method is called from a regular Model vs a relation

When console logging the formData on line 96

fill(formData) {
try {
if (this.isFlexible && this.isFile)
return alert('Sorry, nova-translatable File and Image fields inside Flexible currently do not work.');
const data = {};
const originalAttribute = this.currentField.translatable.original_attribute;
for (const locale of this.locales) {
const tempFormData = new FormData();
const field = this.fields[locale.key];
if (field.fill) field.fill(tempFormData);
const formDataKeys = Array.from(tempFormData.keys());
for (const rawKey of formDataKeys) {
const [key, value] = this.getKeyAndValue(rawKey, locale, tempFormData);
if ((this.isFlexible && key.endsWith(originalAttribute + `[${locale.key}]`)) || this.isSimpleRepeatable) {
if (this.isKeyAnArray(rawKey)) {
if (!data[locale.key]) data[locale.key] = [];
data[locale.key].push(value);
} else {
data[locale.key] = value;
}
} else {
formData.append(key, value);
}
}
}
if (this.isFlexible || this.isSimpleRepeatable) formData.append(originalAttribute, JSON.stringify(data));
return;
} catch (e) {
console.error(e);
}
},

When called from a regular model:
CleanShot 2023-03-06 at 09h53

When called from trough the Morph relationship:
CleanShot 2023-03-06 at 09h56

It seems to me that that somehow within the fill() method there's a need to apply some sort of logic on determining if the update is coming trough a relation.

Hey @miagg!

Could you share more details so we could reproduce your issue?
Currently tested it on nova 4.22.2 and the new hasOne relation was created with the translation.

miagg commented

Hi @eugenl1nde,
Sorry, I forgot to mention that the relation field is a MorphOne field instead of HasOne.
I tried again with Nova 4.22.2 just to be sure and it does not work. See video for more details.

Also, I tried #94 and it seems to do the job.

miagg commented

Any progress on this?
I noticed that validation does not kick either, so I had to revert to hiding the MorphOne field until it is officially supported by the package.

I merged the solution PR-ed by @jaap and it should work a bit better now.