thedevdojo / voyager

Voyager - The Missing Laravel Admin
https://voyager.devdojo.com
MIT License
11.78k stars 2.67k forks source link

Add the ability to create/update the child of a relationship from the parents Add/Edit view. #1879

Open Boldonglen opened 7 years ago

Boldonglen commented 7 years ago

Description:

I think it would be good if you could have the ability to add or edit a child of a relationship from the parents add/edit screen. For example:

Say we have a Company model that has a OneToOne relationship with an Address Model. We create the relationship in Voyager and it shows us a dropdown list of the current addresses in the system. The problem is that this is a new company with a new address. Its not great that we first have to go and create a address before we can create the company.

Here are my suggestions on how it could be implemented (in order of preference):

  1. The one to one relationship has an option "inline", this would show the edit view of the address model within the company add/edit view. (The problem here is there is currently no known easy way to implement this).

  2. The company add/edit view has the dropdown list of addresses as it currently does but also has a "Add/Create" button next to the dropdown list. When this is clicked a popup/modal is opened that allows the user to create a address within the popup, when the save button is pressed (from within the add address popup) it creates the address in the system (saving it to the database) and updates the dropdown list within the company add/edit view to have the new address and have that address set as the selected address, therefore when you save the company it will have a relationship to the new address. (The problem with this is how do you handle multiple nested models, for example what if the Address model also had a one to one relationship with a Country model, this would result in nested popup/modals).

  3. The final way I can think of doing it would be to simply have a "Add/Create" button and a "Refresh/Update" button next to the dropdown. The "Add/Create" opens up a new tab with the edit view of the Address model. The user could then create and save the new address and go back to the Company tab and click the "Refresh/Update" button that would update the list of Addresses in the dropdown to show the newly created address. (The problem with this is that the user has to open multiple tabs).

There may be other ways that this could be done and I would love to hear other suggestions. I would also appreciate it if people could give this issue a thumbs up if its something that you think you would need/like.

Thanks,

Glen

vFire commented 6 years ago

It's cool and futher more we can add such multi-form function in both has-one and has-many relations, but I think it is pretty hard for voyager by now. If the voyogar is purely built on vuejs and APIs, it will be pretty easy to implement.

I've make it done in my own-developed system, multi-childform supported. Even has a basic graphic work-flow which supporting event & action editing. But it didn't use laravel eloquent, I'm not satisfied with it, hope I can implement sub-form function with voyager, it is very useful in real business.

And Voyager is really amazing, I love it.

2017-11-21_070737 2017-11-21_070702 2017-11-21_070454

aldozorzi commented 6 years ago

In my first Laravel / Voyager project, for hasMany relationships I added a list of child entities in main entity view page, and a "add" button passing from_table / from_id vars in GET. The add page uses these vars to set correct value in dropdown select. But I implemented it in a very ugly way, so I didn't request for pull :D. It could be a start point.

artemmolotov commented 6 years ago

+1

Boldonglen commented 6 years ago

@aldozorzi That would be a good starting point however I would like to be able to add and edit the child models from the parents edit screen.

Also one issue you may have the the implementation you describe is that what happens if you click to add a child object (by clicking the add button) before you have saved the parent?

aldozorzi commented 6 years ago

@Boldonglen you have the "classic" select, so if the parent doesn't exist, you can't select it whil you are adding a child. First you have to save parent, and than childs. It's the same behavour as it is now.

mattrabe commented 6 years ago

I am going to be building functionality similar to this on a project in the very near future. I'll see if I can make my solution nice & universal, and submit it as a PR. If anyone else out there has done this or has a good starting point for the views/controllers for this I'd love to take a look at your code before getting started.

vblinden commented 6 years ago

@mattrabe I am working on this. Take a look at https://github.com/vblinden/voyager/tree/child_modules

It needs some finishing touches, but it can be used for every 1.0 Voyager installation

mattrabe commented 6 years ago

@vblinden Wonderful - I'll check it out.

mattrabe commented 6 years ago

@vblinden I'm afraid I'm having trouble seeing this in action. After switching over to your repository and running composer update I see that I do have your files (such as resources/views/formfields/child_module.php), but I don't see any visible changes on my BREAD. I looked in the BREAD editor and I don't see an option to set a field or relationship to "child module". I tried changing a column of type relationship to child_module directly in my db, but that resulted in a PHP error.

The relationship I am trying to demo this on is a one-to-many relationship, where parent Product has multiple ProductSizes children and is related via product_sizes.product_id. The Product model has ->sizes specified via hasMany(), and the ProductSize model has ->product specified via belongsTo().

Does your solution work for hasMany()? Is there a step I am missing in order to get this into my BREAD?

vblinden commented 6 years ago

@mattrabe You need to make a relationship and when the relationship is created, you can change the relationship field to a child module (thus adding child when in a parent). Voyager at the moment doesn't look at the relationships defined in your models. The new BREAD @emptynick is making does, and I think also includes a kind of child module. But that is for version 1.x or 2.0 of Voyager.

yeisonramirez commented 6 years ago

@vblinden how can I do this?. I can't change the field of the relationship.

image

adrielwerlich commented 5 years ago

The link is broken... does anybody solved this inline missing feature?

acicovic commented 5 years ago

Related pull request that might be of interest: #3967

acicovic commented 5 years ago

For those interested, here's a link to the BREAD by @emptynick but apparently it's still a work in progress: https://github.com/emptynick/voyager-bread

emilushi commented 5 years ago

@acicovic This doesn't work with the latest version it throws: voyager/storage/bread/" directory does not exist., I will check why and comment below.

emptynick commented 5 years ago

Its currently heavy work in progress and absolultely unusable.

acicovic commented 5 years ago

Ok, good to know.

emilushi commented 5 years ago

@acicovic This doesn't work with the latest version it throws: voyager/storage/bread/" directory does not exist., I will check why and comment below.

I just had to create bread directory under storage but still as @emptynick says it still has a lot to work on.

alexmayo commented 5 years ago

+1 - Anyone had any luck with this?

nickkecooper commented 5 years ago

+1 - Anyone had luck with this?! This would be a make or break for me.

silici0 commented 5 years ago

I have started doing some codes (but i think thats not the best solution right now for me)... but maybe it can help some one, Product hasMany Texts Captura de Tela 2019-09-10 às 15 33 57 Captura de Tela 2019-09-10 às 15 34 06

Create a TextController to override some methods > php artisan make:controller TextController

On BREAD Texts change controller name as img > Captura de Tela 2019-09-10 às 15 35 57

TextController index return on ajax only the content render view if ($request->ajax()) { $view = View::make($view, compact( 'actions', 'dataType', 'dataTypeContent', 'isModelTranslatable', 'search', 'orderBy', 'orderColumn', 'sortOrder', 'searchNames', 'isServerSide', 'defaultSearchKey', 'usesSoftDeletes', 'showSoftDeleted' )); $sections = $view->renderSections(); return $sections['content']; } else { return Voyager::view($view, compact( 'actions', 'dataType', 'dataTypeContent', 'isModelTranslatable', 'search', 'orderBy', 'orderColumn', 'sortOrder', 'searchNames', 'isServerSide', 'defaultSearchKey', 'usesSoftDeletes', 'showSoftDeleted' )); }

On method create add the return if ($request->ajax()) { $view = View::make($view, compact('dataType', 'dataTypeContent', 'isModelTranslatable')); $sections = $view->renderSections(); return $sections['content']; } else { return Voyager::view($view, compact('dataType', 'dataTypeContent', 'isModelTranslatable')); }

Override edit-add.blade.php to /resources/view/vendor/voyager/products/ and add at end of section('content') ` @if ($edit) @foreach ($dataTypeRows as $row) @if ($row->type == 'relationship') @if ($row->details->type == 'hasMany')

                <div class="relationshipContentAdd">
                </div>
             @endif
        @endif
    @endforeach
@endif

`

On the same file at javascript after jQuery ready statment add the folow code @if ($edit) $.get( "/admin/texts", function( data ) { $( ".relationshipContent" ).html( data ); }); $.get( "/admin/texts/create", function( data ) { $( ".relationshipContentAdd" ).html( data ); var str = window.location.href; var numbers = str.match(/\d+/g).map(Number); var id = numbers[numbers.length -1]; var o = new Option($("[name='name']").val(), id, true, true); // change text_belongsto_product_relationship $('[name="text_belongsto_product_relationship"]').append(o); $('[name="text_belongsto_product_relationship"]').prop('disabled', true); }); @endif

Hope it help you guys to gives some insight how to do it

Gicminos commented 4 years ago

+1 - Any update with this?

acontia commented 4 years ago

Any plans to implement this in the near future? Otherwise, anyone knows an alternative free admin panel package that supports this?

kingIZZZY commented 4 years ago

+1 need this following this

orangeShadow commented 4 years ago

+1

gansky-alexander commented 4 years ago

+1

mattpark22 commented 4 years ago

+1 This is essential for me, thank you

fletch3555 commented 4 years ago

Guys, posting "+1" does nothing. If you want to follow it, click the "subscribe" button on the right: image

We have no plans to spend time on this feature anytime soon. This is an open-source project, so we're certainly open to pull requests.

kingIZZZY commented 4 years ago

@fletch3555 any recommendations about how to approach this? If we would do it one way or another, ex. server-side looping through related records vs. ajax-based related-record form submission, etc. which way would you think works best with the current codebase way of doing things?

fletch3555 commented 4 years ago

I don't personally see a good way to do this in the current iteration of Voyager, which is partly why we're not spending the time to build it ourselves. We left the request open since we know quite a few people want it.

kingIZZZY commented 4 years ago

Are there any known upcoming iterations of Voyager that changes this? Or sets up the code-base in different/better circumstances for implementing this kind of feature?

MrCrayon commented 4 years ago

Voyager 2 should be able to do it.

If you are interested on implementing it now I would do it like this:

srigurubyo commented 4 years ago

I am looking for this feature as well.

+1

Any outlook for the v2?

gmurillofuentes commented 3 years ago

Four years later, the developer continue thinking that's not important feature. But I think is fundamental feature. :(

emptynick commented 3 years ago

In an opensource project, "the developer" is everyone. We are open for pull requests. Nonetheless, this will definitely be possible in v2 (that's why the core team is not implementing this into v1)