I am running into some issues with the AJAX portion of a Wordpress site feature that takes a zip code entered on a form uses a PHP function to find if the zip code refers to a specific location and returns a permalink to that location.
My first question was about the form I built. Right now I have the form-action blank because I don't want the form to really go anywhere, just make the AJAX call. Is there anything extra I need to do in the form to indicate the data entered should go to an AJAX function?
<form id="zipcode" action="" method="post"><input class="form-control search-input" autocomplete="off" name="zipcode" type="text" value="" placeholder="Enter Zip Code" />
The next question I have is about the filter function in my functions.php file. I'm not sure exactly how to go about getting the form data passed inot the filter data, this is what I have tried below, I also included the zip_search function which returns the permalink.
/**
* LOCATION SEARCH FILTER AJAX
*
* call location search filter ajax
*
* #return ajax json data via function.
*/
add_action( 'wp_ajax_locations_search', 'prefix_ajax_locations_search' );
add_action( 'wp_ajax_nopriv_locations_search', 'prefix_ajax_locations_search' ); //used for handling AJAX requests from unauthenticated users
function prefix_ajax_zip_search_filter() {
// Handle request then generate response using WP_Ajax_Response
$zipcode = $_POST[ 'zipcode' ];
//return our filtered location data
echo zip_search($zipcode);
wp_die(); // this is required to terminate immediately and return a proper response
}
//Function that contains zip code search functionality
function zip_search($userZip){
$args = array(
'posts_per_page' => -1,
'post_type' => 'Locations'
);
$wp_query = new WP_Query($args);
if( $wp_query->have_posts() ): while( $wp_query->have_posts() ) : $wp_query->the_post();
$zipField=get_field('zip_codes_services');
$zipString = $zipField . ', ';
$array = explode(', ' , $zipString); //split string into array seperated by ', '
foreach($array as $value) //loop over values
{
if($value==$userZip){
$post_id = get_the_ID();
$permalink=get_permalink($post_id);
return ($permalink); //print
}
}
endwhile;
wp_reset_postdata();
endif;
}
Lastly I created a separate js folder containing the below scripts.js seen below, for now I just wanted it to redirect to an example site if my form is not blank. Right now the only thing that happens when I submit a zipcode into the form is the page refreshes.
$("form#zipcode").on("submit", function(event) {
$('form#zipcode .clear-button').addClass('active');
event.preventDefault();
zipcode_search(zip_search_filter());
});
function zipcode_search(zip_search_filter) {
//add ajax loader
$("form#zipcode .ajax-content-loader").addClass("active");
//process the form
$.ajax({
type: "POST", // define the type of HTTP verb we want to use (POST for our form)
url: ajaxcall.ajaxurl,
data: {
action: "locations_search", //calls the function in the functions.php file
zip_search_filter: zip_search_filter
},
success: function(response) {
//redirect to new page
if (response != "") {
alert("You will now be redirected.");
window.location = "http://www.example.com/";
}
//remove the loader
$("#zipcode .ajax-content-loader").removeClass(
"active"
);
}
});
return false; //prevents the form from submitting to a new page.
}
Does anyone have experience with AJAX calls in Wordpress, any advice is appreciated.
It sounds like the form is submitting before your functions are called. Try moving event.preventDefault() so it is called first, like so:
$("form#zipcode").on("submit", function(event) {
event.preventDefault(); //call this first
$('form#zipcode .clear-button').addClass('active');
zipcode_search(zip_search_filter());
});
Check your syntax, =! should instead be !=;
//correct syntax
if (data != "") {
alert("You will now be redirected.");
window.location = "http://www.example.com/";
}
Also, your success function returns response, but you are referencing data. Change the code so that the proper object is referenced:
success: function(response) {
//redirect to new page
if (response != "") {
alert("You will now be redirected.");
window.location = "http://www.example.com/";
}
or...
success: function(data) {
//redirect to new page
if (data != "") {
alert("You will now be redirected.");
window.location = "http://www.example.com/";
}
First I had to add a form id:
Then I made a number of edits, in functions.php :
/**
* LOCATION SEARCH FILTER AJAX
*
* call location search filter ajax
*
* #return ajax json data via function.
*/
add_action( 'wp_ajax_locations_search', 'prefix_ajax_locations_search' );
add_action( 'wp_ajax_nopriv_locations_search', 'prefix_ajax_locations_search' ); //used for handling AJAX requests from unauthenticated users
function prefix_ajax_locations_search() {
// Handle request then generate response using WP_Ajax_Response
$zipcode = $_POST[ 'zipcode' ];
//return our filtered location data
echo zip_search($zipcode);
wp_die(); // this is required to terminate immediately and return a proper response
}
//Function that contains zip code search functionality
function zip_search($userZip){
$args = array(
'posts_per_page' => -1,
'post_type' => 'Locations'
);
$wp_query = new WP_Query($args);
if( $wp_query->have_posts() ): while( $wp_query->have_posts() ) : $wp_query->the_post();
$zipField=get_field('zip_codes_services');
$zipString = $zipField . ', ';
$array = explode(', ' , $zipString); //split string into array seperated by ', '
foreach($array as $value) //loop over values
{
if($value==$userZip){
$post_id = get_the_ID();
$permalink=get_permalink($post_id);
return ($permalink); //print
}
}
endwhile;
wp_reset_postdata();
endif;
}
I also had to include my custom jquery file and my AJAX file in the enqueue_scripts function functions.php:
wp_enqueue_script( 'custom-js', get_stylesheet_directory_uri() . '/js/scripts.js', array('jquery'), '', true );
wp_localize_script( 'custom-js', 'ajaxcall', array('ajaxurl' => admin_url( 'admin-ajax.php' )));
Finally in scripts.js I made the following changes and instead of redirecting to http://example.com I redirected to the permalink I get from my zip_search function seen above.
/*
* Put all your regular jQuery in here.
* Within this funtion you can use the namespace $ instead of jQuery
* ex. use this $('#id') ... NOT jQuery('#id')
*/
jQuery(document).ready(function($) {
$("form#zipcode").on("submit", function(event) {
event.preventDefault();
$('form#zipcode .clear-button').addClass('active');
//get the entered zipcode value to pass through our function.
var zipcode = $(this).find('input[name="zipcode"]').val();
zipcode_search(zipcode);
});
function zipcode_search(zipcode) {
//add ajax loader
$("form#zipcode .ajax-content-loader").addClass("active");
//process the form
$.ajax({
type: "POST", // define the type of HTTP verb we want to use (POST for our form)
url: ajaxcall.ajaxurl,
data: {
action: "locations_search", //calls the function in the functions.php file
zipcode: zipcode
},
success: function(response) {
//redirect to new page
if (response != "") {
//alert("You will now be redirected.");
window.location = response;
}
//remove the loader
$("#zipcode .ajax-content-loader").removeClass(
"active"
);
}
});
return false; //prevents the form from submitting to a new page.
}
}); /* end of as page load scripts */
Doing all of this solved my problem and the search form now works how I need it to.
Related
I have very simple html form created with one button in it.
<form method="post" id="my_unique_form_id">
<button type="submit" name="'.$name.'" value="'.get_the_ID().'" class="'.$class.'"></button>
</form>
Then I connected it with AJAX
jQuery(document).ready(function() {
jQuery('#my_unique_form_id').on('submit', function(event) {
event.preventDefault();
jQuery.ajax({
type: "post",
url: "",
data: jQuery('#my_unique_form_id').serialize(),
success: function() {
console.log('not reloading the page');
}
})
});
});
So the code above works in a way, that on form submit page does not realod, which is great, but of course I don't get any results I need and nothing is happening.
If I don't use AJAX, everything works perfectly and I get the expected results, but then page is reloading, which I need to avoid. I don't really know how to combine it.
This is php function I am using:
I stored name in a variable (coming from button)
$name = my_function() ? 'remove' : 'add';
my_function setup
function my_function( $post_id = 0, $user_id = 0 ){
if ( ! $post_id ) {
$post_id = get_the_ID();
}
if ( ! $user_id ) {
$user_id = get_current_user_id();
}
$meta_value = get_data( $user_id );
return array_search( $post_id, $meta_value ) !== false;
}
What you need to do is in your jQuery code, pass the data retrieved from the call to the success function like so:
success: function(data){
//Do something
}
That data variable will then contain whatever PHP has echo'd. If you want to access that data in some meaningful way, it will be easiest if you prepare it as an array in PHP i.e. like so:
$dataForjQuery = array('status' => 'OK', 'message' => 'validation passed');
echo(json_encode($dataForjQuery));
this way in jQuery you would do:
success: function(data){
console.log('the status is: ' + data.status); //Will log 'the status is: OK'
console.log('message from server: ' + data.message); //Will log 'message from server: validation passed'
}
p.s. had placed this simply to share the solution.
I'd like to save a post in front end if we click a button using ajax in js:
var title = $("#portfolioTitle").val();
var customFieldValues = $("#customfieldValue").val();
$("#btnClick").on("click", function() {
$.ajax({
url : ajax_url,
type: 'post',
dataType: 'json',
data: {
action: 'data_Publish', portfolioTitle: title, fieldValues: customFieldValues
},
success: function(data) {
if(data == "exists") {
console.log("Add a different title");
} else {
console.log("post added");
console.log(data["link"]);
console.log(data["title"]);
}
}
});
});
Placing my own answer but wondering if there is there any speed or security improvements?
For example we could add a caching system, or define our own ajax (Maybe a help could be answering: How to implement the code in the link using the case scenario we have on this question?) in order not to have wordpress loading all the files but here we are doing a http request, anyway, if any of you would want to give their 2 cents to make it faster, It'd be great.
Let's say we want to add posts via ajax in frontEnd in wordpress and we want to check if the title is unique in the database otherwise tell the user to add a different title:
We have a button to click:
<button type="button" id="btnClick">Load</button>
We have an input for the title and a custom field:
<input type="text" id="portfolioTitle" name="portfolioTitle" value="" placeholder="Your title...">
<input type="text" id="customfieldValue" name="customfieldValue" value="" placeholder="Your customFieldvalue...">
The JS. Firstly you need to load wordpress ajax (This is the bit that could be improved if anyone fances to):
var ajax_url = '<?php echo admin_url( 'admin-ajax.php' ); ?>';
Then your javaScript:
var title = $("#portfolioTitle").val();
var customFieldValues = $("#customfieldValue").val();
$("#btnClick").on("click", function() {
$.ajax({
url : ajax_url,
type: 'post',
dataType: 'json',
data: {
action: 'data_Publish', portfolioTitle: title, fieldValues: customFieldValues
},
success: function(data) {
if(data == "exists") {
console.log("Add a different title");
} else {
console.log("post added");
console.log(data["link"]);
console.log(data["title"]);
}
}
});
});
Then in function.php:
function data_Publish() {
$post_title = $_POST['portfolioTitle'];
$post_custom_field = $_POST['fieldValues'];
$post = array(
'post_title' => $post_title,
'post_status' => 'publish',
'post_type' => 'page',
'page_template' => 'portoflio.php'
);
if ( get_page_by_title( $post_title ) === null ) {
// the title is unique, we can add the new page
$post_id = wp_insert_post( $post );
add_post_meta($post_id, 'customField', $post_custom_field], true);
$link = get_permalink( get_page_by_title( $post_title ) );
$title = get_the_title($post_id);
$newPostAttributes[] = array("link"=>$link, "title"=>$title);
echo json_encode($newPostAttributes);
} else {
// that title already exists, tell the user to change it
echo json_encode("exists");
}
wp_die();
}
add_action('wp_ajax_data_Publish', 'data_Publish');
Basically that function is a normal wordpress query. Therefore you could use the same logic to retrieve post values if You'd want to, for example you won't be using $post_id = wp_insert_post( $post ); but maybe to get the tittle back to the user you'd use $postTile = get_the_title();.
Let's break it down:
In ajax we use action: 'data_Publish', portfolioTitle: title where data_Publish is our php function, and portfolioTitle: title is what we are sending.
In function we can see: $post_title = $_POST['portfolioTitle']; that's our title that we have sent via ajax. With 'page_template' => 'portoflio.php' we can add our own template to that page.
Then we need to use if ( get_page_by_title( $_POST['portfolioTitle'] ) === null ) { to check if that title exists or not, if it doesn't exist, we add the posts to the database with $post_id = wp_insert_post( $post );
Once we added it we use the following to add any other values to our custom field in the newly created postadd_post_meta($post_id, 'customField', $_POST['customfieldValue'], where customField is the name of the custom field we want to create in the new post we just added.
So if the posts doesn't exist, we save it and we can send back to ajax its title and its link so that we could shows it to the user as a response if We'd ever want to.
So we define title and link like this and we create a multidimentional array to send the data back to the front end:
$link = get_permalink( get_page_by_title( $post_title ) );
$title = get_the_title($post_id);
$newPostAttributes[] = array("link"=>$link, "title"=>$title);
If the title exists we send back a response echo json_encode("exists");
We need to die the query for safeness wp_die();
If We'd ever want to make ajax available to no logged user, remember wordpress ajax is only available to admin, so we need to add:
add_action('wp_ajax_data_Publish', 'data_Publish');
add_action( 'wp_ajax_nopriv_data_Publish', 'data_Publish' );
Basically in function.php wordpress uses wp_ajax_ +"name of our function" and wordpress has wp_ajax_nopriv_ to make ajax available if not logged.
I hope It helps anyone and if any of You could improve it, It'll be better for all.
I have a list of dropdown options for a survey, and am counting their choices using jquery. The counting code works fine and has been confirmed. The trouble comes with passing the variable to PHP (from what I've read, I'll need to use the POST function but am having trouble) in order to modify the user's meta data based on the survey responses.
Here's the jquery / counting code which works fine:
$('select').change(function() {
// get all selects
var eSelects = $('select.e');
// set values count by type
var eyes = 0;
// for each select increase count
$.each(eSelects, function(i, s) {
// increase count
if($(s).val() == '1') { eyes++; }
});
// update count values summary
$('.cnteyes').text(eyes);
});
And here's the PHP which is not working (don't understand how to use the POST function, so left that out):
<?php
$response = 'cnteyes';
if ( ! add_user_meta( get_current_user_id(), 'survey', $response, true )) {
update_user_meta ( get_current_user_id(), 'survey', $response );
}
echo get_user_meta( get_current_user_id(), 'survey', true );
?>
Any help would be greatly appreciated! I'm completely stuck and do not understand how to pass jquery to PHP. Thanks for your time.
You can pass data through POST using jQuery.ajax
**JS File**
$.ajax({
url: "path/to/php/file.php",
type: "POST",
data: {
'someData': 'someData' //you pass your results here
},
datatype: "json",
success: function (result) {
}
});
**PHP File**
<?php
$someDate = $_POST['someData']; // you access your results here
?>
// update count values summary
$('.cnteyes').text(eyes);
Above Code should be changed to
// update count values summary
$('.cnteyes').val(eyes);
text() function just fills the input with the text provided but not the value. But Val() function will set the value of the input object to the provided one.
Also on the php snippet the $response should be set to $_POST['cnteyes']
<?php
$response = $_POST['cnteyes'];
if ( ! add_user_meta( get_current_user_id(), 'survey', $response, true )) {
update_user_meta ( get_current_user_id(), 'survey', $response );
}
echo get_user_meta( get_current_user_id(), 'survey', true );
?>
What you want is AJAX, which is asynchronous JavaScript and XML. The answer by #marcus-ekwall here should point you in the right direction, but the short of it is that POST and GET are ancient pre-JavaScript methods that (among other things) result in page refreshes.
Tutorials Point introduces AJAX as follows:
Conventional web application transmit information to and from the sever using synchronous requests. This means you fill out a form, hit submit, and get directed to a new page with new information from the server.
With AJAX when submit is pressed, JavaScript will make a request to the server, interpret the results and update the current screen. In the purest sense, the user would never know that anything was even transmitted to the server.
You may want to begin by looking at their PHP and AJAX Example.
You can try this.
js code
$('select').change(function() {
// get all selects
var eSelects = $('select.e');
// set values count by type
var eyes = 0;
// for each select increase count
$.each(eSelects, function(i, s) {
// increase count
if($(s).val() == '1') { eyes++; }
});
$.post(
"result.php",
{ eye: eyes },
function(data) {
$('.cnteyes').val(eyes);
}
);
});
result.php
<?php
if( $_REQUEST["eye"] ) {
$response = $_REQUEST['eye'];
//write your code here.
}
am trying to process data from htmlform using jquery ajax to codeigniter but It doesn't return any value.
This is the jquery codes am using to process data
$(document).ready(function(){
$("#chat_create_room").submit(function(){
var chat_name = $(".chat_name").val();
$("#response").html('<b>Fetching data...</b>');
$.ajax({
type: 'POST',
url: 'site/create_chat_room',
dataType: 'json',
data: {chat_room_name: chat_name},
success: function(data){
$("#response").html(data.chat_room_name);
$("#submit").css("display", "none");
}
});
return false;
});
And this is the codeigniter controller function am using to grab data from Jquery
public function create_chat_room(){
if($this->session->userdata('logged_in')){
$data = array(
'chat_room_name' => $this->input->post('chat_room_name')
);
$chat_room_name = json_encode($data);
$table_exists = $this->users->table_exists($chat_room_name);
if($table_exists){
echo 'Sorry the table you choose already exist!';
}else{
echo "<strong>".$chat_room_name."</strong> has been created!";
}
}else{
$this->load->view('view_site');
}
But if I try this in codeigniter controller function it works fine
public function create_chat_room(){
$data = array(
'chat_room_name' => $this->input->post('chat_room_name')
);
$chat_room_name= json_encode($data);
echo $chat_room_name;
}
The main thing I want is, to first process the given value (which is Json object) from Jquery to Codeigniter Controller and then check weather the given value exists in the database and if the value exist i alert the user with any message
Thank you
I have been trying different options but finally I got it
, I just had to adjust some few things such as instead of processing json into codeigniter controller I had to just process normal data.
Jquery code
$("#chat_create_room").submit(function(){
var chat_name = $(".chat_name");
$("#response").html('<img src="img/ugchat_loader.GIF"/>');
$.ajax({
type : 'POST',
url : 'site/create_chat_room',
data : chat_name,
success : function(res){
if(res == ""){
$("#response").html('Nothing returned!');
}else{
$("#response").html(res);
}
}
});
$(".chat_name").val('');
return false;
After wards grab every thing using Codeigniter controller
public function create_chat_room(){
if($this->session->userdata('logged_in')){
sleep(3);
$chat_room_name = $this->input->post('chat_room_name');
$table_exists = $this->users->table_exists($chat_room_name);
if($table_exists){
echo '<div class="alert alert-danger"><strong>Error</strong> Sorry the chatroom name is already taken!</div>';
}else{
echo '<div class="alert alert-success"><strong>Success</strong> Your chatroom has been created</div>';
}
}else{
redirect(base_url()."site");
}
And the model
Basically this function check's whether a table is contained in our database
and return true or false;
Afterwards, we evaluate our result and test it in our controller and then return the data back to our html
public function table_exists($table_exists){
$tables = $this->db->table_exists($table_exists);
if($tables){
return true;
}else{
return false;
}
}
I hope it helps
nulldev
I'm trying to do an AJAX request in an WordPress plugin. The request is initiated on the front page embedded in an article using a custom shortcode.
I tried to combine infos from the documentation and this tutorial.
However something is going wrong when testing that method... the AJAX query hook isn't called.
This is how my page.php script is called for short code delivery:
add_shortcode('testshortcode', 'TestShortCodeFunction');
function TestShortCodeFunction($attributes)
{
ob_start();
include(__DIR__.'/page.php');
return ob_get_clean();
}
This is my compacted test script page.php:
<?php
add_action('wp_ajax_test', 'Test');
add_action('wp_ajax_nopriv_test', 'Test');
// do_action('wp_ajax_nopriv_test'); this calls Test()
function Test()
{
echo 'Hallo';
die();
}
?>
<script type='text/javascript'>
jQuery(document).ready(function() {
console.log("JS query started");
// The following does not call test()
jQuery.ajax({
type: "POST",
url: "http://127.0.0.1/wordpress/wp-admin/admin-ajax.php?action=test",
success: function(data) {
console.log("Query returned: "+data);
}
});
});
</script>
Output on the console is:
JS query started
Query returned: 0
The Test() function is never call according to the PHP debugger.
The admin-ajax.php is executed according to the network monitor (URL http://127.0.0.1/wordpress/wp-admin/admin-ajax.php?action=test) but returns 0.
Inside admin-ajax.php do_action('wp_ajax_test') is called according to the PHP debugger.
I'd be really surprised if you managed to make those Ajax action hooks work inside an Output Buffer.
AFAIK, we should only use PHP ob_* functions as last resort.
Here's a standard implementation. A JavaScript file will be enqueued inside the shortcode callback function, and inside it we fire a document.ready Ajax call. The admin-ajax.php URL is passed to a JS object using wp_localize_script. Check the code comments for more info and the Codex for details on each WP function:
<?php
/**
* Plugin Name: (SO) Simple Ajax Shortcode
* Description: Fire an Ajax action when rendering a shortcode
* Author: brasofilo
* Plugin URL: https://stackoverflow.com/a/22585520/1287812
*/
add_shortcode( 'testshortcode', 'shortcode_so_22579460' );
add_action( 'wp_enqueue_scripts', 'enqueue_so_22579460' );
add_action( 'wp_ajax_Test_SO', 'Test_SO' );
add_action( 'wp_ajax_nopriv_Test_SO', 'Test_SO' );
/**
* Enqueue our script inside the shortcode
*/
function shortcode_so_22579460($attributes)
{
wp_enqueue_script( 'my-script' );
return '<h1>Check the broswer console.</h1>';
}
/**
* Register and localize our script
*/
function enqueue_so_22579460()
{
wp_register_script(
'my-script',
plugin_dir_url( __FILE__ ) . 'ajax.js',
array( 'jquery' ) // enqueue jQuery as dependency
);
// We can pass any number of PHP data to the JS 'wp_ajax' object
// Here, only the basics, Ajax URL and a security check
wp_localize_script(
'my-script',
'wp_ajax',
array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'ajaxnonce' => wp_create_nonce( 'ajax_post_validation' )
)
);
}
/**
* Ajax callback
*/
function Test_SO()
{
// Security check
check_ajax_referer( 'ajax_post_validation', 'security' );
// Demonstrative boolean value to return
$random = ( rand() % 2 != 0 );
if( $random )
wp_send_json_error( array( 'error' => 'Random is ODD' ) );
else
wp_send_json_success( 'Random is EVEN' );
}
And the JavaScript file (ajax.js) stored in the same folder as the plugin file:
jQuery(document).ready( function($)
{
var data = {
action: 'Test_SO',
security: wp_ajax.ajaxnonce
};
$.post(
wp_ajax.ajaxurl,
data,
function( response )
{
// Errors
if( !response.success )
{
// No data came back, maybe a security error
if( !response.data )
console.log( 'AJAX ERROR: no response' );
// Error from PHP
else
console.log( 'Response Error: ' + response.data.error );
}
// Success
else
console.log( 'Response Success: ' + response.data );
}
);
});
Here's a similar answer of mine using OOP and jQuery commands to trigger the action. And an article of interest.