Only slideUp the deleted message - javascript

I'm using a PM system and added the delete-message feature. I've got a form which checks for the message_id and message_title. The form posts to delete_message.php page which contains the query to delete the message. This has been done via Javascript as I dont want the page to refresh.
I've got two functions for this:
function deleteMessage() {
$.ajax({
url: "message/delete_message.php",
type: "POST",
data: $("#delMsgForm").serialize(),
success: function(data,textStatus,jqXHR){ finishDeleteMessage(data,textStatus,jqXHR); }
});
}
function finishDeleteMessage( data , textStatus ,jqXHR ) {
$(".inboxMessage").slideUp('slow');
}
Currently when I click on the delete button (image of a trashcan) it deletes the message without reloading the page, as a finishing touch, it slidesUp the divclass (inboxMessage) the message is in. Since I tell it to slide up this class, it slides up every message. This is my piece of code containing the classes and the form:
<div class="inboxMessage">
<div class="inboxMessageImg NoNewMsg"></div>
<div class="inboxMessageHeader">
<a id="ajax" class="inboxMessageLink" onclick="showMessage('.$row['message_id'].')">'.$row['message_title'].'</a>
<p class="inboxMessageStatus Read">'.$inboxMessageStatus_Read.'</p>
</div>
<div class="inboxMessageDescription">'.$inboxMessageDescription.'</div>
<div class="inboxMessageActions">
<form id="delMsgForm" name="delMsgForm" action="message/delete_message.php" method="post">
<input type="hidden" id="msgTitle" value="'.$row['message_title'].'" name="message_title">
<input type="hidden" id="msgID" value="'.$row['message_id'].'" name="message_id">
</form>
<input type="submit" id="ajax" value="" name="deleteMessageButton" class="deleteMessageIcon" onclick="deleteMessage()">
</div>
</div>
What I want it to do is to slideUp only the message which has just been deleted by the user. I know this has to be done by telling javascript to only slideUp the deleted message which contains the message_id and/or message_title.
I've tried several things, but no love whatsoever. I'm also not that familiar with javascript/ajax. Any help would be highly appreciate.
Cheers :)

where do you call deleteMessage from? indirect the function call through another function which knows the parent of your "trash can", and can call slide up on that specific one.
function deleteMessage (element) {
//element will be clicked button
var container = $(element).closest("div.inboxMessage"),
//container div including the trashcan
$.ajax({
url: "message/delete_message.php",
type: "POST",
data: $("#delMsgForm").serialize(),
success: function(data,textStatus,jqXHR){
finishDeleteMessage(container);
}
});
});
and this will be your button
<input type="submit" id="ajax" value="" name="deleteMessageButton" class="deleteMessageIcon" onclick="deleteMessage(this)">

Apparently, you've got more divs with class inboxMessage. Since you're adding this code:
$(".inboxMessage").slideUp('slow');
.. all divs with that class will remove. If you want just one div to remove, give it a unique ID or data-attribute and hide it that way.
For example: add the message-id to the div..
<div class="inboxMessage" id="(message_id)">
..and use..
$(".inboxMessage#message_id").slideUp('slow');
.. to slide up the right div.
Edit:
Add your message ID to the div and to the function deleteMessage(), so it will be deleteMessage(message_id).
function deleteMessage(message_id) {
$.ajax({
url: "message/delete_message.php",
type: "POST",
data: $("#delMsgForm").serialize(),
success: function(){ finishDeleteMessage(message_id); }
});
}
function finishDeleteMessage(message_id) {
$(".inboxMessage#"+message_id).slideUp('slow');
}

Related

How to receive AJAX (json) response in a divs with same class name individually?

I've been getting crazier day after day with this, I can't find an answer, I've spent like 100h+ with this... I hope someone could help me out!
UPDATE:
So to make myself more clear on this issue and be able to get help from others, I basically have 3 containers named "main-container" they all have 3 containers as childs all with the same class name, and when I submit the button, I trigger an ajax function to load the JSON strings comming from php into the child divs, the problem is that I get the 3 "main_containers" to load the ajax at the same time, I only want to load the ajax if I press the button of each "main_container" individually.
I've been using jquery and vanilla JS as well but seems I just can't get it done!
This is how I currently trigger the button with jquery:
$('.trigger_button_inside_divs').click(my_ajax_function);
And this is how my ajax looks like:
function my_ajax_function(){
$.ajax({
dataType: "JSON",
type: 'POST',
url: test.php,
success: function(data) {
$('.div_to_render_JSON_1').html(data.PHP_JSON_1_RECEIVED);
$('.div_to_render_JSON_2').html(data.PHP_JSON_2_RECEIVED);
$('.div_to_render_JSON_3').html(data.PHP_JSON_3_RECEIVED);
}
});
}
HTML looks like this:
<div class="main_container">
<div class="my_div">
//div_to_render_JSON_1
</div>
<div class="my_div">
//div_to_render_JSON_2
</div>
<div class="my_div">
//div_to_render_JSON_3
</div>
<button class="trigger_ajax_function_btn">Click to load ajax</button> //this btn loads ajax into the div class "my_div"
</div>
<div class="main_container">
<div class="my_div">
//div_to_render_JSON_1
</div>
<div class="my_div">
//div_to_render_JSON_2
</div>
<div class="my_div">
//div_to_render_JSON_3
</div>
<button class="trigger_ajax_function_btn">Click to load ajax</button> //this btn loads ajax into the div class "my_div"
</div>
<div class="main_container">
<div class="my_div">
//div_to_render_JSON_1
</div>
<div class="my_div">
//div_to_render_JSON_2
</div>
<div class="my_div">
//div_to_render_JSON_3
</div>
<button class="trigger_ajax_function_btn">Click to load ajax</button> //this btn loads ajax into the div class "my_div"
</div>
So in conclusion, each of those 6 "divs" has a button that triggers an function containing my ajax to render inside that particular div. But what I get is that every time I click that triggering button, I get the ajax to render in all of the 6 divs, instead of render on each particular div only when I click its particular button.
Thanks a lot people, I really hope to get this done!
Cheers.
PD:
This is something a programmer did to achieve what I'm trying to achieve but I just can't figure out what in this code is that is making possible clicking 1 button and affect THAT html element , even though they all have the same class.
(function(){
$("form input[type=submit]").click(function() {
$("input[type=submit]", $(this).parents("form")).removeAttr("clicked");
$(this).attr("clicked", "true");
});
var xhr = new XMLHttpRequest();
var el;
function SetDataInTheForm()
{
var resp = JSON.parse(xhr.response)
var pt=0
var ct=0
var gt=0
Array.prototype.forEach.call(el.querySelectorAll(".test"),function(e,i){
e.innerHTML=resp[i].name
})
Array.prototype.forEach.call(el.querySelectorAll(".p"),function(e,i){
e.innerHTML=parseFloat(resp[i].p).toFixed(0)
pt+=parseFloat(resp[i].p)
})
Array.prototype.forEach.call(el.querySelectorAll(".c"),function(e,i){
e.innerHTML=parseFloat(resp[i].c).toFixed(0)
ct+=parseFloat(resp[i].c)
})
Array.prototype.forEach.call(el.querySelectorAll(".g"),function(e,i){
e.innerHTML=parseFloat(resp[i].g).toFixed(0)
gt+=parseFloat(resp[i].g)
})
el.querySelector(".wtp").innerHTML=parseFloat(resp[0].total).toFixed(0)+" "+resp[0].unit
el.querySelector(".wtc").innerHTML=parseFloat(resp[1].total).toFixed(0)+" "+resp[1].unit
el.querySelector(".wtg").innerHTML=parseFloat(resp[2].total).toFixed(0)+" "+resp[2].unit
el.querySelector(".pt").innerHTML=pt.toFixed(0)
el.querySelector(".ct").innerHTML=ct.toFixed(0)
el.querySelector(".gt").innerHTML=gt.toFixed(0)
}
function HandleSubmit(e)
{
el=e.currentTarget
e.preventDefault();
xhr.open("POST","/url_here.php",true)
xhr.setRequestHeader("content-type","application/x-www-form-urlencoded")
xhr.onload=SetDataInTheForm
var button=e.currentTarget.querySelector("input[type=submit][clicked=true]")
button.removeAttribute("clicked")
xhr.send($("#"+e.currentTarget.id).serialize()+"&"+button.getAttribute("name")+"=on")
}
[].forEach.call(document.querySelectorAll("._form_"),function(form){
form.addEventListener("submit",HandleSubmit,false);
})
})()
Remember that $('.div_container_to_render_JSON') is a new selector that selects all elements with a class div_container_to_render_JSON. What you want to happen is figuring out where that click came from, and find the corresponding div_container_to_render_JSON.
Luckily for you, a jQuery click handler sets the this keyword to the HTMLElement where the click was captured. You can use this to get the parent element.
$('.your-button').on('click', function () {
const myButton = $(this);
$.ajax({
// ...
success (data) {
myButton.parent().html(data.PHP_JSON_RECEIVED);
// or if you need to find a parent further up in the chain
// myButton.parents('.div_container_to_render_JSON').html(data.PHP_JSON_RECEIVED);
}
});
});
The problem is that your class selector is indeed selecting all your divs at the same time.
Solution, set identifiers for your divs as such:
<div class="my_div" id="my_div_1">
and then you can use those id's to fill in the data:
$('#my_div_1').html(data.PHP_JSON_1_RECEIVED);
and repeat for your 6 divs (notice the change from class selector '.' to identifier selector '#')
Thanks for the replies people. I finally figured it out after days of hard work, it was something really simple.. here's the answer:
$('.trigger_button_inside_divs').click(my_ajax_function);
var thisButton = $(this);
var thisDiv = thisButton.closest(".main_container");
function my_ajax_function(){
$.ajax({
dataType: "JSON",
type: 'POST',
url: test.php,
success: function(data) {
thisDiv.find('.div_to_render_JSON_1').html(data.PHP_JSON_1_RECEIVED);
thisDiv.find('.div_to_render_JSON_2').html(data.PHP_JSON_2_RECEIVED);
thisDiv.find('.div_to_render_JSON_3').html(data.PHP_JSON_3_RECEIVED);
}
});
}

How can I improve my Ajax?

I'm trying to figure out if what I'm doing is the right way. I have a comment form and when it gets clicked I'm appending the comment into a div element through Ajax. When the page is refreshed then of course that would disappear and instead of it I have a foreach loop that runs and echos the comments. Since they both have the same CSS attributes they look the same to the user. The reason I'm doing it this way is because the foreach loop gets updated only after a refresh. Is there a better way? Can I update the page directly from the database without refresh? I basically need that every time a user clicks on the comment button that the foreach loop will run again but I couldn't find how to do it. I feel like I'm covering a gun shot with bandage the way I do it at the moment.
Loop:
#foreach($comment as $comments)
#if($comments->image_id == $image->id)
<div id="{{$comments->id}}" class="col-md-5 ajaxrules">
<div class="deletecomment">
<i class="fa fa-trash-o"></i>
</div>
<div class="col-md-2">
<img src="{{$comments->user_avatar}}" class="img-circle buddy">
</div>
<div class="hello col-md-10">
<h4>{!! $image->user_name !!}</h4>
<p class="left">{!!$comments->body!!} </p>
</div>
</div>
#endif
#endforeach
//Where I append the comments through Ajax until the refresh that replaces it with the loop
<div class="man">
</div>
Ajax:
<script>
$(document).ready(function(){
$('.send-form').click(function(e){
e.preventDefault();
var username = "{{ $username }}";
var one = $('textarea[id="{{$image->id}}"]').val();
var value = "{{$image->id}}";
var begin = '<div class="col-md-5 addavatar">'+'<div class="deletecomment">'+'<i class="fa fa-trash-o">'+'</i>'+'</div>'+'<div class="col-md-2">'+'<img src="{{$profile}}" class="img-circle">'+'</div>'+'<div class="hello col-md-10">'+'<h4>' + username +'</h4>'+'<p>'+one+'</p>'+'</div>'+'</div>';
if(one.length > 0){
console.log(username);
$('textarea[id="{{$image->id}}"]').val('');
$.ajax({
url: 'comment',
type: "post",
beforeSend: function (xhr) {
var token = $('meta[name="csrf_token"]').attr('content');
if (token) {
return xhr.setRequestHeader('X-CSRF-TOKEN', token);
}
},
data: {'id': value, 'comment': one},
success:function(data){
$( ".man" ).append([begin]);
},error:function(){
console.log("error!!!!");
}
});
}
});
});
</script>
You are killing yourself.
Manipulate the DOM via javascript code like you do it's really hard work!
You are not suppose to write html inside javascript strings, there must be another way!
And there is... Welcome to AngularJS!
In angular you can write your html and assign a javascript controller to it, perform ajax request and after the ajax complete you can bind the returned data to the html automatically! That means the angular refresh your html and do all the work for you. Even perform loop of let's say, row in a table, etc...

Jquery AJAX id selector and post with change class

I have one question. I am trying to make a ajax post with id and also trying to change the class which data-id selected.
I have created this DEMO from codepen.io
In this demo you can see there is a two container div and the container divs inside some different color div.
So what i am trying to do. When i click .change_pri then that clicked (.style, style1, style2) will automatically change .type style like:
<div class="test" id="1">
<div class="type style">selected color</div> <-- class is style
<div class="select_types">
<div class="type_s"><div class="change_pri style" data-id="0">0</div></div>
<div class="type_s"><div class="change_pri style1" data-id="1">1</div></div>
<div class="type_s"><div class="change_pri style2" data-id="2">2</div></div>
</div>
</div>
after clicking change_pri style2 then it need to looks like this:
<div class="test" id="1">
<div class="type style2">selected color</div> <-- after clicking class is style2
<div class="select_types">
<div class="type_s"><div class="change_pri style" data-id="0">0</div></div>
<div class="type_s"><div class="change_pri style1" data-id="1">1</div></div>
<div class="type_s"><div class="change_pri style2" data-id="2">2</div></div>
</div>
</div>
and post the data-id with ajax.
I do not know how the rest of that section, but I was able to do so. Anyone can help me in this regard ?
$(function() {
var i;
i = $(this).attr('id');
});
$('.change_pri').on('click', function(e) {
e.preventDefault();
$.ajax({
type: "POST",
url: "chage_number.php",
data: {
id: i,
},
});
});
The Javascript with the AJAX request should probably look something like this:
$('.change_pri').click(function(){
var dataid = $(this).attr('data-id');
var id = $(this).closest('.test').attr('id');
$.ajax({
type: "POST",
url: "chage_number.php",
data: { dataid : dataid, id: id }
}).success(function(result){
alert(result);
});
});
And then depending on what you want to do back-end, you can access that variable in chage_number.php via $_POST['id'].
So a simple example would be
chage_number.php
echo $_POST['id'] . ", ". $_POST['dataid'];
This should alert() both ids.
you can try this..
$('.change_pri').on('click', function(e) {
var styletype = $(this).attr('class').split(' ')[1];
var ctoremove = $('.type').attr('class').split(' ')[1];
$('.type').removeClass(ctoremove).addClass(styletype);
$.ajax({
type: "POST",
url: "chage_number.php",
data: { id: i }
}).success(function(result){
alert(result);
});
});
and here is the FIDDLE
I take it as the second container should be an example of what happens clicking the div's of the first one.
See this working example, it should do what you asked for: http://codepen.io/anon/pen/qdxVzW
This is where you get an alert telling you which data-id you clicked and then it changes the class of the .type element
alert($(this).attr('data-id')); //this can be removed, it's just a test
$('#test-1 > .type') //remove styleN and add the needed one
.removeClass('style0')
.removeClass('style1')
.removeClass('style2')
.addClass('style'+$(this).attr('data-id'))
The part about the ajax call remains almost the same, with a little modification when it comes to setting the id to be sent:
$('.change_pri').on('click', function(e) {
//As suggested by #Mackan, a little modification: store data-id
var dataId = $(this).attr('data-id');
$.ajax({
type: "POST",
url: "chage_number.php",
data: {
id: dataId //send the correct id
}
});
});
The function at the beginning of the script can be safely removed, it doesn't affect the rest of the code :)
I was almost forgetting: add a 0 to the style which doesn't have a number, like:
<div class="change_pri style0" data-id="0">0</div></div>
Otherwise when it come's to data-id=0 the script doesn't know what to do. Of course, same thing should be done into css code:
.style0{
background-color:red;
color:#ffffff;
margin:5px;
}

How to detect the div in which a link to a javascript function has been clicked

I have the following html code:
<div id="result1" class="result">
... some html ...
... link
... some html ...
</div>
<div id="result2" class="result">
... some html ...
... link
... some html ...
</div>
<div id="result3" class="result">
</div>
<div id="result4" class="result">
</div>
The goal is to update the content of the next div when I click on the link. So for instance, when I click on a link in #result2, the content of #result3 will be updated.
Here is the javascript function:
<script>
function updateNext(elem, uri) {
$.ajax({
url: uri,
success: function(data) {
elem.closest('.result').nextAll().html('');
elem.closest('.result').next().html(data);
}
});
}
</script>
However, when I use the link, elem is set as the window, not the link itself.
The content of the div is generated by a server which should not know the position of the div in which the code he is generating will be.
I also tried with a
<a href="javascript:" onclick="updateNext(...
with no other result...
any idea ? :-)
Thanks,
Arnaud.
this returns the window when used in href, but here it returns the actual link:
... link
Don't forget to use the jQuery $ in:
$(elem).closest('.result').nextAll().html('');
$(elem).closest('.result').next().html(data);
Why do you use inline scripts when you alrady are using jQuery?
I've setup a Fiddle for you which does what you want: http://jsfiddle.net/eLA3P/1/
The example code:
$('div.result a').click(function() {
$(this).closest('div.result').next().html('test');
return false;
});
First, you must remove those href="javascript:..." attributes. Please never use them again, they are evil.
Then, bind a click handler via jQuery, which you are alredy using:
// since you dynamically self-update the a elements, use "live()":
$("div.result a").live("click", function () {
var $myDiv = $(this).closest("div.result");
$.ajax({
url: "/build/some/url/with/" + $myDiv.attr("id"),
success: function(data) {
$myDiv.next("div.result").html(data);
}
});
return false;
});
Done.
Try to use jQuery to bind the event instead putting a javascript link in the href.
<div id="result1" class="result">
link
</div>
$('.resultLink').click(function(){
var elem = $(this);
$.ajax({
url: uri,
success: function(data) {
elem.closest('.result').nextAll().html('');
elem.closest('.result').next().html(data);
}
});
});
You should do it like this:
http://jsfiddle.net/hJhC7/
The inline JavaScript is gone, and the href is being used to store the "uri", whatever that might be. I'm assuming it's different for each link.
The //remove this lines are just to make $.ajax work with jsFiddle.
$('.update').click(function(e) {
e.preventDefault();
var elem = $(this);
$.ajax({
type: 'post', //remove this
data: {html: Math.random() }, //remove this
url: $(this).attr('href'),
success: function(data) {
//not sure why you're doing this
//elem.closest('.result').nextAll().html('');
elem.closest('.result').next().html(data);
}
});
});
with this HTML:
<div id="result1" class="result">
link
</div>
<div id="result2" class="result">
link
</div>
<div id="result3" class="result">
link
</div>

after success function div value back to first value

<div id="user">username1</div>
<script language="javascript">
$('.button').live('click',function(){
$("#user").html('<img src="loading.gif">');
$.ajax({
type: "POST",
url: "getuserid.php",
data: "userid="+userid,
success: function(html){
$("#user").append(html);
alert(html);
}
});
});
</script>
i have several button with button class
after i click button with .button class i see appended data to #user (returned from server) but after click alerted message, data in "#user" backed to first value "username1".
why?
if i remove alert(html) i cant see appended data at all.
We can only guess because you didn't provide much code, but presumably your .button element is an actual HTML <button /> (or worse, an <input type="button" />) and it's probably leading to your page being refreshed.
Use preventDefault to stop this behaviour:
$('.button').live('click',function(e){
$("#user").html('<img src="loading.gif">');
$.ajax(.....);
e.preventDefault();
});

Categories