Skip to content

Commit

Permalink
Merge pull request #4 from mindtwo/fix/field-update
Browse files Browse the repository at this point in the history
Fix/field update
  • Loading branch information
jonasemde authored Jun 20, 2024
2 parents 8b538f3 + ff62a36 commit 6398cee
Show file tree
Hide file tree
Showing 5 changed files with 436 additions and 16 deletions.
2 changes: 1 addition & 1 deletion dist/js/field.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions dist/js/field.js.LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@
*/

/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */

/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
177 changes: 167 additions & 10 deletions resources/js/components/FormField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
<DefaultField
v-for="locale in locales"
:key="locale"
:field="field"
:errors="errors"
:field="currentField"
:show-help-text="showHelpText"
:full-width-content="fullWidthContent"
>

<FormLabel
:label-for="labelFor || field.uniqueKey"
:label-for="getLabelFor(locale)"
class="space-x-1"
:class="{ 'mb-2': shouldShowHelpText }"
>
Expand All @@ -23,24 +22,52 @@
</FormLabel>

<template #field>
<textarea
v-if="inputType === 'textarea'"
v-bind="extraAttributes"
class="block w-full form-control form-input form-control-bordered py-3 h-auto"
:id="getLabelFor(locale)"
:dusk="field.attribute"
:value="value[locale]"
@input="handleChange($event, locale)"
:maxlength="field.enforceMaxlength ? field.maxlength : -1"
:placeholder="placeholder"
/>
<MarkdownEditor
v-else-if="inputType === 'markdown'"
:ref="`mdEditor-${locale}`"
v-show="currentlyIsVisible"
:class="{ 'form-control-bordered-error': hasError }"
:id="getLabelFor(locale)"
:previewer="previewer"
:readonly="currentlyIsReadonly"
@initialize="initialize(locale)"
@change="handleChange($event, locale)"
/>
<input
:id="field.attribute"
type="text"
v-else
:id="getLabelFor(locale)"
:type="inputType"
class="w-full form-control form-input form-control-bordered"
:class="errorClasses"
:placeholder="field.name"
v-model="value[locale]"
/>

<HelpText class="help-text-error" v-if="localeErrors[locale]">
{{ localeErrors[locale][0] }}
</HelpText>
</template>
</DefaultField>
</div>
</template>

<script>
import { FormField, HandlesValidationErrors } from 'laravel-nova'
import isNil from 'lodash/isNil';
import { DependentFormField, HandlesValidationErrors } from 'laravel-nova';
export default {
mixins: [FormField, HandlesValidationErrors],
mixins: [DependentFormField, HandlesValidationErrors],
props: ['resourceName', 'resourceId', 'field'],
Expand All @@ -61,28 +88,158 @@ export default {
fieldName() {
return this.field.name;
},
inputType() {
return this.field.inputType;
},
localeErrors() {
const { errors } = this.errors;
if (!errors || !errors[this.field.attribute]) {
return {};
}
const fieldErrors = errors[this.field.attribute];
return fieldErrors.reduce((acc, error) => {
const obj = JSON.parse(error);
const entries = Object.entries(obj);
for (const [locale, message] of entries) {
if (!acc[locale]) {
acc[locale] = [];
}
acc[locale].push(message);
}
return acc;
}, {});
},
// TODO preview?
// previewer() {
// if (!this.isActionRequest) {
// return this.fetchPreviewContent
// }
// },
},
methods: {
getLabelFor(locale) {
return `${this.field.uniqueKey}-${locale}`;
},
/*
* Set the initial, internal value for the field.
*/
setInitialValue() {
this.value = {};
for (const locale of this.locales) {
this.value[locale] = this.field.value[locale] || '';
this.value[locale] = this.field.value?.[locale] || '';
}
},
getErrors(locale) {
return this.localeErrors[locale] || [];
},
/**
* Fill the given FormData object with the field's internal value.
*/
fill(formData) {
for (const locale of this.locales) {
formData.append(`${this.field.attribute}[${locale}]`, this.value[locale] || '');
this.fillIfVisible(formData, this.field.attribute, JSON.stringify(this.value));
},
/**
* Update the field's internal value
*/
handleChangeMarkdown(value, locale) {
this.value[locale] = value;
if (this.field) {
this.emitFieldValueChange(this.fieldAttribute, this.value)
}
},
/**
* Update the field's internal value
*/
handleChangeTextarea(event, locale) {
this.value[locale] = event.target.value;
if (this.field) {
this.emitFieldValueChange(this.fieldAttribute, this.value)
this.$emit('field-changed')
}
},
/**
* Update the field's internal value
*/
handleChange(event, locale) {
if (this.inputType === 'markdown') {
// event is only the value
this.handleChangeMarkdown(event, locale);
return;
}
if (this.inputType === 'textarea') {
this.handleChangeTextarea(event, locale);
return;
}
},
listenToValueChanges(value) {
if (this.currentlyIsVisible) {
this.$refs.theMarkdownEditor.setValue(value)
}
this.handleChange(value)
},
/**
* Initialize the Markdown Editor
*/
initialize(locale) {
const mdEditor = this.$refs[`mdEditor-${locale}`];
if (!mdEditor?.length) {
return;
}
mdEditor[0].setValue(this.value[locale] ?? this.currentField.value[locale]);
Nova.$on(`${this.fieldAttributeValueEventName}:${locale}`, this.listenToValueChanges);
},
async fetchPreviewContent(value) {
Nova.$progress.start()
const {
data: { preview },
} = await Nova.request().post(
`/nova-api/${this.resourceName}/field/${this.fieldAttribute}/preview`,
{ value },
{
params: {
editing: true,
editMode: isNil(this.resourceId) ? 'create' : 'update',
},
}
)
Nova.$progress.done()
return preview
},
},
beforeUnmount() {
this.locales.forEach(locale => {
Nova.$off(`${this.fieldAttributeValueEventName}:${locale}`, this.listenToValueChanges);
});
},
}
</script>
2 changes: 1 addition & 1 deletion src/LaravelTranslatableServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public function configurePackage(Package $package): void
// @phpstan-ignore-next-line
\Laravel\Nova\Nova::serving(function (\Laravel\Nova\Events\ServingNova $event) {
\Laravel\Nova\Nova::script('translatable-field', __DIR__.'/../dist/js/field.js'); // @phpstan-ignore-line
\Laravel\Nova\Nova::style('translatable-field', __DIR__.'/../dist/css/field.css'); // @phpstan-ignore-line
// \Laravel\Nova\Nova::style('translatable-field', __DIR__.'/../dist/css/field.css');
});
}
}
Expand Down
Loading

0 comments on commit 6398cee

Please sign in to comment.