0

I have a form I'm trying to submit the data via AJAX & jQuery to an Django API. Submission through the Django admin works fine but through the form, the textarea field is the one cause problems. I have a similar form without the textarea and it works fine. The textarea content is not being submitted and I don't know why. Here is the form:

<form id="addMaintenanceRecordsForm" action="">
    {% csrf_token %}
    <div class="mb-3">
        <div class="row">
            <div class="col-md-12">
                <label>Title <span style="color: #dd0000;">*</span></label>
                <input type="text" class="form-control" name="maintenance_title" placeholder="Enter Title" id="mr-title" required>
            </div>
        </div>
    </div>
    <div class="mb-3">
        <div class="row">
            <div class="col-md-12">
                <label>Details <span style="color: #dd0000;">*</span></label>
                <textarea class="form-control" id="mr-summary" name="summary" placeholder="Describe the nature of maintenance repair..." rows="3" required></textarea>
            </div>
        </div>
    </div>
    <div class="mb-3">
        <div class="row">
            <div class="col-md-12">
                <label>Repair Status <span style="color: #dd0000;">*</span></label>
                <select class="form-select" name="repair_status" id="mr-status" aria-label="Default select example" placeholder="Repair Status" required>
                    <option selected disabled>Choose...</option>
                    <option value="Complete">Complete</option>
                    <option value="Ongoing">Ongoing</option>
                </select>
            </div>
        </div>
    </div>
     
    <button type="submit" class="btn btn-soft-primary btn-sm" id="mr-create">Create New Record</button>
    <button type="button" class="btn btn-soft-secondary btn-sm">Cancel</button>
</form>

This is my jQuery code

$(function() { 
        $('#addMaintenanceRecordsForm').on('submit', function(e) { 
            e.preventDefault();

            console.log($("#addMaintenanceRecordsForm").serializeArray());

            let url = "http://127.0.0.1:8000/api/maintenance/add/";

            $.ajax({
                type : 'POST',
                url : url,
                data : $("#addMaintenanceRecordsForm").serializeArray(),
                dataType: "json",
                success: function(data){
                    alert("New Maintenance Records Added!");
                    location.reload();
                },
                error:function(data){
                    alert("Maintenance Records Not Added!");
                    location.reload();
                }
            });

        });
    });

I keep getting this error:

Bad Request: /api/maintenance/add/
POST http://127.0.0.1:8000/api/maintenance/add/ 400 (Bad Request)

On the console i get this:

{
    "name": "csrfmiddlewaretoken",
    "value": "jZ7Y2WrJB67xrkP34U53ngf11cu4ju1nvzlQ29Krtqv5ehkjuami0uwvyCrFdXAs"
}
{
    "name": "maintenance_title",
    "value": "Pipe Leakages"
}
{
    "name": "summary",
    "value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
}
{
    "name": "repair_status",
    "value": "Ongoing"
}

And the django CMD i get back a dictionary like this

<QueryDict: {'csrfmiddlewaretoken': ['LmbrIAnh7fJcAjjQ0hnEiwSujdFTJfLgXWpjINGZZz7KngO6qxETVK9YQDCuDIkl'], 'maintenance_title': ['Pipe Leakages'], 'summary': ['Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'], 'repair_status': ['Ongoing']}>

I have tried other solutions like:

data : $("#addMaintenanceRecordsForm").serialize(),

or

data : $("#addMaintenanceRecordsForm input, #addMaintenanceRecordsForm textarea").serializeArray(),

or

data : $("#addMaintenanceRecordsForm").find('input', 'select').serializeArray(),

or

$('#mr-create').on('click', function(e) { 
    e.preventDefault();

But they all don't seem to work. What could be the problem with the textarea not serializing?

CoderS
  • 143
  • 1
  • 8
  • You said it's returning 400 Bad Request, do you have Debug Mode on? If so can you hit the same API with Postman and see what it returns? Django Debug mode should help return more information. – Mark Barrett Oct 20 '21 at 12:34
  • @MarkBarrett Debug mode is ON. I did as you recommended and postman returns `"maintenance_title":["This field is required."],"summary":["This field is required."],"repair_status":["This field is required."]}` followed by `Bad Request: /api/maintenance/add/ [20/Oct/2021 18:13:55] "POST /api/maintenance/add/ HTTP/1.1" 400 301` I'm not sure if that's the info you asking for. I have entered new raw data through postman and it works. So the endpoint works just fine in my view. Even `http://127.0.0.1:8000/api/maintenance/add/` works as well. – CoderS Oct 20 '21 at 15:32
  • @MarkBarrett I read other articles on SO like this: [source 1](https://stackoverflow.com/questions/61201405/post-by-jquery-serialize-serializearray-excluding-textarea), [source 2](https://stackoverflow.com/questions/16827543/jquery-textarea-in-form-not-serialized) or [source 3](https://stackoverflow.com/questions/17709014/jquery-serialize-leaves-out-textarea/25071903) but no solution yet. Its the textarea that's the problem. I have done close through 5 forms today for different functionalities and none had a textarea and they all work perfectly. This is the first one with a textarea. – CoderS Oct 20 '21 at 15:32
  • Are you using Django REST? – Mark Barrett Oct 20 '21 at 15:37
  • @MarkBarrett yes I am. I'm from doing a simple experiment. I changed the – CoderS Oct 20 '21 at 15:48

1 Answers1

0

In your code you are showing that you are printing the form to the console like this:

console.log($("#addMaintenanceRecordsForm").serializeArray());

You said that it results in an output like this:

{
    "name": "csrfmiddlewaretoken",
    "value": "jZ7Y2WrJB67xrkP34U53ngf11cu4ju1nvzlQ29Krtqv5ehkjuami0uwvyCrFdXAs"
}
{
    "name": "maintenance_title",
    "value": "Pipe Leakages"
}
{
    "name": "summary",
    "value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
}
{
    "name": "repair_status",
    "value": "Ongoing"
}

If it's a JSON API using Django REST you still need a similar structure to this:

{
    "csrfmiddlewaretoken": "jZ7Y2WrJB67xrkP34U53ngf11cu4ju1nvzlQ29Krtqv5ehkjuami0uwvyCrFdXAs",
    "maintenance_title": "Pipe Leakages",
    "summary": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
    "repair_status": "Ongoing"
}

The reason you are getting a 400 Bad Request is because the JSON you are sending has no key at the top level for each of those fields meaning Django REST can't find them.

I'd suggest maybe looking into what serializerArray actually does as it might not be what you are looking for.

Instead I'd suggest maybe constructing the the JSON object in the JavaScript using the value from each field of the form, like:

{
   "maintenance_title": $("#mr-title").value(),
   "repair_status": $("#mr-status").value()
}

Or perhaps try using the ".serialize()" again to see what it prints to the console then. The fact you are getting a Bad Request and it's saying all fields are missing means it's not just happening with the Textarea.

To test, construct your own object in Postman thats similar to what I have and see if the errors go away.

Mark Barrett
  • 366
  • 2
  • 16
  • I created my own object on postman and there was no error on submission. I replaced `serializeArray()` with `serialize()` in the console.log and i got `csrfmiddlewaretoken=5ya3MJFvKS9V190RkB50t5hVLk4sJFS0h8oVMWYdCcxtO6v7KRmf6jypiK13D8r5&maintenance_title=New%20Paint&summary=Lorem%20ipsum%20dolor%20sit%20amet%2C%20consectetur%20adipiscing%20elit%2C%20sed%20do%20eiusmod%20tempor&repair_status=Ongoing` – CoderS Oct 20 '21 at 18:10
  • and on the django server i received `` I created my own JSON object like `data: {"maintenance_title": $("#mr-title").val(), "summary": $("#mr-summary").val(),"repair_status": $("#mr-status").val()}` but the form is still not submitting. I'm still getting a 400 error. – CoderS Oct 20 '21 at 18:11
  • Okay. Can you try constructing your own object in the JS like I showed above – Mark Barrett Oct 20 '21 at 18:11
  • i did that `data: {"maintenance_title": $("#mr-title").val(), "summary": $("#mr-summary").val(),"repair_status": $("#mr-status").val()} but the form is still not submitting. I'm still getting a 400 error.` – CoderS Oct 20 '21 at 18:14
  • And in that case what did the server receive? – Mark Barrett Oct 20 '21 at 18:56
  • {'csrfmiddlewaretoken': ['5ya3MJFvKS9V190RkB50t5hVLk4sJFS0h8oVMWYdCcxtO6v7KRmf6jypiK13D8r5'], 'maintenance_title': ['New Paint'], 'summary': ['Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor'], 'repair_status': ['Ongoing']} – CoderS Oct 20 '21 at 20:40
  • I figured out the problem! It was with my model. The summary was `summary = models.CharField(max_length=255, verbose_name='Summary')` instead of `summary = models.TextField(verbose_name='Summary')` It now works. I can't believe this has taken me a whole week to figure out. – CoderS Oct 23 '21 at 10:40