My application has to load a modal using Bootstrap 4.1 which contains a form that's generated dynamically upon loading the modal.
The form should submit using AJAX, however it submits as HTML even though the remote: true flag is set.
I understand that because the form wasn't present at the page's load, the Javascript event wasn't bound to it.
The form is added to the page via AJAX, so it's not present when all the even binding happens. The flow is:
- User clicks "Add new affiliation" and opens modal;
- User selects affiliation type;
- Based on affiliation type selected, a form is generated via AJAX and inserted into the modal that's already open.
- When the user clicks "Save", it's expected that the form should be submitted via AJAX, modal goes away and new affiliation is added to the list
In a situation like this, how can you bind the form to the JS event after loading the form? Or what would be the best way to have it submit remotely?
EDIT
So far, I found that, if the page loads directly in the main body and not with AJAX, it works and looks exactly the same as when in the modal.
In the modal, I tried running the submit from the console using a few ways:
$("#new_affiliation").trigger('submit'); Submits the form using HTTP
nativeFormEl = $("#new_affiliation")[0]; Rails.fire(nativeFormEl, 'submit'); Returns true, but does nothing
nativeFormEl = $("#new_affiliation")[0]; Rails.handleRemote.call(nativeFormEl); Submits the form using AJAX, but throws an exception:
TypeError: Cannot read property 'target' of undefined at Rails.stopEverything (application-785dee507ca17b63962581aa57866b38a001fd1a70d0bec06d994151a9cfc39a.js:160) at HTMLFormElement.Rails.handleRemote (application-785dee507ca17b63962581aa57866b38a001fd1a70d0bec06d994151a9cfc39a.js:629) at :1:20
At this point, I'm wondering, why is Rail.fire returning true, but not doing anything?
On the main page
<%= button_tag "New affiliation", type: :button, class: "btn btn-success", id: "new-affiliation-button" %>
Loading the modal:
$ ->
$("#new-button").on 'click', (evt) ->
url = 'some application path'
$.ajax url,
type: 'GET'
dataType: 'script'
data: {
}
error: (jqXHR, textStatus, errorThrown) ->
console.log("AJAX Error: #{textStatus}")
success: (data, textStatus, jqXHR) ->
$("#detail-modal").modal('show')
Load the form on controller's action success (new.js.erb)
$("#detail-form").html("<%= j render(partial: 'form') %>");
The form tag
<%= simple_form_for([@source, @skater, skater_affiliation], remote: true, authenticity_token: true, id: "affiliation-data") do |f| %>
The create action in controller
respond_to do |format|
if @source.valid?
format.html { redirect_to edit_source_path(@source) }
format.json { render "success" }
format.js { render "success" }
else
format.html { render "new" }
format.json { render "new" }
format.js { render "new" }
end
end
The rendered form
<form class="simple_form new_affiliation" id="new_affiliation" novalidate="novalidate" enctype="multipart/form-data" action="/affiliations" accept-charset="UTF-8" data-remote="true" method="post">
[some fields...]
<div class="row top-spacer-20">
<div class="col-12"><input type="submit" name="commit" value="Save" class="btn btn-default btn btn-success" data-disable-with="Save"></div>
</div>
</form>