I'm looking to convert the below php form submission to a JQuery Ajax submission. I have used Ajax with some simple requests before, but I'm not sure how to submit and return data from MySQL for the below code.
The code below submits the user input entry to a MySql query returning single columns rows. A While loop then looks at these rows and fires another mysql query returning the number of user likes per row.
<?php
if(!empty($_POST['Message']))
{
$userid = session_id();
$searchStr = get_post($con,'Message');
$aKeyword = explode(" ", $searchStr);
$aKeyword = array_filter($aKeyword);
$stmt = $con->prepare(
'SELECT m.ID, m.MessageText
FROM MessageMain m
LEFT OUTER JOIN Likes l on m.ID = l.PostID
WHERE MessageText REGEXP ?
GROUP BY m.ID, m.MessageText ORDER BY count(m.id) desc'
);
$regexString = implode('|', $aKeyword);
$stmt->bind_param('s', $regexString);
$stmt->execute();
$result = $stmt->get_result();
$rowcount=mysqli_num_rows($result);
echo "<pre> Returned ". $rowcount . " matches</pre>";
if(mysqli_num_rows($result) > 0) {
$row_count=0;
While($row = $result->fetch_assoc()) {
$postid = $row['ID'];
$row_count++;
// Checking user status
$status_query = $con->prepare("SELECT COUNT(*) AS type FROM likes WHERE userid = ? AND postid = ?");
$status_query->bind_param('ss',$userid,$postid);
$status_query->execute();
$status_result = $status_query->get_result();
$status_row = $status_result->fetch_assoc();
$type = $status_row['type'];
// Count post total likes
$like_query = $con->prepare("SELECT COUNT(*) AS cntLikes FROM likes WHERE postid = ?");
$like_query->bind_param('s',$postid);
$like_query->execute();
$like_result = $like_query->get_result();
$like_row = $like_result->fetch_assoc();
$total_likes = $like_row['cntLikes'];
?>
<div class="post">
<div class="post-text">
<?php
echo nl2br(htmlentities($row['MessageText'],ENT_COMPAT|ENT_IGNORE, "UTF-8") );
?>
</div>
<div class="post-action">
<input type="button" value="Like" id="like_<?php echo htmlentities($postid . "_" . $userid); ?>" class="like" style="<?php if($type == 1){ echo "color: #ffa449;"; } ?>" /> (<span id="likes_<?php echo $postid . "_" . $userid; ?>"><?php echo htmlentities($total_likes); ?></span>)
</div>
</div>
<?php
}
}
}
Easiest would be to rewrite you PHP script to return only the data so you can use this in your JS to build the HTML.
What I would suggest is simply creating a array and adding all your data to this array in you while loop, so for example:
// Add the array declaration somewhere at the beginning of your script ( outside the while loop )
$likesData = array();
Then inside your while loop:
$likesData[] = array(
'ID' => $postid,
'type' => $type,
'totallikes' => $total_likes
);
Then after your while loop:
// Return the array as JSON, die script to ensure no other data gets send after the json response
die( json_encode( $likesData ) );
Then in your JS ( jQuery ) do something like this:
// Do the AJAX request
$.post( "yourscript/url/maybephpfile.php", function( jsonResponse ) {
// Loop over json response
for( var key of Object.keys( jsonResponse ) ) {
$( '.your_existing_element' ).append( `<div class="post"><div class="post-text">${jsonResponse[key].totallikes}</div></div>` );
}
});
Hope this helps you out, if you have any questions let me know.
You need to send from a form in ajax when clicking the button
$.ajax({
method: "POST",
url: "some.php",
data: { message: "message text" }
})
.done(function( msg ) {
// process your data back here
alert( "Data Saved: " + msg );
});
Examples here. https://api.jquery.com/jquery.ajax/
$.post is shortcut of ajax, method post.
I think would be better to split the files and not do everything in one.
form.php -> ajax request -> backend.php -> data retrieved with ajax back to form.php
Related
I'm trying to append a new option in the select list without refreshing the page once the user added a new option through the bootstrap modal
I able to achieve it but there is one problem I'm facing. I also need to append the customer_id in the value attribute of the option tag
Select Tag
<select class="form-control form-control-chosen add-customer-tag" id="invoice_customer_name" name="invoice_customer_name">
<option style="display:none" disabled selected>Customer Name</option>
<option value="add-new-customer">Add New Customer</option>
<?php
if(mysqli_num_rows($select_customer_query)>0){
while($customer_result = mysqli_fetch_assoc($select_customer_query)) {
?>
<option value="<?php echo $customer_result['customer_id']; ?>"><?php echo $customer_result['customer_name']; ?></option>
<?php
}
}
?>
</select>
Ajax call
$.ajax({
url: 'includes/add-customer-modal.inc.php',
type: 'POST',
data: {customer_name:customer_name},
success: function(add_customer_result){
$('.error_message').html(add_customer_result);
if($(add_customer_result).hasClass("alert-success")){
$("#invoice_customer_name").append("<option>" + customer_name + "</option>") // this would insert only the customer name in option, but I need to also insert the customer_id which is coming from database
$("#invoice_customer_name").trigger("chosen:updated");
}
}
});
add-customer-modal.inc.php
<?php
session_start();
include 'db-connection.php';
$user_id = $_SESSION['user_id'];
$customer_name = mysqli_real_escape_string($connection, $_POST['customer_name']);
if(empty($customer_name)){
echo "<span class='alert alert-danger'>Customer name cannot be blank</span>";
} else {
$insert_customer = "insert into customer(user_id,customer_name) values('$user_id','$customer_name')";
$inser_customer_query = mysqli_query($connection,$insert_customer) or die(mysqli_error($connection));
if($inser_customer_query){
echo "<span class='alert alert-success'>Customer has been added</span>";
}
}
?>
and I know my code is vulnerable to sql injection. I will shift to the prepared statement very soon
I was able to append the customer_name in the options list without reloading the page but not the customer_id
Oh dear, we have a bit of a SQL Injection Issue in that code So...
first you need to use prepared parameterised queries, then I would change what is returned from this script to always be JSON, so you can pass the status as well as useful info all in one package of data
<?php
session_start();
include 'db-connection.php';
$user_id = $_SESSION['user_id'];
$response = [];
if(empty($customer_name)){
$response['status'] = 0;
$response['status_msg'] = "Customer name cannot be blank";
} else {
$sql = "insert into customer (user_id,customer_name) values(?,?)";
$stmt = $connection->prepare($sql);
$stmt->bind_param('ss', $_SESSION['user_id'], $_POST['customer_name']);
$ok = $stmt->execute();
if ( $ok ) {
$response['status'] = 1;
$response['status_msg'] = "Customer has been added";
// get the id from the inserted customer
$response['customer_id'] = $connection->insert_id;
} else {
// return some error code and message like above
}
}
echo json_encode($response);
?>
Now in the javascript you have all the info you need you just have to put in where you want it
$.ajax({
url: 'includes/add-customer-modal.inc.php',
type: 'POST',
data: {customer_name:customer_name},
dataType: 'JSON', // tell it to expect a JSON reply
// and will convert the reply to an js object
success: function(response){
if ( response.status == 0){
// error
$('.error_message').html(response.status_msg);
} else {
$("#invoice_customer_name")
.append("<option value='" +
response.customer_id + "'>" + customer_name + "</option>")
$("#invoice_customer_name").trigger("chosen:updated");
}
}
});
in add-customer-modal.inc.php you needs to return the newly created Customer Id
<?php
session_start();
include 'db-connection.php';
$user_id = $_SESSION['user_id'];
$customer_name = mysqli_real_escape_string($connection, $_POST['customer_name']);
if(empty($customer_name)){
$message = "<span class='alert alert-danger'>Customer name cannot be blank</span>";
$array = array(
'status' => 'failed',
'message' => $message
);
} else {
$insert_customer = "insert into customer(user_id,customer_name) values('$user_id','$customer_name')";
$inser_customer_query = mysqli_query($connection,$insert_customer) or die(mysqli_error($connection));
if($inser_customer_query){
$customer_id = mysqli_insert_id($connection);
$message = "<span class='alert alert-success'>Customer has been added</span>";
$array = array(
'status' => 'success',
'message' => $message,
'customer_id' => $customer_id
);
}
}
echo json_encode($array);
?>
Edit Ajax call
$.ajax({
url: 'includes/add-customer-modal.inc.php',
type: 'POST',
data: {customer_name:customer_name},
success: function(add_customer_result){
var result = $.parseJSON(add_customer_result);
$('.error_message').html(result.message);
if(result.status == 'success'){
$("#invoice_customer_name").append("<option value='"+result.customer_id+"'>" + customer_name + "</option>") // this would insert only the customer name in option, but I need to also insert the customer_id which is coming from database
$("#invoice_customer_name").trigger("chosen:updated");
}
}
});
I'm trying to create this like button which goes +1 after clicking on it. You can only click the like once (like is bonded to the account with what u logged in, so a user can not 15x like the same post.)
In my HTML I have this button
<a class="like" id="<?php echo $rows['id']; ?>" href="index.php?id=.$rows['ID']">like</a>
As my AJAX/JQuery I have these
$('a.like').on('click',function () {
var id = $(this).attr('id');
$.ajax({
url:"ajax/post_like.php",
method: "POST",
data: ({ id: id }), // first id is the name, second is the actual id variable we just created
beforeSend: function(data) {
// you can do stuff in here before you send the data, display spinner gif etc
alert('sending the like');
},
success: function(data) {
// same here but when the ajax request is successful
// the data variable is coming from the echo of your PHP script
alert(data);
},
complete: function(data) {
// yet again but on completion
alert('completed the like');
}
});
// stops the browser following the link (href) in the a tag
return false;
});
Now here is the part where I am struggling, mainly the PHP handling. We have created a load more button which loads more posts which works well. The code is as follows. How can I know work out the like part in the same way as the load more button?
<?php
include_once("../classes/db.class.php");
session_start();
$userid = $_SESSION['userid'];
$output = "";
$limit = $_POST['limit'];
if(isset($limit)){
if($limit != ""){
$conn = db::getInstance();
$query ="SELECT posts.id, posts.post_title, posts.picture ,posts.description, posts.location, posts.post_date
FROM posts
INNER JOIN friends
ON posts.user_id = friends.user1_id OR posts.user_id = friends.user2_id
WHERE friends.user1_id='$userid' OR friends.user2_id='$userid'
ORDER BY posts.post_date DESC
LIMIT $limit";
$result = $conn->prepare($query);
$result->execute();
while($row = $result->fetch()) {
$output.=' <div class="post">';
$output .='<div class="post_desc"><p>'. $row['post_title'].'</p></div>';
$output .='<div class="post__picture"><img src="'. $row['picture'].'" alt=""></div>';
$output .='<div class="post_desc"><p>'. $row['description'].'</p></div>';
$output .=' <div class="post_date">'. $row['post_date'].'</div>';
$output .='</div>';
};
echo $output;
}
}
else{
}
?>
Our database is as follows.
Assuming you can set the id column freely, and the userid and postid sections are alphanumerical, you can require the id column to be unique. The following will then always work:
include_once("../classes/db.class.php");
$conn = db::getInstance();
$userid = $_SESSION['userid'];
$postid = $_POST['id'];
$id = "$userid/$postid";
$query = "INSERT INTO likes (id, user_id, post_id) VALUES ('$id', '$userid', '$postid')";
if ($conn->query($sql) === TRUE) {
echo json_encode({postid: postid});
} else {
// There was a small problem processing the like
// You might want to add a check in your success function just to be sure
header('HTTP/1.1 500 Internal Server Error');
}
However, be sure to add a few tests to prevent SQL injections (e.g. by ensuring $postid consists only of integers). If no such guarantee can be made, you should check out this thread.
Otherwise (e.g. if id is generated using AUTO_INCREMENT), you'd have to add a test which tries to retrieve ($userid, $postid) to check if it doesn't exist already:
if (conn->query("SELECT 1 FROM likes WHERE userid=$userid AND postid=$postid")->num_rows == 0) {
// Place the code starting from `$id = ` in here.
};
I've got a dropdown, which when selected, should then go query the DB and get a report back. When the user selects the option from the dropdown, it should dynamically change the field without reloading the page.
However, it does seem to reload the page, and the $_POST data is inserted and visible in the URL.
Code in my custom page (This is in Wordpress btw, but I don't think it's a Wordpress issue)
<form class="get_monthly_report_form" role="form" action="">
<input type="submit" id="function" name="function" value="Retrieve Whole Report"> {code excised here that fills the dropdown}
</form>
<div id="search_results"></div>
and here's the code from the .js file
//Monthly Reports
<script>
// wrap everything in a closure
(function($){
// get our references
var $form = $('form.get_monthly_report_form'),
$search_field = $('#function'),
$results = $('#search_results');
// AJAX search call
function do_search_reps() {
// grab the query value from the search field
var search_text = $search_field.val();
// do a POST ajax call
$.ajax({
type: "POST",
url: '<?php echo admin_url('admin-ajax.php'); ?>',
data: ({
action: "get_and_view_report",
search_text: search_text
}).serialize(),
success: function (response){
console.log(response);
$results.html(response);
}
}); }
// on submit, do the search but return false to stop page refresh
$form.submit(function(e) {
e.preventDefault();
do_search_reps();
return false;
});
})(jQuery);
and the code in my project_functions file is
function get_and_view_report()
{ var_dump ($_POST);
// first, get data passed
$data_passed = explode("++",$_POST["monthly_report_ID"]);
$report_key = $data_passed[0];
$report_type = $data_passed[1];
//print_r ($report_key);
//print_r ($report_type);
//get data about the report as a whole.
$sql = "SELECT * FROM reports_list WHERE report_key ='" . $report_key . "'";
$report_data = $wpdb->get_results ($sql);
//if statement to set up which table to query from NEED TO FINISH THIS
if (substr ($report_data[0]->report_key,0,3) == "sdr")
{
$sql = "SELECT * FROM deployment_list_rows WHERE report_key = '" . $report_key . "' ORDER BY line_number ASC";
}
elseif (substr ($report_data[0]->report_key,0,3) == "Off")
{
$sql = "SELECT * FROM officer_list_rows WHERE report_key = '" . $report_key . "' ORDER BY line_number ASC";
}
elseif (substr ($report_data[0]->report_key,0,4) == "stat")
{
$sql = "SELECT * FROM status_report_rows WHERE report_key = '" . $report_key . "' ORDER BY line_number ASC";
}
elseif (substr ($report_data[0]->report_key,0,3) == "wtr")
{
$sql = "SELECT * FROM service_time_wages_lines WHERE report_key = '" . $report_key . "' ORDER BY line_number ASC";
}
elseif (substr ($report_data[0]->report_key,0,3) == "flr")
{
$sql = "SELECT * FROM fleet_ships_list_rows WHERE report_key = '" . $report_key . "' ORDER BY line_number ASC";
}
//print_r ($sql);
$reports_in_db = $wpdb->get_results($sql);
if (empty($reports_in_db))
{
echo "No Data Returned. Something's Wrong";
}
else
{
//print_r ($reports_in_db);
//print_r ($report_data);
//Time to start building the file to go out.
//so we're going to build an array of things, bringing together all the things
$total_report = array();
foreach($reports_in_db as $key)
{
$total_report [$key->line_number] = $key;
}
// get subtitles/abstract
$sql = "SELECT line_number, field_text FROM subtitle_abstract_summary WHERE report_key = '" . $report_key . "'";
$abs_sums = $wpdb->get_results ($sql);
//now for a series of conditional things
foreach ($abs_sums as $key)
{
$total_report [$key->line_number] = $key;
}
ksort ($total_report, SORT_NUMERIC); //sorting the lines and subtitles into the correct order.
//Now an if statment- calling the sort functions based on report type- NEEDS TO BE DONE
$arrs_to_be_printed = sort_ship_deployment_data_single_report ($total_report);
//Now Create the File headers
$file_headers = array($report_data[0]->report_title, $report_data[0]->report_date, $report_data[0]->transcription_notes, $report_data[0]->labels_row, $arrs_to_be_printed[0]);
print_report_to_screen ($file_headers, $arrs_to_be_printed[1]);
}
}
add_action('wp_ajax_get_and_view_report', 'get_and_view_report');
add_action('wp_ajax_nopriv_get_and_view_report', 'get_and_view_report');
and when I click submit (and try to use the Ajax call - what happens is that the page reloads (when I don't want it to) and the URL now is something like
"view-monthly-report/?monthly_report_ID=OffRec1514581778%2B%2Bofficer_list&function=Retrieve+Whole+Report"
Which looks to me like the post data is being put into the URL - and when in the function, var_dump, the result is
"array(0) { } No Data Returned. Something's Wrong"
As I do testing- it seems that the action hook isn't working.
I would appreciate any help.
Afternoon
My php and Ajax is now almost complete, but I'm stuck on one thing I'm getting the data sent back through to the ajax but its only showing [object Object] in the div I've specified and I'm wanting the number of results sent back to be in there.
<? $call="SELECT * FROM notifications WHERE notification_targetuser='$user1_id' ORDER BY notification_id DESC LIMIT 1";
$chant=mysqli_query($mysqli,$call) or die(mysqli_error($mysqli));
$num=mysqli_num_rows($chant);
while($notification_id=mysqli_fetch_array($chant))
{
?>
<script type="text/javascript">
setInterval(function(){
var notification_id="<?php echo $notification_id['notification_id'] ;?>"
$.ajax({
type: "GET",
url: "viewajax.php?notification_id="+notification_id,
dataType:"json",
cache: false,
success: function(response){
$("#mes").prepend(response);
}
});
},20000);
</script>
<? }?>
Vuewajax.php
<?php
include"database.php";
if(isset($_GET['notification_id'])){
$id=$_GET['notification_id'];
$user1_id=$_SESSION['id'];
$json = array();
$com=mysqli_query($mysqli,"select notification_id from notifications where notification_id > '$id'");
echo mysqli_error($mysqli);
$num = mysqli_num_rows($com);
if($num>0){
echo '<span id="mes">'.$num.'</span>';
}
$resultArr = mysqli_fetch_array($com);
$json['notification_id'] = $resultArr['notification_id'];
mysqli_free_result($com);
echo json_encode($json);
}
?>
My returned response in firebug
<span id="mes">1</span>{"notification_id":"3306"}
You are returning a json object, so you need to access the correct propery, in this case notification_id. Its also good practice to set the correct content-type header:
//php set json header
header('Content-Type: application/json');
echo json_encode($json);
//js access property of returned object
$("#mes").prepend(response.notification_id);
EDIT as per comment - if you are sending json, only send json, not mixed in html:
if($num>0){
$json['num'] = $num;
}else{
$json['num'] = 0;
}
$resultArr = mysqli_fetch_array($com);
$json['notification_id'] = $resultArr['notification_id'];
mysqli_free_result($com);
header('Content-Type: application/json');
echo json_encode($json);
//js
$("#mes").prepend('<span id="mes">'+ response.num + '</span>');
Further EDIT
You can check the value of num, and only prepend if its not 0. As 0 evaluates to false, the following will work
if(response.num){
$("#mes").prepend('<span id="mes">'+ response.num + '</span>');
}
This answer can seems to be off-topic but the code you show us is not secure. He's prone to easy sql injection
eg :
$id = $_GET['notification_id'];
$com = mysqli_query($mysqli,"select notification_id from notifications where notification_id > '$id'");
Injecting "'; DELETE FROM users WHERE 1 or username = ''" in your notification_id parameter will delete all your users !
Use prepared statements, it's easy and far safer an XKCD ;-)
I'm currently doing a form whereby customers will have to do the survey form, I'll have a AJAX "Save" button to allow me to save the data into database when the customers did not managed to finish the form itself and then when the customers login again, the form which they did halfway will pop out again and ask them to continue finish the survey form.
Is it possible where AJAX/javascript/jQuery can work with php codes in it (because of the insert query)?
Not very sure with AJAX and all so Thanks for helping!
This is for the "Save" button.
<input type="button" onClick="save();" value="Save">
This is the insert query whereby it will be inserted in database.
<?php
include("dbFunctions.php");
$idQuery = "SELECT id,question,input FROM db_ExtApp1.scFormLayout WHERE surveyID ='$lastID'";
$idResult = sqlsrv_query($conn, $idQuery);
while ($row = sqlsrv_fetch_array($idResult)) {
$fcID = $row['id'];
$question = $row['question'];
$surveyTitle = $_SESSION['surveyTitle'];
$input = $row['input'];
if (isset($_POST['qns' . $fcID])) {
$answer = implode(",", $_POST['qns' . $fcID]);
$newAns = str_replace($singleQuote,$changeQuote,$answer);
} else {
$newAns = '';
}
if (isset($_POST['others'.$fcID])) {
$others = $_POST['others' . $fcID];
$newOthers = str_replace($singleQuote,$changeQuote,$others);
}else {
$newOthers = 'N.A.';
}
$connectionInfo['ConnectionPooling']=0; // this creates a new connection on the next line...
$newconn = sqlsrv_connect($serverName, $connectionInfo);
if ($input != 'Normal text line, no input required*') {
$query = "INSERT INTO db_ExtApp1.scFormResult(surveyID, answer, others, title, question, name)
VALUES ('$lastID','$newAns','$newOthers', '$surveyTitle','$question', '$name')";
$status = sqlsrv_query($newconn, $query);
} }
if ($status === false) {
die(print_r(sqlsrv_errors(), true));
}
sqlsrv_close($conn);
You can use jquery $.ajax() to send data from client side to PHP. (eg)
$.ajax({
url : 'path/to/php/page',
data : { id : '1', name : 'name' },
dataType : 'JSON',
type : 'POST',
cache: false,
success : function(succ) {
alert(succ);
},
error : function(err) {
alert(err);
}
});
Then in PHP page, use $_POST[] to capture data and insert it into database.
$id = $_POST['id'];
$name = $_POST['name'];
Make sure you escape the values and make it safe for sql insert.