[Answer]-How to load Django new dynamic content in a Jquery Dialog?

1👍

I did this not long ago in. I found it easier to send the errors in json, and then handle them client-side and attach them to the relevent fields. Like so:

  1. Use ajax to load the form from a view into the jQuery dialog box
  2. When the user sends the data send the information to same view
  3. If validation fails, send errors as a json array. Use js on client-side to attach them to the relevant fields
  4. If succeeds send a positive response of some kind

Check out this excellent example for reference

edit

Here’s a working example. Not sure I’m using the best methods to do this, but I think it’s pretty understandable. Also, I’m not accounting for the possibility of non-ajax form submit (it’s easy enough to do, some logical conditioning using form.is_ajax() and see example linked above for further reference).

So first the views (ContactForm is the same as the one linked):

import json
from django.http import HttpResponse
from django.shortcuts import render_to_response

def home(request):
    return render_to_response('index.html') #nothing special here


from django.views.decorators.csrf import csrf_exempt
from cStringIO import StringIO 

@csrf_exempt #you should use csrf, I'm just skipping this for the example
def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        response = {}

        if form.is_valid(): 
            response["status"] = "OK"
            # save the data, or do whatever.

        else:
            response["status"] = "bad"
            response.update(form.errors)

        # now just to serialize and respond
        s = StringIO()
        json.dump(response, s)
        s.seek(0)
        return HttpResponse(s.read())

    else:
        form = ContactForm() # An unbound form

    return render_to_response('contact.html', {
        'form': form,
    })

As you can see, if there’s nothing here you get an html with the form, if not, you get a json response with an object called response which contains ‘status’ and might also contain errors. I’m using StringIO with json.dump(data, file) as it has always proved the least buggy and most fluent way I ever used to serialize to json (seriously. You won’t believe how easily it can break).

Now let’s go over the client side:

base.html:

<html>
    <head>
         <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
          <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
          <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
          <link rel="stylesheet" href="http://getbootstrap.com/2.3.2/assets/css/bootstrap.css">
    </head>
    <body>

    {% block content %}
    {% endblock %}

    </body>
</html>

contact.html:

{% extends 'base.html' %}
{% block content %}
    <form method="post" id='myform'>
    {{ form.as_p }}
    </form>
{% endblock %}

and finally, the main.html with the relevant js. This is where the magic happens:

{% extends 'base.html' %}
{% block content %}

        <button class='btn'>Contact!</button>
        <div id="dialog-modal">
        </div>

    <script>
    $(function() {
        $('button').on('click', function() { 

            // first things firts, fetch the form into the dialog
            $('#dialog-modal').load('contact/ #myform');

            // initiate dialog
            $('#dialog-modal').dialog({
                  height: 450,
                  modal: true,

                  // I'm using the built-in buttons, but you can use your own
                  buttons: {
                        Send: function() { 
                            var dialog = $(this), 
                                form = $('#myform'),
                                data = form.serialize();

                        $('.off').remove(); // this is to avoid duplicates

                        // run ajax post call
                        $.ajax({ 
                            url: 'contact/',
                            data: data,
                            type: 'post',

                            // if successful print response
                            success: function(response) {
                                res = $.parseJSON(response);

                                // if form was successful:
                                if (res['status'] == 'OK') {
                                    // form was successful
                                    alert('Thank you! Form has been submitted'); // say thank you
                                    dialog.dialog('close'); // close dialog
                                }

                                // if not... 
                                else if (res['status'] == 'bad') {
                                    delete res['status'] // we don't need this anymore...
                                    var errors = res; // just for simplicity

                                    $.each(errors, function(key, value) {
                                        // i.e. key='subject' and value is the error message itself

                                        var err = $('<span></span>', {
                                                        'class': 'off',
                                                        'text': value
                                                }),
                                            br = $('<br></br>', {
                                                'class': 'off',
                                            }),
                                            input = $('#id_'+key).parent(); //find the parent div for the relevant input by key

                                        // add a small break
                                        br.appendTo(input);

                                        // add the error
                                        err.appendTo(input);

                                        // add some styling
                                        err.css('color', 'red').css('font-size', '10px');

                                    });
                                }
                            }

                          });

                        }
                      }
                });


        });
    });
    </script>
{% endblock %}

Hope that’s not too much. Here’s an image how it looks after attempting to send:

enter image description here

Pick it up from here. There’s a lot of room to play around and extend this.
Good luck!

👤yuvi

Leave a comment