I'm looking for a little assistance, but mostly an explanation so I can avoid this issue in the future.
I have a PHP script that is called using AJAX. The output of that script is as follows:
<div id="schedule_wrapper_all>
<div class="appointments">
<div class="appt" value="2">
<p class="c_name">William Davis</p>
<div class="c_info" style="display: block;">
<p class="c_street">230 N State Rd</p>
<p class="c_city">Davison</p>
<p class="c_time">11:00:00</p>
<p class="c_phone">Phone 1: </p>
<p class="c_phone_alt">Phone 2: </p>
</div>
<div class="c_functions" style="display: block;">
<p><button type="button" class="view_notes">View Notes</button></p>
<div class="d_view_notes" style="display: none;"></div>
<p><button type="button" class="add_note">Add Note</button></p>
<p><button type="button" class="reschedule">Reschedule</button></p>
<p><button type="button" class="reassign">Reassign</button></p>
</div>
</div>
</div>
</div>
Here is the jQuery:
$('#schedule_wrapper_all').on('click', '.appointments .view_notes', function(e) {
e.stopPropagation();
var leadID = $(this).closest('.appt').attr('value');
$.ajax({
method: 'post',
url: 'scripts/get_notes.php',
data: {
'leadID': leadID
},
success: function(data) {
//===========================PROBLEMATIC AREA=============================
$('.d_view_notes').html(data);
$('.d_view_notes').slideToggle();
//========================================================================
}
});//end ajax - Fill Notes
});
get_notes.php:
<?php
include 'mysql_login_pdo.php';
include '../functions/db_functions.php';
$cond = array();
$params = array();
if ($_POST['leadID'] == '') {
return;
}
if (isset($_POST['leadID']) && $_POST['leadID'] != '') {
$leadID = $_POST['leadID'];
}
if (!empty($leadID)) {
$cond[] = 'id_lead = ?';
$params[] = "$leadID";
}
$query = "SELECT `leads_notes`.`message`, `leads_notes`.`created`, `status`.`status` FROM `leads_notes`,`status`";
if (count($cond)) {
$query .= ' WHERE ' . implode(' AND ', $cond);
}
$query .= ' AND `status`.`id` = `leads_notes`.`id_status`';
$query .= ' ORDER BY `created` DESC';
//echo $query;
$stmt = $db->prepare($query);
$stmt->execute($params);
$notes = '';
foreach ($stmt->fetchAll(PDO::FETCH_OBJ) as $row) {
$status = $row->status;
$message = $row->message;
$created = $row->created;
$notes .= '<div class="notes">';
$notes .= "<p>$status</p>";
$notes .= "<p>$created</p>";
$notes .= "<p class='note_text'>$message</p>";
$notes .= '</div><br/>';
}
$db = null;
print $notes;
The script works, except the data
filled by the AJAX call fills to all divs with the class 'd_view_notes', and there are multiple on the screen. What I want to happen is that when the button is clicked, it only fills the 'd_view_notes' contained within the selected 'appt' div.
After hours of trying, the closest I have come to getting the right selector is:
$(this).closest('.c_functions').children('.d_view_notes').html(data)
but is is not working. I would not only appreciate the right selector, but a quick explanation of WHY I need to choose that selector. Thanks!
If you need more information, I asked a question similar to this this morning: jQuery - Simple "on('click')" Selector Issue
I ended up adding a button to the 'c_functions' div and some jQuery to test the source code of 'd_view_notes':
...
<p><button type="button" class="reassign">Reassign</button></p>
<p><button type="button" id="view_source">Source</button></p>
...
And the jQuery:
$('#schedule_wrapper_all').on('click', '.appointments #view_source', function(e) {
e.stopPropagation();
alert($(this).closest('#schedule_wrapper_all > .appointments > .appt > .c_functions').find('.d_view_notes').html());
}); //This works, but only after the d_view_notes div is filled
Once the 'd_view_notes' div is filled with text, jQuery can detect the closest 'd_view_notes' html, and show the source code fine. For some reason, I can't fill the closest 'd_view_notes' div from my previous function though.
Does this one work?
$(this).closest('.c_functions').find('.d_view_notes').html(data).slideToggle();
The .closest('.c_functions')
returns the nearest .c_functions
ancestor of the clicked button, while the .find('.d_view_notes')
returns that element's descendants with class d_view_notes
. Also the slideToggle()
(as you used it) shows the element (because it currently have display: none
)
From what I understand, the div was not in the success callback. (credits to jakecigar). I had to capture the button before the AJAX call (as var that), and then pass 'that' to the 'success' callback.
Working Code:
$('#schedule_wrapper_all').on('click', '.appointments .appt .view_notes', function(e) {
e.stopImmediatePropagation();
var leadID = $(this).closest('.appt').attr('value');
var that = $(this).closest('#schedule_wrapper_all > .appointments > .appt > .c_functions').find('.d_view_notes');
$.ajax({
method: 'post',
url: 'scripts/get_notes.php',
data: {
'leadID': leadID
},
success: function(data) {
$(that).html(data).slideToggle();
}
});//end ajax - Fill Notes
});