Open donmbelembe opened 7 years ago
Hi,
Has anyone figured this one out?
I am programatically creating my bread as follows:
$dataRow = $this->dataRow($userDataType, 'user_hasone_user_details_relationship');
if (!$dataRow->exists) {
$dataRow->fill([
'type' => 'relationship',
'display_name' => 'Details',
'required' => 0,
'browse' => 1,
'read' => 1,
'edit' => 1,
'add' => 1,
'delete' => 0,
'details' => '{"model":"App\\\Models\\\UserDetails","table":"user_details","type":"hasOne","column":"user_id","key":"id","label":"id","pivot_table":"users","pivot":"0"}',
'order' => 10,
])->save();
}
Is it possible to add the anchor tag in this way? I have tried adding "page_slug": "/users"
to my details string but with no results.
I have had a look at the BreadRelationshipParser
trait and it would seem that this is possible?
Any help or advice would be greatly appreciated.
@fletch3555 do you have any advice one this one?
@nickbryan, the link would be handled in the view. Did you check the view (likely bread/browse.blade.php
)? I'm not certain this is possible in the current version (meaning it likely broke at some point)
Hi @fletch3555, thanks for the reply and apologies for the duplicate ticket. I have had a look at the view it seems it should handle it. Seems like the issue might be in https://github.com/the-control-group/voyager/blob/1.0/src/Http/Controllers/Traits/BreadRelationshipParser.php#L104 this method although as I am not 100% familiar with your code base I cant be certain. It would seem that the $relations = $item->getRelations();
call is not bringing back any relationship data. Not sure if I am missing something?
@nickbryan did you ever find a way around this/fix!
Nop, Still looking for a solution
This might be late but I got it working. below are steps I did 1.) create custom fields LinkFormField.php
use TCG\Voyager\FormFields\AbstractHandler;
class LinkFormField extends AbstractHandler {
protected $codename = "link";
public function createContent($row, $dataType, $dataTypeContent, $options)
{
return view('formfields.link', [
"row" => $row,
'options'=> $options,
'dataType' => $dataType,
"dataTypeContent" => $dataTypeContent
]);
}
}
under resources/views
create subfolder vendor/voyager/formfields
create link.blade.php
@if(isset($options->model) && isset($options->type))
@if(class_exists($options->model))
@php $relationshipField = $row->field; @endphp
@if($options->type == 'belongsTo')
@if(isset($view) && ($view == 'browse' || $view == 'read'))
@php
$relationshipData = (isset($data)) ? $data : $dataTypeContent;
$model = app($options->model);
$query = $model::find($relationshipData->{$options->column});
@endphp
@if(isset($query))
<a href="/admin/{{ $options->table }}/{{ $query->{$options->key} }}">{{ $query->{$options->label} }}</a>
@else
<p>{{ __('voyager::generic.no_results') }}</p>
@endif
@endif
@endif
@endif
@endif
2.) Override the view (under resources/views
create subfolder vendor/voyager/{{slug_name}} create browse.blade.php) and copy the code from
vendor/tcg/voyager/resources/views/bread/browse.blade.php`
look for the following code
@elseif($row->type == 'relationship')
@include('voyager::formfields.relationship', ['view' => 'browse','options' => $row->details])
change it to this
@elseif($row->type == 'relationship')
@include('voyager::formfields.link', ['view' => 'browse','options' => $row->details])
This might be late but I got it working. below are steps I did 1.) create custom fields LinkFormField.php
use TCG\Voyager\FormFields\AbstractHandler; class LinkFormField extends AbstractHandler { protected $codename = "link"; public function createContent($row, $dataType, $dataTypeContent, $options) { return view('formfields.link', [ "row" => $row, 'options'=> $options, 'dataType' => $dataType, "dataTypeContent" => $dataTypeContent ]); } }
under
resources/views
create subfoldervendor/voyager/formfields
create link.blade.php@if(isset($options->model) && isset($options->type)) @if(class_exists($options->model)) @php $relationshipField = $row->field; @endphp @if($options->type == 'belongsTo') @if(isset($view) && ($view == 'browse' || $view == 'read')) @php $relationshipData = (isset($data)) ? $data : $dataTypeContent; $model = app($options->model); $query = $model::find($relationshipData->{$options->column}); @endphp @if(isset($query)) <a href="/admin/{{ $options->table }}/{{ $query->{$options->key} }}">{{ $query->{$options->label} }}</a> @else <p>{{ __('voyager::generic.no_results') }}</p> @endif @endif @endif @endif @endif
2.) Override the view (under
resources/views
create subfoldervendor/voyager/{{slug_name}} create browse.blade.php) and copy the code from
vendor/tcg/voyager/resources/views/bread/browse.blade.php` look for the following code@elseif($row->type == 'relationship') @include('voyager::formfields.relationship', ['view' => 'browse','options' => $row->details])
change it to this
@elseif($row->type == 'relationship') @include('voyager::formfields.link', ['view' => 'browse','options' => $row->details])
this file create in which place please aknow
@sandipiweb under App\FormFields
see the doc for custom formfields
I managed to make it work. Here's how I do:
app/FormFields/LinkFormField.php
as stated above by @blitzen12
<?php
namespace App\FormFields;
use TCG\Voyager\FormFields\AbstractHandler;
class LinkFormField extends AbstractHandler { protected $codename = "link";
public function createContent($row, $dataType, $dataTypeContent, $options)
{
return view('formfields.link', [
"row" => $row,
'options'=> $options,
'dataType' => $dataType,
"dataTypeContent" => $dataTypeContent
]);
}
}
2. register this class in `app/Providers/AppServiceProvider.php` (don't forget to update the `use` statements)
```PHP
public function register()
{
Voyager::addFormField(LinkFormField::class);
}
create a new view resources/views/vendor/voyager/formfields/link.blade.php
with the following contents (also from @blitzen12)
create a new empty folder resources/views/vendor/voyager/bread/
copy vendor/tcg/voyager/resources/views/bread/browse.blade.php
and vendor/tcg/voyager/resources/views/bread/read.blade.php
into resources/views/vendor/voyager/bread/
in files under resources/views/vendor/voyager/bread/
, locate ...
@elseif($row->type == 'relationship')
@include('voyager::formfields.relationship', ['view' => 'browse','options' => $row->details])
... and replace by ...
@elseif($row->type == 'relationship')
@include('voyager::formfields.link', ['view' => 'browse','options' => $row->details])
(use 'view' => "read"
in read.blade.php instead of browse
of course).
Now EVERY RELATIONSHIP in browse and read will display link instead of label :+1:
The above solution works only for belongsTo relationships so I needed to find a better option.
resource/views/vendor/voyager/formfields/relationship.blade.php
with the below contentNo every type of relationship (including belongsToMany) will display links.
@if(isset($options->model) && isset($options->type))
@if(class_exists($options->model))
@php $relationshipField = $row->field; @endphp
@if($options->type == 'belongsTo')
@if(isset($view) && ($view == 'browse' || $view == 'read'))
@php
$relationshipData = (isset($data)) ? $data : $dataTypeContent;
$model = app($options->model);
$query = $model::find($relationshipData->{$options->column});
$slug = Voyager::model('DataType')->where('model_name', $options->model)->firstOrFail()->slug;
@endphp
@if(isset($query))
<p><a href="{{ route("voyager.{$slug}.show", $query->{$options->key}) }}">{{ $query->{$options->label} }}</a></p>
@else
<p>{{ __('voyager::generic.no_results') }}</p>
@endif
@else
<select
class="form-control select2-ajax" name="{{ $options->column }}"
data-get-items-route="{{route('voyager.' . $dataType->slug.'.relation')}}"
data-get-items-field="{{$row->field}}"
@if(!is_null($dataTypeContent->getKey())) data-id="{{$dataTypeContent->getKey()}}" @endif
data-method="{{ !is_null($dataTypeContent->getKey()) ? 'edit' : 'add' }}"
>
@php
$model = app($options->model);
$query = $model::where($options->key, old($options->column, $dataTypeContent->{$options->column}))->get();
@endphp
@if(!$row->required)
<option value="">{{__('voyager::generic.none')}}</option>
@endif
@foreach($query as $relationshipData)
<option value="{{ $relationshipData->{$options->key} }}" @if(old($options->column, $dataTypeContent->{$options->column}) == $relationshipData->{$options->key}) selected="selected" @endif>{{ $relationshipData->{$options->label} }}</option>
@endforeach
</select>
@endif
@elseif($options->type == 'hasOne')
@php
$relationshipData = (isset($data)) ? $data : $dataTypeContent;
$model = app($options->model);
$query = $model::where($options->column, '=', $relationshipData->{$options->key})->first();
$slug = Voyager::model('DataType')->where('model_name', $options->model)->firstOrFail()->slug;
@endphp
@if(isset($query))
<p><a href="{{ route("voyager.{$slug}.show", $query->{$options->key}) }}">{{ $query->{$options->label} }}</a></p>
@else
<p>{{ __('voyager::generic.no_results') }}</p>
@endif
@elseif($options->type == 'hasMany')
@if(isset($view) && ($view == 'browse' || $view == 'read'))
@php
$relationshipData = (isset($data)) ? $data : $dataTypeContent;
$model = app($options->model);
$slug = Voyager::model('DataType')->where('model_name', $options->model)->firstOrFail()->slug;
$selected_values = $model::where($options->column, '=', $relationshipData->{$options->key})->get()->map(function ($item, $key) use ($options, $slug) {
return sprintf('<a href="%s">%s</a>', route("voyager.{$slug}.show", $item->{$options->key}), $item->{$options->label});
})->all();
@endphp
@if($view == 'browse')
@php
$string_values = implode(", ", $selected_values);
@endphp
@if(empty($selected_values))
<p>{{ __('voyager::generic.no_results') }}</p>
@else
<p>{!! $string_values !!}</p>
@endif
@else
@if(empty($selected_values))
<p>{{ __('voyager::generic.no_results') }}</p>
@else
<ul>
@foreach($selected_values as $selected_value)
<li>{!! $selected_value !!}</li>
@endforeach
</ul>
@endif
@endif
@else
@php
$model = app($options->model);
$query = $model::where($options->column, '=', $dataTypeContent->{$options->key})->get();
$slug = Voyager::model('DataType')->where('model_name', $options->model)->firstOrFail()->slug;
@endphp
@if(isset($query))
<ul>
@foreach($query as $query_res)
<li><a href="{{ route("voyager.{$slug}.show", $query_res->{$options->key}) }}">{{ $query_res->{$options->label} }}</a></li>
@endforeach
</ul>
@else
<p>{{ __('voyager::generic.no_results') }}</p>
@endif
@endif
@elseif($options->type == 'belongsToMany')
@if(isset($view) && ($view == 'browse' || $view == 'read'))
@php
$relationshipData = (isset($data)) ? $data : $dataTypeContent;
$slug = Voyager::model('DataType')->where('model_name', $options->model)->firstOrFail()->slug;
$selected_values = isset($relationshipData) ? $relationshipData->belongsToMany($options->model, $options->pivot_table, $options->foreign_pivot_key ?? null, $options->related_pivot_key ?? null, $options->parent_key ?? null, $options->key)->get()->map(function ($item, $key) use ($options, $slug) {
return sprintf('<a href="%s">%s</a>', route("voyager.{$slug}.show", $item->{$options->key}), $item->{$options->label});
})->all() : array();
@endphp
@if($view == 'browse')
@php
$string_values = implode(", ", $selected_values);
@endphp
@if(empty($selected_values))
<p>{{ __('voyager::generic.no_results') }}</p>
@else
<p>{!! $string_values !!}</p>
@endif
@else
@if(empty($selected_values))
<p>{{ __('voyager::generic.no_results') }}</p>
@else
<ul>
@foreach($selected_values as $selected_value)
<li>{!! $selected_value !!}</li>
@endforeach
</ul>
@endif
@endif
@else
<select
class="form-control @if(isset($options->taggable) && $options->taggable === 'on') select2-taggable @else select2-ajax @endif"
name="{{ $relationshipField }}[]" multiple
data-get-items-route="{{route('voyager.' . $dataType->slug.'.relation')}}"
data-get-items-field="{{$row->field}}"
@if(!is_null($dataTypeContent->getKey())) data-id="{{$dataTypeContent->getKey()}}" @endif
data-method="{{ !is_null($dataTypeContent->getKey()) ? 'edit' : 'add' }}"
@if(isset($options->taggable) && $options->taggable === 'on')
data-route="{{ route('voyager.'.\Illuminate\Support\Str::slug($options->table).'.store') }}"
data-label="{{$options->label}}"
data-error-message="{{__('voyager::bread.error_tagging')}}"
@endif
>
@php
$selected_values = isset($dataTypeContent) ? $dataTypeContent->belongsToMany($options->model, $options->pivot_table, $options->foreign_pivot_key ?? null, $options->related_pivot_key ?? null, $options->parent_key ?? null, $options->key)->get()->map(function ($item, $key) use ($options) {
return $item->{$options->key};
})->all() : array();
$relationshipOptions = app($options->model)->all();
$selected_values = old($relationshipField, $selected_values);
@endphp
@if(!$row->required)
<option value="">{{__('voyager::generic.none')}}</option>
@endif
@foreach($relationshipOptions as $relationshipOption)
<option value="{{ $relationshipOption->{$options->key} }}" @if(in_array($relationshipOption->{$options->key}, $selected_values)) selected="selected" @endif>{{ $relationshipOption->{$options->label} }}</option>
@endforeach
</select>
@endif
@endif
@else
cannot make relationship because {{ $options->model }} does not exist.
@endif
@endif
In olders version we created relationship like this
{ "relationship": { "key": "id", "label": "name" } }
and we could optionally add a new property to the relationships object in the BREAD details in order to display proper links to relationship records. i.e.:
{ "relationship": { "key": "id", "label": "name", "page_slug": "admin/users" } }
So how to do the same thing with the new version of voyager?