Executing Javascript in a Bootstrap 4 modal using Rails

I am working on a Rails 5.1 application where I'm implementing a patient record creation functionality using Ajax within a form using coffeescript/JS. The code I have been using for this task works seamlessly:

_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

Within the patient modal, I have incorporated bootstrap-datepicker to select a date of birth. Additionally, I have written some coffeescript to automatically calculate the age and populate it as shown 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

While adding a patient and displaying the modal, I am able to input details such as name, etc. However, after choosing the date of birth using the datepicker and allowing the coffeescript to calculate the age, the values appear in the fields until I close the bootstrap-datepicker. Upon closing, the entire modal form, including the first and last name fields, gets cleared.

Upon inspecting, I did not come across any errors in the console, and the coffeescript seems to be functioning correctly.

Being more proficient in Ruby than in Javascript/coffeescript, I am uncertain about the issue causing the input fields to clear, whether within my callback or in the calculation itself.

I would greatly appreciate any assistance. Despite researching and browsing through Stack Overflow, I have yet to resolve this minor functionality issue.

Update Upon disabling the bootstrap-datepicker and manually entering the date of birth, the coffeescript successfully calculated the age without clearing the entire form. Therefore, it appears to be an issue with the bootstrap-datepicker. However, I am uncertain about the underlying problem causing this.

Answer №1

After seeking assistance beyond Stack Overflow, I was directed to a helpful solution on this link.

I adapted my code as follows:

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

Hats off to Jacob M. for providing an additional set of Google eyes.

Answer №2

The reason for this behavior is that the datepicker's modal triggers the 'hide.bs.modal' event when closed, which then bubbles up to the '.patient-modal'. Find out more about event bubbling and capturing here.

To prevent this bubbling effect, you can use the event.stopPropagation() method on the datepicker's modal event.

Alternatively, you can specifically target the form in the event handler like so:

$form = $(e.target).find('#new_patient')
$form.trigger 'reset' if $form

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The server's request is being processed through jQuery's ajax functionality

Recently, I've started working with jQuery and AJAX. Essentially, the webpage sends an HTTP post request, and the server-side DLL responds by writing a JSON-formatted response back to the page. I'm trying to understand how to handle this response ...

When attempting to fetch JSON data using the Angular 2 `http.get()` method, the data returned is undefined and the component does not reflect any

My http-data.service is set up to accept json for output in the component template. Initially, the console displays that the first few calls return undefined, while subsequent calls start returning json. However, upon checking the component, it is evident ...

Activate the feature of smooth shading using Three.js

When rendering an object with textures using MTL and OBJ files in Three.js, I encountered an issue where my model was displayed with flat shading. How can I enable smooth shading? var scene = new THREE.Scene(); var mtlLoader = new THREE.MTLLoader(); mtl ...

Mongoose: No documents are being returned by the .find() method

UPDATE : Similar question posted here: Trouble with Mongoose find() method I'm still new to working with nodejs and nosql databases. Today, I am building an API that retrieves data from my user collection which currently has two entries : https://i. ...

Techniques for finding the total value of a JSON array

After retrieving values from a database, I am using them in JSON/javascript as an array. For example, see https://i.sstatic.net/nLzk9.png The issue arises when trying to calculate the sum of the array elements. I attempted to solve it with this code: v ...

The second JSP page fails to load following an AJAX POST request

The following code snippet is found in page1.jsp. $.ajax({ type: "post", url: "page2.jsp", data: newdata, success:function(msg){ return msg; } ...

Toastr - encountering a problem with the settings

After invoking a toastr message using the following command: Command: toastr["success"]("foo") toastr.options = { "closeButton": false, "debug": false, "newestOnTop": false, "progressBar": false, "positionClass": "toast-bottom-right", "prev ...

Looking for assistance in setting up an auto-suggest feature that displays retrieved or matched data from the database in a list format

I am currently facing an issue with the following problem: I have a form that includes a single search field with autosuggest functionality. I want to be able to type either a name or mobile number in this field. As I type, suggestions should appear base ...

Choosing a specific element within another element of the same type using JQuery

I've created a complex nested HTML structure shown below: <ul class="root"> <li>Foo 1 <label class="bar-class">bar</label> <ul> <li>Foo 2 <label class="bar-class">bar</label> ...

Utilize Vue.js and express.js to distribute HTML files securely

Currently, my tech stack includes Vue.js for the frontend and Express.js for the backend. When I kick off the express.js server using npm start, my goal is to serve the Vue frontend component. By utilizing the Vue generator and Express generator, I attemp ...

Surprising "unexpected end of line" JavaScript lint notification out of nowhere

In this simplified version of my JavaScript code: function addContent() { var content = []; content.append( makeVal({ value : 1 }) ); // lint message generated } After running a lint program, I received the followi ...

jquery counter is malfunctioning

I noticed a strange issue with the counters on my website. They count up as expected when the page loads, but for some reason, when the screen width shrinks below 800px, they don't start automatically. However, if I quickly scroll to where the counter ...

Google Sheets displaying blank values after submission via an AJAX call

I have been working on transferring data from my web app to a Google spreadsheet and I am encountering some issues. I followed the script provided by Martin Hawksey, which can be found here: https://gist.github.com/mhawksey/1276293 Despite setting everyth ...

Effectively generating observables that extract a designated element from a collection of observables

Within my application, I am utilizing a RxJS subject to broadcast changes within a collection. Each time the collection is updated, the subject emits the new contents as an array format. let collectionSubject = new Rx.BehaviourSubject(); collectionSubjec ...

Is there a way to utilize a POST request to pass a React component from server.js to App.js for rendering?

I am new to React and JavaScript and still in the learning process :) I'm working on a magic 8 ball application where, upon clicking the button using the post method, I aim to retrieve a random answer (one of the 20 in my server.js) back to the same ...

There was an issue with retrieving the image URL from the source, causing an error message to display: "

I encountered an error while trying to access my product. Here is the error message https://i.stack.imgur.com/fTmL0.png It seems that the image URL from the sanity database cannot be rendered, even though it worked fine in the tutorial I was following. I ...

Ways to eliminate an item in a JSON structure?

Allow me to elaborate. I received a JSON containing numerous objects: data = [{"id":"784","label":"blah","publisher":"me"},{"id":"785","label":"bleh","publisher":"you"},{"id":"786","label":"blih","publisher":"she"}]; For instance, I am looking to elim ...

The page is not able to be uploaded successfully, receiving a HTTP 200 status

Currently, my application is running in Express and I have a button that sends a POST request to the server. After receiving a 200 OK response, the HTML page is displayed. The issue I am facing is that even though I can see the HTML payload in Firebug, my ...

Using AngularJS to show content based on a callback function

I'm a beginner in angular and it seems like I might be overlooking something. For the registration form, I need users to provide their location. Depending on whether they allow/support navigator.geolocation, I want to display a drop-down menu for cho ...

Revive the JavaScript library for handling mouse wheel events

Utilizing the wheel-indicator JavaScript library, I am looking to revert the mouse wheel event back to its original state after it was initially set to preventDefault(). Despite attempting to use indicator.setOptions({preventMouse:"false"}) as suggested b ...