i'm using $.get() to get some elements from a php script and then show the results by "writing" them into a div. This is done periodically, as well as when the div is clicked or when the page reloads. Here's the code:
function fetchnew(){
var status = $J.cookie("status_on");
if (status == 'on'){
//fetch new items
//results from new-items.php have this format:
//<p>Item1</p><p>Item2</p>...
$J.get(modulebaselink+'new-items.php', '', function(newitems){
$J('#content').html(newitems);
updatestatus();
});
}
fetchnew_timeout = setTimeout('fetchnew();', refresh_rate);
}//end fetchnew()
function updatestatus(){
var status = $J.cookie("status_on");
if (status == 'on'){
//Show number of loaded items
var totalItems=$J('#content p').length;
$J('#status').html("Items ("+totalItems+")");
}
}
My problem is that the #status contents display with some delay after page reload. When the page loads i get 'Items(0)' for about ~1 sec, and then 0 changes to the real value. Is there any way to void the 'Items(0)' before displaying the real value? Or at least, cache the previous value and display 'Items(old_value)' instead of 'Items(0)' before the 'Items(new_value)' appears. I tried cookies to do the last one, but 'Items(0)' was there again...
Sounds like a reasonable usecase for the localStorage. Extend updatestatus() like this:
// this should be called at some entry point of your script
var ls_available = 'localStorage' in window;
if(ls_available && localStorage.getItem('totalItems'))
$J('#status').html("Items ("+localStorage.getItem('totalItems')+")");
function updatestatus(){
var status = $J.cookie("status_on");
if (chat_status == 'on'){
var totalItems=$J('#content p').length;
$J('#status').html("Items ("+totalItems+")");
if(ls_available) localStorage.setItem('totalItems', totalItems);
}
}
If your page (the one where fetchnew() is called) is rendered in PHP, call the same function that the Ajax file (new-items.php) calls. That way, your content is there immediately.
Related
I'm trying to implement SEO friendly infinite scrolling in accordance with google's recommendations as seen here (http://scrollsample.appspot.com/items?page=7). I have a jquery function that sends a request to a php file, (which requests the data from the db) anytime someone scrolls to the bottom of the page, now everything is working fine except that when the user scrolls to the bottom of the page, the request function gets fired more than once. So duplicate entries of the data gets loaded into the page, now i know this isn't from my php file because i opened the page directly in my browser and everything was fine. Checkout the bug here http://devx.dx.am/haze/categor.php?artemis=foo&&page=1
I have already tried the solutions here (jQuery .load() callback function fires multiple times) and here ($(window).load() is executing 2 times?) and a few others as well.
$(window).bind('scroll', function() { //#cagorwrap is the div that should contain the data retrieved
if($(window).scrollTop() >= $('#cagorwrap').offset().top + $('#cagorwrap').outerHeight() - window.innerHeight) { //344.6
var queryParameters = {}, queryString = location.search.substring(1),
re = /([^&=]+)=([^&]*)/g, m;
while (m = re.exec(queryString)) {
queryParameters[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
}
var url2 = "modules/paginate.php?numpages=set";
// #rc is a hidden div too
$("#rc").load(url2, function() {
var rc = $(this).html();
if (queryParameters['page'] < rc) {
queryParameters['page']++;
console.log(rc);
var stateObj = queryParameters['page'];
let cagh = $('#cagorwrap').height() + 344.6 - 75;
$("#cagorwrap").height(cagh);
history.pushState(null, null, "categor.php?artemis=cat&&page="+stateObj);
var url = "modules/paginate.php?artemis=cats&&page="+stateObj;
$("#obtainer").load(url, function () {
$("#cagorwrap").append($(this).html());
}); //#obtainer is a hidden div that receives the data at first before it is appended to #cagorwrap
} else{
//unbind scroll here
}
});
}
});
well if all else fails and you absolutely need a solution, you can add a
counter=1; on the start
and only fire the request function in the case below
counter++;
if (counter%2==0){//fire request}
It's not clean, but if you're loosing too much time with this and want to return to the problem later on...
I have an index.php file that I would like to run getdata.php every 5 seconds.
getdata.php returns multiple variables that need to be displayed in various places in index.php.
I've been trying to use the jQuery .load() function with no luck.
It's refreshing the 12 <div> elements in various places on the index.php, but it's not re-running the getdata.php file that should get the newest data.
But If I hit the browser refresh button, the data is refreshed.
getdata.php returns about 15 variables.
Here is some sample code:
<script>
var refreshId = setInterval(function()
{
$('#Hidden_Data').load('GetData.php'); // Shouldn´t this return $variables
$('#Show_Data_001').fadeOut("slow").fadeIn("slow");
$('#Show_Data_002').fadeOut("slow").fadeIn("slow");
$('#Show_Data_003').fadeOut("slow").fadeIn("slow");
$('#...').fadeOut("slow").fadeIn("slow");
}, 5000); // Data refreshed every 5 seconds
*/
</script>
Here's an example of GetData.php:
$query = "SELECT column1, COUNT(column2) AS variable FROM table GROUP BY column";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
$column1 = $row['column1 '];
$variable = $row['variable '];
if($column1 == "Text1") { $variable1 = $variable; }
elseif($column1 == "Text2") { $variable2 = $variable; }
... continues to variable 15 ...
}
Then further down the page the HTML elements display the data:
<div id="Hidden_Data"></div>
<div id="Show_Data_001"><?php echo $variable1; ?></div>
<div id="Show_Data_002"><?php echo $variable2; ?></div>
<div id="Show_Data_003"><?php echo $variable3; ?></div>
...
I tried using the data parameter as suggested here:
https://stackoverflow.com/a/8480059/498596
But I couldn't fully understand how to load all the variables every 5 seconds and call them on the index page.
Today the GetData.php page just returns $variable1 = X; $variable2 = Y and so on.
UPDATE
For some reason the jQuery is not loading the GatData.php file and refreshing the variables.
I tried adding to "Hidden_Data" to the include('GetData.php') and then the variables are readable on the page.
If I remove this part, the page displays "variable not set" warning that suggesting that the jQuery is not loading the GetData.php script into the Hidden_Data <div>.
Try
<script>
var refreshId = setInterval(function()
{
$('#Hidden_Data').load('GetData.php', function() { // Shouldn´t this return $variables
$('#Show_Data_001').fadeOut("slow").fadeIn("slow");
$('#Show_Data_002').fadeOut("slow").fadeIn("slow");
$('#Show_Data_003').fadeOut("slow").fadeIn("slow");
$('#...').fadeOut("slow").fadeIn("slow"); });
}, 5000); // Data refreshed every 5 seconds
*/
</script>
Above is assuming, that your code returns snippet of HTML elements (Show_Data_XXX), but now that you've clarified your question above wont help you alone...
What you need to do is either in your php send back new value elements or send back your results as data and update existing elements.
Put your elements into a php Array and then send it back
data.php after sql call
$results = Array();
while($row = mysql_fetch_array($result)){
$column1 = $row['column1 ']; // change Text1 in db to Show_Data_001 in html or vice versa
$variable = $row['variable '];
$results[$column1] = $variable;
}
echo json_encode($results);
in your javascript something like this...
$.getJSON('GetData.php',function(data) {
$.each(data, function(key, val) {
$('#'+key).text(val);
});
});
I didn't put the fadeOut and fadeIn into the example, because it complicates it a bit. You could do fadeOut to all those elements before calling getJSON and the fadeIn as the results pouring in. Hope this helps
First of all, make sure you have correct respond from server, just like this:
//We won't use load() to load content for now
window.setInterval(function(){
$.ajax({
url : "path_to_your_php_script.php",
type : "GET",
beforeSend: function(){
//here you can display, smth like "Please wait" in some div
},
error : function(msg){
//You would know if an error occurs
alert(msg);
},
success : function(respondFromPHP){
//Are you getting distinct results every 5 sec?
alert(respondFromPHP);
return;
//if respondFromPHP contains data you want
//ONLY THEN, add some effects
}
});
}, 5000);
The only difference between this approach and yours, is that, you can handle errors and make sure you are getting data you want.
Can you show me the code of GetData.php?
Rather than using Jquery.load you can actually get the page with $.post or $.get and format your results from GetData.php to Json or xml you can easily map it to your javascript.
Using $.post it will allow you to have a callback after getting the value from GetData.php and you can check it if it's working right or not. If it gets a data from your GetData.php then you can populate it to your DIV elements.
You can check more information regarding POST and GET here:
http://api.jquery.com/jQuery.post/
I am trying to delete the data against the remove (Ajax) option.When i click the remove button it deletes the data from the database and the page should automatically disappear the data.But it does not happen,it deletes the data but not disappeared from the screen.When i refreshed the page then in the page the data is disappeared......Please help me
The html code...
<table><tr><td>Remove</td>
<td id="resId"></td></tr></table>
The ajax function is....
function remove(){
var http = GetXmlHttpObject();
http.onreadystatechange = function()
{
if(http.readyState==4)
{
document.getElementById("resId").innerHTML = http.responseText;
//alert(http.responseText);
}
}
var name1 = document.getElementById("bn").innerHTML;
//alert(name);
var url = "index.php?menu=remove_cart&ajax=ajax&q="+name1;
http.open('POST',url,true);
http.send(null);
}
And the PHP function is....
function remove_cart($name1){
global $template;
$sql = "DELETE FROM tbl_buy WHERE b_name = '$name1'";
$this->db->executeQuery($sql);
$template->main_content = $template->fetch(TEMPLATE_DIR . 'my_cart.htm');
}
By using AJAX to modify your database, you have disabled the browser's default refresh mechanism: the page reload. Therefore, you have to provide your own page refresh mechanism with JavaScript. You'll want to add some custom success messaging in your PHP that tells your JS that everything is good.
if(http.readyState==4)
{
document.getElementById("resId").innerHTML = http.responseText;
//alert(http.responseText);
if (http.status==200){ //on successful server response
//check responsetext for successful DB delete
if ('successful DB delete'){ //pseudo-code condition
//javascript to remove element representing the DB row from the HTML DOM
//ie. element.parentNode.removeChild(element);
}
}
}
For the 'element' JS variable to mean the element that was clicked, modify your remove() function and the way it's called:
function remove(element){
//...
}
and
<table><tr><td>Remove</td>
<td id="resId"></td></tr></table>
where this.parentNode.parentNode references the <tr> above the <a>.
Hope that helps.
As you are removing data using ajax call and must be getting success/failure response from server side.
I suggest you to refresh the or area where you are displaying data when you get success response from server
In the callback where you have the following code:
document.getElementById("resId").innerHTML = http.responseText;
Write some functionality that removes the item from the dom.
At the moment you are just writing the response to the innerHTML of some html element which is probably going to result in nothing.
I seriously recomend jQuery for dom manipulation and as an ajax library.
EDIT:
Noticing a comment above mentioning a "cart template" is used. You'll need to update the innerHTML of the element that contains your cart, with the responseText.
I like to use:
http://api.jquery.com/remove/
To remove the DOM element. Or, if you want to keep the element, but make it's child elements and text delete, use:
http://api.jquery.com/empty/
Hope that helps...
One quick and dirty way to acomplish this would be to refresh the page on successfull ajax call, like this:
if(http.readyState==4 && xmlhttp.status==200)
{
document.getElementById("resId").innerHTML = http.responseText;
//alert(http.responseText);
//refresh page
window.location.href=window.location.href;
}
I'm having a problem with my infinite scrolling. As I scroll down, it loads the next items fine but it keeps sending those items. I've been using this jquery to give it a unique id because I have ordered the items with mysql with an algorithm:
$("#image-list li").each(function(index) {
$(this).attr('id', index);
});
and inorder to label the newly given items from an external php file, I have to use this code in the file as well.
To send the information about the items given, I've been using this jquery:
function last_db_item_function()
{
var ID=$(".db-item:last").attr("id");
$('div#last-db-item-loader').html('<img src="loading.gif" height="30px" />');
$.post("index.php?action=get&last_db_item="+ID,
function(data){
if (data != "") {
$(".db-item:last").after(data);
}
$('div#last-db-item-loader').empty();
});
};
$(window).scroll(function(){
if ($(window).scrollTop() == $(document).height() - $(window).height()){
last_db_item_function();
}
});
but the problem is that it does not seem to work. Which I mean it doesn't not gather that last item id from the newly parsed php file. To parse the php I've been doing this:
$last_db_item = $_GET['last_db_item'];
$action = $_GET['action'];
if($action != "get")
{
.... Code Here....
}else{
include ('secondimages.php');
}
So my question is, why does this seem to go on forever?
It looks like you're never assigning a new ID to the new elements when you append them to the list. The first snippet you have either needs to be called after every new element is added, or similar code needs to be applied to that one element when you add it (unless it's coming back in the php, at which point we'd need to know more about what you're returning)
I have a form that when you submit it, it sends the data for validation to another php script via ajax. Validation errors are echo'd back in a div in my form. A success message also is returned if validation passes.
The problem is that the form is still displayed after submit and successful validation. I want to hid the div after success.
So, I wrote this simple CSS method which works fine when called from the page the form is displayed on.
The problem is that I cannot seem to call the hide script via returned code. I can return html like
echo "<p>Thanks, your form passed validation and is being sent</p>";
So I assumed I could simply echo another line after that
echo "window.onload=displayDiv()"; inside script tags (which I cannot get to display here)...
and that it would hide the form div.
It does not work. I am assuming that the problem is that the javascript is being returned incorrectly and not being interpreted by the browser...
How can I invoke my 'hide' script on the page via returned data from my validation script? I can echo back text but the script call is ineffective.
Thanks!
This is the script on the page with the form...
I can call it to show/hide with something like onclick="displayDiv()" while on the form but I don't want the user to invoke this... it has be called as the result of a successful validation when I write the results back to the div...
<script language="javascript" type="text/javascript">
function displayDiv()
{
var divstyle = new String();
divstyle = document.getElementById("myForm").style.display;
if(divstyle.toLowerCase()=="block" || divstyle == "")
{
document.getElementById("myForm").style.display = "none";
}
else
{
document.getElementById("myForm").style.display = "block";
}
}
</script>
PS: I am using the mootools.js library for the form validation if this matters for the syntax..
The AJAX call is:
window.addEvent('domready', function(){
$('myForm').addEvent('submit', function(e) {
new Event(e).stop();
var log = $('log_res').empty().addClass('ajax-loading');
this.send({
update: log,
onComplete: function() {
log.removeClass('ajax-loading');
}
});
});
});
Div ID log is where the ajax call back text (validation errors and success message) and loading graphic appear
This is a duplicate of How to make JS execute in HTML response received using Ajax? where I provided the chosen solution.
var response = "html\<script type=\"text/javascript\">alert(\"foo\");<\/script>html";
var reScript = /\<script.*?>(.*)<\/script>/mg;
response = response.replace(reScript, function(m,m1) {
eval(m1); //will run alert("foo");
return "";
});
alert(response); // will alert "htmlhtml"
Your AJAX call should have a "success" callback. It looks like you can simply call displayDiv() in that callback.
Also note that the var divstyle = new String(); line is unnecessary. Strings are immutable in JavaScript, so you are creating an empty string object, which remains unreferenced in the following line. Simply declare the variable when you assign it from document.getElementById():
var divstyle = document.getElementById("myForm").style.display;
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
//Since your making php do the validation, there would be two cases,
//the first case is that the php script is not echoing any thing on success, and
//the other case is that its echoing the error massages which will be assignedxmhttp.responseText
//so we need to check that xmlhttp.resposeText has been asigned a value.
if(xmlhttp.resposeText){
document.getElementById(displayContainers_id).innerHTML=xmlhttp.responseText;
}
}