nulltek nulltek - 10 months ago 101
CoffeeScript Question

Rails Executing Javascript in Bootstrap 4 modal

I have a Rails 5.1 application where I'm creating a patient record using Ajax inside of a form using coffeescript/JS. This works fine no problem using the following code:

_form.html.erb

<div class="modal fade patient-modal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="mySmallModalLabel">Add Patient</h4>
</div>
<div class="modal-body">
<%= form_for Patient.new do |f| %>
<div class="form-group">
<%= f.label :first_name %>
<%= f.text_field :first_name, class: "form-control" %>
<%= f.label :last_name %>
<%= f.text_field :last_name, class: "form-control" %>
<%= f.label :date_of_birth %>
<%= f.text_field :date_of_birth, class: "form-control", id: 'patient_dob_modal', placeholder: 'yyyy-mm-dd' %>
<%= f.label :age %>
<%= f.text_field :age, class: "form-control", id: 'patient_age_modal' %>
<%= f.label :sex %>
<%= f.text_field :sex %>
</div>
<div class="form-group">
<%= f.submit class: "btn btn-sm btn-primary" %>
</div>
<% end %>
</div>
</div>
</div>
</div>


application.js

$(document).on('turbolinks:load', function() {
$('#patient_date_of_birth_modal').datepicker({
format: 'yyyy-mm-dd',
zIndexOffset: 100000,
forceParse: false
});
});


patients.coffee

$(document).on 'turbolinks:load', ->
selectizeCallback = null
$('.patient-modal').on 'hide.bs.modal', (e) ->
if selectizeCallback != null
selectizeCallback()
selectizeCallback = null
$('#new_patient').trigger 'reset'
$.rails.enableFormElements $('#new_patient')
return
$('#new_patient').on 'submit', (e) ->
e.preventDefault()
$.ajax
method: 'POST'
url: $(this).attr('action')
data: $(this).serialize()
success: (response) ->
selectizeCallback
value: response.id
text: response.first_name
selectizeCallback = null
$('.patient-modal').modal 'toggle'
return
return
$('.patient').selectize create: (input, callback) ->
selectizeCallback = callback
$('.patient-modal').modal()
$('#patient_first_name').val input
return
return


In the patient modal I'm using bootstrap-datepicker to choose a date of birth, then I wrote some coffeescript to calculate the age and populate it automatically as seen in this code below in patients.coffee

$(document).on 'turbolinks:load', ->
getAge = (dateString) ->
today = new Date
birthDate = new Date(dateString)
age = today.getFullYear() - birthDate.getFullYear()
m = today.getMonth() - birthDate.getMonth()
if m < 0 or m == 0 and today.getDate() < birthDate.getDate()
age--
age

$('#patient_dob_modal').on 'change', ->
date = $(this).val()
age = getAge(date)
$('#patient_age_modal').val age
return
return


When I go to add a patient and the modal fires/shows up I can fill in the fields such as name, etc but when I choose the date of birth using the datepicker and let the coffeescript calculate the age it will show up in the fields until I dismiss the bootstrap-datepicker, then it will clear the entire modal form including the first and last name.

I see no errors in the console when I inspect and I do see the coffeescript executing properly.

I'm honestly not sure what the problem is with this as I'm not as well-versed in Javascript/coffeescript as I am in Ruby. I was wondering if there's something I'm doing wrong that's causing the input fields to clear either somewhere in my callback or in the calculation itself.

Any help would be greatly appreciated. I've googled and searched stack and found a few articles about executing JS inside of a modal and have yet to have success with this small piece of functionality.

Update I disabled the bootstrap-datepicker and just manually typed in the date of birth field and the coffeescript calculated without clearing out the entire form. So it looks to be like some issue with the bootstrap-datepicker. But I'm not sure where the problem lies.

Answer Source

After reaching out for help outside of Stack, I was pointed to https://github.com/uxsolutions/bootstrap-datepicker/issues/50#issuecomment-90855951

So I changed my code to this:

$(document).on('turbolinks:load', function() {
  $('#patient_date_of_birth_modal').datepicker({
    format: 'yyyy-mm-dd'
  }).on('hide', function(event) {
    event.preventDefault();
    event.stopPropagation();
  });
});

Thanks to Jacob M. for the extra pair of Google eyes.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download