Simultaneous AJAX submissions result in form cache not getting updated for the second submission.

First AJAX request enters with form_id: form-F33rMm15SpMLv373G_xn3hRopsteTfkhm70Wi1PceSw
New form is built with new form_id: form-JR1EXYiJjXD6F4YgT2Dkq_sd2oJcSQfr1g-9Ai8MDK4
Response contains

{
  "command": "update_build_id",
  "old": "form-F33rMm15SpMLv373G_xn3hRopsteTfkhm70Wi1PceSw",
  "new": "form-JR1EXYiJjXD6F4YgT2Dkq_sd2oJcSQfr1g-9Ai8MDK4"
} 

which updates form_build_id using update_build_id in ajax.js

update_build_id: function (ajax, response, status) {
  $('input[name="form_build_id"][value="' + response.old + '"]').val(response.new);
}

Second AJAX request enters with same original form_build_id as first form-F33rMm15SpMLv373G_xn3hRopsteTfkhm70Wi1PceSw
New form is built with form_id: form-CyMki8IJH0TDuqWVj3Hn0DMqrYvIoNyviLbKcJfosoc
Response contains

{
  "command": "update_build_id",
  "old": "form-F33rMm15SpMLv373G_xn3hRopsteTfkhm70Wi1PceSw",
  "new": "form-CyMki8IJH0TDuqWVj3Hn0DMqrYvIoNyviLbKcJfosoc"
} 

however as form_build_id was updated by first request, the input field is not found in update_build_id.

Proposed change is to update form_build_id without using value if only one form exists on the page.

update_build_id: function (ajax, response, status) {
  var build_ids = $('input[name="form_build_id"]');
  if (build_ids.length == 1) {
   $('input[name="form_build_id"]').val(response.new);
  } else {
    $('input[name="form_build_id"][value="' + response.old + '"]').val(response.new);
  }
},

or update the form_build_id without using value if one cannot be found with the value of response.old

update_build_id: function (ajax, response, status) {
  var old_build_id = $('input[name="form_build_id"][value="' + response.old + '"]');
  if (old_build_id.length == 0) {
    $('input[name="form_build_id"]').val(response.new);
  } else {
    $('input[name="form_build_id"][value="' + response.old + '"]').val(response.new);
  }
}

Repro steps:

  1. click two ajax buttons at the same time (the second button must be clicked before the first one finishes processing). refer to image 1
  2. search through the response of each ajax submission for "update_build_id" and copy that whole command somewhere for reference. refer to image 2
  3. compare two responses. they will have the same "old" build id. refer to image 3

alternatively, you can put a breakpoint at the update_build_id function in core/misc/ajax.js and inspect the response data.

Comments

Tyler_Rivard created an issue. See original summary.

Tyler_Rivard’s picture

This issue severely effects modules that modify the form like inline_entity_form.

Tyler_Rivard’s picture

cilefen’s picture

Status: Active » Needs review
Issue tags: +JavaScript

Please put code tags around the code samples in the issue summary.

The last submitted patch, 3: multipleAjaxCallsOption1-2871829-3.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 3: multipleAjaxCallsOption2-2871829-3.patch, failed testing.

sudhanshug’s picture

Issue summary: View changes