I am using JavaScript, jQuery and PHP. How do I limit the JavaScript function to execute once?
My MainJQuery file has Ajax. display.php execute for a while:
....
$.ajax({
type:'POST',
url: 'display.php',
data:'id='+id ,
success: function(data){
$("#response").html(data);
//Here Get_list should be execute only once.
get_list('get');
// Display should execute as usual
display();
}//success
}); //Ajax
.......
get.Php file writes a value to JavaScript:
<?php
print "<script language='javascript'>";
print " g_cost[g_cost.length]=new Array('STA-VES','East',4500);";
print " g_cost[g_cost.length]=new Array('STA-CRF','West',5400);";
print "</script>";
?>
My JavaScript function has the following value from PHP:
function get_list('get'){
for(var i=0;i<g_cost.length;i++)
var temp = g_cost[i];
var Name = temp[0];
var direction = temp[1];
var cost = temp[2];
..
some code
...
}
function display(){
for(var i=0;i<g_cost.length;i++)
alert(g_cost.length);
var temp = g_cost[i];
alert(temp[0]);
alert(temp[1]);
alert(temp[2]);
}
Is it possible to limit to execute a JavaScript function in the jQuery Ajax success portion?
In jQuery you can use the .one() function to bind a method that will execute only once. For example,
$("#someAnchorId").one("click", function(){
//Ajax method here
});
See jQuery one help topic.
You can replace the function with an empty function - this is essentially the same as Rene Saarsoo' solution, but looks nicer:
var get_list = function(param1, param2, ...) {
// your code here
get_list = function() {};
};
Three options:
Set a boolean flag in global scope, set it after a successful run, and check it before running
After a successful run, disable the button (or whatever control you are using to call the one-time method)
Slightly less preferred, but you can also do the validation on server side, i.e. call the method each time, but validate on server-side. The up side is that this will ensure data consistency on the server.
To create a function that executes only once:
get_list = (function(){
var counter = 0;
return function(param1, param2, ...) {
if (counter > 0) {
return;
}
counter++;
// your normal function code here
};
})();
This is almost the same as using a global variable for tracking how many times function is executed, except that instead of a global variable we create a variable, that only the inner function can see. After that you use it get_list as any other function.
This could probably be refactored into something more general in function prototye, so it could be used like this:
get_list = (function (param1, param2, ...) {
...
}).once();
Fastest way is to add one extra line to success declaration:
$.ajax({
type:'POST',
url: 'display.php',
data:'id='+id ,
success: function(data){
if(!arguments.callee.stop){ arguments.callee.stop = true; }else{ return; }
$("#response").html(data);
//Here Get_list should be execute only once
get_list('get');
// display should execute as usual
display();
}//success
}); //ajax
Try disabling the Ajax trigger (link, button, etc.) after a successful call.
Example of a trigger:
<a id="ajax_trigger" href="#" onclick="yourAjaxCall(); return false;">Get List</a>
...
success: function(data){
$("#response").html(data);
//Here Get_list should be execute only once
get_list('get');
// Some code to disable, or hide #ajax_trigger
// in other words, make it unclickable or disappear.
$("#ajax_trigger").css('display': 'none'); // IIRC
// Display should execute as usual
display();
}//success
Related
What i want to do is, to show a message based on certain condition.
So, i will read the database after a given time continuously, and accordingly, show the message to the user.
But i want the message, to be updated only on a part of the page(lets say a DIV).
Any help would be appreciated !
Thanks !
This is possible using setInterval() and jQuery.load()
The below example will refresh a div with ID result with the content of another file every 5 seconds:
setInterval(function(){
$('#result').load('test.html');
}, 5000);
You need a ajax solution if you want to load data from your database and show it on your currently loaded page without page loading.
<script type="text/javascript" language="javascript" src=" JQUERY LIBRARY FILE PATH"></script>
<script type="text/javascript" language="javascript">
var init;
$(document).ready(function(){
init = window.setInterval('call()',5000);// 5000 is milisecond
});
function call(){
$.ajax({
url:'your server file name',
type:'post',
dataType:'html',
success:function(msg){
$('div#xyz').html(msg);// #xyz id of your div in which you want place result
},
error:function(){
alert('Error in loading...');
}
});
}
</script>
You can use setInterval if you want to make the request for content periodically and update the contents of your DIV with the AJAX response e.g.
setInterval(makeRequestAndPopulateDiv, "5000"); // 5 seconds
The setInterval() method will continue calling the function until clearInterval() is called.
If you are using a JS library you can update the DIV very easily e.g. in Prototype you can use replace on your div e.g.
$('yourDiv').replace('your new content');
I'm not suggesting that my method is the best, but what I generally do to deal with dynamic stuff that needs access to the database is the following method :
1- A server-side script that gets a message according to a given context, let's call it "contextmsg.php".
<?php
$ctx = intval($_POST["ctx"]);
$msg = getMessageFromDatabase($ctx); // get the message according to $ctx number
echo $msg;
?>
2- in your client-side page, with jquery :
var DIV_ID = "div-message";
var INTERVAL_IN_SECONDS = 5;
setInterval(function() {
updateMessage(currentContext)
}, INTERVAL_IN_SECONDS*1000);
function updateMessage(ctx) {
_e(DIV_ID).innerHTML = getMessage(ctx);
}
function getMessage(ctx) {
var msg = null;
$.ajax({
type: "post",
url: "contextmsg.php",
data: {
"ctx": ctx
},
success: function(data) {
msg = data.responseText;
},
dataType: "json"
});
return msg;
}
function _e(id) {
return document.getElementById(id);
}
Hope this helps :)
I have a notification div. When someone clicks one of the links, the number of notification will be changed and after that the user will be redirected to the link that he clicked. Here is the php script inside the div.
<?php
while($row = stmt->fetch(PDO::FETCH_OBJ))
{
echo "<p><a href='http://example.com/blog/index.php?t_id=".$t_id."&c_id=".$c_id."'>".$title."</a></p>";
}
?>
I am using the following Jquery inside the div:
<script>
$('p').click(function(event){
event.preventDefault();
$.ajax({
type: "POST",
url: "http://www.example.com/change_notification.php"
})
.done(function( msg ) {
$("#changed_notification_value").text( msg );
var n_url = $('a', this).attr('href');
window.location.href = n_url;
});
});
</script>
Number of the notification changes successfully but when trying to redirect, the value of n_url shows undefined.
I think you have a problem of scope when using this. You can do something like this to fix the problem. Get the n_url before making the ajax request.
$('p').click(function (event) {
event.preventDefault();
var n_url = $('a', this).attr('href');
$.ajax({
type: "POST",
url: "http://www.example.com/change_notification.php"
}).done(function (msg) {
$("#changed_notification_value").text(msg);
window.location.href = n_url;
});
});
try this
var n_url = $(this).find('a').attr('href');
Try this:
var n_url = $(this).find("a").attr('href');
window.location.href = n_url;
this does not work like it does in other languages. When not inside a function (think global space) this refers to the Window object of the current browser. By default, new functions are created as children of Window.
For example;
function foo() {
return this;
}
Is actually the same as Window.foo = function() { return this; } (unless browser is in strict mode).
So when you call foo() the following is true.
foo() === window; // True, because foo() returns this which is window.
Since by default this refers to the object the function is bound to. You can change the default value of this by binding the function to a different object.
var o = {
x: 99,
foo: function() {
return this.x;
}
};
console.log(o.foo()); // will output 99
It doesn't matter when you bind the function to an object. As in this example.
var a = {
x: 99
};
var b = {
x: 77
};
function foo() {
return this.x;
}
a.f = foo;
b.f = foo;
console.log(a.f()); // will output 99
console.log(b.f()); // will output 77
In the above example the function foo is the same, but this changes depending on which bound object reference was used to call it.
So what is going on with DOM events?
The function is bound to the DOM element, and that's a Javascript object. So this refers to the object that triggers the event. Even if the same function is bound to multiple elements. this always refers to the one that triggered the function.
So now back your source code and problem. Your using this inside the .done(function(msg){....}) function. jQuery has bound the ajax object to the function so that this refers to that object.
You can change what this refers too by using the bind() function. bind lets you change what object is bound to the function so that this refers to that object instead.
$('p').click(function(event){
event.preventDefault();
$.ajax({
type: "POST",
url: "http://www.example.com/change_notification.php"
}).done(function( msg ) {
$("#changed_notification_value").text( msg );
var n_url = $('a', this).attr('href');
window.location.href = n_url;
}.bind(this));
});
Above, I didn't change your source code but just added .bind(this) to the end of your function(msg){...}.bind(this). The object this refers to outside the function is the DOM element that triggered the event, and by binding it to your callback function for done your source code should now work.
I'm working with this code snippet plugin : http://www.steamdev.com/snippet/ for my blog
but the plugin doesn't work on page load.
It only works at first page refresh.
I load my content in a specific div with jquery.ajax request and i'm trying this :
$(window).on("load", function(){
$("pre.cplus").snippet("cpp",{style:"acid"});
$("pre.php").snippet("php",{style:"acid"});
});
I also tried to trigger the load event but i don't know if it is correct..
Another question : i build my html with php string like this example:
$string = '<pre class="cplus">
#include <iostream>
int main()
{
//c++ code
}
</pre>
<pre class="php">
<?php
function foo()
{
// PHP code
}
?>
</pre>';
echo $string; // ajax -> success
but the PHP snippet shows empty (the c++ is ok). Any other way (or plugin) to show php code snippet on my page?
Thank you.
SOLVED:
The problem isn't the plugin or Iserni suggestions.. i had a problem in page load (ajax)..
This is how i load the pages:
function pageload(hash) {
if(hash == '' || hash == '#php')
{
getHomePage();
}
if(hash)
{
getPage();
}
}
function getHomePage() {
var hdata = 'page=' + encodeURIComponent("#php");
//alert(hdata);
$.ajax({
url: "homeloader.php",
type: "GET",
data: hdata,
cache: false,
success: function (hhtml) {
$('.loading').hide();
$('#content').html(hhtml);
$('#body').fadeIn('slow');
}
});
}
function getPage() {
var data = 'page=' + encodeURIComponent(document.location.hash);
//alert(data);
$.ajax({
url: "loader.php",
type: "GET",
data: data,
cache: false,
success: function (html) {
$('.loading').hide();
$('#content').html(html);
$('#body').fadeIn('slow');
}
});
}
$(document).ready(function() {
// content
$.history.init(pageload);
$('a[href=' + window.location.hash + ']').addClass('selected');
$('a[rel=ajax]').click(function () {
var hash = this.href;
hash = hash.replace(/^.*#/, '');
$.history.load(hash);
$('a[rel=ajax]').removeClass('selected');
$(this).addClass('selected');
$('#body').hide();
$('.loading').show();
getPage();
return false;
});
// ..... other code for menus, tooltips,etc.
I know this is experimental , i have made a mix of various tutorials but now it works..
comments are much appreciated..
Thanks to all.
The PHP snippet seems empty because the browser believes it's a sort of HTML tag.
Instead of
$string = '<pre class="php">
<?php
function foo()
{
// PHP code
}
?>
</pre>';
you need to do:
// CODE ONLY
$string = '<?php
function foo()
{
// PHP code
}
?>';
// HTMLIZE CODE
$string = '<pre class="php">'.HTMLEntities($string).'</pre>';
As for the jQuery, it is probably due to where you put the jQuery code: try putting it at the bottom of the page, like this:
....
<!-- The page ended here -->
<!-- You need jQuery included before, of course -->
<script type="text/javascript">
(function($){ // This wraps jQuery in a safe private scope
$(document).ready(function(){ // This delays until DOM is ready
// Here, the snippets must be already loaded. If they are not,
// $("pre.cplus") will return an empty wrapper and nothing will happen.
// So, here we should invoke whatever function it is that loads the snippets,
// e.g. $("#reloadbutton").click();
$("pre.cplus").snippet("cpp",{style:"acid"});
$("pre.php").snippet("php",{style:"acid"});
});
})(jQuery); // This way, the code works anywhere. But it's faster at BODY end
</script>
</body>
Update
I think you could save and simplify some code by merging the two page loading functions (it's called the DRY principle - Don't Repeat Yourself):
function getAnyPage(url, what) {
$('.loading').show(); // I think it makes more sense here
$.ajax({
url: url,
type: "GET",
data: 'page=' + encodeURIComponent(what),
cache: false,
success: function (html) {
$('.loading').hide();
$('#content').html(hhtml);
$('#body').fadeIn('slow');
}
// Here you ought to allow for the case of an error (hiding .loading, etc.)
});
}
You can then change the calls to getPage, or reimplement them as wrappers:
function getHomePage(){ return getAnyPage('homeloader.php', "#php"); }
function getPage() { return getAnyPage('loader.php', document.location.hash); }
ok for the first issue I would suggest to
see what your JS error console saying
ensure correspondent js plugin file is loaded
and use the following code when you are using ajax (the key thing is "success" event function):
$.ajax({
url: 'your_url',
success: function(data) {
$("pre.cplus").snippet("cpp",{style:"acid"});
$("pre.php").snippet("php",{style:"acid"});
}
});
for the second issue lserni answered clearly
you need to use to jquery on load function like so:
$(function(){
RunMeOnLoad();
});
I want to use $.post function of jquery to do a div refresh, only if the content returned in the json data from the php script is modified. I know that ajax calls with $.post are never cached. Please help me with $.post, or $.ajax if it is not possible with $.postor any other method with which this is possible.
Thanks
Why don't you cache the response of the call?
var cacheData;
$.post({.....
success: function(data){
if (data !== cacheData){
//data has changed (or it's the first call), save new cache data and update div
cacheData = data;
$('#yourdiv').html(data);
}else{
//do nothing, data hasan't changed
This is just an example, you should adapt it to suit your needs (and the structure of data returned)
var result;
$.post({
url: 'post.php'
data: {new:'data'}
success: function(r){
if (result && result != r){
//changed
}
result = r;
}
});
Your question isn't exactly clear, but how about something like this...
<script type="text/javascript">
$(document).ready(function(){
$("#refresh").click(function(){
info = "";
$.getJSON('<URL TO JSON SOURCE>', function(data){
if(info!=data){
info = data;
$("#content").html(data);
}
});
});
});
</script>
<div id="content"></div>
<input id="refresh" type="submit" value="Refresh" />
I think you should use .getJSON() like I used it there, it's compact, and offers all the functionality you need.
var div = $('my_div_selector');
function refreshDiv(data){
// refresh the div and populate it with some data passed as arg
div.data('content',data);
// do whatever you want here
}
function shouldRefreshDiv(callback){
// determines if the data from the php script is modified
// and executes a callback function if it is changed
$.post('my_php_script',function(data){
if(data != div.data('content'))
callback(data);
});
}
then you can call shouldRefreshDiv(refreshDiv) on an interval or you can attach it to an event-handler
Lets say I have a file called functions.php, and it has two separate functions inside:
One would get the time
And the other would get the date
How will I, using JQuery AJAX retrieve data from the function that retrieves the date. How do I specify in the JQuery code which function on the server to pick.
I hope I am making sense. Thanks.
You could include a selector in the ajax request data. For example:
$.ajax({
url: "functions.php",
data: "function=time", // or function=date if you want date
...
});
Then in your PHP code, a simple if-statement will check which one to output.
if(isset($_GET['function'])) {
if($_GET['function'] == 'time') {
// do time stuff
} elseif($_GET['function'] == 'date') {
// do date stuff
}
}
You don't specify in jQuery what function to execute in PHP. What you do is request a document, possibly with a query string, and read the results. Your functions.php script is responsible for executing whatever is requested.
So, you might from jQuery request functions.php?fn=time in one place and functions.php?fn=date in another. Then, in functions.php, you would examine the query string and execute the appropriate function for what was requested, returning the results to jQuery.
$(document).ready(function()
{
$(".link").click(function()
{
var data['func'] = "time";
var url = functions.php
$.get(url, data, function(result)
{
$("#feedback").html(result);
});
});
});
then your php file would be,
if(isset($_GET['func']))
{
if($_GET['func'] == "time")
{
showTime();
}
else
{
showDate();
}
}
function showTime()
{
//show time
}
function showDate()
{
//show date
}
Code is untested but should be a good starting point for you.
you can add a parameter to the url:
example:
function.php?g=1
now, on the serverside check for the get parameter:
if($_GET['g']==1)
{
echo date();
}
else
{
echo time();
}
What is the response your are getting. You are getting the response in XML or some other format. If your response is XML try with this option.
$.ajax({
url:path,
data:{projectId:inpprojectId},
dataType:"xml",
success:function(data){
$(data).find("CheckAmount").each(function(){
total = $(this).find("TotalAmount").text();
usdAmt = $(this).find("PettyCashAmount").text();
validateBudget(total,inp);
});
}
});