So I got a select menu and when an user select an option, it calls a post function via ajax that generates some table rows via PHP and then it returns the html coding for it. In it, there is an Add button.
What I am trying to do is that when the user clicks the add button, a form shows up.
But for some reason, it is not working...
Here is the code:
$(document).ready(function () {
$(".add_form").hide();
$("#console").change(function () {
var id = $(this).val();
var dataString = 'console_id=' + id;
$.ajax({
type: "POST",
url: "generate-games-list",
data: dataString,
cache: false,
success: function (html) {
$("#games_table_body").html(html);
}
});
});
$(".add_button").click(function () {
alert("HELLO");
var id = this.id;
$.post('manage_games', 'game_id=' + id, function (response) {
alert(response);
});
$("#game_id").val(id);
$(".add_form").show();
});
});
Here is the PHP code that returns the table rows:
$console = Console::find(Input::get('console_id'));
$type = GameType::find(Input::get('type_id'));
if(!Input::has('console_id'))
return "Error";
else{
foreach($console->games()->get() as $console_game){
$available_consoles_string = "";
$game_types_string = "";
//Get all the consoles the game can be played on
foreach($console_game->consoles()->orderBy('name', 'asc')->get() as $available_consoles){
$available_consoles_string = $available_consoles_string . " " .$available_consoles->name .", ";
}
//Get all the types that the game falls in
foreach($console_game->types()->orderBy('type', 'asc')->get() as $game_types){
$game_types_string = $game_types_string . " " .$game_types->type .", ";
}
return "<tr><td>" .$console_game->name. "</td><td>". $available_consoles_string. "</td><td>" .$game_types_string. "</td><td><input type='button' id='" .$console_game->id. "' class='add_button' value='Add'/> / View</td></tr>";
}
}
Any idea why it is not working? When I mean not working, I mean the alert is not showing up but I am not getting any error on the Chrome Console...
Thanks,
Ara
Simply use .on():
$(document).on("click", ".add_button", function(){
// your event code
});
When your js runs a click event is attached to all current elements with the .add_button class. However, you're adding extra buttons via ajax and these won't have trigger the same click event.
To fix this use the code above. It attaches the event to the document so even if you add buttons once the page has loaded the click event will be triggered by them.
Related
I create a load more button for load more posts from the database but when I add like button for that if one time clicks on load more button and then click on the like button, like.php file runs two times and adds two lines in likes table. if I click 2 times on load more then like.php file runs 3 times and...
I want to know how I should create a loadmore button and like the button to works fine.
this is simple of my codes:
posts.php :
<div id="comnts2"></div>
<button id="btn2" >load more</button><script>
$(document).ready(function() {
var comco2 = 2;
var offset2 = 0;
$("#btn2").click(function() {
$.ajax({
method: "POST",
url: "ld_comco.php",
data: { comnco2 : comco2, offset2 : offset2}
})
.done(function(msg2) {
$("#btn2").hide();
} else {
$("#comnts2").append(msg2);
});
offset2 = offset2 + comco2;
});
$("#btn2").trigger("click");
});
</script>
ld_comco.php:
<?php
$comnco2=$_POST['comnco2'];
$offset2=$_POST['offset2'];
$rzp=mysqli_query($conn,"SELECT * FROM `tbl_users_posts` WHERE uid = '$uid' ORDER BY id DESC limit $offset2, $comnco2");
while($rp=mysqli_fetch_assoc($rzp)){
$sid=$rz['id'];
$lik=$rz['lik'];
echo $sid."<br>";
/*like*/
echo'<img class="li_ik1" data-id="'.$sid.'" src="pc3/up.png">'.$lik.' Likes</img>';
?>
</span>
<?php }?>
<script type="text/javascript">
$(document).ready(function() {
var uid=<?php echo $uid;?>;
$(document).on("click", ".li_ik1", function() {
var psid = $(this).data('id');
$.ajax({
method: "POST",
url: "like.php",
data: {psid: psid, uid: uid}
}).done();
});
});
</script>
like.php:
<?php
$id=$_POST['psid'];
$uid=$_POST['uid'];
$Y=mysqli_query($conn,"INSERT INTO `t_plik` (pid,uid) VALUES ('$id','$uid')");
$Q=mysqli_query($conn,"UPDATE `tbl_users_posts` SET lik=lik+1 WHERE id='$id'");
?>
thanks
I think the problem is, that you bind your like button multiple times globally. Each time you load the content from ld_comco.php you also call $(document).on("click", ".li_ik1", ...) in the $(document).ready block, which means you bind all ".li_ik1" buttons on the entire document (but some of them has already been bind).
I would remove the $(document).ready(...) block from the ld_comco.php and move the logic into the posts.php right before you render your content. A further positive aspect is you have your business logic at one place.
KEEP IN MIND: You get a response of buttons in msg2, thats why you do not need to filter $msg2 anymore. But if you wrap your buttons with further html tags in ld_comco.php, your buttons will be on a deeper level, so you need to use a selector again, like you did with .on("click", ".li_ik1", ...).
posts.php
...
var $msg2 = $(msg2);
// Now you bind only the loaded buttons instead of
// the buttons in the entire document for multiple times
$msg2.on("click", function() {
var $element = $(this);
var psid = $element.data('id');
var uid = $element.data('uid');
$.ajax({
method: "POST",
url: "like.php",
data: {psid: psid, uid: uid}
}).done();
});
$("#comnts2").append($msg2);
...
In your ld_comco.php you need to add the data-uid="'.$uid.'" and remove the script block. Then your file should look like this:
<?php
$comnco2=$_POST['comnco2'];
$offset2=$_POST['offset2'];
$rzp=mysqli_query($conn,"SELECT * FROM `tbl_users_posts` WHERE uid = '$uid' ORDER BY id DESC limit $offset2, $comnco2");
while($rp=mysqli_fetch_assoc($rzp)){
$sid=$rz['id'];
$lik=$rz['lik'];
echo $sid."<br>";
/*like*/
echo'<img class="li_ik1" data-id="'.$sid.'" data-uid="'.$uid.'" src="pc3/up.png">'.$lik.' Likes</img>';
}
?>
$("#btn2").trigger("click");
this in posts.php means click the #btn2
so after clicking it, you click it again
$(document).ready(function() {
var comco2 = 2;
var offset2 = 0;
$("#btn2").click(function() {
$.ajax({
method: "POST",
url: "ld_comco.php",
data: { comnco2 : comco2, offset2 : offset2}
})
.done(function(msg2) {
$("#btn2").hide();
} else {
$("#comnts2").append(msg2);
});
offset2 = offset2 + comco2;
});
$("#btn2").trigger("click");
});
</script>
I'm loading data from mysql to php with ajax. I want to create edit function for my website. This edit will be on modal.
Select input with options (subcategories) is loading by ajax after radio input categories is loaded with previous ajax.
I've tried several jquery events to change select option, but no one worked.
This is script code in my modal file.
<script>
$(document).ajaxComplete(function() {
$("#editexp'.$poz.'").on("shown.bs.modal", function(){
$("input[name=payment'.$poz.'][value='.$method.']").prop("checked", true);
$("input[name=kategoria'.$poz.'][value='.$catid.']").prop("checked", true);
var category = '.$catid.';
var poz = '.$poz.';
$.ajax({
url:"expense_subcategory_change.php",
method:"POST",
data:{category:category,
poz:poz
},
success:function(data){
$("#subcategory'.$poz.'").html(data);
}
});
$("input[type=radio][name=kategoria'.$poz.']").change(function(){
var category = $(this).val();
var poz = '.$poz.';
$.ajax({
url:"expense_subcategory_change.php",
method:"POST",
data:{category:category,
poz:poz
},
success:function(data){
$("#subcategory'.$poz.'").html(data);
}
});
});
});
});
$("#subcategory'.$poz.'").ajaxComplete(function() {
$("#subcategory'.$poz.' ").find("option").each( function() {
var $this = $(this);
if ($this.val() == '.$subcatid.') {
$this.prop("selected","selected");
return false;
}
});
});
</script>
I've also tried this:
$("#subcategory'.$poz.'").ajaxComplete(function() {
$("#subcategory'.$poz.' option[value='.$subcatid.']").prop("selected","selected");
});
also these two functions without ajaxComplete for #subcategory or with second ajaxComplete for document
Input with options is loading but first option is always selected.
This is main part of my expense_subcategory_change code:
$result = mysqli_query($connection,"$sql_query");
$output .= '<select class="mb-3 w-50-100 " name="subcategory'.$poz.'">';
while($row = mysqli_fetch_array($result))
{
$output .= '<option value="'.$row['id'].'" >'.$row['sub'].'</option>';
}
$output .= '</select>';
echo $output;
The issue is in your selector. You are using 'name' in the select element but using '#' (id) to search the dom for the element. Change your PHP code to:
$output .= '<select class="mb-3 w-50-100 " id="subcategory'.$poz.'">';
And I tested with the second method you provided as it seemed cleaner
$("#subcategory'.$poz.' option[value='.$subcatid.']").prop("selected","selected");
See the solution (simplified code) working here https://jsfiddle.net/79kugn60/
If you are using any event. Try Bind that event in your function. So that everytime event gets binded. After firing.
I am using bootstrap , php and mysql for an application . With this , whenever the users are logged in , the admin will post messages across to all users that will be displayed as an alert on the page . Below is my ajax code :
$.ajaxSetup(
{
cache: false,
beforeSend: function() {
$('#admin_message').hide();
},
complete: function() {
$('#admin_message').show();
},
success: function() {
$('#admin_message').show();
}
});
var $admin_msg = $("#admin_message");
$admin_msg.load("get_message_board.php");
var refreshId = setInterval(function()
{
$admin_msg.load('get_message_board.php');
}, 10000);
Below is my alert holder holder
<div class="alert alert-success" id="alert_holder">
<p id="admin_message" style="text-align: center;font-size: 20px"></p>
</div>
PHP SCRIPT :
include './functions.php';
$sql = "select message from msg_db3 where user_group ='".$_SESSION['active_user_group']."' order by id DESC LIMIT 1";
$temp = return_results($sql);
echo $temp['0']['message'];
Now i want to make sure that the div (with id='alert_holder') is hidden by default and shows up only if echo $temp['0']['message'] is not empty .If it is empty , it should be hidden . Also the transition is a bit odd since it shakes the entire page while bringing the alert up on the screen .
Please advice on the above .
THanks in advance .
EDIT:
can you try with normal Ajax?
$.ajax({
url: "get_message_board.php"
})
.done(function( data) {
console.log(data);
if(data.length>0){
$('#admin_message').show();
} else {
alert('not found');
}
}
});
Check your response length and show if it's not null
success: function(data) {
if(data.length>0){
$('#admin_message').show();
}
}
In php script you can change to
if(isset($temp['0'])){
echo $temp['0']['message'];
}
The main problem with your code is with
complete: function() {
$('#admin_message').show();
},
This code will show #admin_message every time when ajax is completed.
if you remove this unnecessary part you can make only my first change with if detection.
I have a button in my page:
if($posts = $q->fetchAll()) {
foreach ($posts as $post) {
$username = $post[0];
$post_id = $post[2];
$status = $post[1];
echo $username . " " . $status . "<br/>";
echo "<button value = '$post_id' id = 'like' class='like' type='submit'>Like</button>";
}
}
Let's assume I have ten result from the query, I will definitely have 10 LIKE button with the same ID.
Now my jQuery is coming this way:
$("#like").click(function() {
var menuId = $(this).val();
var request = $.ajax({
url: "likes.php",
type: "POST",
data: { id : menuId },
dataType: "html"
});
request.done(function( msg ) {
$(".likecount").html( msg );
});
});
Every click on a single button applies to all 10 buttons. How do I differentiate them and have the database affected accordingly?
First off, you're adding like elements via ajax, but you're binding the event handler to whichever like element is already part of the dom at any given moment:
$(document).ready(function()
{
//when dom is loaded, #like is selected, and event is bound
$('#like').click(function(){});
});
inside the click handler, you perform an ajax call that may add another like element to the page, but you never bind an event handler to that new element.
You have 2 options: add an event handler for each element that is added to the page dynamically (not so good, bad for performance). OR delegate the event. As an added bonus, you don't need the ID's of the like buttons anymore. You can use the like class to delegate!
$(document).ready(function()
{
$('body').on('click', '.like', function()
{
//handle click on like button here
});
});
This adds an event listener to the body tag, that will call the callback function whenever a click is registered on an element that has the like class.
I'll edit this response, to give you a, purely hypothetical way to ensure unique like id's
Using a closure, you can easily get unique ID's, by exploiting the fact that closure vars can outlive the closure function. But as you can see, just from the verbosity and added complexity of the code below, this approach is not to be recommended. Simply use the class, and leave the ID out. delegation all the way!
$('body').on('click', '.like', (function(count)
{//closure, pass like buttons currently on page
var idNum = 0;
count.each(function()
{
$(this).attr('id', $(this).attr('id') + idNum);
++idNum;//increment
});
return function()
{//this is the actual callback
request.done(function( msg )
{
var chunk = $(msg);//parse HTML response
chunk.find('.like').each(function()
{
$(this).attr('id', ($(this).attr('id') || 'like') + idNum);
++idNum;
});
});
};
}($('.like'))));
Or, if for some reason you don't want to delegate the event:
$('.like').on(function handler()
{//callback should be named, you'll see why
request.done(function( msg )
{
$('.like').off('click', handler);//remove handler
//add msg to DOM
$('.like').on('click', handler);//add handler, now including new DOM elements
});
});
You could (and IMO should) optimize this further, by storing the $.each callback in a closure reference, too:
$('body').on('click', '.like', (function(count)
{//closure, pass like buttons currently on page
var idNum = 0, eachCallback = function()
{
$(this).attr('id', ($(this).attr('id') || 'like') + idNum);
++idNum;//increment
};
count.each(eachCallback);
return function()
{//this is the actual callback
request.done(function( msg )
{
var chunk = $(msg);//parse HTML response
chunk.find('.like').each(eachCallback);
});
};
}($('.like'))));
This way, you avoid creating a callback function object on each click event... but read up on closures to fully understand why this is a better approach, performance wise.
Why not change your PHP to:
if($posts = $q->fetchAll()){
foreach ($posts as $post){
$username = $post[0];
$post_id = $post[2];
$status = $post[1];
echo $username . " " . $status . "<br/>";
echo "<button value = '$post_id' id = 'like_$post_id' class='like' type='submit'>Like</button>";
}
As each item relates to a post with a (I hope) unique ID, why not just append that value to the id property?
ID values MUST BE UNIQUE
Then you'll need to change your jQuery selector, how about:
$("button.like").click(function()
Don't use ID as selectors in your jquery, use class selector if your buttons are going to use the same class.
For example:
if($posts = $q->fetchAll()){
foreach ($posts as $post){
$username = $post[0];
$post_id = $post[2];
$status = $post[1];
echo $username . " " . $status . "<br/>";
// Removing Id like, because Id should be unique in DOM.
echo "<button value = '. $post_id. ' class='like' type='submit'>Like</button>";
}
}
Your jQuery will look like:
// class selector is a dot (.), if you use an id selector (hashtag #) and you
// you have more than 1 element with that Id, jQuery will only select the first one.
$('body').on('click', '.like', function(){
var menuId = $(this).val();
var request = $.ajax({
url: "likes.php",
type: "POST",
data: { id : menuId },
dataType: "html"
});
request.done(function( msg ) {
$(".likecount").html( msg );
});
});
I have this
"fsField" is the class of all elements in the form. So whenever the user blurs to another field it submits the form using the function autosave() - given below. It saves data when the user blurs but when the user clicks the button with class "save_secL" to go to next page it does not save.
$('.fsField').bind('blur', function()
{
autosave();
}
});
but when i use this code
$('.save_secL').click(function()
{
var buttonid = this.id;
{
var answer = confirm("You have left some questions unanswered. Click OK if you are sure to leave this section? \\n Click CANCEL if you want stay in this section. ");
if(!answer)
{
var spl_items = valid().split(',');
$(spl_items[0]).focus();
return false;
}
else
{
$('#hidden_agree').append('<input id="secLuseragreed" name="secL_user_agreed" value="unanswered" type="hidden" />');
autosave();
window.location= buttonid+".php"
}
}
else
{
$('#hidden_agree').append('<input id="secLuseragreed" name="secL_user_agreed" value="answered all" type="hidden" />');
autosave();
window.location= buttonid+".php"
}
}
});
**autosave_secL.php is the php source thats saving the data in the database. I ran it independently and it does save data okay. **
function autosave()
{
var secL_partA_ques_1_select = $('[name="secL_partA_ques_1_select"]').val();
var secL_partA_ques_1 = $('[name="secL_partA_ques_1"]:checked').val();
var secL_partA_ques_2_select = $('[name="secL_partA_ques_2_select"]').val();
$.ajax(
{
type: "POST",
url: "autosave_secL.php",
data: "secL_partA_ques_1_select=" + secL_partA_ques_1_select + "&secL_partA_ques_1=" + secL_partA_ques_1 + "&user_id=<?php echo $row_token[user_id]?>" + "&updated_by=<?php echo $member."-".$key;?>",
cache: false,
success: function()
{
$("#timestamp").empty().append('Data Saved Successfully!');
}
});
}
**
valid() is a validation function that checks if any field is empty and returns a value if there is an empty field.**
function valid()
{
var items = '';
$('.fsField').each(function()
{
var thisname = $(this).attr('name')
if($(this).is('select'))
{
if($(this).val()=='')
{
var thisid = $(this).attr('id')
items += "#\"+thisid+\",";
$('[name=\"'+thisname+'\"]').closest('td').css('background-color', '#B5EAAA');
}
}
else
{
$('[name=\"'+thisname+'\"]').closest('td').css('background-color', '');
}
});
return items;
}
Can anyone please help? i am stuck for a day now. Can't understand why it saves when the user goes field to field but does not save when button is clicked with validation.
Tested with Firefox. this line appears in red with a Cross sign beside when the button(save_secL class) is clicked. I am using a ssl connection.
POST https://example.com/files/autosave_secL.php x
Here is the modified code trying to implement the solution
$('#submit_survey_secL').click(function()
{
if(valid() !='')
{
var answer = confirm("You have left some questions unanswered. Are you sure you want to Submit and go to Section B? ");
if(!answer)
{
var spl_items = valid().split(',');
$(spl_items[0]).focus();
return false;
}
else
{
$('#hidden_agree').append('<input id=\"secLuseragreed\" name=\"secL_user_agreed\" value=\"unanswered\" type=\"hidden\" />');
autosave(function(){
window.location= "part1secM.php?token=1&id=4"
});
}
}
else
{
$('#hidden_agree').append('<input id=\"secLuseragreed\" name=\"secL_user_agreed\" value=\"unanswered\" type=\"hidden\" />');
autosave(function(){
window.location= "part1secM.php?token=1&id=6"
});
}
});
function autosave(callback)
{
var secL_partL_ques_1_select = $('[name="secL_partL_ques_1_select"]').val();
var secL_partL_ques_1 = $('[name="secL_partL_ques_1"]:checked').val();
var secL_partL_ques_2_select = $('[name="secL_partL_ques_2_select"]').val();
$.ajax(
{
type: "POST",
url: "autosave_secL.php",
data: "secL_partL_ques_1_select=" + secL_partL_ques_1_select + "&secL_partL_ques_1=" + secL_partL_ques_1 + "&user_id=<?php echo $row_token[user_id]?>" + "&updated_by=<?php echo $member."-".$key;?>",
cache: false,
success: function()
{
$("#timestamp").empty().append('Data Saved Successfully!');
if($.isFunction(callback))
{
callback();
}
}
});
}
I don't understand why this doesn't work as callback should totally work. Firebug does not show POST https://example.com/files/autosave_secL.php in red any more but it shows that it has posted but I think the callback is not triggering for some reason
$('.save_secL').click(function() {
//...
//start autosave. Note: Async, returns immediately
autosave();
//and now, before the POST request has been completed, we change location...
window.location= buttonid+".php?token=$row_token[survey_token]&$member=$key&agr=1"
//....and the POST request gets aborted :(
Solution:
function autosave(callback)
{
//...
$.ajax(
{
//...
success: function()
{
$("#timestamp").empty().append('Data Saved Successfully!');
if($.isFunction(callback))
callback();
}
});
}
//and
autosave(function(){
window.location= buttonid+".php?token=$row_token[survey_token]&$member=$key&agr=1"
});
By the way, your autosave function is pretty hard for your server. Did you consider using localStorage + a final POST request containing all data?
I got the solution.
It might be one of the several. scr4ve's solution definitely helped. So here are the points for which I think its working now.
Moved "cache: false, " and removed "async:false" before url: in the ajax autosave function. Before I was putting it after "data: "
Added a random variable after autosave_secL.php/?"+Match.random()
Added scr4ve's solution so that POST is completed before redirect