jrief / django-angular

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

ModelMultipleChoiceField and CheckboxSelectMultiple #261

Closed craftycorvid closed 8 years ago

craftycorvid commented 8 years ago

Adding a ModelMultipleChoiceField with its widget set to CheckboxSelectMultiple results in 4 input fields that are tied to the same Angular model. Using the djng.forms.widgets.CheckboxSelectMultiple results in a syntax error.

forms.py

from django import forms
from djng.forms import NgFormValidationMixin, NgModelFormMixin
from djng.forms.widgets import CheckboxSelectMultiple
from djng.styling.bootstrap3.forms import Bootstrap3ModelForm

class Form(NgModelFormMixin, NgFormValidationMixin, Bootstrap3ModelForm):
    scope_prefix = 'data'
    form_name = 'form'
    tracked_products = forms.ModelMultipleChoiceField(widget=CheckboxSelectMultiple(),
                                                      queryset=[model_field].objects.none(), required=False)

   class Meta:
        model = [model]

Part of rendered HTML

<div class="has-feedback form-group"><label class="control-label" for="id_tracked_products_0">Tracked products</label><ul ng-form="tracked_products" class="ng-pristine ng-valid">
<li><label for="id_tracked_products_0"><input checked="checked" class="form-control ng-pristine ng-untouched ng-valid" id="id_tracked_products_0_0" name="tracked_products.4" ng-model="data['tracked_products'].4" type="checkbox" value="4"> PRODUCT-4</label></li>
<li><label for="id_tracked_products_1"><input checked="checked" class="form-control ng-pristine ng-untouched ng-valid" id="id_tracked_products_1_1" name="tracked_products.1" ng-model="data['tracked_products'].1" type="checkbox" value="1"> PRODUCT-1</label></li>
<li><label for="id_tracked_products_2"><input checked="checked" class="form-control ng-pristine ng-untouched ng-valid" id="id_tracked_products_2_2" name="tracked_products.3" ng-model="data['tracked_products'].3" type="checkbox" value="3"> PRODUCT-3</label></li>
<li><label for="id_tracked_products_3"><input checked="checked" class="form-control ng-pristine ng-untouched ng-valid" id="id_tracked_products_3_3" name="tracked_products.2" ng-model="data['tracked_products'].2" type="checkbox" value="2"> PRODUCT-2</label></li>
</ul><ul class="djng-form-control-feedback djng-field-errors" ng-show="form['tracked_products'].$dirty"><li ng-show="form['tracked_products'].$valid" class="valid"></li></ul><ul class="djng-form-control-feedback djng-field-errors" ng-show="form['tracked_products'].$pristine"><li ng-show="form['tracked_products'].$valid" class="valid"></li><li ng-show="form.tracked_products.$message" class="invalid ng-binding" ng-bind="form.tracked_products.$message"></li></ul></div>

Angular.js error

http://errors.angularjs.org/1.5.7/$parse/syntax?p0=.4&p1=is%20an%20unexpected%20token&p2=41&p3=data%5B'tracked_products'%5D.4&p4=.4

It looks to me like the generated ng-models are invalid. Am I overlooking something?

jrief commented 8 years ago

Please retry with Angular 1.3 or 1.4. If you have some time, please find out the difference, so that someone can fix it

craftycorvid commented 8 years ago

Same error under 1.4.12

http://errors.angularjs.org/1.4.12/$parse/syntax?p0=.4&p1=is%20an%20unexpected%20token&p2=41&p3=data%5B%27tracked_products%27%5D.4&p4=.4

jrief commented 8 years ago

Yes, this seems to be a bug. It presumably is caused because of missing escaping for numbers – alphabetical attributes would work. I'll check it.

jrief commented 8 years ago

ModelMultipleChoiceField currently does not override its widget renderer. This is a bug/missing feature which causes your problem.

I'm quite busy at the moment, but you can try to fix it yourself by adding a ModelMultipleChoiceFieldMixin, similar to the MultipleChoiceFieldMixin. Otherwise wait a few week and eventually remind me.

Thanks for reporting.

Sherevv commented 8 years ago

I have the same issue. But there is another bug with rendering of this field: <li><label for="id_tracked_products_0"><input checked="checked" class="form-control ng-pristine ng-untouched ng-valid" id="id_tracked_products_0_0" name="tracked_products.4" ng-model="data['tracked_products'].4" type="checkbox" value="4"> PRODUCT-4</label></li>

Label's "for" attributes are not equal to input's ids: id_tracked_products_0 != id_tracked_products_0_0 So, by clicking on a label there is no effect.

jrief commented 8 years ago

@Ivan0xFF @Sherevv please retry with the current version from Github. If everything works in your environment, I'll release version 0.8.3.

Sherevv commented 8 years ago

The first error with angular is gone. But there is a difference in rendering of label's "for" attribute: If I use ModelMultipleChoiceField: <label class="checkbox-inline" for="id_registration_options_4"> <input id="id_registration_options_4_4" .... and if MultipleChoiceField: <label for="id_registration_options_4_4"> <input id="id_registration_options_4_4" ....

jrief commented 8 years ago

This for me seems to be a less serious bug. Could you do me a favor? Fork this repo and change the example, so that I can reproduce it. I then might come up with a solution.