All products

Editable Columns

Let you admins make quick edits, right from the table view.

The Whole Fruit Manifesto

This package adds a few editable columns for projects that use Backpack for Laravel v5:

  • editable_text
  • editable_checkbox
  • editable_switch
  • editable_select

When edited, those columns will submit an AJAX request to the controller, so that attribute is updated in the database. The developer is in complete control of the saving process, to make these column as versatile as possible:

  • the saving process can succeed => will show green dot or green text (and/or notification bubble)
  • the saving process can fail => will show red dot or red text (and/or notification bubble)

Backpack Editable Columns Addon

For the editable_text column, as an admin, you'll notice that:

  • the columns that are editable are underlined (dotted)
  • you can click that value to edit it, then
    • Enter saves the value
    • Esc reverts the changes
    • (up arrow) moves one row up (same editable column)
    • (down arrow) moves one row down (same editable column)
    • Tab moves to the next editable input
    • Shift + Tab moves to the previous editable input
    • clicking out of the input keeps the changes, but does not submit them (text becomes greyed out)

For the editable_select:

  • the columns that are editable are underlined (dotted) and there is a dropdown arrow
  • you can click the dropdown to edit the value as you normally do with a select input
  • once the value is selected, it is saved immediately, but you can disable this by setting the save_on_change to false (it will save on only on focus out)
  • the navigation between the editable_select is the same as for the editable_text (Enter, Esc, , , Tab, Shift + Tab)
    • Space or Enter opens the dropdown

For the editable_checkbox and editable_switch columns, as an admin... you'll notice that it "just works".

Installation

Step 1. Buy access to this package and you'll get an access token. With that token in hand, you should instruct your project to pull in missing packages from our private repository, instead of Packagist:

  • add your token to your project's auth.json file by running composer config http-basic.backpackforlaravel.com [your-token-username] [your-token-password]
  • add the Backpack private repo to your composer.json:
"repositories": [
    {
        "type": "composer",
        "url": "https://repo.backpackforlaravel.com/"
    }
],

Step 2. In your project, via command line:

composer require backpack/editable-columns

Usage

Step 1. Inside your ProductCrudController (for example), use this new operation we've provided:

class ProductCrudController extends CrudController
{
    use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\CloneOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
+   use \Backpack\EditableColumns\Http\Controllers\Operations\MinorUpdateOperation;

    public function setup()
    {
        CRUD::setModel(\App\Models\Product::class);
        CRUD::setRoute(config('backpack.base.route_prefix').'/product');
        CRUD::setEntityNameStrings('product', 'products');
    }

Step 2. In your ListOperation, instead of using text, number, check, select_from_array columns, use the columns this package provides, if you want them editable:

public function setupListOperation() 
{
    // editable_text
    CRUD::addColumn([
        'name'             => 'price',
        'type'             => 'editable_text',
        'label'            => 'Price',

        // Optionals
        'underlined'       => true, // show a dotted line under the editable column for differentiation? default: true
        'min_width'        => '120px', // how wide should the column be?
        'select_on_click'  => false, // select the entire text on click? default: false
        'save_on_focusout' => false, // if user clicks out, the value should be saved (instead of greyed out)
        'on_error' => [
            'text_color'          => '#df4759', // set a custom text color instead of the red
            'text_color_duration' => 0, // how long (in miliseconds) should the text stay that color (0 for infinite, aka until page refresh)
            'text_value_undo'     => false, // set text to the original value (user will lose the value that was recently input)
        ],
        'on_success' => [
            'text_color'          => '#42ba96', // set a custom text color instead of the green
            'text_color_duration' => 3000, // how long (in miliseconds) should the text stay that color (0 for infinite, aka until page refresh)
        ],
        'auto_update_row' => true, // update related columns in same row, after the AJAX call?
    ]);

    // editable_checkbox
    CRUD::addColumn([
        'name'  => 'agreed',
        'label' => 'Agreed',
        'type'  => 'editable_checkbox',

        // Optionals
        'underlined' => true, // show a dotted line under the editable column for differentiation? default: true
        'on_error' => [
            'status_color'          => '#df4759', // set a custom text color instead of the red
            'status_color_duration' => 0, // how long (in miliseconds) should the text stay that color (0 for infinite, aka until page refresh)
            'switch_value_undo'     => false, // set checkbox to the original value (user will lose the value that was recently input)
        ],
        'on_success' => [
            'status_color'          => '#42ba96', // set a custom text color instead of the green
            'status_color_duration' => 3000, // how long (in miliseconds) should the text stay that color (0 for infinite, aka until page refresh)
        ],
        'auto_update_row' => true, // update related columns in same row, after the AJAX call?
    ]);

    // editable_switch
    CRUD::addColumn([
        'name'  => 'agreed',
        'label' => 'Agreed',
        'type'  => 'editable_switch',

        // Optionals
        // All the options available on editable_checkbox are available here too, plus;
        'color'   => 'success',
        'options' => ['✓', '✕'],
    ]);

    // editable_select
    CRUD::addColumn([
        'name'    => 'categories',
        'label'   => 'Categories',
        'type'    => 'editable_select',
        'options' => \App\Models\Category::all()->pluck('name', 'id')->toArray(),
        // or 
        // 'options' => [
        //     '1' => 'One',
        //     '2' => 'Two',
        //     '3' => 'Three',
        // ],

        // Optionals
        'underlined'       => true, // show a dotted line under the editable column for differentiation? default: true
        'save_on_focusout' => true, // if user clicks out, the value should be saved (instead of greyed out)
        'save_on_change'   => true,
        'on_error' => [
            'text_color'          => '#df4759', // set a custom text color instead of the red
            'text_color_duration' => 0, // how long (in miliseconds) should the text stay that color (0 for infinite, aka until page refresh)
            'text_value_undo'     => false, // set text to the original value (user will lose the value that was recently input)
        ],
        'on_success' => [
            'text_color'          => '#42ba96', // set a custom text color instead of the green
            'text_color_duration' => 3000, // how long (in miliseconds) should the text stay that color (0 for infinite, aka until page refresh)
        ],
        'auto_update_row' => true, // update related columns in same row, after the AJAX call?
    ]);
}

Step 3.A. Then inside setupMinorUpdateOperation(), define what FormRequest you want to use for validation. You can use the exact same FormRequest that you've used in your Create/Update operations, because MinorUpdate will only consider the validation rule for the currently edited attribute (and ignore everything else). So in most cases you just need to do:

protected function setupMinorUpdateOperation()
{
    $this->crud->setValidation(StoreRequest::class);
}

Step 3.B. Alternatively, if you don't want to use a FormRequest for validation, but instead want to write some custom validation logic, or you need to modify the saving process, you can easily do that too. Just override the methods saveMinorUpdateFormValidation() (to override the validation), and saveMinorUpdateEntry() (to override the saving process). This methods are used by saveMinorUpdate() which you may also override although it's not really neccessary. The example below shows how to confirm/deny the edit. Modify it so it fits your project, it's in your control.

public function saveMinorUpdateFormValidation()
{
    // validation example for the "price"
    // note that this is just an example, you may do this with the FormRequest
    if (request('attribute') === 'price' && !is_numeric(request('value'))) {
        throw ValidationException::withMessages([
            'price' => ['The price has to be a number.'],
        ]);
    }
}
public function saveMinorUpdateEntry()
{
    // Save the minor update
    $entry = $this->crud->getModel()->find(request('id'));
    $entry->{request('attribute')} = request('value');
    
    // Perform specific logic
    $entry->status = 'draft';

    return $entry->save();
}

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

Big thanks to Kevin Ohashi of Review Signal and NameBio.com, who has sponsored building this addon. If you need a Backpack addon too, reach out, we love to build them. Created by:

License

This project was released under EULA, so you can install it on top of any Backpack & Laravel project. Please see the license file for more information.

Package Access

You don't currently have access to this package. To gain access, go ahead and purchase it. You'll get:

Next 12 months
  • download or install using Composer;
  • all updates (major, minor and patch);
After 12 months
  • can still access all versions and updates you paid;
  • can still install using Composer;
  • no new versions or updates;
Buy for 99 EUR