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 column
To add the column(s) from the controller
- For a single column,
$this->registerColumn($column)
- For multiple columns,
$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 section
Column 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
- For a single field,
$this->registerField($field)
- For multiple fields,
$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
- For a single filter,
$this->registerFilter($filter)
- For multiple filters,
$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
- For a single widget,
$this->registerWidget($widget)
- For multiple widgets,
$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: selectHasMany
,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/column
Only 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'
* ]
* ]
*/