I am creating a card calculator form where you can select a card type and select a quantity and a price is returned.
I am using a csv file for the pricing and I have it all working great. as a simple HTML Form displayed through a shortcode in WordPress.
<?php
// Get CSV
$ch = fopen($standard_csv, "r");
$header_row = fgetcsv($ch);
// Get array of rows
$rows = array_map('str_getcsv', file($standard_csv));
// Remove first row (header row) as we already have this separately
unset( $rows[0] );
?>
<!-- The Form -->
<form action="" method="post" name="calc" id="calc">
Type:
<select name="card" id="card">
<option value="">Please Select</option>
<?php
// Remove first blank cell from $header
unset( $header_row[0] );
foreach ( $header_row as $key => $card ){
echo '<option value="' . $key . '">' . $card . '</option>';
}
?>
</select>
Quantity:
<select name="quantity" id="quantity">
<option value="">Please Select</option>
<?php
foreach ( $rows as $key => $row ){
echo '<option value="' . $key . '">' . $row[0] . '</option>';
}
?>
</select>
<input type="submit" name="get-price" value="Get Price!">
</form>
<?php
if ( isset( $_POST['get-price'] ) ){
$card = $_POST['card'];
$quantity = $_POST['quantity'];
echo 'Price: £' . $rows[$quantity][$card];
}
?>
This is great but I want to display the returned price using AJAX so I do not have to refresh the page when a user requests a price for their chosen card and quantity.
I have my scripts enqueued like so:
wp_enqueue_script( 'custom_script', plugin_dir_url( __FILE__ ) . 'js/custom.js', array('jquery'), '1.0' );
wp_localize_script( 'custom_script-script', 'ajax_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ),
add_action('wp_ajax_get_price', 'get_price');
add_action('wp_ajax_nopriv_get_price', 'get_price');
function get_price(){
$card = $_POST['card'];
$quantity = $_POST['quantity'];
return 'Price: £' . $rows[$quantity][$card];
}
I have this in my Javascript File
$('#calc').submit(function (event) {
event.preventDefault();
var card = jQuery('#card').val();
var quantity = jQuery('#quantity').val();
jQuery.ajax({
type: 'POST',
url: ajax_object.ajax_url,
data: {
action: 'get_price',
card: card,
quantity: quantity
},
success: function (data) {
console.log(data);
},
error: function (errorThrown) {
console.log(data);
alert(errorThrown);
}
});
});
I have totally confused myself and I have tried to follow many tutorials, but I just cant work out the correct logic to be able to output a price from the CSV file using AJAX without reloading the page.
I know this code is totally not right, but please any help to set me in the right direction would be extremely appreciated.
I just need help understanding the logic on how to handle passing the variables and prices between the ajax and the php function in order to return a price from the CSV File.
Thank you.
Don't return from ajax - exit.
Replace return 'Price: £' . $rows[$quantity][$card];
with
wp_die('Price: £' . $rows[$quantity][$card]);
Best wishes,
Mitchell
Related
I have been following a few tutorials online for how to do this, and I do not know where I missed the mark... when I press my submit button, it does nothing but reload the page. I do not see any errors in loading my js though in the console of chrome so I think that might be my issue. But still unsure.
Basically, people can provide a new billing_address on their dashboard, and the billing address is associated with a user and sku.
Here is my form with three items (user, sku, address);
$loop = new WP_Query( $args );
echo '<form id="addressform" method = "post">';
echo '<br><select id="sku" name="sku" required >';
echo '<option value="empty">-- Select Coin--</option>';
while ( $loop->have_posts() ) : $loop->the_post();
global $product;
echo '<option value=' . $product->get_sku() . '>' . $product->get_sku() . ' </option>';
endwhile;
echo '</select>';
echo '<input type="text" placeholder="Insert new address here" id="address" name="address" size="40" required />';
echo '<input type="hidden" id="userid" name="userid" value="' . $userid . '">';
echo '<input type="submit" id="submit" name="submit" value="Submit">';
echo '</form>';
echo '<div class="alert alert-danger display-error" style="display: none"></div>';
here is my javascript file known as address_submit.js
jQuery(document).ready(function($) {
jQuery('form#addressform').on('submit', function(e){{
jQuery.ajax({
type: 'POST',
dataType: 'json',
url: submitaddress_ajax_obj.ajaxurl,
data: {
'userid' : jQuery('form#addressform #userid').val(),
'sku' : jQuery('form#addressform #sku').val(),
'address' : jQuery('form#addressform #address').val(),
'action' : 'submitaddress'
},
success : function(data){
if (data.code == "200"){
alert("Success: " +data.msg);
} else {
jQuery(".display-error").html("<ul>"+data.msg+"</ul>");
jQuery(".display-error").css("display","block");
}
}
});
e.preventDefault();
});
});
and lastly, I knew I needed to add it to my functions.php for my child theme so I created a second file (address_verifier.php) and included it like this in my themes functions.php :
require_once( __DIR__ . '/include/address_verifier.php');
And lastly, here is what is in the address_verifier.php
function submitaddress_ajax_enqueue() {
// Enqueue javascript on the frontend.
wp_register_script('submitaddress-ajax-script', get_stylesheet_directory_uri() . '/js/address_submit.js', array('jquery') );
wp_enqueue_script('submitaddress-ajax-script');
// The wp_localize_script allows us to output the ajax_url path for our script to use.
wp_localize_script('submitaddress-ajax-script','submitaddress_ajax_obj',array( 'ajaxurl' => admin_url( 'admin-ajax.php' ),'loadingmessage' => __('Submitting Address...') ));
}
add_action( 'wp_enqueue_scripts', 'submitaddress_ajax_enqueue' );
add_action( 'wp_ajax_submitaddress', 'submitaddress' );
add_action( 'wp_ajax_nopriv_submitaddress', 'submitaddress' );
function submitaddress() {
global $woocommerce,$wpdb,$product;
$errorMSG = [];
//check if data is present
$user = $_POST['userid'];
//check sku selected
if (empty($_POST['sku'])) {
$errorMSG .= "<li>Please select a product.</li>";
} else {
$sku = $_POST['sku'];
}
//check address input
if (empty($_POST['address'])) {
$errorMSG .= "<li>Please enter an address.</li>";
} else {
$address = $_POST['address'];
}
if(empty($errorMSG)){
$updateaddress = $wpdb->query( $wpdb->prepare("REPLACE INTO ".$wpdb->prefix."newaddress (user, sku, address) VALUES (%d, %s, %s)", $user, $sku, $address ) );
$msg = "<strong> <i class='fa fa-check' aria-hidden='true'></i> Your <font color='red'>" . $sku . " </font>address has been updated. </strong>";
echo json_encode(['code'=>200, 'msg'=>$msg]);
die;
}
echo json_encode(['code'=>404, 'msg'=>$errorMSG]);
die();
}
move e.preventDefault(); to the top of the function.
I have two select boxes in which I want to select a value for one and the second select box should get same value.
Currently I am passing id and want my designation also to pass to ajax. Can I know how this can be implemented via ajax. Any help will be highly appreciated.
<select name="designation" class="form-control" id="desig" >
<option value="">Select a Designation/Role</option>
<?php
$sql = mysql_query("SELECT id, designation FROM tbl where status =1 and designationtype_id = 1 ");
while ($rows = mysql_fetch_assoc($sql)){
echo "<option value=" . $rows['id'] . ">" . $rows['designation'] . "</option>";
}
?> <select name="dd" id="dd" class="form-control" disabled>
<option value=""></option>
</select>
My AJAX,
<script type="text/javascript">
$(document).ready(function() {
$("#desig").change(function() {
var id = $(this).val();
var dataString1 = 'id=' + id;
var des = $(this).val();
var dataString2 = 'designationname=' + des;
$.ajax({
type: "POST",
url: "escalation_ajax.php",
data: dataString,
cache: false,
success: function(html) {
var data = html.split(",");
$('#rephead').val(data[0]);
}
});
});
});
</script>
escalation_ajax.php
<?php
if ($_POST['id'])
{
if ($_POST['des'])
{
$des_id = $_POST['id'];
$designation = $_POST['des'];
$sql = mysql_query("SELECT designation_id, reporting_head FROM aafmindia_in_sbi.tbl_reporting_head WHERE status=1 and reporting_head_for='$des_id'");
if ($sql === FALSE)
{
trigger_error('Query failed returning error: ' . mysql_error() , E_USER_ERROR);
}
else
{
while ($row = mysql_fetch_array($sql))
{
$id = $row['designation_id'];
$reporting_head = $row['reporting_head'];
echo '<option value="' . $id . '">' . $reporting_head . '</option>' . ',' . '<option value="' . $des_id . '">' . $designation . '</option>';
}
}
}
}
?>
What you could do, is have the second select (the one that needs the same value as the first) in a seperate file that you load via AJAX.
AJAX function:
function selection()
{
var selectValue=$("select#dd option:selected").val();
$.ajax({
type : "POST",
url : "escalation_ajax.php",
data : { id : selectValue },
success: function (html) {
$("#secondSelectorDiv").html(html);
}
})
}
What this does, is that when the selection() function is called, it will post the selected value of the first select to "escalation_ajax.php". It will then load that page into an element (div element in my example) with the id "secondSelectorDiv".
The html for the select with the function (which I will call onchange in this example), can look like this:
<select id="dd" onchange="selection();">
<option value=""></option>
</select>
<div id="secondSelectorDiv"></div>
Now in escalation_ajax.php you can retrieve the post variable and use it to look for the id in question for the second select.
<?php
$id=$_POST['id'];
/*
If you're using the id to fetch something in your database,
which it looks like you're doing, then use the post variable
to fetch your rows and build the select from that.
*/
$sql="SELECT * FROM table_name WHERE id='$id'";
$result_set=mysql_query($sql);
$row=mysql_fetch_array($result_set);
$count=mysql_num_rows(result_set);
$counter=0;
//this is the id you will check for in order to see what's to be selected
$idToCheck=$row['id'];
?>
<select id="dd2">
while($count > $counter)
{
counter++;
echo '<option value=""'; if($idToCheck == $id){ echo 'selected="selected"'; } echo '></option>';
}
?>
If you want the second select to be displayed before the first select has a value, you can simply just call an AJAX function that loads in the second select on page load.
IMPORTANT!: You should really switch to mysqli_* or PDO instead of using the deprecated mysql_*. You should at the very least look into sanitizing your inputs.
I have an ajax form that filters posts based on the category.
Setup:
HTML form
PHP function to echo ouput
jQuery ajax request to load php
function
Question: How can I parse a value to the php function ($test, see below) from within the jQuery ajax function?
Form - Outputs html select field and button to filter posts
<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
<?php
if( $terms = get_terms( 'category', 'orderby=name' ) ) : // to make it simple I use default categories
echo '<select name="categoryfilter"><option>Select category...</option>';
foreach ( $terms as $term ) :
echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; // ID of the category as the value of an option
endforeach;
echo '</select>';
endif;
?>
<button>Apply filter</button>
<input type="hidden" name="action" value="myfilter">
</form>
<div id="response"></div>
PHP function - Outputs result on button click in HTML form
function misha_filter_function($test){
// Do something with $test, but how to parse it with jQuery into this php function?
$args = array(
'orderby' => 'date', // we will sort posts by date
'order' => $_POST['date'] // ASC или DESC
);
// for taxonomies / categories
if( isset( $_POST['categoryfilter'] ) )
$args['tax_query'] = array(
array(
'taxonomy' => 'category',
'field' => 'id',
'terms' => $_POST['categoryfilter']
)
);
$query = new WP_Query( $args );
if( $query->have_posts() ) :
while( $query->have_posts() ): $query->the_post();
echo '<h2>' . $query->post->post_title . '</h2>';
endwhile;
wp_reset_postdata();
else :
echo 'No posts found';
endif;
die();
}
add_action('wp_ajax_myfilter', 'misha_filter_function');
add_action('wp_ajax_nopriv_myfilter', 'misha_filter_function');
jQuery - Question: how to parse php value $test to the above php function?
jQuery(function($){
$('#filter').submit(function(){
var filter = $('#filter');
$.ajax({
url:filter.attr('action'),
data:filter.serialize(), // form data
type:filter.attr('method'), // POST
beforeSend:function(xhr){
filter.find('button').text('Processing...'); // changing the button label
},
success:function(data){
filter.find('button').text('Apply filter'); // changing the button label back
$('#response').html(data); // insert data
}
});
return false;
});
});
You serialize data so accesed by:
parse_str($_POST['data'], $inputValues); //$inputValues will be array with your form fields
I'm using a Wordpress plugin that I'm trying to customize for my needs but I'm very new to Javascript. The plugin calculates the distance between two zip codes which is what $distance is. I created a drop down menu with different values based on vehicle size. What I want to do is display the distance multiplied by the value assigned to each vehicle size (which is the cost per mile). Any help would be appreciated. Thank you.
<?php
/**
* Plugin Name: WP Distance Calculator
* Plugin URI: http://phpcodingschool.blogspot.com/
* Description: This plugin claculates distance between two near by locations.
* Version: 1.0.0
* Author: Monika Yadav
* Author URI: http://phpcodingschool.blogspot.com/
* License: GPL2
*/
class DistanceWPCalculator
{
public function __construct()
{ //action definations
add_shortcode( 'distance_calculator', array( &$this, 'distanceWPfrontend' ) );
add_action( 'wp_ajax_nopriv_distancewpcalculator', array( &$this, 'distancewpcalculator_calculate' ) );
add_action( 'wp_ajax_distancewpcalculator', array( &$this, 'distancewpcalculator_calculate' ) );
add_action( 'init', array( &$this, 'init' ) );
}
public function init()
{
wp_enqueue_script( 'distancewpcalculator', plugin_dir_url( __FILE__ ) . 'js/calculatedistance.js', array( 'jquery' ) );
wp_localize_script( 'distancewpcalculator', 'DistanceCalculator', array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
) );
?>
<script>
var ajaxurl = "<?php echo admin_url('admin-ajax.php'); ?>";
</script>
<?php
wp_enqueue_style( 'DistanceWPCalculator-Style', plugin_dir_url( __FILE__ ) . 'css/style.css', array(), '0.1', 'screen' );
}
public function distancewpcalculator_calculate()
{
// The $_POST contains all the data sent via ajax
if ( isset($_POST) ) {
$from = urlencode($_POST['from']);
$to = urlencode($_POST['to']);
$data = file_get_contents("http://maps.googleapis.com/maps/api/distancematrix/json?origins=$from&destinations=$to&language=en-EN&sensor=false");
$data = json_decode($data);
$time = 0;
$distance = 0;
foreach($data->rows[0]->elements as $road) {
$time += $road->duration->value;
$distance += $road->distance->value;
}
$time =$time/60;
$distance =round($distance/1609.344);
//Output
if($distance!=0){
echo "<div id='result_generated'>";
echo "From: ".$data->origin_addresses[0];
echo "<br/>";
echo "To: ".$data->destination_addresses[0];
echo "<br/>";
echo "Time: ".gmdate("H:i", ($time * 60))." hour(s)";
echo "<br/>";
echo "Distance: ".$distance." mile(s)";
echo "</div>";
}else{
echo "Sorry only nearby distance can be calculated.";
}
}
die();
}
//Function to display form on front-end
public function distanceWPfrontend( $atts ) {
?>
<form method ="post" id="calculator" >
<div class="DC_title">Distance Calculator</div>
<input type="text" id="from" name="from" placeholder="From.."></br>
<input type="text" id="to" name="to" placeholder="To.."></br>
<select id="carType" onchange="carsize()">
<option value=".45">Motorcycle</option>
<option value=".6">Small Sedan</option>
<option value=".65">Large Sedan</option>
<option value=".7">Wagon/Hatchback</option>
<option value=".7">Small SUV</option>
<option value=".8">Large SUV</option>
<option value=".8">Minivan</option>
<option value=".75">Small Truck</option>
<option value=".8">Large Truck</option>
</select>
<input type="button" id="calculate" name="calculate" value="Calculate">
</form></br>
<div id="result"></div>
<?php
}
}
$distancewpcalculator = new DistanceWPCalculator();
?>
This is actually PHP. In your distancewpcalculator_calculate() function you calculate the distance based on the results that the Google Maps API returns. You store the calculated distance in the $distance variable (specifically $distance =round($distance/1609.344);). In that assignment you convert the recorded $distance value from Km to Mi.
You should modify your HTML select tag and values to something like this:
<select id="carType" name="carType">
<option value=".45">Motorcycle</option>
<option value=".6">Small Sedan</option>
<option value=".65">Large Sedan</option>
<option value=".7">Wagon/Hatchback</option>
<option value=".7">Small SUV</option>
<option value=".8">Large SUV</option>
<option value=".8">Minivan</option>
<option value=".75">Small Truck</option>
<option value=".8">Large Truck</option>
</select>
Doing this will include the "carType" value in the $_POST data. Now that it is in the post data, you can get the value selected by doing $_POST['carType']. Now that data is recorded we can multiply the value of the distance by the carType selected.
public function distancewpcalculator_calculate()
{
// The $_POST contains all the data sent via ajax
if (isset($_POST)) {
...
$distance = round($distance / 1609.344);
$carType = $_POST['carType'];
$cost = $carType * $distance;
//Output
if ($distance != 0) {
...
echo "Distance: " . $distance . " mile(s)";
echo "<br />";
echo "Cost: {$cost}";
echo "</div>";
} else {
...
}
}
}
The calculated $cost is a product of the selected vehicle type ($carType) and the calculated distance between the two locations ($distance);
I'm trying to send AJAX data to my wordpress table but all I can get from my PHP is a 0. Its on the admin side. Can anyone help me?
Also all of this code is inside my plugin-admin.php file inside my plugin folder.
<?php
if ( ! defined( 'ABSPATH' ) || ! current_user_can( 'manage_options' ) ) exit;
global $wpdb;
global $wp_version;
$results = $wpdb -> get_results(
"
SELECT ID, post_title, post_excerpt
FROM $wpdb->posts
WHERE post_type = 'post' and post_status NOT LIKE 'auto-draft'
AND post_title NOT LIKE 'Auto Draft'
AND post_status = 'publish'
ORDER BY post_title
"
);
add_action( 'wp_ajax_featured_submit_action', 'featured_submit_callback' );
function featured_submit_callback(){
echo "hi";
wp_die();
}
?>
<div class="wrap">
<h2>Select Posts</h2>
<select id="selected-posts" multiple="multiple">
<?php
foreach ( $results as $result ){
?><option value="<?php echo $result->ID; ?>"> <?php echo $result->post_title; ?> </option> <?php
}
?>
</select>
<br>
<input type="submit" id="sposts-submit"></input>
</div>
<script>
jQuery(document).ready(function($) {
var spostsarray = new Array();
//Click button
$("#sposts-submit").click(function(){
var spostsarray = new Array();
$("#selected-posts").each(function(item){
spostsarray.push( $(this).val() );
});
console.log(spostsarray);
var data = {
"action": "featured_submit_action",
"posts": spostsarray
}
$.ajax({
url: "<?php echo admin_url('admin-ajax.php'); ?>",
type: "POST",
action: "featured_submit_action",
data: {"posts": spostsarray},
success: function(data){
console.log(data);
}
});
});
});
</script>
I've condensed it a bit but the general idea is that I can grab all the recent posts and the user can select which ones they want to feature, send that to the PHP method and edit the table with it.
The problem is with my AJAX callback I only ever return 0 and not the data sent from the javascript.
SOLVED:
After some help from Rohil_PHPBeginner I figured it out. The reason it didn't work is that I was executing the code from the menu page at at that point it was too late to add a hook. Here is the page I used to solve it:
AJAX in WP Plugin returns 0 always
Below code worked perfectly fine for me:
<?php
global $wpdb;
global $wp_version;
$results = $wpdb -> get_results(
"
SELECT ID, post_title, post_excerpt
FROM $wpdb->posts
WHERE post_type = 'post' and post_status NOT LIKE 'auto-draft'
AND post_title NOT LIKE 'Auto Draft'
AND post_status = 'publish'
ORDER BY post_title
"
);
?>
<div class="wrap">
<h2>Select Posts</h2>
<select id="selected-posts" multiple="multiple">
<?php
foreach ( $results as $result ){
?><option value="<?php echo $result->ID; ?>"> <?php echo $result->post_title; ?> </option> <?php
}
?>
</select>
<br>
<input type="submit" id="sposts-submit"></input>
</div>
<?php
add_action( 'wp_ajax_featured_submit_action', 'featured_submit_callback' );
add_action( 'wp_ajax_nopriv_featured_submit_action', 'featured_submit_callback' );
function featured_submit_callback(){
echo "hi";
wp_die();
}
?>
<script>
jQuery(document).ready(function($) {
//Click button
$("#sposts-submit").click(function(){
var spostsarray = new Array();
$("#selected-posts").each(function(item){
spostsarray.push( $(this).val() );
});
console.log(spostsarray);
var data = {
"action": "featured_submit_action",
"posts": spostsarray
}
$.ajax({
url: ajaxurl,
type: "POST",
data: data,
success: function(data){
console.log(data);
}
});
});
});
</script>
You don't need to pass the AJAX url in that way because when I used your code, it is showing me with PHP. WordPress provides a default url for AJAX so you can use that( ajaxurl which I used in below code).
Other than that You have not added code for no-privilege user (if it is going to use only for privileged user then it is okay otherwise you need to add code for that).
WordPress returns 0 when an ajax call doesn't find a valid callback function (though the 0 could be return from many other things).
WordPress looks for callbacks matching wp_ajax_{callback} when a user is logged in and wp_ajax_nopriv_{callback} when the user is logged out. {callback} is populated with the POST'd value of the "action" hidden input. Note that you're not passing the action into your AJAX call. You should change:
data: {"posts": spostsarray},
to
data: data
Since you're not going to match a callback function without passing in action, WordPress is returning 0