Crud: [Feature Request] Adding Crud Entities in the select field type

Created on 5 Dec 2016  路  14Comments  路  Source: Laravel-Backpack/CRUD

Hi...

thank you for this awesome package .... It has any feature that I want but one feature I couldn't find . Can we add entry in select field ? for example we have two models , Book and Category. In Book view we can select a category by select or select2 field but cant add a category . for this situation we must go to category view and add it .
I attached a picture (from another admin package that has this feature ) that shows what Im after .

untitled

Most helpful comment

I've added this to the backlog now for future discussion when people have appropriate time as its not an issue - is a agreed future feature :)

All 14 comments

So you mean that you want to be able to add a "Category" from within your "Book" form?

@tabacitu might have a better solution, but you'd most likely have to build this as a custom feature.

I don't think its easily generic enough for a core feature as "Category" might have validation and other information that it needs to work.

The easiest thing to do would be to use the custom html field and add a button yourself that says "new category" that takes you to the new category page

yes I want to be able add a "Category" from within my "Book" from .

yes the solution that you've suggested is good but in my project I have many these situations for example add tags from within "Post" form or add author from within "Post" form again , and so on .
I think its a good feature that this package need it.

Yes you might need it a lot, but I don't think it will be a priority for Backpack, for the reasons I mentioned, it is not always as simple.

Imagine if you had a "Category" which needed a URL slug, SEO title, Status/Active and had validation on "Category Description" and the database was $table->string('description'); and needed a value.

This is all far too complicated to to consider, baring in mind Backpack is designed to as flexible and simple as possible. This is not simple for users.

So with that being said, maybe one day something similar will be available, but for now unless @tabacitu has another idea, I think this would be too bespoke to considered "this package needs it".

Feel free to create a PR with the feature so it can be added, but I would suggest developing this yourself if you need it.

All the best

@tabacitu what is your solution ?

We don't have a solution, this is your own custom desired bespoke functionality, I've suggested you can add a button to open a new window to add it, otherwise you can visit here and find out about bespoke costing

Well this topic got a little fire :-) Relax, guys, we all want the same thing: for Backpack to cover most of our recurring needs. But it's a process, so covering everything will take some time.

I guess I agree with both of you:

  • having an option to add an entry right there will be a huge UX improvement; the admin won't need to go into 2 forms to create that entry; and this does happen pretty ofter, so we do need to solve this problem;

However:

  • building a general solution will take some time, I do not expect we'll have this done very soon; 1-3 months, I expect;
  • if you need it right now for your project, you can create a custom field type, as @OwenMelbz suggested;

I've reopened the issue, because it's a feature I do think we should build. Here are my thoughts how to implement it generally:

  • a new field type, select_from_ajax_or_add; it would show a select2, like the screenshot above, and an "add item" button by its side;
  • upon clicking on the "add item" button, a modal would show up, which would show the form for adding that entry (load the HTML code, not an iFrame);
  • when completing the modal form, the request would be submitted through AJAX, see if there are any validation errors and either:

    • A: show the validation errors;

    • B: load the category that was just inserted in the select2;

In order to achieve this, and not have to write the create/edit options twice in your CrudController, you'd basically need an API for category - the ability to add items without an actual interface. Which I think is a great idea, because it would also give a boost to those building mobile apps or using MVC javascript libraries on the front-end.

For completeness, the API would provide the following methods and routes, inside a CrudApi trait:

  • category/api/create @ storeFromAjax()

    • would run the create() method, but instead of redirecting to a new page, it would return a JSON response with either the errors or the item that was just inserted;

  • category/api/update @ updateFromAjax()

    • same

  • category/api/destroy @ destroyFromAjax()

    • same

This would need to happen while still keeping the controller Restful. And that's tricky.

I see no clean way we can achieve the API, while allowing the developer to write their before_create or after_create callbacks only once, except if we:

  • make CrudController::storeCrud() and CrudController::updateCrud() no longer depend on the interface; it would work just insert/update;
  • create beforeStore(), afterStore(), beforeUpdate(), afterUpdate() methods, where people can do their thing;
  • have separate methods for the interface and AJAX that construct the response, be it a JSON response or a redirect;

So something like this:

class TestCrudController extends CrudController
{
    public function setup() {}
    public function store(StoreRequest $request)
    {
        $this->beforeStore();
        $response = parent::storeCrud();
        $this->afterStore();
        // TODO: calculate redirect_location
        return $redirect_location;
    }
    public function update(UpdateRequest $request)
    {
        $this->beforeUpdate();
        $redirect_location = parent::updateCrud();
        $this->afterUpdate();
        // TODO: calculate redirect_location
        return $redirect_location;
    }
}

trait Api
{
    public function storeFromAjax()
    {
        $this->beforeStore();
        // TODO: do the validation (we can't use Laravel Form Request validation in the API)
        $response = parent::storeCrud();
        $this->afterStore();
        // TODO: construct the JSON response
        return $response;
    }
    public function updateFromAjax()
    {
        $this->beforeUpdate();
        // TODO: do the validation (we can't use Laravel Form Request validation in the API)
        $response = parent::updateCrud();
        $this->afterUpdate();
        // TODO: construct the JSON response
        return $response;
    }
    public function destoryFromAjax($id) {}
}

@OwenMelbz , what do you think? I'm 99% we can find a better way, this definitely needs more thought.

@tabacitu a modal was the only method I could see this working for.

It would be a shame to add ANOTHER field type which does the same as the others. I think ideally adding an extra param to them would be better as you could add a closure, which maybe houses the fields you want to display. Unless you expect to display them all from the setup method?

There's actually 2 other pull requests around that are already a start of what your suggesting,

I've added one which already has a 'beforeStore' etc which can be used, and the 'withUnicity' which enables extra routes, so you could do 'withQuickAdd("admin/category")' this would setup the extra end points.

I could technically start/draft this today, but would need the other PR first, and not sure how to keep them all synced without causing dupe PRs. (And lots of inline JS) would be nice to get the core ones into js files

But other than that, the solution seemed similar to what I would have done.

@tabacitu
Thanks very much for your help...I try that .... if I find a better idea.I will share it

@OwenMelbz , completely agree - those PRs will prove to be the baby steps we need to get this going. Let's keep this feature in mind and come back to in after they're all merged and public.

I think it would be much easier something like a select2 field where you write the new record that is checked on create/update to see if it exists in its object table and if not to be added (with some default attributes in case they are required - i mean i understand that you cannot make a list with all the categories of the books before adding the books but you can add just the category's name when you add the book and at the end you may just update that category however you want).

To be honest, the more I think about this, the more its re-creating the wheel.

Realistically I feel the most sensible option is to have a button next to the select menu that says "New Entity" you click it, which opens a new tab/window which is on the create screen of the entity, then when you close the tab/window a "refresh" button is next to the "new entity" which reloads the data in the dropdown.

Otherwise you'll end up potentially re-creating complicated "add" forms in a modal.

I've added this to the backlog now for future discussion when people have appropriate time as its not an issue - is a agreed future feature :)

saw all your comments but what if I don't want to get the select box data from the database I just want to add a select box with some static values??

@krtrth docs reveal all https://laravel-backpack.readme.io/docs/crud-fields#section-select2_from_array

Was this page helpful?
0 / 5 - 0 ratings

Related issues

abewartech picture abewartech  路  3Comments

M0H3N picture M0H3N  路  3Comments

sokvebolkol picture sokvebolkol  路  3Comments

sseggio picture sseggio  路  3Comments

sonoftheweb picture sonoftheweb  路  3Comments