community-forum
community-forum copied to clipboard
[Feature Request] @field and @label directives for custom views/forms
Feature Request - @field and @label directives for custom views/forms.
What's the feature you think Backpack should have?
The ability to use @field in custom form blades in show/edit modes. In most use cases, this would also require the label for all fields to be optional, toggled by a $blade-crud variable. Then we use @labels directives to place the labels exactly where we want then in relation to the @field
Have you already implemented a prototype solution, for your own project?
Yes. I might be able to submit a PR, but would definitely bea ble to share what we've done
Do you see this as a core feature or an add-on?
I think it must be in core.
It requires an @if() in each field.blade.php to make the label optional
Example form uses:

Hello there! Thanks for opening your first issue on this repo!
Just a heads-up: Here at Backpack we use Github Issues only for tracking bugs. Talk about new features is also acceptable. This helps a lot in keeping our focus on improving Backpack. If you issue is not a bug/feature, please help us out by closing the issue yourself and posting in the appropriate medium (see below). If you're not sure where it fits, it's ok, a community member will probably reply to help you with that.
Backpack communication channels:
- Bug Reports, Feature Requests - Github Issues (here);
- Quick help (How do I do X) - Gitter Chatroom;
- Long questions (I have done X and Y and it won't do Z wtf) - Stackoverflow, using the
backpack-for-laraveltag; - Showing off something you've made, asking for opinion on Backpack/Laravel matters - Reddit;
Please keep in mind Backpack offers no official / paid support. Whatever help you receive here, on Gitter, Slack or Stackoverflow is thanks to our awesome awesome community members, who give up some of their time to help their peers. If you want to join our community, just start pitching in. We take pride in being a welcoming bunch.
Thank you!
-- Justin Case The Backpack Robot
Our directive implementation in BladeServiceProvider.php
Blade::directive('field', function ($name) {
if (! $name) {
return 'ERROR IN BLADE';
}
$field = '$fields['.$name.']';
$namespace = '($fields['.$name."]['view_namespace'] ?? 'crud::fields')";
$view = $namespace." . '.' . ".$field."['type']"; // Path to your view
$field = "\$__env->make({$view}, ['field' => {$field}], Arr::except(get_defined_vars(), ['__data', '__path']))->render();";
return "<?php echo {$field} ?>";
});
Blade::directive('label', function ($expression) {
$label = '$fields['.$expression.'][\'label\']';
$name = Str::replaceLast('\'', '', Str::replaceFirst('\'', '', $expression));
$str = "<label for=\"{$name}\"><?php echo {$label}?></label>";
return $str;
});
Example usage in custom view (included in larger view)
<?php
?>
<div class="row">
<div class="col-lg-6 col-md-6 text-nowrap">
@label('workorderno') : @field('workorderno')
@if($isRevision)
@label('revisionno') : @field('revisionno')
@endif
</div>
<div class="col-lg-6 col-md-6">
@label('contract_id') : @field('contract_id')
</div>
</div>
<div class="row">
<div class="col-lg-6 col-md-6 text-nowrap">
@label('signaturePO') :
@field('signaturePO')
</div>
<div class="col-lg-6 col-md-6">
@if(isset($viewMode) && $viewMode == 'PDF')
@label('contract_date') :<br/>
<div class="form-control ml-2" readonly="readonly" disabled="disabled">
{{ $entry->contract_date }}
</div>
@else
@label('contract_date') : @field('contract_date')
@endif
</div>
</div>
<div class="row">
<div class="col-lg-6 col-md-6 text-nowrap">
@if ($statusFinalOrLess && ! $isRevision) @label('status'):<br/>
<div id="etat-bdt">{{ WorkorderStatuses::getDescription($entry->status) }}</div>
@endif
@field('status')
</div>
<div class="col-lg-6 col-md-6"></div>
</div>
Modified time.blade.php showing the conditional label display logic, which displays the label unless disabled:
@include('crud::fields.inc.wrapper_start')
@unless(isset($nolabel)) <!-- modification here -->
<label>{!! $field['label'] !!}</label>
@endunless <!-- modification here -->
@include('crud::fields.inc.translatable_icon')
<input
type="time"
name="{{ $field['name'] }}"
value="{{ old(square_brackets_to_dots($field['name'])) ?? $field['value'] ?? $field['default'] ?? '' }}"
@include('crud::fields.inc.attributes')
>
{{-- HINT --}}
@if (isset($field['hint']))
<p class="help-block">{!! $field['hint'] !!}</p>
@endif
@include('crud::fields.inc.wrapper_end')
Hey @flap152 thanks alot for the feedback and for providing your solution for it. I am sure it will help people looking for the same.
But bare with me here: any reason why not directly @include('crud::fields.some_field') ? It's just because of label placement or is there any other reason ? Maybe just a config for fields show_label => true/false for that scenario would work ?
Let me know. Pedro
Pedro beat me to it 😀 Yeah, that's what I wanted to say too - you can already do that now using @include(). But in the future (hopefully in v5) we might refactor fields to Components. So you'll be able to do:
<x-field-text name="first_name" :default="$firstName" />
<x-field-number name="price" :default="$price" />
// or
<x-field type="text" name="first_name" :default="$firstName" />
<x-field type="number" name="price" :default="$price" />
@tabacitu, @pxpm, unless I missed something, with @field instead of @include(), the definition of the field ie. its type (selecte2_from_array or select2_ajax), data source, attributes, etc. remain in the controller and the blade is only concerned with placement and formatting.
The label visibility toggle/option is indeed just for placement, but needs to be set at the controller/operation level because not all our show/edit forms are custom and many other forms use standard views.
Oh I get it. Then you should be able to do that using @include('crud::fields.text', CRUD::fields()['slug']) but... yeah, I guess this is a little bit verbose... This should be easier to do after we rewrite to components too, because you'll be able to do something like BackpackField::render('slug'). We could add some @field and @label helpers too, I guess that would be even more convenient.
But they don't really make sense until we refactor to components, as it's not really recommended to use Backpack fields that way, until then...
Let's leave this issue open until after we do that, so we don't forget. Thanks for the idea @flap152 🙏
Cleaning up old issues. Been thinking about this... rather than add a new Blade directive for this, I would rather people use @include() or the component syntax itself. Fewer steps, easier to understand. So I gotta say "no" to this one. Good idea, but not worth the trouble imho.
Thanks for the suggestion, but sorry it didn't make the cut. Don't take this the wrong way please, 80% of my ideas don't make it either 😅