Thank you! Your feedback has been delivered
Thank you! Your feedback has been sent

get django-angular and django-crispy-forms work together nicely

Does anyone have ideas about how to get django-angular and django-crispy-forms work together nicely or make django-crispy-forms ready for angularjs?

Use of django-angular is excellent in combination with the django-rest-framework. But the problematic thing is rendering the form exactly the way one wants the html to look (e.g. like the django-crispy-forms layout function does it).


I have decided to not use django forms because of flexibility and clarity. It is more coding work in html but maybe the better solution for now.

User Gravatar

cwirz

Posted Jul 2 2014 10:43 UTC

$200


  • Assigned To cwirz
  • Solved
  • angular.js
    django
    python
  • 2432 Views

6 Replies


From what I have been reading, it's been consistently suggested to not go down this route. Crispy-Forms is very jQuery dependent and the main reason for using Angular is to replace jQuery. I would look in this github issue thread to see if you can use the as_div method provided as a solution, but if not then I would try another route. The code in the thread is not my solution, it is the solution of the owner of that github repo. Just trying to guide you to the answer :).

User Gravatar

gwilakers

Posted Jul 2 2014 11:02 UTC

Ok thanks I see the problem here, but did you have any idea about another route? I really like the way how django-crispy-forms handle the layout with the helper class.

User Gravatar

cwirz

Posted Jul 2 2014 11:19 UTC

Django-angular has some code for building forms, so can you be a little bit more specific about what you want that isn't provided by the library? Would help me understand what you want better :)

User Gravatar

Dearon

Posted Jul 2 2014 11:33 UTC

I would like to implement the layout technic from django-cispy-forms into the django-angular project

or

create another app like django-crispy-forms using a helper class (or mixin classes) to render the form for angularjs -> Applying ng-model, scope-prefix and error messages...

Example how I solved this 4 now:

class PaymentForm(forms.Form):
number = CreditCardField(
    required=True,
    label=_("Kartennummer"),
)
first_name = forms.CharField(
    required=True,
    label=_("Kartenhalter Vorname"),
    max_length=60
)
last_name = forms.CharField(
    required=True,
    label=_("Kartenhalter Nachname"),
    max_length=60
)
expiration = CCExpField(
    required=True,
    label=_("Ablaufdatum")
)
ccv_number = forms.IntegerField(
    required=True,
    label=_("Sicherheitsnummer"),
    max_value=9999,
    widget=forms.TextInput(attrs={'size': '4'})
)

def __init__(self, *args, **kwargs):
    super(PaymentForm, self).__init__(*args, **kwargs)
    self.helper = FormHelper()
    self.helper.layout = Layout(
        Fieldset(
            '',
            Div(
                Div(
                    "number",
                    css_class="col-md-12",
                ),
                css_class="row",
            ),
            Div(
                Div(
                    "first_name",
                    css_class="col-md-6",
                ),
                Div(
                    "last_name",
                    css_class="col-md-6",
                ),
                css_class="row",
            ),
            Div(
                Div(
                    MultiWidgetField(
                        'expiration',
                        attrs=(
                        {'style': 'max-width: 100px;float:left;'},
                        {'style': 'max-width: 100px;float:left;margin-left:10px;'}
                        ),
                    ),
                    css_class="col-md-12",
                ),
                css_class="row",
            ),
            Div(
                Div(
                    "ccv_number",
                    css_class="col-md-12",
                ),
                css_class="row",
            ),
        ),
        ButtonHolder(
            HTML(
                u'<input type="submit" value="Submit" ng-click="payment_form_submit()" />')
        )
    )

But this wont work with the django-angular mixin because of error messages and other stuff.

So:

class PaymentAngularForm(PaymentForm):
form_name = 'payment_form'

def __init__(self, user, data=None, *args, **kwargs):
    super(PaymentFormBestellung, self).__init__(data, *args, **kwargs)

    self.fields['number'].widget.attrs.update({'required': 'true', 'ng-model': 'payment_form_model.number'})
    self.fields['first_name'].widget.attrs.update({'required': 'true', 'ng-model': 'payment_form_model.first_name'})
    self.fields['last_name'].widget.attrs.update({'required': 'true', 'ng-model': 'payment_form_model.last_name'})
    self.fields['ccv_number'].widget.attrs.update({'required': 'true', 'ng-model': 'payment_form_model.ccv_number'})

I created a template to render each field separately:

...
    <div class="row">
    <div class="col-md-12">
        <div class="form-group"
             ng-class="{'has-error': {{ form.form_name }}.{{ form.number.name }}.$invalid && {{ form.form_name }}.{{ form.number.name }}.$dirty || {{ form.form_name }}.{{ form.number.name }}.$error.serverMessage}">
            <label for="{{ form.number.id }}">{{ form.number.label }}</label>
            {{ form.number|attr:"server-error"|add_class:"form-control" }}
            <div class="help-block"
                 ng-hide="{{ form.form_name }}.$pristine">
                <span style="display: block;"
                      ng-show="{{ form.form_name }}.{{ form.number.name }}.$error.serverMessage">
                    {$ {{ form.form_name }}.{{ form.number.name }}.$error.serverMessage $}
                </span>
            </div>
        </div>
    </div>
</div>
...

And in controller:

        $scope.payment_form_submit = function () {
        $http.post(urls.payment_form, {
            data: $scope.payment_form_model,
            bestell_nr: bestellnummerService.getNummer(),
            ids: ids
        })
        .success(function (out_data) {
            if (out_data.success) {
                $scope.payment_form.$setPristine();
                window.location = out_data.redirect_url;
            }
            else {
                if (out_data.errors) {
                    for (var fieldName in out_data.errors) {
                        var message = out_data.errors[fieldName];
                        $scope.payment_form.$setValidity(fieldName, false, $scope.payment_form);
                        var serverMessage = $parse('payment_form.' + fieldName + '.$error.serverMessage');
                        serverMessage.assign($scope, message[0]);
                    }
                }
                if (out_data.payment_error) {
                    alert(out_data.payment_error);
                }
            }
        });
    };

What is better to make this more general -> Helper class or mixin classes?

User Gravatar

cwirz

Posted Jul 2 2014 12:47 UTC

To stick with the Django 'DRY' design philosophy, the consensus is to use a mixin class (eg. NgModelFormMixin). It also seems there has been some recent developments on this issue, read this https://github.com/jrief/django-angular/issues/51. As of 6 hours ago, the author closed the thread stating that "django-angular now supports quite well form styling"

User Gravatar

ServA1

Posted Jul 12 2014 8:02 UTC

Ok yes i saw it. I will check this out.

User Gravatar

cwirz

Posted Jul 20 2014 9:20 UTC

Solution

This didn't solve your task? Get your own custom solution.

Add a reply

By posting a reply on CodersClan you agree to our Terms & Conditions