Downloads
Stars
Version
In the table view of backpack/crud list operation, if a column exists in database table, it's by default searchable and orderable unless instructed otherwise. Also, to add a column or field to the operation, it is required to pass an array. In PHP, array keys are case-sensitive and this make it tedious when adding a field or column. This package allows class based imperative approach over passing the array. So no more tedious, repetitive typing game matching the exact array keys. BE FORGETFUL sometimes? 🤷
To install the package, run
composer require anik/laravel-backpack-extension
Instead of extending the \Backpack\CRUD\app\Http\Controllers\CrudController
,
use \Anik\LaravelBackpack\Extension\Controllers\CrudController
in your controllers.
To instantiate a Column
new \Anik\LaravelBackpack\Extension\Columns\Column(string $name, [?string $label = null])
\Anik\LaravelBackpack\Extension\Columns\Column::create(string $name, [?string $label = null])
\Anik\LaravelBackpack\Extension\Columns\Column::ID([?string $label = null], [?string $name = null])
- To create an
ID type columnTo add the column(s) from the controller
$this->registerColumn($column)
$this->registerColumns($columns)
By default, all Column instances are not orderable and not searchable.
use Anik\LaravelBackpack\Extension\Columns\Column;
use Anik\LaravelBackpack\Extension\Controllers\CrudController;
class AccountCrudController extends CrudController
{
public function setupListOperation () {
$columns = [
Column::ID()->orderable(), // Only this column will be orderable
Column::create('email')->searchable(), // Makes this field searchable
Column::create('name')->searchable(
fn ($q, $column, $term) => strlen($term = trim($term)) >= 3 ? $q->where('name', 'LIKE', sprintf('%%%s%%', $term)) : null)
), // Also makes this field searchable with custom logic
];
$this->registerColumns($columns);
$this->registerColumn((new Column('is_verified', 'Verified'))->setType('boolean'));
}
}
orderable()
- Make the column orderablesetOrderable(bool $orderable)
searchable()
- Make the column searchablesetSearchLogic(bool|Closure $logic)
- Make the column searchable with logic or not searchablesetKey(string $key)
setType(string $type)
- Set column typesetEntity(bool|string $entity)
setAttribute(string $attribute)
setModel(string $model)
setPriority(int $priority)
shouldNotEscape()
- Do not escape the value in the view {!! $value !!}
setEscaped(bool $escape)
setValue(mixed $value)
setLimit(int $limit)
setDefault(mixed $default)
setPrefix(mixed $prefix)
setSuffix(mixed $prefix)
setWrapper(mixed $wrapper, bool $mergeRecursive = false)
setOptions(mixed $options, bool $mergeRecursive = false)
isExportOnlyField()
isNotExportOnlyField()
shouldBeVisibleInTable()
shouldNotBeVisibleInTable()
shouldBeVisibleInModal()
shouldNotBeVisibleInModal()
isTableColumn()
isNotTableColumn()
setTableColumn(bool $tableColumn)
related(Relation $relation, bool $mergeRecursive = false)
- Check Relation sectionColumn class uses \Anik\LaravelBackpack\Extension\Extensions\Attributable
trait.
Check Attributable section.
To instantiate a Field
new \Anik\LaravelBackpack\Extension\Fields\Field(string $name, [?string $label = null])
\Anik\LaravelBackpack\Extension\Fields\Field::create(string $name, [?string $label = null])
Or to create an OptionalField
new \Anik\LaravelBackpack\Extension\Fields\OptionalField(string $name, [?string $label = null])
\Anik\LaravelBackpack\Extension\Fields\OptionalField::create(string $name, [?string $label = null])
To add the field(s) from the controller
$this->registerField($field)
$this->registerFields($fields)
By default, all the Field instances are required.
use Anik\LaravelBackpack\Extension\Controllers\CrudController;
use Anik\LaravelBackpack\Extension\Fields\Field;
class AccountCrudController extends CrudController
{
public function setupCreateOperation () {
$fields = [
Field::create('email')->setType('email'),
Field::create('is_admin')->checkbox(),
];
$this->registerFields($fields);
$this->registerField((new Field('csrf_token'))->hidden());
}
}
required()
- Make field requiredoptional()
- Make field optionalsetType(string $type)
- Set field typerelated(Relation $relation, bool $mergeRecursive = false)
- Check Relation sectionsetRelationType(string $type)
setEntity(bool|string $entity)
setAttribute(mixed $attribute)
setModel(string $model)
setBaseModel(string $baseModel)
showAsterisk()
setShowAsterisk(mixed $value)
allowsMultiple()
setMultiple(mixed $multiple)
setPivot(mixed $pivot)
setSubfields(mixed $subfields)
setParentFieldName(mixed $value)
setPrefix(string $prefix)
setSuffix(string $suffix)
setDefault(mixed $default)
setValue(mixed $value)
setHint(string $hint)
setInline(mixed $inline)
hidden()
- Make hidden type fieldcheckbox()
- Make checkbox type fieldradio()
- Make radio type fieldnumber()
- Make number type fieldpassword()
- Make password type fieldsetPlaceholder(string $placeholder)
isReadOnly()
- Make field readonlyisDisabled()
- Make field disabledsetClass(string $class)
- Set field element css classsetAttributes(array $attributes, bool $mergeRecursive = true)
- Add additional attribute for field elementsetWrapper(mixed $value, bool $mergeRecursive = true)
setFake(bool $fake)
setStoresIn(string $storesIn)
setOptions(mixed $options, bool $mergeRecursive = true)
allowsNull()
setAllowsNull(bool $allowNull)
setTab(string $tab)
Field class uses \Anik\LaravelBackpack\Extension\Extensions\Attributable
trait.
Check Attributable section.
To instantiate a Filter
new \Anik\LaravelBackpack\Extension\Filters\Filter(string $name, [?string $label = null])
\Anik\LaravelBackpack\Extension\Filters\Filter::create(string $name, [?string $label = null])
\Anik\LaravelBackpack\Extension\Filters\AjaxFilter::create(string $name, [?string $label = null], [?string $url = null], [?string $method = null])
To add the filters(s) from the controller
$this->registerFilter($filter)
$this->registerFilters($filters)
use Anik\LaravelBackpack\Extension\Controllers\CrudController;
use Anik\LaravelBackpack\Extension\Filters\Filter;
use Anik\LaravelBackpack\Extension\Filters\AjaxFilter;
class AccountCrudController extends CrudController
{
public function setupListOperation () {
$filters = [
Filter::create('status')
->setValues([1 => 'Draft', 2 => 'Pending', 3 => 'Published',])
->setLogic(fn($status) => $this->crud->query->where('status', $status)),
AjaxFilter::create('user_id'),
];
$this->registerFilters($filters);
$this->registerFilter((new Filter('is_deleted'))->setValues([0, 1]));
}
}
setType(string $type)
- Set filter typesetViewNamespace(string $namespace)
setPlaceholder(string $placeholder)
setValues(string|array|callable $values)
setLogic(callable $logic)
setFallbackLogic(callable $fallbackLogic)
Filter class uses \Anik\LaravelBackpack\Extension\Extensions\Attributable
trait.
Check Attributable section.
To instantiate a Widget
new \Anik\LaravelBackpack\Extension\Widgets\Widget([?string $type = null], [?string $name = null], [?string $section = null])
\Anik\LaravelBackpack\Extension\Widgets\Script::create(string $src, [?string $name = null])
\Anik\LaravelBackpack\Extension\Widgets\Style::create(string $href, [?string $name = null])
new \Anik\LaravelBackpack\Extension\Widgets\Hidden([?string $type = null], [?string $name = null], [?string $section = null])
To add the widget(s) from the controller
$this->registerWidget($widget)
$this->registerWidgets($widgets)
use Anik\LaravelBackpack\Extension\Controllers\CrudController;
use Anik\LaravelBackpack\Extension\Widgets\Script;
use Anik\LaravelBackpack\Extension\Widgets\Style;
use Anik\LaravelBackpack\Extension\Widgets\Widget;
class AccountCrudController extends CrudController
{
public function setupListOperation () {
$widgets = [
Script::create('assets/js/common.js'),
Style::create('assets/css/common.css'),
];
$this->registerWidgets($widgets);
$this->registerWidget((new Widget('script'))->setContent('assets/js/another_common.js'));
}
}
setSection(string $section)
setContent(mixed $content)
setViewNamespace(string $namespace)
shouldBeHidden()
shouldBeFirst()
shouldBeLast()
Script::setSrc(string $src)
Script::setStack(string $stack)
Style::setRel(string $rel)
Style::setHref(string $href)
Style::setStack(string $stack)
Widget class uses \Anik\LaravelBackpack\Extension\Extensions\Attributable
trait.
Check Attributable section.
If a Column or Field points to an Eloquent relationship, then you can
use Anik\LaravelBackpack\Extension\Relations\Relation
.
To instantiate a Relation
new \Anik\LaravelBackpack\Extension\Relations\Relation(stirng $type, string $method, [?string $attribute = null])
new \Anik\LaravelBackpack\Extension\Relations\CustomRelation::create(string $type, string $method, [?string $attribute = null])
new \Anik\LaravelBackpack\Extension\Relations\BelongsTo::create(string $method, [?string $attribute = null])
new \Anik\LaravelBackpack\Extension\Relations\HasOne::create(string $method, [?string $attribute = null])
new \Anik\LaravelBackpack\Extension\Relations\BelongsTo::BelongsToMany(string $method, [?string $attribute = null])
new \Anik\LaravelBackpack\Extension\Relations\HasOne::HasMany(string $method, [?string $attribute = null])
Parameters:
$method
- The method name of the relationship in the eloquent model.$attribute
- The field/column/attribute of the related eloquent model.$type
- Used by backpack to pick the view to show the value calculated from the relationship.The package provides 4 relations out-of-the-box which uses the type suggested by Backpack.
HasOne
, BelongsTo
- Type: select
HasMany
, BelongsToMany
- Type: select_multiple
If you want a customized Relationship, you can use \Anik\LaravelBackpack\Extension\Relations\CustomRelation
.
use Anik\LaravelBackpack\Extension\Columns\Column;
use Anik\LaravelBackpack\Extension\Controllers\CrudController;
use Anik\LaravelBackpack\Extension\Fields\Field;
use Anik\LaravelBackpack\Extension\Relations\BelongsTo;
use Anik\LaravelBackpack\Extension\Relations\HasMany;
class AccountCrudController extends CrudController
{
public function setupListOperation () {
$columns = [
// Other columns
Column::create('phone')->related(HasMany::create('phones', 'number')),
];
$this->registerColumns($columns);
}
public function setupCreateOperation() {
$fields = [
// Other fields
Field::create('country_id', 'Country')->related(BelongsTo::create('country', 'name')),
];
$this->registerFields($fields);
}
}
setValueResolver(Closure $resolver)
- Set a closure which will be responsible to calculate the value for
field/columnOnly CustomRelation class uses \Anik\LaravelBackpack\Extension\Extensions\Attributable
trait.
Check Attributable section.
The Attributable trait allows classes to save and retrieve attributes in array format. Classes that use the trait will have access to the following methods.
addAttribute(string $key, mixed $value, bool $mergeRecursive = false)
addAttributes(array $attributes, bool $mergeRecursive = false)
unset(string $key)
toArray(): array
$mergeRecursive
indicates to if merge should be done using array_merge vs array_merge_recursive.
addAttribute
, addAttributes
, unset
methods allows dot notation based keys when adding or unsetting
values.
use Anik\LaravelBackpack\Extension\Fields\Field;
$field = Field::create('name');
$field->addAttribute('attributes.readonly', 'readonly'); // ['attributes' => ['readonly' => 'readonly']]
// $field->addAttribute('attributes.disabled', 'disabled'); // w/o the parameter [mergeRecursive: true] -> ['attributes' => ['disabled' => 'disabled']]
$field->addAttribute('attributes.disabled', 'disabled', true); // ['attributes' => ['readonly' => 'readonly', 'disabled' => 'disabled']]
$field->addAttributes(['wrapper.class' => 'col-md-12'], true);
$field->addAttributes(['wrapper' => ['another' => ['key' => 'value']]], true);
// $field->addAttributes(['wrapper.another.key' => 'value'], true); // Alternative implementation of the above line
/**
* STRUCTURE: $field->toArray();
*
* [
* 'attributes' => [
* 'readonly' => 'readonly',
* 'disabled' => 'disabled'
* ],
* 'wrapper' => [
* 'class' => 'col-md-12',
* 'another' => [
* 'key' => 'value'
* ]
* ]
* ]
*/
$field->unset('wrapper.another');
/**
* STRUCTURE: $field->toArray();
*
* [
* 'attributes' => [
* 'readonly' => 'readonly',
* 'disabled' => 'disabled'
* ],
* 'wrapper' => [
* 'class' => 'col-md-12'
* ]
* ]
*/