form validaiton on form submit without page reload - javascript

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'
}

Related

How to save a post and custom fields values with ajax in front end in wordpress?

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.

Problems making an AJAX call in a Wordpress site

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.

Delete post using $.ajax

I am new to $.ajax and don't know so much and i have following button to delete user post by article ID
<button type="button" onclick="submitdata();">Delete</button>
When click this button then following $.ajax process running.
<script>
var post_id="<?php echo $userIdRow['post_id']; ?>";
var datastring='post_id='+post_id;
function submitdata() {
$.ajax({
type:"POST",
url:"delete.php",
data:datastring,
cache:false,
success:function(html) {
alert(html);
}
});
return false;
}
</script>
And delete.php is
<?php
// connect to the database
include 'conn.php';
$dbClass = new Database();
// confirm that the 'post_id' variable has been set
if (isset($_GET['post_id']) && is_numeric($_GET['post_id'])) {
// get the 'post_id' variable from the URL
$post_id = $_GET['post_id'];
// delete record from database
if ($userPostsQuery = $dbClass::Connect()->prepare("DELETE FROM user_posts WHERE post_id = :post_id")) {
$userPostsQuery->bindValue(":post_id", $post_id, PDO::PARAM_INT);
$userPostsQuery->execute();
$userPostsQuery->close();
echo "Deleted success";
} else {
echo "ERROR: could not prepare SQL statement.";
}
}
?>
This code not working post not deleted. Please how do I do?
You likely want to not only match the "GET" you use in your PHP but also add the ID to the button
<button class="del" type="button"
data-id="<?php echo $userIdRow['post_id']; ?>">Delete</button>
using $.get which matches your PHP OR use $.ajax({ "type":"DELETE"
$(function() {
$(".del").on("click", function() {
$.get("delete.php",{"post_id":$(this).data("id")},
function(html) {
alert(html);
}
);
});
});
NOTE: Please clean the var
Do htmlspecialchars and mysql_real_escape_string keep my PHP code safe from injection?
Using ajax DELETE with error handling
$(function() {
$(".del").on("click", function() {
$.ajax({
url: "delete.php",
method: "DELETE", // use "GET" if server does not handle DELETE
data: { "post_id": $(this).data("id") },
dataType: "html"
}).done(function( msg ) {
$( "#log" ).html( msg );
}).fail(function( jqXHR, textStatus ) {
alert( "Request failed: " + textStatus );
});
});
});
In the PHP you can do
if ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
$id = $_REQUEST["post_id"] ....
}
since you're sending a post request with ajax so you should use a $_POST iin your script and not a $_GET
here is how it sould be
<?php
// connect to the database
include 'conn.php';
$dbClass = new Database();
// confirm that the 'post_id' variable has been set
if (isset($_POST['post_id']) && is_numeric($_POST['post_id'])) {
// get the 'post_id' variable from the URL
$post_id = $_POST['post_id'];
// delete record from database
if ($userPostsQuery = $dbClass::Connect()->prepare("DELETE FROM user_posts WHERE post_id = :post_id")) {
$userPostsQuery->bindValue(":post_id", $post_id, PDO::PARAM_INT);
$userPostsQuery->execute();
$userPostsQuery->close();
echo "Deleted success";
} else {
echo "ERROR: could not prepare SQL statement.";
}
}
?>
for the JS code
<script>
var post_id="<?php echo $userIdRow['post_id']; ?>";
function submitdata() {
$.ajax({
type:"POST",
url:"delete.php",
data:{"post_id":post_id},
cache:false,
success:function(html) {
alert(html);
}
});
return false;
}
</script>
here i've supposed thqt the give you the real id post you're looking for !!
The reason is pretty simple. You should change your request type to GET/DELETE instead of POST. In PHP you expect GET request but in AJAX you send POST request
Change:
type:"POST",
url:"delete.php",
data:datastring,
to
type:"DELETE",
url:"delete.php?" + datastring,
in PHP
if ($_SERVER['REQUEST_METHOD'] === 'DELETE' && !empty($_REQUEST["post_id") {
$id = $_REQUEST["post_id"];
// perform delete
}
DELETE is actually the only valid method to delete objects. POST should create an object and GET should retrieve it. It may be confusing at first time but it's good practicet specially used in REST APIs. The other one would be UNLINK if you wanted to remove relationship between objects.
Follow #roberts advise and also:
You should have a way to handle errors eg.
to your ajax code add this:
error:function(e){
alert(e.statusText)// if you like alerts
console.log(e.statusText)// If you like console
}
You should also check your error logs. Assuming you use apache2 and linux
execute this in terminal:
tail -f /var/log/apache2/error.log
This gives you a very elaborate way to code. You also eliminate the problem of trial and error.

AJAX take data from POST with PHP

i have a little problem with my script.
I want to give data to a php file with AJAX (POST).
I dont get any errors, but the php file doesn't show a change after AJAX "runs" it.
Here is my jquery / js code:
(#changeRank is a select box, I want to pass the value of the selected )
$(function(){
$("#changeRank").change(function() {
var rankId = this.value;
//alert(rankId);
//$.ajax({url: "/profile/parts/changeRank.php", type: "post", data: {"mapza": mapza}});
//$("body").load("/lib/tools/popups/content/ban.php");
$.ajax({
type: "POST",
async: true,
url: '/profile/parts/changeRank.php',
data: { 'direction': 'up' },
success: function (msg)
{ alert('success') },
error: function (err)
{ alert(err.responseText)}
});
});
});
PHP:
require_once('head.php');
require_once('../../lib/permissions.php');
session_start();
$user = "test";
if($_SESSION["user"] != $user && checkPermission("staff.fakeLogin", $_SESSION["user"], $mhost, $muser, $mpass, $mdb))
$_SESSION["user"] = $user;
header('Location:/user/'.$user);
die();
When i run the script, javascript comes up with an alert "success" which means to me, that there aren't any problems.
I know, the post request for my data is missing, but this is only a test, so im planning to add this later...
I hope, you can help me,
Greets :)
$(function(){
$("#changeRank").change(function() {
var rankId = this.value;
//alert(rankId);
//$.ajax({url: "/profile/parts/changeRank.php", type: "post", data: {"mapza": mapza}});
//$("body").load("/lib/tools/popups/content/ban.php");
$.ajax({
type: "POST",
async: true,
url: '/profile/parts/changeRank.php',
data: { 'direction': 'up' },
success: function (msg)
{ alert('success: ' + JSON.stringify(msg)) },
error: function (err)
{ alert(err.responseText)}
});
});
});
require_once('head.php');
require_once('../../lib/permissions.php');
session_start();
$user = "test";
if($_SESSION["user"] != $user && checkPermission("staff.fakeLogin", $_SESSION["user"], $mhost, $muser, $mpass, $mdb))
$_SESSION["user"] = $user;
echo json_encode($user);
This sample code will let echo the username back to the page. The alert should show this.
well your js is fine, but because you're not actually echoing out anything to your php script, you wont see any changes except your success alert. maybe var_dump your post variable to check if your data was passed from your js file correctly...
Just return 0 or 1 from your php like this
Your PHP :
if($_SESSION["user"] != $user && checkPermission("staff.fakeLogin", $_SESSION["user"], $mhost, $muser, $mpass, $mdb))
{
$_SESSION["user"] = $user;
echo '1'; // success case
}
else
{
echo '0'; // failure case
}
Then in your script
success: function (msg)
if(msg==1)
{
window.location = "home.php"; // or your success action
}
else
{
alert('error);
}
So that you can get what you expect
If you want to see a result, in the current page, using data from your PHP then you need to do two things:
Actually send some from the PHP. Your current PHP redirects to another URL which might send data. You could use that or remove the Location header and echo some content out instead.
Write some JavaScript that does something with that data. The data will be put into the first argument of the success function (which you have named msg). If you want that data to appear in the page, then you have to put it somewhere in the page (e.g. with $('body').text(msg).

Check all possible AJAX responses

I have an AJAX function which POST data to a PHP handler. I echo back either "success" or "failure" from PHP to determine if it was completed as intended. Unfortunately I am not used to JS/AJAX and have trouble finding documentation that answers my questions.
Do I need to JSON encode the response? I only check for .done() in my AJAX function, should I also check success and failed? My code inside of .done() which is just an alert box isn't working, despite the functionality in the PHP handler running without issue.
JS/AJAX:
<script type="text/javascript">
function powerSignal(device, signal)
{
var cfm = confirm("Do you wish to ___ the server?");
if (cfm==true)
{
$.ajax({ type: "POST", url: "https://domain.net/modules/power_functions.php", data: { device: device, 'power_signal': signal }}).done(function(result)
{
alert("success!");
});
}
}
</script>
PHP:
if ( isset($_POST["device"]) && isset($_POST["power_signal"]) )
{
$deviceid = $_POST["device"];
$signal = $_POST["power_signal"];
//API: Get Device Inventory
$url = 'http://domain.net/dp/api/set_device_power_status';
$fields = array('deviceid' => urlencode($deviceid), 'power_signal' => urlencode($signal));
$result = curl_get($url, $fields);
$json = json_decode($result);
$status = $json->{'status'};
if ($status == "success")
{
echo "success";
}
echo "failed";
}
the content of the result variable will be what the server sends back, you'll have to test it :
$.ajax({ type: "POST", url: "https://domain.net/modules/power_functions.php", data: { device: device, 'power_signal': signal }}).done(function(result)
{
if(result=='success'){
alert("success!");
}else{
alert("failure!");
});
To answer the comment below, here is how I do in my current project with a simple get request :
$.get( "/getResult/"+data, function( results ) {
$('.popin_content').html('<p>Vos documents ont bien été créés :</p><br/><ul><li>Plan PDF</li><li>Devis PDF</li></ul>');
});

Categories

Resources