Open mrleblanc101 opened 5 months ago
Also, my field is show in the edit view and save just fine.
Repeater::make(__('Links'), 'links')
->repeatables([
\App\Nova\Repeater\ProjectLink::make()->confirmRemoval(),
])->asJson(),
But is it normal that my field is not shown in the detail view ?
The ->confirmRemoval()
does not appear to do anything either 🤔
Having the same, seems weird it does not show anything when viewing the resource detail page. It should display an overview of the line items.
@Navi2016 Yeah I opened a PR to the docs, but they don't seem to care: https://github.com/laravel/nova-docs/pull/570.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Not stale
@Navi2016 Yeah I opened a PR to the docs, but they don't seem to care: laravel/nova-docs#570.
I don't think it's a matter of not caring - it's not apparent from that pull request that you're wanting the repeater details to display in the detail view.
Which BTW I would like to see also
@sp4cecat The doc PR was to inform that the component was for display only by they closed it and didn't add any info about this in the doc
Text::make('Item content', 'line_items', function ($value, $resource, $attribute) {
if ($value) {
$value = json_decode($value);
$arr = [];
foreach ($value as $item) {
$arr[] = $item->fields->item_content;
}
return implode("
", $arr);
}
})->asHtml();
Text::make('Item content', 'line_items', function ($value, $resource, $attribute) { if ($value) { $value = json_decode($value); $arr = []; foreach ($value as $item) { $arr[] = $item->fields->item_content; } return implode("", $arr); } })->asHtml();
Thanks for having a crack :)
jsondecode is not needed if you've cast the repeated field in your model file, ie:
protected $casts = [
'line_items' => 'array',
];
And also the individual line item structure is a bit more complex than that -
- type (string)
- fields (array)
\
[key, value]...
Any Update/Roadmap on this?
Ive made a quick Shortcut where one can pass a Repeater to view it on Detail:
Usage:
Panel::make('Panel', [
...RepeaterDetailView::makeBoth(Repeater::make('Label', 'attribute'), $request)
]);
app/Nova/Fields/RepeaterDetailView.php
<?php
namespace App\Nova\Fields;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\Field;
use Laravel\Nova\Fields\Hidden;
use Laravel\Nova\Fields\Repeater;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;
class RepeaterDetailView {
public static function makeBoth(Repeater $repeater, NovaRequest $request): array {
return [
$repeater,
self::make($repeater, $request)
];
}
public static function make(Repeater $repeater, NovaRequest $request): Text {
return Text::make(
$repeater->name, function (Model $model) use ($repeater, $request): string {
$items = $model->{$repeater->attribute};
if (is_null($items)) return '';
$tables = [];
foreach ($items as $item) {
$type = $repeater->repeatables->findByKey($item['type']);
/** @var Collection<Field> $fields */
$fields = $type->fields($request);
$table = [
'headers' => [],
'rows' => [[]]
];
foreach ($fields as $field) {
if ($field instanceof Hidden) continue;
$table['headers'][] = $field->name;
$table['rows'][0][] = $item['fields'][$field->attribute];
}
$tables[] = $table;
}
return implode(
'<br />',
array_map(
fn(array $table) => view('partials.table',
$table
)->render(),
$tables
)
);
})->onlyOnDetail()->asHtml();
}
}
table.partials.php
<table class="table w-full divide-y divide-gray-100 dark:divide-gray-700 mb-6">
<thead>
<tr>
@foreach($headers as $header)
<th>{{$header}}</th>
@endforeach
</tr>
</thead>
<tbody class="divide-y divide-gray-100 dark:divide-gray-700">
@foreach($rows as $row)
<tr class="table-row">
@foreach($row as $cell)
<td class="">
{{ $cell }}
</td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
This wasn't obvious for me, so posting for other who also might struggle with this issue.
Basically in your Nova/Resource file you can have both Repeater and HasMany:
Repeater::make('Line Items')
->repeatables([
\App\Nova\Repeater\LineItem::make()
])
->asHasMany()
->showOnDetail(),
HasMany::make('Line Items'),
However for some unknown reason, each calls a different functions in Model:
Repeater::make('Line Items') calls line_items()
but
HasMany::make('Line Items') calls lineItems()
You can however mitigate that by a few more arguments:
HasMany::make('Line Items', 'line_items', \App\Nova\LineItem::class),
This way you will see Repeater editor while editing and table view of when viewing.
Description:
Is it normal that the repeater trash icon is not uniform with the rest of nova ?