jrief / django-angular

Let AngularJS play well with Django
http://django-angular.awesto.com/
MIT License
1.23k stars 294 forks source link

Does this work well with nested Formsets? #197

Closed thebarty closed 6 years ago

thebarty commented 9 years ago

Hi guys,

2 questions: 1) Does this work with Django Formsets? If yes: is there an example you can show? 2) If I want to do a custom form layout and render the single fields myself: Is there a way to do this?

Kind regards Mike

jrief commented 9 years ago

1) it should work, but please try yourself. 2) yes, just render field by field – but you then also have to render the placeholders for errors, labels etc. I do not recommend this. If you absolutely have to style fields, try with CSS. I sometimes do this using the Form attribute field_css_classes.

trubliphone commented 8 years ago

I am trying to do something very similar and it is not quite working. I have described my specific issue here.

I found that I had to distinguish between "stand-alone" forms and forms that are part of a formset, and use that information to override the names that are used when rendering for form. This required changing get_widget_attrs to override how "ng-model" is set.

I am sure that I have to do something similar w/ get_field_errors but I haven't yet worked out how to do that. Any tips?

trubliphone commented 8 years ago

I am answering my own comment in case anybody else runs into a similar issue.

The problem was that a django-angular form uses a custom TupleErrorList class instead of the Django ErrorList class. This was being overwritten by the FormSet _construct_form fn. To fix this, I added {"error_class": TupleErrorList} to the FormSet init fn.

jrief commented 8 years ago

@trubliphone Thanks for your answer. Do you think this can be added, without monkey-patching Django and without implementing a, say DgngFormSet class? Otherwise please add a PR stating this problem in the docs.

trubliphone commented 8 years ago

@jrief I'm a bit new to Django and Angular (and github). Bear w/ me...

I do think this can be added w/out monkey-patching Django.

I do not think this can be added w/out adding a custom DgngFormSet class. But I am willing to do that.

I do not know what "PR" stands for.

adrienbrunet commented 8 years ago

A PR means "pull request" =) It's when you try to get your code on github merged in a branch.

ticalcster commented 8 years ago

The first problem I had with formset was the prefix problem fix in with #199. Thank you!

BaseFormSet creates a new prefix for each form by appending a dash and the index (or model id) of the form. My solutions was to overload the the add_prefix function on Django's BaseFormSet class to make it an underscore. As mentioned the ErrorList also had to be changed to TupleErrorList. I did this similar to NgFormBaseMixin. I created a new formset mixin, NgBaseFormSetMixin, to include these changes.

BaseFormSet also does not have a form_name attribute to use with Angular's form validation. I took some code from the NgFormBaseMixin class to handle setting form_name the same in the formset and the forms. This may not be the best solution as Angular sees the list of forms as one form. The only problem I've found so far is with the extra forms. Django will see empty extra forms as valid (by default) but Angular will not. Another solutions would be to have nested Angular forms using ng-form, but that would require extra work on how django renders formsets (or passed to the developer to add) and the form_name can't be just based on the base64 of the class name. form_name would have to have some kind of index added similar to how Django formsets create each form prefix.

The next thing that needs to be handled is the ManagementForm. Submitting a POST call back to Django will work fine with the current management form. The problem is the ManagementForm is not an NgForm so it will not be in $scope. You won't be able to use it with AJAX requests which means it will not pass formset validation in Django. Having it in $scope would be nice to let the client add / remove forms in the formset. Was thinking of creating an Angular module, djangoFormset. Which would let you do something like, <button ng-click="addForm('{{ form.prefix }}')">Add</button>, in the Django template. I'm relatively new to both Django and Angular. I'm not sure about the best way to go about this.

Sorry for the long post.

jrief commented 6 years ago

@ticalcster django-angular-2.0 supports forms-sets. This means that you can control and upload the data, from two or more forms using one request. Please check the new demo at https://django-angular.awesto.com/model_scope/ and let me know, if it works for you.

django-angular-2.0 will be released soon and currently is in review stage, so please participate.

I'm closing this in favor of the new feature.

ticalcster commented 6 years ago

@jrief This is great news. Thank you!

ImanoWilliams commented 6 years ago

@ticalcster I am new to Django and would love to angular to create forms in the html templates. Can you provide any information about to do the following:

You mentioned nested formset in your django-angular documentation, but I have no clue on how to do a Django Dynamic Nested Formsets with AngularJS.

I would like to do the following:

Is there a way to dynamically add/remove multiple nested inline formsets with angularJS in Django? Please see "Desired Result" below.

Scenarios:

I have a basic flow form with a field called "basicDescription". Below this form is a related Alt Flow form with its field called "altDescription. If I click "+ Add Alt Flow", it should add another related Alt Flow form to the basic flow. Conversely, if I click "- Remove Alt Flow", it should remove the related Alt Flow form from the basic flow.

If I click "- Remove Basic Flow", it should remove the basic flow form along with any related Alt Flow forms. Conversely, if click "+ Add Basic Flow", it should display default nested form set view as the example below.

Desired Result:

Basic Flow
1 basicDescription:________________ - Remove Basic Flow
            Alt Flow:
            altDescription:______________ - Remove Alt Flow
           + Add Alt Flow
+ Add Basic Flow

ticalcster commented 6 years ago

I don't think dynamic formsets will be possible without a lot of work django-angular. AngularJS has to know all the meta data about the form fields (field names, help text, widgets, etc) in order to create a new blank form. None of that information is passed to AngularJS with this package. I was working on creating new make_formset functions to mimic the Django functions that created a dummy form and angular directives to copy the dummy form input fields into the formset, but never had it working well (this was before they officially supported formsets). Custom layouts would also have been hard to support. It was a lot of copied code from Django and would make it hard to maintain.