I'm building push notifications for my messaging system and have a weird bug.
I'm using an ajax to get recent messages. In my PHP script I have a while loop where I go through my results. So each <li> is a 'recent message'.
In my mind it would be simple. I put an ajax function in the <li> and as it iterates through the while loop it will send the values received from the iteration. Below is my PHP script.
$output .= "
<li>
<img src='$profilephoto' class='rm_pp' alt=''>
<div class='imNotification'>
<script>
function getIMNotification() {
$.ajax({
url: 'getIMNotification.php',
method: 'POST',
data:{user2:'$id'},
success:function(data) {
$('.imNotification').html(data);
}
});
}
getIMNotification();
</script>
</div>
</li>
";
For example, in my getIMNotification.php if i just echo the user2 value sent from my AJAX, it will echo the same value for each result. But, since it's in the while loop, shouldn't it receive new values each iteration?
Is it because of the function being called? The one value being echoed is the last id in the loop. Any logic as to why it's doing that?
You shouldn't redefine the function in the loop. You should define the function once, and have it take the ID as a parameter. Then you can call it separately for each LI.
You also need to put the result in the specific DIV for that message. .imNotification selects all the DIVs with that class. You can use $id in the ID of the DIV to target each one.
The function doesn't need to come from AJAX, you can just put this in the original HTML:
function getIMNotification(id, target) {
$.ajax({
url: 'getIMNotification.php',
method: 'POST',
data: {
user2: id
},
success: function(data) {
$('#' + target).html(data);
}
});
}
Then the PHP would be:
$output .= "
<li>
<img src='$profilephoto' class='rm_pp' alt=''>
<div class='imNotification' id='imNotification-$id'>
<script>
getIMNotification('$id', 'imNotification-$id');
</script>
</div>
</li>
";
Related
i have been on this one for a week now folks. I have a newsfeed consisting of many posts. When users comment on a particular post. I want to append their comment to the specific post they commented on without refreshing the page. I have something that is currently working, but not properly.
Code below each time a user comment, the response is appended at the very last post. If it's 100 post loaded on the page and a user comment at number 1. The comment will append at the bottom at the 100 mark.
I am using the postID for my unique ID. Oh my Javascript is in my php loop too. Any help, anyone please.
<ul class='post-comment-list we-comet' id='insertPostsComment$enCodePostsID'>
<!--Post comment echo-->
$getPostComments
<!--Post comment echo-->
<li>
<a href='#' title='' class='showmore underline'>more comments</a>
</li>
<li id='commentForm$enCodePostsID' class='post-comment empty-comment-form'>
<!--Comment form ajax out put-->
<!--Comment form ajax out put-->
</li>
</ul>
/*send comment to post comment reply controller with postID when button is clicked function*/
function sendComment(e) {
$('#submitCommentBtn').addClass('disabled');
comment = $('textarea[name=commentField]').val();
if(comment == ''){
$('div#commentStatus').html('<small>comment is a required field *</small>').css('color', 'red').fadeIn();
return false;
}
//get domain name only
var urLorigin = window.location.origin;
$.ajax({
type: 'POST',
url: urLorigin + '/appName/profile/ajaxSendComment',
cache: false,
data: $('form[name=comment-form]').serialize(),
success: function (response) {
$('textarea[name=commentField]').val(''); //empty textarea
/*display successs message*/
$('div#commentStatus').html('<small>Sent ✓</small>').css('color', 'green').fadeIn();
/*apend comment after send*/
$('div.coment-area').each(function(){
//append
$(response).clone().appendTo($(this).find('ul#insertPostsComment$enCodePostsID'));
});
/*apend comment after send*/
/*delay message closing for 5 seconds*/
$('div#commentStatus').delay(5000).fadeOut(0);
$('#submitCommentBtn').removeClass('disabled');
},
error: function(){
alert('An unknown error occurred!');
}
});
}
i have a feed page which loads posts (known as 'shouts' in my code) from a database based on who the user is following ('scouting' in my code). The basic information is displayed correctly. However, in each post i would like to load a separate file using ajax which will control the likes of the post. Below is my PHP for the feed page:
$findShouts = $pdo->prepare('SELECT * FROM feed WHERE name IN (SELECT scouting FROM scout WHERE scouted =? OR scouting =?) ORDER BY timestamp DESC');
//execute query and variables
$findShouts->execute([$username, $username]);
if ($findShouts->rowCount() > 0)
{
//get the shouts for each scout
while($row = $findShouts->fetch(PDO::FETCH_ASSOC)){
$shoutID[] = $row['id'];
$shoutUsername[] = $row["username"];
$shoutName[] = $row["name"];
$shoutText[] = $row["text"];
$shoutTimestamp[] = $row["timestamp"];
}
$shoutCount = count($shoutUsername);
for($indexShout=0; $indexShout < $shoutCount; $indexShout++) {
print'
<div class=feedNewShout>
<div class=shoutInformation>
<div class=shoutName>
<p>'. $shoutName[$indexShout] .'</p>
</div>
<div class=shoutTimestamp>
<p>'. timeElapsed("$shoutTimestamp[$indexShout]", 2) .'</p>
</div>
<div class=shoutText>
<p>'. $shoutText[$indexShout] .'</p>
</div>
<input type="hidden" name="feedID" class="feedID" value="'. $shoutID[$indexShout] .'">
<div class=likesAjax>
</div>
</div>
</div>';
}
unset($shoutID);
unset($shoutUsername);
unset($shoutName);
unset($shoutText);
unset($shoutTimestamp);
}
In each post the div class=likesAjax performs an ajax call which sends the hidden $feedID to feedlikes.php.
feedLikes.js
$(document).ready(function()
{
var feedID = $(".feedID").val();
$.ajax({
url: "feedLikes.php",
cache: false,
type: "POST",
data: {feedID: feedID},
dataType: "html",
success: function(html){
$(".likesAjax").empty();
$(".likesAjax").append(html);
}
});
});
feedLikes.php
if (isset($_POST['feedID']))
{
$feedID = ($_POST['feedID']);
echo "$feedID";
}
the problem i have is that i can see the ajax goes through every post and echos the feedID, however, every time a new call is made, all the feedID's change to the same thing. I know this is because my success call in my ajax updates every likesAjax class to the same thing. So whatever the feedID is of the last post, will be displayed for all of them.
My question is, how can i load feedLikes.php so that every post is shown with its own $feedID?
Note, feedLikes.php will eventually do something with the ID, the echo is just for test purposes.
Without changing your codes' logic, in PHP you can add an attribute to each ".likesAjax" box called data-id:
<div class="likesAjax" data-id="'.$shoutID[$indexShout] .'">
Now in jQuery in your ajax success function you can update your selector to look for this attribute as well in order to update the correct ".likesAjax" element:
$(".likesAjax[data-id='"+ feedID +"']").append(html);
To put these all together you would need to loop through your .likesAjax elements. To make your code a little cleaner you should make a function with the feedID as a parameter that will be executed for every step of the loop. This will look like the following:
$(".likesAjax").each(function() {
var feedID = $(this).attr("data-id");
loadFeedLikes(feedID);
});
function loadFeedLikes(feedID) {
$.ajax({
url: "feedLikes.php",
cache: false,
type: "POST",
data: {feedID: feedID},
dataType: "html",
success: function(html){
$(".likesAjax[data-id='"+ feedID +"']").html(html);
}
});
}
If you want to make this lighter you can create a new feedLikes.php that takes all the feedLikes you have and pushes them in an array. This array should contain the content you need and the feedId. Then you would only need one ajax call and with a for loop you could loop through the results and update all the $(".likesAjax") elements at once. This way you will have only one query to your db and only one ajax call to fetch your data.
This is my tree view
I have already done that when i do right click tree name(For example ,Asset, Non Current , Shah) and click add head Then there will come jquery dialog form and I add head code and head name and it is saved successfully in mysql database using codeigniter frame work in php.
Basically , it is created subhead under head.
I need when after submitting, it will be display subhead under that head without refresh tree. For Example ,
If i create subhead under asset then append subhead after "104-Kamrul" without refresh and Display without Change.
How can i solve it, Please any suggestions?
i think you need ajax to make what you need, just use a specific class for each tree parent for example:
<div class="parent-1">
<div class="child-1"></div>
<div class="child-2"></div>
</div>
<div class="parent-2">
<div class="child-1"></div>
<div class="child-2"></div>
</div>
now just load what you need following parents classess:
$('.parent-1').children('.child-1').load('http://site.com/url/to/load/new/childs');
or
var _childs = $.get('http://site.com/url/to/get/some/childs');
$('.parent-1').append(_childs);
Given the following markup:
<div id="tree">
<ul>
<li>Asset
<ul>
<li>101-Non Current</li>
<li>102-Current Asset</li>
<li>103-Abdul Halim Shah
<ul>
<li>10301-Shah
<ul>
<li>1030101</li>
</ul>
</li>
</ul>
</li>
<li>104-Kamrul</li>
</ul>
</li>
<li>2-Expenses</li>
</ul>
</div>
I wrote a couple of jQuery functions to dynamically add new nodes. One adds the node below the selector specified and the other adds it as a sibling:
function addSibling(selector, content) {
var markup = '<li>' + content + '</li>';
$(selector).parent().append(markup);
}
function addChild(selector, content){
var obj = $(selector);
var markup='<li>' + content + '</li>';
var element;
if ($('ul', selector).length > 0){
//nested list
element = obj.find('> ul');
} else {
element = obj;
markup = '<ul>' + markup + '</ul>';
}
element.append(markup);
}
Although you'll have to adapt them to your code, you can use the following click function to test them:
$("#tree ul").click(function (e) {
//addSibling(e.target, 'new one');
addChild(e.target, 'new one');
e.stopPropagation();
});
I didn't understand what your variable were, but to get the data to the server without a page load, you can use an ajax function something like the following:
$('#form').submit(function() {
var headCode = $('input[name="headCode"]').val();
var headName = $('input[name="headName"]').val();
$.ajax({
url: "load.php",
type: 'POST',
data: {
head_code: headCode,
head_name: headName
},
cache: false,
success: function(json){
alert('loaded');
}
});
return false;
});
I want to use the jQuery UI sortable function to allow users to set an order and then on change, write it to the database and update it. Can someone write an example on how this would be done?
The jQuery UI sortable feature includes a serialize method to do this. It's quite simple, really. Here's a quick example that sends the data to the specified URL as soon as an element has changes position.
$('#element').sortable({
axis: 'y',
update: function (event, ui) {
var data = $(this).sortable('serialize');
// POST to server using $.post or $.ajax
$.ajax({
data: data,
type: 'POST',
url: '/your/url/here'
});
}
});
What this does is that it creates an array of the elements using the elements id. So, I usually do something like this:
<ul id="sortable">
<li id="item-1"></li>
<li id="item-2"></li>
...
</ul>
When you use the serialize option, it will create a POST query string like this: item[]=1&item[]=2 etc. So if you make use - for example - your database IDs in the id attribute, you can then simply iterate through the POSTed array and update the elements' positions accordingly.
For example, in PHP:
$i = 0;
foreach ($_POST['item'] as $value) {
// Execute statement:
// UPDATE [Table] SET [Position] = $i WHERE [EntityId] = $value
$i++;
}
Example on jsFiddle.
Thought this might help as well. A) it was designed to keep payload to its minimum while sending back to server, after each sort. (instead of sending all elements each time or iterating through many elements that server might chuck out) B) I needed to send back custom id without compromising the id / name of the element. This code will get the list from asp.net server and then upon sorting only 2 values will be sent back: The db id of sorted element and db id of the element next to which it was dropped. Based on those 2 values, server can easily identify the new postion.
<div id="planlist" style="width:1000px">
<ul style="width:1000px">
<li plid="listId1">List 1</li>
<li plid="listId2">List 1</li>
<li plid="listId3">List 1</li>
<li plid="listId4">List 1</li>
</ul>
<div id="pl-1"></div>
<div id="pl-2"></div>
<div id="pl-3"></div>
<div id="pl-4"></div>
</div>
<script type="text/javascript" language="javascript">
$(function () {
var tabs = $("#planlist").tabs();
tabs.find(".ui-tabs-nav").sortable({
axis: "x",
stop: function () {
tabs.tabs("refresh");
},
update: function (event, ui) {
//db id of the item sorted
alert(ui.item.attr('plid'));
//db id of the item next to which the dragged item was dropped
alert(ui.item.prev().attr('plid'));
//make ajax call
}
});
});
</script>
You're in luck, I use the exact thing in my CMS
When you want to store the order, just call the JavaScript method saveOrder(). It will make an AJAX POST request to saveorder.php, but of course you could always post it as a regular form.
<script type="text/javascript">
function saveOrder() {
var articleorder="";
$("#sortable li").each(function(i) {
if (articleorder=='')
articleorder = $(this).attr('data-article-id');
else
articleorder += "," + $(this).attr('data-article-id');
});
//articleorder now contains a comma separated list of the ID's of the articles in the correct order.
$.post('/saveorder.php', { order: articleorder })
.success(function(data) {
alert('saved');
})
.error(function(data) {
alert('Error: ' + data);
});
}
</script>
<ul id="sortable">
<?php
//my way to get all the articles, but you should of course use your own method.
$articles = Page::Articles();
foreach($articles as $article) {
?>
<li data-article-id='<?=$article->Id()?>'><?=$article->Title()?></li>
<?
}
?>
</ul>
<input type='button' value='Save order' onclick='saveOrder();'/>
In saveorder.php; Keep in mind I removed all verification and checking.
<?php
$orderlist = explode(',', $_POST['order']);
foreach ($orderlist as $k=>$order) {
echo 'Id for position ' . $k . ' = ' . $order . '<br>';
}
?>
This is my example.
https://github.com/luisnicg/jQuery-Sortable-and-PHP
You need to catch the order in the update event
$( "#sortable" ).sortable({
placeholder: "ui-state-highlight",
update: function( event, ui ) {
var sorted = $( "#sortable" ).sortable( "serialize", { key: "sort" } );
$.post( "form/order.php",{ 'choices[]': sorted});
}
});
I can change the rows by following the accepted answer and associated example on jsFiddle. But due to some unknown reasons, I couldn't get the ids after "stop or change" actions. But the example posted in the JQuery UI page works fine for me. You can check that link here.
Try with this solution: http://phppot.com/php/sorting-mysql-row-order-using-jquery/
where new order is saved in some HMTL element.
Then you submit the form with this data to some PHP script,
and iterate trough it with for loop.
Note: I had to add another db field of type INT(11) which is updated(timestamp'ed) on each iteration - it serves for script to know which row is recenty updated, or else you end up with scrambled results.
I had to ask this one again, sorry. So I am running this jQuery to slide toggle a span in my PHP loops output. I have some PHP that generates some calls to the db to get more detailed information back for each item.
I know so far I have got it making the call to the PHP script. I can see the packets returning with the HTML echoed from the PHP file. but I'm having difficulty getting jQuery to insert the returned data into the specified span.
This is a simplified version of what the loop items look like:
<span class="searchitem">
<span style="visibility:hidden;" class="name">some name</span>
<span class="btn">Details</span>
<span class="itemdetails" style="display: none;">
//hidden area to populate with returned ajax html from php script
</span>
</span>
<span class="searchitem">
<span style="visibility:hidden;" class="name">another name</span>
<span class="btn">Details</span>
<span class="itemdetails">
<div>
<p>
this is the area i need the html to populate
</p>
</div>
</span>
</span>.................
This is the jQuery that I'm trying to run. I know everything works up to success. I can't get the data from there.
<script type="text/javascript">
var ajax_load = "<img src='images/loading.gif' style='width:50px;' alt='loading...' />";
var loadUrl = "ajax/item_details.php";
$(document).ready(function ()
{
$('.searchitem').each(function () {
var itemname = $(this).find('.name').text();
var ename = encodeURI(itemname);
var requestUrl = loadUrl + ename;
$(this).find('.itemdetails').hide();
$(this).find('.btn').click(function ()
{
var returned = "";
$.ajax({
type: "GET",
url: loadUrl,
data: "name=" + ename,
dataType: "text",
error: function () { alert("error") },
success: function (data) { $(".ptavail").append(data); alert("successful") }
});
$(this).parent().find('.ptavail').html(ajax_load).slideToggle(1500).html(returned);
});
});
});
</script>
As you can see from the code I'm trying to get the click function the set everything off. I know the PHP file is receiving the call and returning the data but I'm stuck trying to get the jQuery to fill the .itemdetails with the returned data.
What is wrong with this? Would I need to put the AJAX into a separate function for it to behave like I need, or do I need to make it synchronous for it to work? I'm trying to basically replace everything between .itemdetails spans with first a loading symbol and then the data returned with AJAX.... As it is now I get error alert so there's something wrong with the ajax call I know it does the request properly and the PHP returns the results but getting AJAX to read them is proving problematic.
I can see that the content type in the headers is text, so how do I get the AJAX to do the call properly?
Put $(this).parent().find('.itemdetails').html(ajax_load).slideToggle(1500).html(data);
inside the "success" part of the Ajax request.
success: function(data) {
$(this).parent().find('.itemdetails').html(ajax_load).slideToggle(1500).html(data);
}
The success function is there to say "when the Ajax has worked, do this"