Reputation: 1387
I have a Bootstrap modal that displays both Read and Unread messages from a database:
It shows a notification badge (see top) if there are unread messages. I've added a delete button, but can't figure out how to remove the entire div that contains that specific button, including the hr tag. The problem is that it only deletes the second div and hr tag you see there, but not the first. I even have an alert set up and it shows me the correct div id for the second. The first does nothing. This is what I tried. It's the code for the entire modal div:
<div id="messages_modal" class="modal fade" role="dialog">
<div class="modal-dialog modal-messages-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="modal_label">Messages
<button class="close" data-dismiss="modal">×</button>
</h4>
</div>
<div class="modal-body">
<?php
$subject = "";
$query = "SELECT id FROM `users` WHERE username=?";
if (!$stmt = $connection->prepare($query)) {
echo $stmt->error;
} else {
if (!$stmt->bind_param('s', $username)) {
echo $stmt->error;
} else {
$stmt->execute();
$stmt->bind_result($recip_id);
$stmt->fetch();
$stmt->close();
}
}
$query = "SELECT username, avatar, conversation_id, conversation_subject, time, msg_seen FROM `users` INNER JOIN `conversation` ON `users`.id = `conversation`.user_1
WHERE user_2 = ? ORDER BY time DESC";
if (!$stmt = $connection->prepare($query)) {
echo $stmt->error;
} else {
if (!$stmt->bind_param('i', $recip_id)) {
echo $stmt->error;
} else {
$stmt->execute();
$stmt->bind_result($sender_name, $avatar, $msg_id, $subject, $timestamp, $msg_seen);
while ($stmt->fetch()) {
$div_count++;
if ($msg_seen == 0) {
$notification_count++;
}
$subject = (strlen($subject) > 16) ? substr($subject, 0, 14) . '...' : $subject;
?>
STARTING POINT OF WHERE I WANT TO DELETE
<div id="msg_content_<?php echo $div_count;?>" class="msg-content">
<div class="avatar-container">
<a href="../pages/messages.php?id=<?php echo $msg_id; ?>" class="lighten"><img
src="<?php echo $avatar; ?>" class="msg-avatar"></a>
<div class="text-container">
<span class="show-sender"><?php echo $sender_name; ?></span>
<span class="show-msg-status"><?php
if ($msg_seen == 0) {
echo "Unread";
} else {
echo "Read";
}
?></span>
<br/>
<span class="show-msg"> Subject: <em><?php echo $subject; ?></em></span>
<button id="msg_delete_btn_<?php echo $div_count;?>" class="delete-btn">delete</button>
<br/>
<span class="show-timestamp"><?php echo date('D, F jS, Y h:i A', strtotime($timestamp)); ?></span>
</div>
</div>
</div>
<hr id="<?php echo $div_count;?>">
ENDING POINT OF WHERE I WANT TO DELETE
<?php
}
$stmt->close();
}
}
?>
</div>
</div>
</div>
Screenshot of what I need deleted:
Here is my jQuery. The alert shows me "msg_delete_btn_2", which is the correct dynamically generated id, but it this is only working for 2nd message.
$(document).ready(function () {
$('#msg_delete_btn_<?php echo $div_count;?>').click(function() {
$('#msg_content_<?php echo $div_count;?>').remove(); //<-- REMOVES DIV
$('#<?php echo $div_count;?>').remove(); //<-- REMOVES <hr> TAG
alert(this.id); //<-- SHOWS ME "msg_delete_btn_2" for 2nd div, which is correct. First div does nothing.
});
});
So, how can I access any div via the delete button? I tried giving the button and the div their own id by creating a count variable to no avail.
Upvotes: 0
Views: 164
Reputation: 54831
Your problem is that after all iterations of a while
, variable $div_count
holds the last value.
So, if you have two rows, your js code becomes:
$('#msg_delete_btn_2').click(/* other code */);
So your code knows nothing about other msg_delete_btn_
buttons.
The simple solution is to use class
instead, you already have it delete-btn
, or add another class:
$('.delete-btn').click(function() {
// remove following hr element which is after closest `div.msg-content` in which this button is
$( this ).closest( ".msg-content" ).next( "hr" ).remove();
// remove closest `div.msg-content` in which this button is
$( this ).closest( ".msg-content" ).remove(); // remove
// first `hr` then `div` because if you first
// delete `div` then `hr` WILL NOT BE FOUND
});
More sopisticated solution (if your markup will change) can be to store current $div_count
in a data
attribute of a button and generate proper ids
using it. Something like:
<button data-id="<?php echo $div_count;?>" class="delete-btn">delete</button>
$('.delete-btn').click(function() {
var itemId = $( this ).data( "id" );
$( "msg_content_" + itemId ).remove();
// more codes
Upvotes: 1
Reputation: 217
Try this one, It should work!
$(document).ready(function() {
$('.delete-btn').on('click', function() {
$(this).closest('.msg-content').next('hr').remove(); //<-- REMOVES <hr> TAG
$(this).closest('.msg-content').remove(); //<-- REMOVES DIV
});
})();
Upvotes: 1
Reputation: 9034
Use class
and remove the unnecessary id
tags.
You can use $(this)
to target the current element and the closest .msg-content
class.
$(document).on('click', '.delete-btn', function(){
$(this).closest('.msg-content').remove();
});
Another improvement:
No need to have hr
tags instead give the them a style of border-bottom:1px solid #d3d3d3;
.msg-content{border:1px solid #d3d3d3;}
.msg-content:last-child{border:1px solid transparent;} /* Hide border of last element */
Upvotes: 1