How to use data-toggle with Ajax and PHP - javascript

I am using Bootstrap (which is heavily modified) and love the use of data-toggle. My current script is pretty straight forward, it's an image upload script. I use the following code to list images from the database:
$stmt = $db->query('SELECT * FROM img_slider ORDER BY id ');
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "<li>
<div class='thumbnail removable'>
<div class='remove' id='{$row['id']}' data-toggle='remove'></div>
<img src='../{$row['path']}'>
</div>
</li>"
;}
Notice data-toggle='remove' - This function works great removing images statically, but what say I want to remove the images in the database? I understand the best method would be to utilise Ajax. Here is what I mean:
My PHP file delete.php:
$id = $_REQUEST['id'];
$db->beginTransaction();
$st = $db->prepare('DELETE FROM img_slider WHERE id = :id');
$st->execute(array(':id' => $id));
$db->commit();
I am trying to execute this with the following jquery/ajax:
$("a[data-toggle=remove]").click(function()
{
var image_id = $(this).attr('id');
$.ajax({
cache: false,
type: 'POST',
url: 'actions/delete.php',
data: 'id='+image_id,
});
});
Any help would be greatly appreciated! I just don't know how to utilise bootstraps data-toggle with PHP, tried search for the solution, came up empty handed. Here is an image of how the image upload works:

If it is the selector that is the problem, tt should be
$('div[data-toggle="remove"]').click(function() {
but if it is click on the image you mean
$('div[data-toggle="remove"]').next().click(function() {
Edit. I just tested your question like so :
<div class='thumbnail removable'>
<div class='remove' id='27' data-toggle='remove'></div>
<img src='1.gif'>
</div>
$('div[data-toggle="remove"]').next().click(function() {
var image_id = $(this).prev().attr('id');
alert(image_id);
$.ajax({
cache: false,
type: 'POST',
url: 'actions/delete.php',
data: 'id='+image_id
});
});
alerts 27 and and try to XHR with id: 27.
If it is click on the data-toggle <div>
$('div[data-toggle="remove"]').click(function() {
var image_id = $(this).attr('id');

Take a look at jQuery function ON: http://api.jquery.com/on/
The issue is you are binding the click event at load, when you are loading elements in to the page async then they will not events binded. On should bind the events now and in the future.
$("body").on( "click", ".remove", function() {
// Remove stuff
});

Related

Turning jquery into an includable, callable function

I'm so frustrated! As an ok PHP developer I can't get my head around the simplist of jquery problems!
I have recently moved my HTML jquery include to the end of the HTML body, instead of in the head to improve google pagespeed score.
This has broken some jquery which is used for simple comment voting. This was written badly as it repeats for every comment.
<div id="voterow-19907" class="commentfooter">UP</a> | <a id="comment-vote-down-19907" href="#" rel="nofollow">DOWN</a></div>
<script>
$("#comment-vote-up-19907").click(function() {
$.ajax({
type: "GET",
url: "/ajax.php",
data: "a=rv&v=19907&d=up",
success: function(data){
$("#voterow-19907").text("Thank you for your vote")
}
});
return false;
});
$("#comment-vote-down-19907").click(function() {
$.ajax({
type: "GET",
url: "/ajax.php",
data: "a=rv&v=19907&d=down",
success: function(data){
$("#voterow-19907").text("Thank you for your vote")
}
});
return false;
});
</script>
Since moving the jquery include to the bottom of the page this naturally doesn't work.
What I'm trying to do is turn the above code into a mini function I can include after the jquery include, then pass the ID and VOTE-DIRECTION to the function from the HTML a hrefs using the jquery DATA- attribute.
Any help would be greatly appreciated. I'm running out of hair!
I think, repeated codes will hurt your page than placement of JQuery file.
You can solve this problem using more general event listener. Remove all listeners inside code (all of them) and append the code below after Jquery include.
$('[id^=comment-vote]').click(function() {
var elementId = $(this).attr('id');
var elementIdParts = elementId.split("-");
var voteType = elementIdParts[2];
var id = elementIdParts[3];
$.ajax({
type: "GET",
url: "/ajax.php",
data: "a=rv&v="+id+"&d="+voteType,
success: function(data){
$("#voterow-"+id).text("Thank you for your vote")
}
});
return false;
});
$('[id^=comment-vote]") selects all elements which have id starting with "comment-vote". If user clicks one of these elements, event handler gets id of elements, split into parts like "comment", "vote", "up", "19900". 2nd part is voteType and 3rd part is ID of row. We can use these variables while generating/operating AJAX request.
I didn't try the code but the idea behind that would be beneficial for you.
To really give a great working answer, I would need to see your an example page / the exact structure of your html, but here's what I have for you.
In a script file that you include after jQuery, you can include something similar to the below code assuming your html is as follows:
<div id="voterow-1" class="voterow">
<p class="voteresult"></p>
<a class="upvote" href="#" rel="nofollow">UP</a>
<a class="downvote" href="#" rel="nofollow">DOWN</a>
</div>
<div id="voterow-2" class="voterow">
<p class="voteresult"></p>
<a class="upvote" href="#" rel="nofollow">UP</a>
<a class="downvote" href="#" rel="nofollow">DOWN</a>
</div>
Having the class of upvote and downvote makes it easy to target these elements in jQuery:
// After jQuery is loaded, the function passed to ready() will be called
$(document).ready(function () {
// bind a click event to every direct child with the upvote class of an element with the voterow class
$('.voterow > .upvote').click(function (event) {
// get the voterow parent element
var $parent = $(event.target).parent();
// use regex to strip the id number from the id attribute of the parent
var id = parseInt($parent.attr('id').match(/^voterow-(\d+)/)[1]);
// call your ajax function
vote(id, 'up', $parent.find('.voteresult');
});
$('.voterow > .downvote').click(function (event) {
var $parent = $(event.target).parent();
var id = parseInt($parent.attr('id').match(/^voterow-(\d+)/)[1]);
vote(id, 'down', $parent.find('.voteresult');
});
function vote(id, direction, $resultElement) {
$.ajax({
type: "GET",
url: "/ajax.php",
// here we have the id and the direction needed to make the ajax call
data: "a=rv&v=" + id + "&d=" + direction,
success: function(data){
$resultElement.text("Thank you for your vote")
}
});
}
});
Here is a demo: https://plnkr.co/edit/ECL376hZ3NOz8pBVpBMW?p=preview

how can I make one button correspond to different clicked div html jquery php?

You can see my code below. I face a challenge that I don't know how to use one button to correspond different click. On the php, if I put the button inside the foreach loop, it will create a lot of button, that's not what I want. In the js, if I put the on.click button inside the foreach elements loop, it will also create a lot of on.click button, so I click one button, it will run many times depends on the number of label_name. I think about addClass, if I clicked the heart div, I use js to add a class, and then get the attr('id') inside button.on.(click), so I can differentiate them in my server php and mysql can request the correspond data. But the problem is that if a user click every div, then every div add classes, then problem again.
var current_page = 1;
var elements_body = {
"heart": "1",
"eye": "2",
"ear_nose_throat": "3",
"hand_foot_mouth": "4"
};
jQuery.each(elements_body, function (label_name, label_num) {
var disease_label = $('#' + label_name + '_d');
disease_label.on('click', function () {
var data = {
action: 'body_part_keyword', //wordpress loading url
postSearchNonce: MyAjaxSearch.postSearchNonce,
current_page: current_page,
label_name: label_name //this label_name will differentiate data that need to request from mysql in the action.php
};
$.ajax({
url: MyAjaxSearch.ajaxurl,
type: 'POST',
cache: false,
data: data,
success: function (data) {
disease_menu_result.append(data);
current_page++
}
}); //ajax
});
}); //jQuery.each
$('#loadmorebutton_body').on('click', function () {
//I dont know how can I make this button to correspond above code
});
<div id="disease_menu">
<?php
$arr = Array(
'heart'=>'heart',
'eye'=>'eye',
'ear_nose_throat'=>'ear nose throat',
'hand_foot_mouth'=>'hand foot mouth'
);
foreach ($arr as $key=>$value) {
?>
<div class="disease_li" id="disease_li_<?php echo $key;?>">
<span class="disease_span" id="<?php echo $key;?>_d"><label>(<?php echo $value;?>)</label>diseases</span>
</div>
<!--disease_li-->
<?php }?>
</div>
<!--disease_menu-->
<button id="loadmorebutton_body">Load More</button>
Use javascript functions :
function MyFunction() {
jQuery.each( elements_body, function( label_name, label_num) {
var disease_label= $('#'+ label_name + '_d');
disease_label.on('click',function(){
var data={
action: 'body_part_keyword',//wordpress loading url
postSearchNonce : MyAjaxSearch.postSearchNonce,
current_page:current_page,
label_name:label_name//this label_name will differentiate data that need to request from mysql in the action.php
};
$.ajax({
url: MyAjaxSearch.ajaxurl,
type:'POST',
cache: false,
data: data,
success: function(data){
disease_menu_result.append(data);
current_page++
}
});//ajax
});
});
}
$('#loadmorebutton_body').on('click',function(){
MyFunction();
}

Jquery removing issue divs still remains

Yesterday I coded a Commentbox in PHP, HTML and ajax. The ajax part gives me the opportunity to delete a comment without refreshing the page. The way I do this, is that I give each and every comment (div) a unique id via the database. So let us for example say that in my mysql database this is how a comment looks like:
Username: blabla<br>
Comment: haha this is so funny<br>
id: 52
This will be printed out in the html page likes this for example:
<div class="commentStyle" id="<?php echo $commentid; ?>">
This comment will now have the id of 52
<div class="deleteComment">Delete the comment here!</div>
</div>
AND THEN!
Comes the ajax part which is coded something like this:
$(document).ready(function(){
$(".deleteComment").click(function(){
//Getting the id of comment
id = $(".deleteComment").attr("id");
$.ajax{
Type: 'GET',
url: 'deletecomment.php',
data: "id=" + id,
success: function(){
$("#" + id).hide();
}
}
});
});
This works fine when deleting the first comment. But it WONT LET ME DELETE OTHER COMMENTS UNLESS I REFRESH THE PAGE >.<. The first comment can be perfectly deleted without refreshing the page, but when I want to delete other comments I have to refresh the page multiple times.
How do I solve this?
The code in your document ready event would work properly only for the first click. In order to get this work, you must have an on click event registered within the tag.
Example :
<div class="deleteComment" onclick="DeleteMe(id)">Delete the comment here!</div>
</div>
function DeleteMe(id)
{
$.ajax{
Type: 'GET',
url: 'deletecomment.php',
data: "id=" + id,
success: function(){
$("#" + id).hide();
}
}
});
}
If the on click on a div does not work, you can use an anchor tag (Delete here) instead.
.deleteComment is child of <div class="commentStyle".., so you can select it with parent() selector:
var id = $(this).parent().attr("id");
Or more specifically:
var id = $(this).parent('.commentStyle').attr("id");
Looks like you need to get the id from the parent element first and then target the child, the element you clicked, to hide the comment from it after the ajax request returns success:
$(".deleteComment").click(function(){
var id = $(this).parent().attr("id");
var child = $(this);
$.ajax({
type: 'GET',
url: 'deletecomment.php',
data: "id=" + id,
success: function(){
child.hide();
// or if you want to delete the entire element with the id of X
// child.parent().hide();
}
});
});
There are few changes which need to be done in your code.
First of all add ID tag to the inner div.
<div class="commentStyle" id="<?php echo $commentid; ?>">
This comment will now have the id of 52
<div class="deleteComment" id="<?php echo $commentid; ?>">Delete the comment here! </div>
</div>
Secondly use this
id = $(this).attr("id");
instead of...
id = $(".deleteComment").attr("id");
Thirdly change the ajax call like this:
$.ajax({
Type: 'GET',
url: 'deletecomment.php',
data: "id=" + id
}).done(function(){
$("#" + id).hide();
});
Hope this works for you, if not just reply me.

click event on dynamic li elements

Updated the question as per #Jonathan Kuhn's feedback and it works like a charm
I am building a messaging system for my web application.
where the users should be able to communicate with me via messages (ajax)
I am being able to append <ul> with additional <li> from jQuery
$('#send').click(function(e){
e.preventDefault();
var reply = $('#reply').val();
var project_id = 44; // just for reference
$.ajax({
type: "post",
url: "<?php echo base_url(); ?>messages/send",
data:{ msg:reply, project_id:project_id },
success: function (response) {
if(response=="success"){
$(".messages").append('<li class="message" id="message">'+reply+'<a id="delete">delete</a></li>');
var clearText = "ture";
}else{
}
}
});
Which is working perfectly fine. But I am having problem while deleting the dynamically added list element.
I tried bind() and on() jQuery functions but as I am not much good at it, I am facing a lot of issues.
$("#messages").on('click', '#delete', function(event) {
event.preventDefault();
var id = 22 ; // just for reference
$.post( "<?php echo base_url(); ?>messages/delete", { type:'single', id:id } )
.done(function( data ) {
});
$(this).closest('li').remove();
});
My HTML structure is as below
<ul class="messages" id="messages">
<li class="message" id="message">sdaghds<a id="delete">delete</a></li>
</ul>
You have id="#messages" on the <ul>. Remove the # and then the .on one should work.
Also, ids are supposed to be unique throughout the page. So you shouldn't have multiple message ids throughout. If you need multiple, use classes. Remove the id from the <li>.

jQuery selectors after dynamic reload, and $(this)

I need some help. I load a list of entries in a div every 5 seconds. Each entry is a div and has a unique ID. Like this:
<div class="entry">
<div class="textbox">
<p class="entry-text">
<?php echo $text;?>
</p>
</div>
<div class="infobox">
<p class="date"><a #<?php echo $id;?> id="<?php echo $id;?>" href="gen_details.php?id=<?php echo $id;?>"><?php echo $t;?></a> </p>
<p class="ip"><?php echo $ip;?></p>
</div>
These, as I said are loaded each 5 seconds. I'm adding a details page for every entry, with this:
$('.date a').click(function () {
var dataString = 'id=' + $(this).attr("id");
//alert(dataString);
$.ajax({
type: "POST",
url: "gen_details.php",
data: dataString,
success: function(data) {
$("#content").hide().fadeOut('fast');
$("#content").html(data).show('fast');
refresh = 0;
},
});
return false;
});
This works perfectly fine, until it reloads. It seems to lose the handle for the a href and instead of doing the procedure it goes to gen_details.php
I have tried to use .on() but I don't know how would I get the ID of the entry using .on(), as I cant use $(this) (afaik).
I hope I explained my problem at least half-well. English is not my first language so it wasn't that easy.
Thanks in advance.
Try this selector
$('div').on('click', '.date a', function () {
This will delegate the event to its parent div. So it should work for dynamically created elements as well.
Live click event bind event handler to element even after you reload some element. Default click event bind to element when a page load once you reload that element then it also delete event handler of that element.
works on till jquery 1.7 version.
$('.date a').live('click',(function (e) {
e.preventDefault()
var dataString = 'id=' + $(this).attr("id");
//alert(dataString);
$.ajax({
type: "POST",
url: "gen_details.php",
data: dataString,
success: function(data) {
$("#content").hide().fadeOut('fast');
$("#content").html(data).show('fast');
refresh = 0;
},
});
});
//when jQuery > 1.7 then used this method
$('body').on('click' '.date a',function () {
//call
});

Categories

Resources