So I've modified a piece of code that includes a call to the Google Distance Matrix API.
I wanted it to only work out the distance to a specific address. But I now also want to use it on a different page than originally intended.
I've created a second shortcode, which creates a second form with a different postcode in the hidden field, but while the first form works fine, the second one doesn't do anything.
Can anyone help?
Code below with addresses and API keys removed
<?php
/**
* Plugin Name: WP Distance Calculator
* Plugin URI: /
* Description: This plugin claculates distance between two near by locations.
* Version: 1.0.0
* Author: Monika Yadav
* Author URI: /
* License: GPL2
*/
class DistanceWPCalculator
{
public function __construct()
{ //action definations
add_shortcode( 'distance_calculator', array( &$this, 'distanceWPfrontend' ) );
add_shortcode( 'distance_calculator_LC', array( &$this, 'distanceWPfrontendLC' ) );
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(";origins=$from&destinations=$to&key=");
$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/1000);
//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." miles";
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="hidden" id="to" name="to" value="Postcode 1">
<input type="text" id="from" name="from" placeholder="From.."></br>
<input type="button" id="calculate" name="calculate" value="Calculate" class="wpcf7-form-control wpcf7-submit btn btn-accent btn-lg">
</form></br>
<div id="result"></div>
<?php
}
public function distanceWPfrontendLC( $atts ) {
?>
<form method = "post" id="calculator" >
<div class="DC_title">Distance Calculator</div>
<input type="hidden" id="to" name="to" value="Postcode2">
<input type="text" id="from" name="from" placeholder="From.."></br>
<input type="button" id="calculate" name="calculate" value="CalculateLC" class="wpcf7-form-control wpcf7-submit btn btn-accent btn-lg">
</form></br>
<div id="result"></div>
<?php
}
}
$distancewpcalculator = new DistanceWPCalculator();
?>
JS
jQuery( document ).ready(function() {
jQuery("#calculate").click( function(){
// This does the ajax request
var from = jQuery('#from').val();
var to = jQuery('#to').val();
jQuery.ajax({
url : ajaxurl,
type : 'POST',
data: {
'action':'distancewpcalculator',
'from' : from,
'to' : to
},
success:function(data) {
// This outputs the result of the ajax request
jQuery('#result').html(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
});
});
So I've modified a piece of code that includes a call to the Google Distance Matrix API.
I wanted it to only work out the distance to a specific address. But I now also want to use it on a different page than originally intended.
I've created a second shortcode, which creates a second form with a different postcode in the hidden field, but while the first form works fine, the second one doesn't do anything.
Can anyone help?
Code below with addresses and API keys removed
<?php
/**
* Plugin Name: WP Distance Calculator
* Plugin URI: http://phpcodingschool.blogspot/
* Description: This plugin claculates distance between two near by locations.
* Version: 1.0.0
* Author: Monika Yadav
* Author URI: http://phpcodingschool.blogspot/
* License: GPL2
*/
class DistanceWPCalculator
{
public function __construct()
{ //action definations
add_shortcode( 'distance_calculator', array( &$this, 'distanceWPfrontend' ) );
add_shortcode( 'distance_calculator_LC', array( &$this, 'distanceWPfrontendLC' ) );
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("https://maps.googleapis/maps/api/distancematrix/json?units=imperial&origins=$from&destinations=$to&key=");
$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/1000);
//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." miles";
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="hidden" id="to" name="to" value="Postcode 1">
<input type="text" id="from" name="from" placeholder="From.."></br>
<input type="button" id="calculate" name="calculate" value="Calculate" class="wpcf7-form-control wpcf7-submit btn btn-accent btn-lg">
</form></br>
<div id="result"></div>
<?php
}
public function distanceWPfrontendLC( $atts ) {
?>
<form method = "post" id="calculator" >
<div class="DC_title">Distance Calculator</div>
<input type="hidden" id="to" name="to" value="Postcode2">
<input type="text" id="from" name="from" placeholder="From.."></br>
<input type="button" id="calculate" name="calculate" value="CalculateLC" class="wpcf7-form-control wpcf7-submit btn btn-accent btn-lg">
</form></br>
<div id="result"></div>
<?php
}
}
$distancewpcalculator = new DistanceWPCalculator();
?>
JS
jQuery( document ).ready(function() {
jQuery("#calculate").click( function(){
// This does the ajax request
var from = jQuery('#from').val();
var to = jQuery('#to').val();
jQuery.ajax({
url : ajaxurl,
type : 'POST',
data: {
'action':'distancewpcalculator',
'from' : from,
'to' : to
},
success:function(data) {
// This outputs the result of the ajax request
jQuery('#result').html(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
});
});
The problem is that if your JavaScript is referring to the IDs of the forms and inputs, so if you have both on the same page the script will only run with the values of the first form.
The simplest solution would be to use different IDs for the elements in each shortcode, but a better permanent solution would be to make you script work based on a class, and use the values from the submitted form, rather than global IDs.
So change your form to just have a class on the form
element:
<form class="distance-calculator">
<input type="hidden" name="to" value="Postcode2">
<input type="text" name="from">
<input type="submit" value="Calculate">
</form>
<div class="result"></div>
I've removed everything not relevant to the question for clarity. I also removed method="post"
since POST is not appropriate for getting a value. I also changed the result div to use a class.
Then update your JavaScript to target submission of the .distance-calculator
form, and use the from
and to
value only from the submitted form. Then use only the .result
after the form.
jQuery( '.distance-calculator' ).on( 'submit', function( event ) {
event.preventDefault();
var form = this;
var from = form.from.value;
var to = form.to.value;
jQuery.ajax( {
url : ajaxurl,
type : 'GET',
data: {
'action' : 'distancewpcalculator',
'from' : from,
'to' : to
},
success: function( data ) {
jQuery.next( '.result' ).html( data );
},
error: function( errorThrown ) {
console.log(errorThrown);
}
} );
} );
I also changed the POST
to GET
here. As I mentioned before POST
is not appropriate for this type of request. POST
should only be used for creating or updating a resource, while GET
should be used for retrieving data. It just means you'll need to update your PHP to use $_GET
instead of $_POST
.