I have a set of 5 HTML dropdowns that act as filters for narrowing results returned from a mySQL database. The three pertinent filters are for "Province", "Region", and "City" selection, respectively.
I have three functions:
findSchools(), which runs when any of the filters (marked with CSS class .filter) are changed, and fetches the results via AJAX from a PHP script. Once that is done, two other functions are called...
changeRegionOptions(), which, upon changing the "Province" filter, and updates the available options using the same method as the first function, but posting to a different script.
changeCityOptions(), which runs if the "Region" filter was changed, and updates options, again using the same method.
The problem is that since I want these AJAX functions to run simultaneously, and they by nature run asynchronously, I've tried using $.when to control the execution of the functions, but it doesn't fix the problem.
The functions run, but the Region and City filters return blank (no options); the FireBug report shows absolutely no output, even though the POST request went through. The posted parameter for filter_province gets sent normally, but the one for region gets cut off at the end -- it sends as filter_region=, with no value passed. So I'm presuming my logic is wrong somewhere. The code is below:
// When any of the filters are changed, let's query the database...
$("select.filter").change(function() {
findSchools();
});
// First, we see if there are any results...
function findSchools() {
var sch_province = document.filterform.filter_province.value;
var sch_region = document.filterform.filter_region.value;
var sch_city = document.filterform.filter_city.value;
var sch_cat = document.filterform.filter_category.value;
var sch_type = document.filterform.filter_type.value;
$.post("fetch_results.php",
{ filter_province : sch_province,
filter_region : sch_region,
filter_city : sch_city,
filter_category : sch_cat,
filter_type : sch_type },
function(data) {
$("#results").html("");
$("#results").hide();
$("#results").html(data);
$("#results").fadeIn(600);
}
);
// Once the results are fetched, we want to see if the filter they changed
was the one for Province, and if so, update the Region and City options
to match that selection...
$("#filter_province").change(function() {
$.when(findSchools())
.done(changeRegionOptions());
$.when(changeRegionOptions())
.done(changeCityOptions());
});
};
This is just one of the ways I've tried to solve it; I've tried using an IF statement, and tried calling the functions directly inside the general select.filter.change() function (after findSchools(); ), but they all return the same result.
Any help with this would be great!
You need to turn async to false. After that, your code will be executed line by line.
For example like this, before calling $.post
$.ajaxSetup({async:false});
Try this .hope this is what you were expecting. jsfiddle->sample code
Related
i am tying to build an application where user can reorder items (and save the order to database). The items user is reordering are navigation links, which are generated dynamically on the page from php loop:
$nav_links.='<li class="collection-item ui-state-default item" data-ord="'.$navorder.'" data-url="'.$pageurlname.'"><a>' .$pagename. '</a></li>';}
$navorder is order of the page in the navigation
$pageurlname is string which is used to call the page dynamically (index.php?page=$pageurlname) and is unique key in the table.
I am using jqueryUi sortable funcion to make the process drag & drop, it is working fine and each time i reorder the links, the new order is updated to "data-ord".. the sript:
$('#sortable').sortable({
stop: function(event, ui){
$(".sortable li").each(function(i, el){
$(el).attr('data-ord',$(el).index()+1);
});
}
});
Now to the problem, which is my ajax script:
$(document).on('click','.saveorder',function(){
var neworder = $('.collection-item').attr('data-ord');
var pgurl = $('.collection-item').attr('data-url');
$.ajax({
type:'POST',
dataType:'text',
url:'/rs/pages/nav_order.php',
data: { neworder:neworder, pgurl:pgurl },
success: function(data) {console.log(data); $('#response').html(data);},
error: function(data) {console.log('Error!', data); }
});
});
I am new to ajax, so it is mostly build on scripts i found in other quiestions here. (I was able to succesfully implement cript link this to my other functions) however it is not working in this case. The problem seems to be that i am trying to post multiple data for multiple rows (At this time i have 4 links i am trying to reorder, but the link count can be more or less). When i tried to get values of variables "neworder" and "pgurl" (using alert), it always show only the values for the first item.
I have tried lot of solutions found in similar quiestion but none of them worked, simply because user were posting form data and then serialized it, which is not my case because i am not sending data from the form.
Lastly here is the nav_order.php (i guess it is wrong here too, probably need to add foreach but at first i need to have the ajax working correctly):
<?php
include "/rs/include/db.php";
$neworder = $_POST['neworder'];
$pgurl = $_POST['pgurl'];
$query = mysqli_query($Connection, "UPDATE horus_pages SET nav_order='$neworder' WHERE url_name='$pgurl'") or die (mysqli_error($Connection));
echo 'Reordered';
?>
Also when i check the console, there is no data.
So please can you tell me how to correct the ajax script to send the data for each object and then handle it correctly in the php script? Hope i described my problem clearly. Thank you for any help.
Put data-id="your_database_id" in your links html. Selecting them in your database with href, will be slow and bug things if there are multiple records with the same href.
You have save button which sends the order and href of the first link it finds? And what happens when multiple items change their order? If you have many links, you will be throwing hundreds of mysql updates for each save?
You should be better off sending json to your php. Something like that:
[{id:123, order: 332}, {id:124, order:334}, ... ]
dataType:'text' becomes dataType:'json'
If you don't care about scalability, then this will work on the backend.
$data = file_get_contents("php://input");
$links = json_decode($data, true);
foreach($links as $link) {
$order = intval($link['order']);
$id = intval($link['id'])
// UPDATE table SET `order` = '$order' WHERE id = '$id'
}
Btw. Your php code allows SQL injection. Thats bad
Perhaps you can make the order 'float' and make an algorithm which finds empty spot. This will allow you to reduce these 100's of SQL requests to 1.
I have come across this problem before and expect to do so again: I want to run a subtotal calculation in both javascript and PHP. I may want to change the calculation at some point.
It needs to run in javascript to maximise the speed of the calculation, so that the user knows what to expect.
It needs to run in PHP so that I am getting a valid subtotal which a malicious user cannot interfere with.
As such:
If I only run the calculation on the client-side (in javascript), a malicious user may hack the javascript and change the subtotal.
If I only run the calculation on the server-side (in PHP), an AJAX call would have to be waited on for the user to get their updated subtotal.
So I want to perform the calculation on both sides. The only way I have seen this done is by programming the calculation in PHP and programming the calculation in separate javascript.
My question is, what pattern, technique or technology would people recommend that I use to create the calculation on the server-side and make it compatible with javascript when it is sent to the client-side?
An idea I had, for example, was a PHP array for the calculation, which gets translated into PHP code and javascript code, e.g:
array(
array(type => "operand", "name" => "variable_A"),
array(type => "operator", "name" => "multiply"),
array(type => "operand", "name" => "variable_B"),
)
This might convert into PHP:
return $variable_A * $variable_B;
And into Javascript:
return variable_A * variable_B;
That's an example operational pattern. I don't know what real ones would look like if they exist.
ajax?
you can pass all the variable entered with javascript and leave the process server based.
or i misunderstand your question?
The way I think about your problem is like you described it: do double calculation.
And I believe that's how the "big boys" do it.
Example: Add up two numbers.
So you have a code like this:
HTML snippet:
<form method="post" action="/add.php">
<input id="firstOperand" name="firstOperand" placeholder="First operand"/>
<input id="secondOperand" name="firstOperand" placeholder="Second operand"/>
<input type="submit" onclick="doCalculation()" value="Add"/>
</form>
<div id="result" />
Your JS might look like:
function doCalculation() {
var first = parseInt(document.getElementById('firstOperand').value);
var second = parseInt(document.getElementById('secondOperand').value);
var result = first + second;
// the minimum amount of error checking
if isNan('result') return false;
document.getElementById('result').innerHTML = result;
// Now use some framework (like jQuery) to make an Ajax call and pass the result to callback.
Framework.Ajax('/add.php?format=json', 'POST', {first: first, second: second}, callback);
return false;
}
function callback(response) b
var res = response.json.result;
var resultEl = document.getElementById('result');
var errorEl = document.getElementById('error');
// if our result is not correct, we want to update the user on it
if (res != parseInt(resultEl.innerHTML)) {
Framework.removeClass(errorEl, 'hidden');
}
document.getElementById('result').innerHTML = res;
}
Of course, your PHP result page (add.php) would return json with the result. The added value here is that you can also return a plain HTML result (like if js is disabled).
Your callback could also check if there was an error in the returned result and display that error message too. Or if the result times out, display a notification that the "result" is not saved. But that's out of the scope of the question, I guess (at least, out of the scope of the answer).
Note: this is just the code off the top of my head, not tested, written directly in the answer box, probably a few things should be done better.
My first time writing, but not the first here. I felt forced to ask here because none of those apparently alike questions here were able to give me a clear workaround or solution.
My projects involves a tic-tac-toe game, all jQuery, PHP and log file based. It's working fine, but for every information sent to the txt log, I have to star a new $.post to retrieve the information that will be displayed in different parts of the page, not all in a single list (specially O and X that are retrieved back to their original text element) ...
The game is real-time, multiplayer and is working fine, but is using two txt logs written by PHP which also manages the game: one log keeps the position (filled space) and the other what char was used (X or O). Nice, but I'm calling the two via $.post, storing their data in respective global variables and using them in a setInterval, to update on time for the other player. But as there are many other informations like name and remaining moves (from 9 to 1), I'd like to put everything in a single log, something easier to be retrieved all in a time and be displayed in their respective positions through the game page. My problem (now what I need to get working for now) here is retrieving them from PHP. During tests, I simulate three informations: position, char (O or X) and player's name, put them in an array and echo them with json_encode, as it follows (my jQuery post and then my PHP):
<script type="text/javascript" src="jquery.js"></script>
$.post ("json.php", {pos:"pos",weapon:"weapon",nome:"nome"}, function(data){
alert (data); //returns null...
//alert (data.pos); //nothing, script ignores execution
//alert (data[0].pos); //returns null...
//alert (data[1].pos); //returns null...
//alert (data[2].pos); //returns null...
//alert (data[3].pos); //returns null...
//tests above based on some suggestions I'fe found through the web, ineffective...
},"json");
And my PHP:
<?php
//Simulating values being received during the game:
$pos='s3'; //simulation player's move on slot 3
$weapon='O'; //player puts O on slot 3
$name= 'fulano';
//Putting general player info into the array to be used by jQuery:
$coord= array();
$coord['pos']= $pos; //Sets the position where the player put his char
$coord['weapon']= $weapon; //The "weapon" to be put in respective "pos"
$coord['nome']=$name; //Player's name to be displayed during the game
echo json_encode($coord); //encoded json is returning {"pos":"s3","weapon":"O","nome":"fulano"} nicely
?>
Both are post, both using json, jQuery returns something, but is null, PHP echoes alright... $.ajax simply didn't make it either...
What I need: that $.post retrieves every datum so that I can store one by one in their respective global variables, but if alert can't even show one of them coming, something's wrong. Changed every variable names to avoid any kind of conflict, not solved...
I made this test just to make sure PHP json would be clearly gotten by jQuery, what's not happening here. My HTML is using default charset, I'm testing it in localhost, I have the main project working perfectly here, this was a side test to test specifically json response. I simply had no success in using $.ajax ({}) (my jQuery is 1.7.1), no matter what, the script simply stops executing, PHP keeps responding alright here, but jQuery is not giving me what it should other than "null", I've tested it on FF15 and IE8, problem is just with my json routine on jQuery, PHP is working fine and my $.posts here and on the main project, too. What could be going wrong here? Why is it simply returning data as null regardless to what I may try? I thank everyone in advance, I'm just asking because there were no examples here and outside that really gave me the answer, and 99,9% depend on Ajax, but Ibelieve it can be simpler like this.
Add this to your code
$.post ("json.php", {pos:"pos",weapon:"weapon",nome:"nome"}, function(data){
$(data).each(function(){
alert(this.s3);
alert(this.0);
alert(this.fulano);
});
},"json");
Valid JSON is as follows: {"key":"value"} not {key:"value"}
Note: All quote encapsulated, not just the value. Hope that helps.
I've researched and played around a fair bit, but I am stumped. Essentially I want to setup my site so that it can detect if a user is 'logged in' and thereby change the way it looks: removing the "Sign In" link and replacing it with a "Sign Out" link, and so forth.
For testing purposes I started my index.html page with:
<?php
session_start();
$_SESSION["username"]="javaman";
?>
Next, I call my setup function from within the jquery document.ready:
$(document).ready(function() {
setup_page();
};
The setup function looks like:
function setup_page()
{
var username = get_user();
//check for error
var index = username.indexOf("error");
//if not an error
if(username.length > 0 && index == -1)
{
//do the jquery calls to hide/show links
}
}
And that get_user function looks like:
function get_user()
{
var result;
$.post("./session.php", {action : "get", key : "username", value : "val"}, function(data){
result = data;
});
return result;
}
The session.php is a simple app that takes in 3 post values and hopefully spits out the proper result, the problem I am running into is that the js result variable is often undefined, especially so when I debug via the IE dev toolbar. FF seems ok though. Am I using the callback in the correct way? I've tried putting alert() functions everywhere to figure out where the code is screwing up, but that doesn't help either as often the alert's say the result is undefined. Meanwhile, it seems like the get_user calls the post function but the stack immediately returns and never gets to the return statement until AFTER the get_user has returned a value of.. undefined. I believe I am misunderstanding the code flow here. I am used to C where logically one function follows another. In that vein I am interpreting the callback to essentially be like:
int i = callback_function(post("some data"));
So in my mind the post completes it's action and then calls another function or at least performs another action and then that completes and then the get_user can return it's value.
Or is the order of operation: post, get_user, callback?
...confused in Seattle
Internet Explorer does not natively support indexOf on arrays. Use jQuery's $.inArray() instead:
var index = $.inArray("error", username);
Keep in mind that AJAX stands for Asynchronous Javascript and XML. So the callback fires as soon as a response comes, but the rest of execution goes on. If you want to lock the execution until AJAX-request will be completed, use
$.ajaxSetup({async:false});
before AJAX call.
I'm trying to create a very simple message board (author, text, and date written) that will auto-update every few moments to see if a new message has arrived, and if it has, auto load the latest message(s).
I'm proficient in PHP, but my knowledge in AJAX is lacking.
The way I see it, I would have to create a PHP file called get_messages.php that would connect to a database and get through a $_GET variable return all posts beyond date X, and then I would somehow through jquery call this PHP file every few minutes with $_GET=current time?
Does this sound correct?
How would I got about requesting and returning the data to the web page asynchronously?
You're pretty close, you'll need a PHP script that can query the database for your results. Next, you'll want to transfigure those results into an array, and json_encode() them:
$results = getMyResults();
/* Assume this produce the following Array:
Array(
"id" => "128","authorid" => "12","posttime" => "12:53pm",
"comment" => "I completely agree! Stackoverflow FTW!"
);
*/
print json_encode($results);
/* We'll end up with the following JSON:
{
{"id":"128"},{"authorid":"12"},{"posttime":"12:53pm"},
{"comment":"I completely agree! Stackoverflow FTW!"}
}
*/
Once these results are in JSON format, you can better handle them with javascript. Using jQuery's ajax functionality, we can do the following:
setInterval("update()", 10000); /* Call server every 10 seconds */
function update() {
$.get("serverScript.php", {}, function (response) {
/* 'response' is our JSON */
alert(response.comment);
}, "json");
}
Now that you've got your data within javascript ('response'), you are free to use the information from the server.
Ignore the ASP.NET stuff, this link is a good start:
http://www.aspcode.net/Timed-Ajax-calls-with-JQuery-and-ASPNET.aspx
What you're going to use is a javascript function called setTimeout, which asynchronously calls a javascript function on an interval. From there, jQuery has a fancy function called "load" that will load the results of an AJAX call into a DIV or whatever element you're looking for. There are also numerous other ways to get jQuery to do alter the DOM the way you'd like.
There are a hundred ways to do this, but I'd say avoid writing plain Javascript to save yourself the headache of cross-browser functionality when you can.
I suggest you go for the Simple AJAX Code-Kit (SACK) available on Google code.
I've been using it since before it was on Google code. It's very light and straightforward. It's one js file that you have to include. I've seen it being used in online browser games as well.
http://code.google.com/p/tw-sack/
Example for loading page contents from get_messages.php in a div (if you don't care about the page contents from get_messages.php, and simply want to call the php file, simple remove the ajax.element line):
<script type="text/javascript" src="tw-sack.js"></script>
<script>
var ajax = new sack();
ajax.method = "GET"; // Can also be set to POST
ajax.element = 'my_messages'; // Remove to make a simple "ping" type of request
ajax.requestFile = "get_messages.php";
ajax.setVar("user_name","bobby");
ajax.setVar("other_variables","hello world");
ajax.setVar("time",dateObject.getTime());
ajax.onCompleted = whenCompleted;
ajax.runAJAX();
function whenCompleted(){
alert('completed');
}
</script>
<div id="my_messages">Loading...</div>
You don't need to specify an "ajax.element" if you want to do a simple "ping" type of request and ignore the output of the php file. All you have to do to implement your requirements now is to use a "setTimeout" making the ajax calls.
There are also many other options like:
//ajax.onLoading = whenLoading;
//ajax.onLoaded = whenLoaded;
//ajax.onInteractive = whenInteractive;
No need to learn or include huge frameworks. And you'll get started in no time with tw-sack.