0

I use the below template to create a list of some object cards. Each card has a unique doctor id and a button to book appointment. When I click the button, it works well for the first card. Then when I click the other cards, first it sends request with the clicked card's doctor id and then with the previous cards' ids. Is this issue caused by the change event? How to solve it?

function getDoctorTemplate(doctor){
    const $template = $($('#doctor-template').html());
    $template.find('#template-doctor-name').text(doctor.name);
    $template.find('#template-doctor-contacts').text(doctor.contactDetails);
    $template.find('#book-appointment').click(function(){
        console.log("doc id ",doctor.id);
        $('#appointment-date').change(function(){
            let doctorId = doctor.id;
            let date = $('#appointment-date').val();
            $.ajax({
                url:"schedule/doctor/search",
                method:"GET",
                data:{
                    doctorId: doctorId,
                    date: date
                },
                success: function(data){
                    console.log(data);
                    if(data.length != 0){
                        $('#appointment-hour-select').empty();
                        for(let i=data.fromHour;i<data.toHour;i++){
                            $('#appointment-hour-select').append($('<option>', {
                                value: i,
                                text: (i<10?"0"+i+":00":i+":00")
                            }));
                        }
                    }else{
                        alert("Schedule not available yet!");
                    }
                    if(data == null){
                        alert("Schedule not available yet!");
                        clearModal();
                    }
                },
                fail: function(){
                    alert("Schedule search completed with fail!")
                }
            });
        });
        clearModal();
    });
    return $template;
}

enter image description here enter image description here

Doctor with id 34 has no item with the selected date, so it returns empty data, then the select is filled with the data of the first request. I want to "forget" the first requests data. Is this possible? When I use off or unbind for the change, the code does not work.

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css" rel="stylesheet">
    <link href="https://code.jquery.com/ui/1.13.0/themes/base/jquery-ui.css" rel="stylesheet"></link>

    <title>MyDoc</title>
  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-light" style="background-color: #e3f2fd;">
        <div class="container-fluid">
          <a class="navbar-brand" href="#">MyDoc.com</a>
          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
          </button>
          <div class="collapse navbar-collapse" id="navbarText">
            <ul class="navbar-nav me-auto mb-2 mb-lg-0">
              <li class="nav-item">
                <a class="nav-link active" href="patients.html">Doctors</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" aria-current="page" href="schedule.html">Schedule</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="patients.html">Patients</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="profile.html" active>Profile</a>
              </li>
            </ul>
            <span class="navbar-text">
              <a class="nav-link" href="#" id="logout">Logout</a>
            </span>
          </div>
        </div>
    </nav>
    <div class="container-fluid col-md-10 mt-3">
        <div class="row mt-3 mt-md-5">
            <div class="col-12 col-md-4">
              <div class="card mt-2 mt-md-0">
                <div class="card-body">
                  <h5 class="card-title mt-3">Search</h5>
                  <form>
                    <div class="mb-3">
                        <input id="search-doctor-location" class="form-control w-50 d-inline" type="text" placeholder="Location">
                    </div>
                    <div class="mb-3">
                        <input id="search-doctor-specialty" class="form-control w-50 d-inline" type="text" placeholder="Specialty">
                    </div>
                    <div class="mb-3">
                        <button id="find-doctors" type="button" class="btn btn-primary w-25 d-inline">Find</button>
                        <button id="hide-search-doctors-results" type="button" class="btn btn-primary w-25 d-inline d-none">Hide</button>
                    </div>
                  </form>
                </div>
            </div>           
           </div>
            <div class="col">
              <div class="card mt-2 mt-md-0 d-none" id="search-doctor-results-card">
                <div class="card-body">
                  <div class="d-flex justify-content-between align-items-center mb-2">
                    <h5 class="card-title">Results from search</h5>
                  </div>
                  <hr/>
                  <p id="search-doctors-results-to-show" class="d-none">No results to show</p>
                  <div id="doctors-search-list" class="row">
                        
                  </div>
                </div>
              </div>
                <div class="card mt-2 mt-md-0">
                    <div class="card-body">
                      <div class="d-flex justify-content-between align-items-center mb-2">
                        <h5 class="card-title">Results</h5>
                      </div>
                      <hr/>
                      <p id="doctors-results-to-show" class="d-none">No results to show</p>
                      <div id="doctors-list" class="row">
                        
                      </div>
                    </div>
               </div>
        </div>
    </div>
    
    <!-- Book Appointment Modal -->
    <div class="modal fade" id="bookAppointmentModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
      <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">Add schedule</h5>
            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
          </div>
          <div class="modal-body">
            <div class="row g-3 align-items-center">
              <div class="col-auto">
                <label class="form-label">Select date</label>
              </div>
              <div class="col-auto">
                <input id="appointment-date" class="form-control w-75 d-inline" type="text">
              </div>
            </div>
            <div class="mt-3 row g-3 align-items-center">
              <div class="form-floating">
                <select class="form-select" id="appointment-hour-select" aria-label="Floating label select example">
                  <!-- <option value="1">01:00</option>
                  <option value="2">02:00</option>
                  <option value="3">03:00</option> -->
                </select>
                <label for="appointment-hour-select">Appointment hour</label>
              </div>
            </div>
            <div class="mt-3 row g-3 align-items-center">
              <div class="mb-3 ">
                <label for="condition" class="form-label">Health condition / Reason:</label>
                <textarea class="form-control" id="condition" name="condition"></textarea>
              </div>
            </div>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="close-appointment">Close</button>
            <button type="button" class="btn btn-primary" id="book-appointment">Book</button>
          </div>
        </div>
      </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://code.jquery.com/ui/1.13.0/jquery-ui.min.js" integrity="sha256-hlKLmzaRlE8SCJC1Kw8zoUbU8BxA+8kR3gseuKfMjxA=" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment-with-locales.min.js"></script>
    <script src="js/main.js"></script>
    <script src="js/doctors.js"></script>

    <div id="doctor-template" class="d-none">
        <div class="card border-info mb-3" style="height: fit-content;">
            <div class="row g-2">
              <div>
                <div class="card-body row">
                  <div class="col-md-10">
                    <h5 id="template-doctor-name" class="d-inline"></h5>
                    <div id="template-doctor-age" class="text-muted d-inline"></div>
                    <div id="template-doctor-experience" class="d-inline text-muted">
                    </div>
                    <div>
                        <h6 class="d-inline text-muted">Specialties:</h6>
                        <h6 id="template-doctor-specialties" class="d-inline">
                        </h6>
                        <div>
                            <h6 id="template-doctor-location" class="d-inline"></h6>
                        </div>
                        <hr>
                        <div id="template-doctor-overview" class="card-text"></div>
                    </div>
                  </div>
                  <div class="col justify-content-end">
                    <div class="">
                        <div class="d-flex justify-content-end align-items-center">
                            <button id="book-appointment" type="button" class="btn btn-outline-info" data-bs-toggle="modal" data-bs-target="#bookAppointmentModal">Book now</button>
                        </div>
                        <div class="text-end">
                            <p class="text-muted">
                            <small>Contact details:</small>
                            <small id="template-doctor-contacts">
                            </small>
                            </p>
                        </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
        </div>
    </div>

  </body>
</html>
Enchantres
  • 853
  • 2
  • 9
  • 22
  • 1
    It's difficult to find the problem without having your `html` code, but there is one problem in your code, you are defining `change` event handler ` $('#appointment-date').change(function(){...}` everytime `#book-appointment` has clicked, it cause adding a `change` event listener to `#appointment-date` with every click on `#book-appointment`. – Saeed Shamloo Dec 12 '21 at 19:17
  • How can I remove the change event listener so it cannot be appended to every click? – Enchantres Dec 12 '21 at 19:29
  • Why don't you define it before or after you set onClick for `#book-appointment` ? – Saeed Shamloo Dec 12 '21 at 19:32
  • I set it before and the behaviour has not been changed. Still shows all the ids. – Enchantres Dec 12 '21 at 19:42
  • Could include your html code. – Saeed Shamloo Dec 12 '21 at 20:08
  • It is included now. – Enchantres Dec 12 '21 at 20:37
  • Far too much code here that isn't relevant to the specific problem. Please try to scale it down to a [mre] – charlietfl Dec 12 '21 at 21:28
  • "*I use the below template to create a list of some object cards*" - does it mean you are duplicating `$template`, which is `#doctor-template`, multiple times on the page? If yes, that's the (or at least *one*) problem - HTML IDs must be unique. https://stackoverflow.com/questions/11114622/jquery-id-selector-works-only-for-the-first-element – Don't Panic Dec 13 '21 at 02:22
  • I have found that I have button with the same id two times. – Enchantres Dec 13 '21 at 19:03
  • OK, let's close this as a duplicate then ... – Don't Panic Dec 13 '21 at 21:38
  • Does this answer your question? [jQuery ID selector works only for the first element](https://stackoverflow.com/questions/11114622/jquery-id-selector-works-only-for-the-first-element) – Don't Panic Dec 13 '21 at 21:38

0 Answers0