I'm beginning to work with AJAX, and I'm struggling with the next few things.
I'm working in Wordpress, with custom tables.
By the way, that's why the global $wpdb is there.
First, I have a Select, when you choose an option, the ID value will get stored in a variable in jQuery. This is done by the
onchange="selectRequest(this)"
global $wpdb;
$Estado = $wpdb->get_results("SELECT * FROM cor_estado;");
?>
<p>Busqueda por Estado</p>
<select class="select" id="estado" name="estado" value="" type="text" onchange="selectRequest(this);">
<option value="" disabled selected>Seleccione un estado...</option>
<?php
foreach ($Estado as $Estados ) {
echo "<option value='".$Estados->estado_id."' type='text'>".$Estados->nombre_estado."</option>";
}
?>
</select>
The Select will fill up with the id on value and the name.
This is my jQuery, but I'm having a problem here, if I leave everything on the jQuery(document).ready(){CODE HERE}, the Function selectRequest(id), won't work at all, I don't know if that has anything to do with the way that I am getting the id from the select.
Here it changed, now I am trying to receive HTML, I created the complete table on "table.php", and now I am trying to get it back
<script type="text/javascript">
function selectRequest(id){ // id of select
var selectVal = jQuery(id).val(); // currently selected
selectVal = selectVal.toString();
alert(selectVal);
jQuery.ajax({
type:"POST",
url:"<?php echo get_template_directory_uri(); ?>/table.php",
dataType: "html",
data:{selectVal:selectVal},
success:function(resultHtml){
jQuery("#resultado").html(resultHtml);
},
error:function(resultHtml){
alert("What follows is blank: " + data);
}
});
}
</script>
my PHP is like this at the moment, one big change was in the WHERE, since I am using an INNER JOIN, I needed to specify on which table the "estado_id" was going to be, since Wordpress uses table prefix, it was necessary to add it in this place too.
Like I said before, I decided to build the table here, and send it to AJAX with an echo, I created $table, and each time something was created inside the table, I added it with ".=".
Testing this inside the table.php without the "If(isset($_post['selectVal']))", and having an static ID it worked on the table.php document, but if I echo $table, I get nothing on AJAX, it appears as blank.
<?php
//table.php
global $wpdb;
if(isset($_POST["selectVal"])){
$Estado_id = $_POST["selectVal"];
$Estado = $wpdb->get_results("SELECT * FROM cor_municipio INNER JOIN cor_estado ON cor_municipio.estado_id = cor_estado.estado_id WHERE cor_estado.estado_id = $Estado_id;");
$table = "<table>";
$table .="<thead>";
$table .="<tr>";
$table .="<th>Municipio</th>";
$table .="<th>Estado</th>";
$table .="</tr>";
$table .="</thead>";
$table .="<tbody>";
foreach ($Estado as $row) {
$table .="<tr>";
$table .="<td>".$row->nombre_municipio."</td>";
$table .="<td>".$row->nombre_estado."</td>";
$table .="</tr>";
}
$table .="</tbody>";
$table .="</table>";
echo $table;
}
?>
This is the HTML div where I want to display the echo $table content. At the moment if I select an option, the only thing that happens is that the P element disappears.
<div id="resultado">
<p>Estado Seleccionado</p>
</div>
The new problem is receiving this echo $table and displaying it where AJAX receives it.
instead of receiving data in JSON format, use HTML formatted data & replace your data directly in table. Using that your base issue "the amount of information in them will be different on each select option" will be resolved.
There's not a fixed rule... Sometimes is faster to create the html in the php and return it formatted so you can show it directly and sometimes is better to return raw data and handle it in javascript/jquery.
If the data you get from the ajax request is just for showing and you don't need to modify anything that depends of other elements in your current view, I will format the html response directly in the php. If you need to change something, then maybe I will go with JSON.
In your ajax request you establish JSON as the data format, so the response in your PHP has to be JSON. You almost have it. Uncomment the foreach but instead of independent variables ($info1, $info2) create an array with the fields you need for your response, and set key names. For example...
$response = array();
foreach ($Estado as $row) {
$response['municipio'] = $row->nombre_municipio;
$response['estado'] = $row->nombre_estado;
.....
}
Once you have the array created, convert it to JSON and return with...
print_r(json_encode($response));
Then, in your jquery ajax success function you can access each field with...
data.municipio or data['municipio']
data.estado or data['estado']
...
I hope it helps
So, the basic problem here was that I was following the steps to do this using the tools (JS, PHP, HTML and CSS) outside the Wordpress environment, this was the issue. I'm still solving some aspects about my AJAX request, I will try to update this answer as fast as I can.
In this Wordpress Codex entry, they explain it in detail.
Basically Wordpress has it's own way of using AJAX, so no matter if this 'looked' correct to me, the Wordpress site wasn't going to display anything from it.
Here is the solution that I used to solve my problem.
<!-- language: lang-js -->
UPDATED CODE
jQuery(document).ready(function() {
jQuery('#estado').change(function() {
var selectVal = jQuery('option:selected').val();
selectVal = selectVal.toString();
jQuery.ajax({
url:"/cors/wp-admin/admin-ajax.php",
type:"POST",
data:{action:'my_action', selectVal: selectVal},
success:function(data){
jQuery("#municipio_result").hide(500);
jQuery("#municipio_result").removeData();
jQuery("#municipio_result").html(data);
jQuery("#municipio_result").show(500);
},
});
});
});
STEP #1
/wp-admin/admin-ajax.php //will be the URL for all your custom AJAX requests.
This is absolutely necessary, because this document verifies the AJAX 'actions', and points them to your functions.php
STEP #2
data:{action:'your_action_name', val1: 1, val2: 2 ...}
The first variable that you have to send will always be action, the value can be the anything you want.
As I said earlier, admin-ajax.php looks for the variable action when it receives an AJAX request from any file, it will look for action, once it finds it, it will redirect it to the functions.php file located inside your_theme folder.
STEP #3
Inside you functions.php file, you will add the PHP code as a function, like this:
<!-- language: lang-sql -->
function selectEstado(){
global $wpdb;
if(isset($_POST["selectVal"])){
$Estado_id = $_POST["selectVal"];
$Estado = $wpdb->get_results("SELECT * FROM cor_municipio INNER JOIN cor_estado ON cor_municipio.estado_id = cor_estado.estado_id WHERE cor_estado.estado_id = $Estado_id;");
$table = "<table>";
$table .="<thead>";
$table .="<tr>";
$table .="<th>Municipio</th>";
$table .="<th>Estado</th>";
$table .="</tr>";
$table .="</thead>";
$table .="<tbody>";
foreach ($Estado as $row) {
$table .="<tr>";
$table .="<td>".$row->nombre_municipio."</td>";
$table .="<td>".$row->nombre_estado."</td>";
$table .="</tr>";
}
$table .="</tbody>";
$table .="</table>";
echo $table;
wp_die();
}
}
add_action('wp_ajax_my_action', 'selectEstado');
add_action('wp_ajax_nopriv_my_action', 'selectEstado');
STEP #4
Inside your functions.php file you will create a function, can be called whatever you want, for example 'your_function_name'.
To access easily to the database, Wordpress uses the variable $wpdb, by including the line like this global $wpdb; now you can use it to access the database without any problems.
Now you have to check if the values after action got there, the if(isset($_POST)) will take care of it. To check the Database, you use the $wpdb->get_result("");
Basically what I am doing with the INNER JOIN, is checking a column name, and checking where the two tables match, and then pulling the rest of the columns that the element on the table has in "cor_municipio" and "cor_estado".
(In this code I am using JOINS, if you want to know more about them, I'll leave a link below)
Here they explain JOINS with Venn diagrams
Then I created a variable that each time a part of the table was created, it was being added to it.
You echo your data, and don't forget "wp_die();"
STEP #5
This is the last part to have your AJAX request working on Wordpress.
The next two lines are very important for it to work, this is the action that admin-ajax.php is looking for, and it's here that it references it's value, these lines look like this for every new AJAX request you need to make:
add_action('wp_ajax_', '');
add_action('wp_ajax_nopriv_', '');
this is the "default" way the lines are written, but you will need to complete them with two things.
The action value you used in the AJAX request, in my case is 'my_action', or in this example 'your_action_name'.
The second value is the name of the function created inside your functions.php file.
It will end up looking like this for me:
add_action('wp_ajax_my_action', 'selectEstado');
add_action('wp_ajax_nopriv_my_action', 'selectEstado');
Using the value of 'your_action_name' and 'your_function_name':
add_action('wp_ajax_your_action_name', 'your_function_name');
add_action('wp_ajax_nopriv_your_action_name', 'your_function_name');
The first line is for logged in users, and the second one is for visitors, if you want to display something different for logged in users and another one for visitors, you will need to create a function for each of them, and just use one attribute.
add_action('wp_ajax_your_action_name', 'your_function_name1'); // for registered users
add_action('wp_ajax_nopriv_your_action_name', 'your_function_name2'); // for visitors
Again, this is PHP code written in admin-ajax.php, if you want to look deeper into it.
I already found out my problem, when I was sending the data on the first time I was using:
data:{action:'my_action', selectVal: 'selectVal'},
Basically what I was sending to Wordpress on selectVal, was the string
selectVal
So when my function tried to find the id based on the receiving data, it wasn't going to find anything, because it was a string with those letter.
SOLUTION
jQuery(document).ready(function() {
jQuery('#estado').change(function() {
var selectVal = jQuery('option:selected').val();
selectVal = selectVal.toString();
jQuery.ajax({
url:"/cors/wp-admin/admin-ajax.php",
type:"POST",
data:{action:'my_action', selectVal: selectVal}, // The right way to send it
success:function(data){
jQuery("#municipio_result").hide(500);
jQuery("#municipio_result").removeData();
jQuery("#municipio_result").html(data);
jQuery("#municipio_result").show(500);
},
});
});
});
What I am sending now is the value, and now my AJAX success:function, receives the complete table, I also changed the jQuery code, because in the first example, when adding ".hide() or .show()", it was sending multiple errors.
To add conditions by user role you can edit the admin-ajax.php to make it simpler for all the AJAX requests.
I know is way too long, but if you were having some trouble, I wanted to explain all the different elements that are used, to make it easier to understand what is happening with AJAX in Wordpress.
I am developing a web application and i am stuck with a problem.
i have two drop-down list, one is dynamically populated from my db, while the the other is static html.
When a user selects an item form the dynamic drop-down and select an item from the static html drop-down, and clicks submit on the form, I would like the dynamic selected list item to print out the entire selected row in the db.
here is my code sample
if ($contactc =="Yes"){
$result = mysql_query("SELECT * FROM company_details where comid = '$selectsector'");
while ($row = mysql_fetch_array($result)){
echo $row["fname"]." ".$row["comname"]."<br/>";
}
}
maybe this is what you wanted, though you will have to use JQuery
HTML
<form id="when_user_clicks_submit_button">
<input class="data_to_send" type="text" value="MySQL Selection data"></input>
<input type="submit" value="Submit"></input>
</form>
JavaScript|JQuery for Ajax Request:
document.getElementById('when_user_clicks_submit_button').onsubmit = function() {
$.ajax({
type: "POST",
url: "php_code_script.php",//php script location
data: { "data_from_form": data_to_send }, //data to send in JSON format
success: function(data) { //callback if the script execution is successful
$('<p>' + data + '</p>').appendTo('body');//this returns the selected information from the MySQL database and inserts it somewhere, make sure to echo or print the selected data inside the php script.
}
)}
};
PHP
if($_POST['data_from_form']) {
if ($contactc =="Yes"){
$selectsector = $_POST['data_from_form']; //gets the sended data from the form page to use for selection in the MySQL database
$result = mysqli_query("SELECT * FROM company_details where comid = '$selectsector'");
while ($row = mysqli_fetch_array($result)){
echo $row["fname"]." ".$row["comname"]."<br/>";
}
}
}
Maybe this is sort of what you wanted, you basically send the information you want to use to select from the database, the php script then handles it and echoes the selected information from the database, that data then returns to the form page where it becomes the value pf an DOM Element(HTML tag). This is just to give an example of what you maybe want, I didn't think about security or anything(I don't know much about it yet). Note I also changed the mysql to mysqli to make it more compatible with newer versions of PHP because mysql is no longer supported in newer versions or for the future.
Below is how i made my select option list
<select id="roomtype" name="roomtype" class="form-control select-block">
<?php
// Populate dropdown list of room types
$room = new Rooms;
$room_types = $room->Bind_Room_Types();
foreach ($room_types as $key => $value)
{
echo '<option id="roomtypeoption" value="'.$key.'">'.$value.'</option>';
}
unset($room);
?>
</select>
Now on an update request i made an ajax call which in return gives me a json data like below
[{"id":"1","roomno":"102","floor":"2nd","beds":"2 beds","roomtypeid":"1"}]
After getting the response i populated all the values on my form fields like below
success: function(response) {
// Taking ajax response into javascript objects to fill the form fields
console.log(response);
var object = {};
object = $.parseJSON(response);
$("#roomid").attr('value', object[0].id);
$("#roomnumber").attr('value', object[0].roomno);
$("#roomfloor").attr('value', object[0].floor);
$("#roombeds").attr('value', object[0].beds);
$("#roomtypeoption").remove(); // not working
$("#roomtypeoption").attr('value', object[0].roomtypeid); //not work.
$("#submit").attr('id', 'update').off('click');
}
now in case of text fields its working fine , but when i came to select tag it is not getting updated.
2nd problem is that as you can see in my json i have pasted above. there is 'roomtypeid:1'. This is actually a foreign key. What i want is when my select list get updated on success of ajax then 'roomtypeid' should be placed in How to display the value against foreign key (roomtypeid)
I'm lost in this :(
Please help thanks
I changed my approach. Closing the question.
I have a form to insert data into a MySQL table that uses two drop down menus. The first is a list of parks and the second a list of rides. The second drop down box should only display items linked to the first by the column 'park_id'. I need a simple way for the second box to populate based on the first's selection.
This is the form so far:
<tr><td>Select Park:</td>
<td><select name="park_id">
<option value="">Select Park</option>
<?php foreach ($res as $row) {
printf('<option value="%s">%s</option>' . PHP_EOL, $row['park_id'], $row['name'] );
} ?>
</select></td></tr>
<tr><td>Select Ride:</td>
<td><select name="ride_id">
<option value="">Select Ride</option>
<?php foreach ($res2 as $row2) {
printf('<option value="%s">%s</option>' . PHP_EOL, $row2['ride_id'], $row2['name'] );
} ?>
</select></td></tr>
So somehow a query needs to run after selecting a park and use '$park_id = $row[park_id]' to help generate the results for the 'Select Ride' dropdown.
This is the query I need to use for the second drop down:
$qry2 = "SELECT ride_id, name FROM tpf_rides WHERE park_id = $park_id ORDER BY name ASC";
Can anyone talk me through this? Also my skill are very limited so a relatively simple solution would be great.
Thanksark
For this you will have to get into AJAX, and I highly recommend using jQuery's implementation. You will also need to get a good grip on JSON string coding and decoding.
The basic Idea of your code will be like so:
// listen for user to change the <select> item
$('select#park').on('change', function(){
$.ajax({
url: 'getrides.php' // send a park id to this script
,cache: false // do not cache results in browser
,type: 'POST' // send POST to getrides.php
,data: {'park_id': $('select#park').val()} // getrides.php will receive $_POST['park_id']
,dataType: 'json' // this AJAX call expects a JSON string as a return value
,success: function(data){ // the data variable will be converted to an array from JSON
// check out all your data
console.log(data);
// loop through your array
$.each(data, function(index, info){
// see your array indexes
console.log(index);
// see data in each array item
console.log(info);
});
}
});
UPDATE
You can also load all of the parks and rides into a Javascript array and based on what the user chooses from the dropdown then populate the second dropdown with those array members.
<script>
var rides = new Array();
rides['park1'].push('ride1');
rides['park1'].push('ride2');
rides['park1'].push('ride3');
rides['park1'].push('ride4');
rides['park1'].push('ride5');
rides['park2'].push('ride1');
rides['park2'].push('ride2');
rides['park2'].push('ride3');
rides['park2'].push('ride4');
rides['park2'].push('ride5');
// listen for user to change the <select> item
$('select#park').on('change', function(){
// clear current DD options
$('select#rides').html();
// loop through array of available rides for selected park
$.each(rides[''+$(this).val()+''], function(index, value){
// dynamically create the proper DD options
$('select#rides').append('<option>'+value+'</option>');
});
});
</script>
you have to write another file that uses the id of the first selected from the bikes list value to load the options of the second select tag the rides list
then make an empty div on the first file that will be loaded with the result of the second file which is the list of rides
$(function() {
$('#ID_of_the_park_selecttag').change(function() {
var value = $("#ID_of_the_park_selecttag").find('option:selected').text();
$("#ID_OF_THE_DIV").html("");
$("#ID_OF_THE_DIV").load('theOtherFile.php', {"bikename":value } );// value is the value of the select option from the first <select tag>
});});
then on the second file you can get the value of the bike selected as $_POST['bikename'] and do your query then fill the list
I had to do this recently myself. Here's what I did, feel free to use what makes sense to you. I tried what seemed like a simple way to myself.
<select name="department_list" id="department_list" onchange="$('#singleUser').load('yourextraphppage.php?nid='+this.value);">
<option value='none'>Select a department</option>
Then load your first select list with data and close the select tag... Add a blank div where you want the 2nd select. I used the value from the first select list for my parameter for the 2nd select list's query. (it was the foreign key in the 2nd table for the 2nd select list)
<div id="singleUser" class="singleUser">
</div>
Last, you need the additional PHP page that you called from the first select list. Here's a barebones version of my code.
echo "<option value='none'>Select user</option>";
try {
$db = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
$stmt = $db->prepare("SELECT dm.empid AS empid, u.name AS name FROM mytable dm
JOIN mytable2 u ON dm.empid = u.id
WHERE dm.deptid = :id
ORDER BY u.name");
$stmt->bindParam(':id', $id);
$stmt->execute();
while ($r = $stmt->fetch()) {
$empid = $r['empid'];
$userName = $r['name'];
echo "<option value='".$empid."'>".$userName."</option>";
}
echo "</select>";
echo "</p>";
$db = null;
}
catch (PDOException $ex) {
echo "An Error occurred!";
}
I hope this helps. I'm rather busy so I can't go in detail explaining it at the moment. I'll check back later to see if you have any questions.
I was helping somebody a similar page a day or say ago:
2 dropdown selects and the list of options in the second dropdown changed according to the choice selected in the first.
The solution involved the use of <optgroup> elements within the <select> and jQuery (which is not all that easy for a beginner but at least you can copy the code.
See here for the question: jQuery - on page load select optgoup and children in second select by a default selected option in a parent select
And here to see the code in action here: http://jsfiddle.net/goodegg/phj8q/
(although there is a mistake in it).
EDIT
Go here for my forked version of the code: http://jsfiddle.net/annabels/7xksa/
I am new to PHP and I am trying to learn how to re-populate a dropdown once a new category has been added.
Right now the user can create a new category and a message is sent back on success. I am lost on how to re-populate the drop-down on success.
Here is some related code:
//Handles the submit to DB
$.post("addHourlyScheduleCB.php", {
schedule: $("#schedule").val()
},
function(list){
$("#message").removeClass().html(list);
//inject the latest drop down info
$("#scheduleSelect").load("scheduleSelect.php");
$("html,body").animate({scrollTop:0},'slow');
$.unblockUI()
}
);
On success I tried to inject the with a PHP page that pulls the updated data from the DB.
Here is the HTML
<select name="scheduleSelect" id="scheduleSelect">
<?php
while ($row = $db->sql_fetchrow($rateScheduleSQLresult)) {
echo "<option value=".$row['Rate_Schedule_ID'].">$row[schedule]</option>\n";
}
?>
</select>
Here is the page that is called in the success function of the jQuery:
<?php
require_once("models/config.php");
$rateScheduleSQL = "SELECT * FROM rateschedules ORDER BY schedule";
$rateScheduleSQLresult = $db->sql_query($rateScheduleSQL);
while ($row = $db->sql_fetchrow($rateScheduleSQLresult)) {
echo "<option value=".$row['Rate_Schedule_ID'].">$row[schedule]</option>\n";
}
?>
*EDIT: The initial dropdown shows the expected results. It is one the success of the post that the dropdown shows no results. I believe this is an issue of how I am trying to update the dropdown. I believe there must be a much better way. *
Within your callback, try seeing what is actually returned by the AJAX call. Add console.log(list) to make sure something is returned (this will show in your developer tools/firebug console).
The .load() function is an event handler, it acts when the called-upon element (#scheduleSelect) is loaded, it doesnt populate it with any info.
You want to make another $.post call to get the data from scheduleSelect.php, and populate the dropdown with the callback variable. (try to do a console.log(variable) with the 2nd post)