Keeping a live log while looping through PHP in an AJAX call - javascript

I am creating a Wordpress plugin to call an API and create new Wordpress posts for each object returned in the response. Here is the PHP for my function that loops over the API response to create new Wordpress posts:
add_action('wp_ajax_sync_posts', 'sync_posts_from_api' );
function sync_posts_from_api() {
// MAKING API CALL HERE
foreach ($data as $post) {
$new_post = array(
'post_type' => 'post',
'post_title' => $post->title,
'post_status' => 'publish',
'post_author' => 1,
'post_content' => $post->description,
);
$wp_post = wp_insert_post($new_post);
echo '<pre>Post ID ' . $wp_post->ID . ') has been created.</pre>';
}
}
And then I have my Javascript like this:
jQuery(function($) {
$('form').submit(function(e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: ajaxurl,
data: {
action: 'sync_posts'
},
}).done(function(response) {
$('.log').html(response);
});
});
});
This works after the AJAX call is completely finished, but I am hoping to be able to append each echo to the .log container as it goes, instead of all at once when the call is finished. How would I go about making that change?

You can only access the ajax request response after the request finishes. The proper way of accomplishing what you want is using web sockets.
In the old days we used to create an iframe loading with something like this:
foreach ($data as $post) {
echo "
<script>
window.parent.postMessage({message: '".$post."'}, 'http://localhost/');
</script>
";
flush();
}
The browser executes the js in real time when loading the page and the js sends a message to the parent frame. You'll also need the proper js code on the parent frame to receive and process those posts. Even though this may still work, it's very sketchy and not recommended.

Related

Ajax javascript php

I'm going to ask a question that has been mentioned very often but I can't understand what is missing in my code to make it work.
I have two PHP files, one that acts as a viewer and the other one that processes, performs processes and a javascript file where I put my ajax requests. My goal is simple to pass a variable between my Js and my PHP.
My global.js file
window.onload = function(){
for($i = 0; $i <= 0; $i++){
console.log("after for");
console.log($i);
$input = document.getElementsByClassName('from_1')[$i].textContent;
$sub = document.getElementsByClassName('subject_1')[$i].textContent;
$recei = document.getElementsByClassName('received_1')[$i].textContent;
$preview = document.getElementsByClassName('bodypreview_1')[$i].textContent;
$body_1 = document.getElementsByClassName('body_1')[$i].textContent;
console.log("*********************");
console.log($input);
console.log($sub);
console.log($recei);
console.log($preview);
console.log($body_1);
console.log("*********************");
}};
I recover data with getElementsById and store it in variables. Then in the same file I make my Ajax call
function btn_urgent(html){
console.log("*************************");
console.log("btn_urgent");
console.log($input);
console.log("*************************");
$.ajax({url: '../../wp-content/plugins/game_plugin/process_general.php',
type: 'POST',
data: {info: 'insert_to_db', $input: $input},
success: function(output) {
console.log("*************************");
console.log("ssrtsgsgsg");
alert(output);
console.log("*************************");
return($input);
}
In my game. php file I have an onclick that calls my function "btn_urgent".
<button type="submit" class="btn btn-primary col-2" onclick="btn_urgent()" >urgent</button>
Once my Ajax function is called it calls another function insert_to_db in the process_general file.
function insert_to_db($input){
global $wpdb;
echo json_encode;
$wpdb->insert(
'test_insert', //table name
array(
'id' => 550,
'from_mail' => $input,
), //columns
array(
'%d',
'%s',
)
);
}
As you can see I'm trying to make a $input insert when I click my onclick. but it doesn't work. On the other hand my function insert_to_db is well called by my Ajax request but it does not pass $input.
I think I'm forgetting something in the success story, but I don't know what. If someone has a few tips solution to offer me I am a buyer.
I don't know how important this is, but I'm getting into wordpress.
I remain available if necessary, thank you all and have a good day.
On your ajax data, it have invalid field name:
data: {info: 'insert_to_db', $input: $input},
Change to this:
data: {info: 'insert_to_db', input: $input},
on your php, you need grab the data like this:
$info = $_POST['info'];
$input= $_POST['input'];
// Then call the function
insert_to_db($input)

ajax request is successful, but php is not running

I have a very simple jquery function that sends an Ajax call to a php file that should echo out an alert, but for the life of me, cannot get it to run. For now, I'm just trying to trigger the php to run. Here is the javascript:
function getObdDescription(){
var $code = document.getElementById("vehicle_obd_code").value;
var $length = $code.length;
if($length == 5){
window.confirm($length);
$.ajax({ url: '/new.php',
data: {action: 'test'},
type: 'post',
success:function(result)//we got the response
{
alert('Successfully called');
},
error:function(exception){alert('Exception:'+exception);}
});
}
return false;
}
Here is new.php
<?php
echo '<script language="javascript">';
echo 'alert("message successfully sent")';
echo '</script>';
?>
I'm testing in Chrome, and have the network tab up, and can see that the call is successful, as well, I get the 'Successfully called' message that pops up, so the jquery is running, and the Ajax call is successful. I also know that the url: '/new.php is correct, because when I delete new.php from my server, I get a status "404 (Not Found)" from the console and network tab. I've even test without the conditional if($length ==... and still no luck. Of course, I know that's not the problem though, because I get the 'Successfully called' response. Any ideas?
This isnt the way it works if you need to alert the text, you should do it at the front-end in your ajax success function, follow KISS (Keep It Simple Stupid) and in the php just echo the text . that is the right way to do it.
You should do this:
function getObdDescription() {
var $code = document.getElementById("vehicle_obd_code").value;
var $length = $code.length;
if ($length == 5) {
window.confirm($length);
$.ajax({
url: '/new.php',
data: {
action: 'test'
},
type: 'post',
success: function (result) //we got the response
{
alert(result);
},
error: function (exception) {
alert('Exception:' + exception);
}
});
}
return false;
}
In your php
<?php
echo 'message successfully sent';
?>
You are exactly right Muhammad. It was not going to work the way I was expecting it. I wasn't really trying to do an Ajax call, but just to get an alert box to pop up; I just wanted confirmation that the call was working, and the PHP was running. Changing the alert('Successfully called'); to alert(result); and reading the text from the php definitely confirmed that the php was running all along.
I want to stay on topic, so will post another topic if that's what's needed, but have a follow-up question. To elaborate a bit more on what I'm trying to do, I am trying to run a function in my php file, that will in turn, update a template variable. As an example, here is one such function:
function get_vehicle_makes()
{
$sql = 'SELECT DISTINCT make FROM phpbb_vehicles
WHERE year = ' . $select_vehicle_year;
$result = $db->sql_query($sql);
while($row = $db->sql_fetchrow($result))
{
$template->assign_block_vars('vehicle_makes', array(
'MAKE' => $row['make'],
));
}
$db->sql_freeresult($result);
}
Now, I know that this function works. I can then access this function in my Javascript with:
<!-- BEGIN vehicle_makes -->
var option = document.createElement("option");
option.text = ('{vehicle_makes.MAKE}');
makeSelect.add(option);
<!-- END vehicle_makes -->
This is a block loop, and will loop through the block variable set in the php function. This work upon loading the page because the page that loads, is the new.php that I'm trying to do an Ajax call to, and all of the php runs in that file upon loading. However, I need the function to run again, to update that block variable, since it will change based on a selection change in the html. I don't know if this type of block loop is common. I'm learning about them since they are used with a forum I've installed on my site, phpBB. (I've looked in their support forums for help on this.). I think another possible solution would be to return an array, but I would like to stick to the block variable if possible for the sake of consistency.
I'm using this conditional and switch to call the function:
if(isset($_POST['action']) && !empty($_POST['action'])) {
$action = $_POST['action'];
//Get vehicle vars - $select_vehicle_model is used right now, but what the heck.
$select_vehicle_year = utf8_normalize_nfc(request_var('vehicle_year', '', true));
$select_vehicle_make = utf8_normalize_nfc(request_var('vehicle_make', '', true));
$select_vehicle_model = utf8_normalize_nfc(request_var('vehicle_model', '', true));
switch($action) {
case 'get_vehicle_makes' :
get_vehicle_makes();
break;
case 'get_vehicle_models' :
get_vehicle_models();
break;
// ...etc...
}
}
And this is the javascript to run the Ajax:
function updateMakes(pageLoaded) {
var yearSelect = document.getElementById("vehicle_year");
var makeSelect = document.getElementById("vehicle_make");
var modelSelect = document.getElementById("vehicle_model");
$('#vehicle_make').html('');
$.ajax({ url: '/posting.php',
data: {action: 'get_vehicle_makes'},
type: 'post',
success:function(result)//we got the response
{
alert(result);
},
error:function(exception){alert('Exception:'+exception);}
});
<!-- BEGIN vehicle_makes -->
var option = document.createElement("option");
option.text = ('{vehicle_makes.MAKE}');
makeSelect.add(option);
<!-- END vehicle_makes -->
if(pageLoaded){
makeSelect.value='{VEHICLE_MAKE}{DRAFT_VEHICLE_MAKE}';
updateModels(true);
}else{
makeSelect.selectedIndex = -1;
updateModels(false);
}
}
The javascript will run, and the ajax will be successful. It appears that the block variable is not being set.

How to get data from AJAX in PHP without using a function

NOTE: No more down-votes please, just because you cannot answer the question/ or cannot understand the problem doesn't mean you have to down-vote. I clearly said I can provide more information/be more specific if you need me too.
Edited title for clarification
I am using javascript to validate the form client side, then using ajax to pass 3 arrays worth of data to a separate PHP page for processing. Just trying to perform a basic query with one of arrays before i begin.
the ajax request says it's working, and when I go into the network tab, then click response, it shows all the arrays with the correct values/indexes.
But on the PHP side nothing is happening. I have no idea how to debug the PHP because it's on a different page. I'm assuming this has something to do with my syntax, as I have got this too work before, but i used ajax in a function. I am very new to ajax, so I am not too sure if I am doing this correctly. I have tried a valid $wpdb query on the page and nothing is happening. How do i properly structure my PHP page to work with the ajax? Any way I can debug my PHP when ajax fires?
If you need additional information please let me know.
AJAX CALL:
$.ajax({
type: "POST",
url: "?page_id=251",
data: { vData: videoData, tsData: tsValues, dData: tsDescriptions},
success: function(){
$("#errorMessage").text("ajax success.");
}});
?page_id=251 (PHP page)
<?php
$videoData = $_POST['vData']; // i have also tried $_GET['vData'];
$vSRC = $videoData[0];$vTIT = $videoData[1];$vDES = $videoData[2];$vPDF = $videoData[3];$vDAT = $videoData[4];
$uID = get_current_user_id();
global $wpdb;
$wpdb->insert( $wpdb->prefix."uservideo", array(
"user_id" => $uID,
"video_src" => $vSRC,
"video_title" => $vTIT,
"video_description" => $vDES,
"pdf_file" => $vPDF,
"video_date" => $vDAT
));
?>
I found the solution to the issue.
I needed to call a function with the ajax, cannot just call a page. I'm sure you can just call the page but no one knows how apparently.
AJAX
<script type="text/javascript">
function insert_data(vidData,timesData,descData){
$.ajax({
url: '?page_id=251',
type: 'POST',
data: {action: 'insert_video', vData: vidData, tsData: timesData, dData: descData },
dataType: 'json',
success: function(response){
alert('dhsdhjsdjhsjhdjhsd');
}
});
}
</script>
PHP
<?php
function insert_video($videoData,$tsValue,$tsDesc){
$videoData = $_POST['vData'];
$vSRC = $videoData[0];$vTIT = $videoData[1];$vDES = $videoData[2];$vPDF = $videoData[3];$vDAT = $videoData[4];
$tsValue = $_POST['tsData'];
$tsDesc = $_POST['dData'];
$uID = get_current_user_id();
global $wpdb;
$wpdb->insert( $wpdb->prefix."uservideo", array(
"user_id" => $uID,
"video_src" => $vSRC,
"video_title" => $vTIT,
"video_description" => $vDES,
"pdf_file" => $vPDF,
"video_date" => $vDAT
));
}
echo insert_video($_POST['vData'], $_POST['tsData'], $_POST['dData']);
?>

How to save my data to Mysql without page refresh

code in my view is bellow:
<?php echo $form->create( "ChatForm", array("id" => "chat_form", "type" => "post",'class'=>'form_chat',"url" => array( "controller" => "qasamples", "action" => "quick_request" ) ) );
echo $form->hidden( 'ChatForm.pid', array('class'=>'chat_input_hidden') );
echo $form->hidden( 'ChatForm.uid', array('class'=>'chat_input_hidden') );
echo $form->textarea('ChatForm.text',array('id'=>'text_input','rows'=>'14','cols'=>'400','style'=>'resize:none;width:907px;border:0px;','onkeyup'=>"onTextChange()")); ?>
<p style="text-align:center;margin-top:20px;"><button type=submit id="chat_send">Send</button></p>
<?php $form->end(); ?>
here is the controller code:
public function quick_request(){
if(!empty($this->data))
{
$fields=array('QasampleAnswer.uid','QasampleAnswer.pid','QasampleAnswer.text');
$data=array(
'uid'=>$this->data['ChatForm']['uid'],
'pid'=>$this->data['ChatForm']['pid'],
'text'=>$this->data['ChatForm']['text']);
if($this->QasampleAnswer->save($data))
{
$data_update=array(
'id'=>$this->data['ChatForm']['pid'],
'status'=>'0');
if($this->Qasample->save($data_update))
$this->render('text2');
}
}
}
Can I just send the message and without fresh my page?
I heard that CakePHP and AJAX can make it work, but I'm a new learner of CakePHP and Javascript also. I hope you guys can help me with it. Thank you very much. The page text2 is to turn the page back to where I was,but it not working well.So I hope I could send my message and just stay this page without refreshing.
Post your data with Ajax, jquery gives you a lot of options to do that... you can also implement a JavaScript and make it call when the for. is submitted (this can be achieved when you add in the array at $form->create array('onsubmit'=>'return yourFunction()') then you have to red your form data in this function, post it via ajax and very important return false in this function (it will prevent the form submitting) you can also make a button instead of the submit button that calls this function but then you have to implement in the text-field that when the user presses enter it should send the data... it is more comfortable with the onsubmit thing.
If you need an example I can also provide a practical code for this...
I will use a cake-less example of the JavaScript
<?php echo $form->create( "ChatForm", array("id" => "chat_form", "type" => "post",'class'=>'form_chat',"url" => array( "controller" => "qasamples", "action" => "quick_request", "onsubmit"=>"return performPostRequest(this)") ) );
this is the part you use to create the form
<script type="text/javascript">
function performPostRequest(form) {
parameters="";
for(var i=0;i<form.elements.length;i++) {
if(parameters!="")
parameters+="&";
if(form.elements[i].checked==true || !(form.elements[i].type=="radio" || form.elements[i].type=="checkbox"))
parameters+=form.elements[i].name+"="+encodeURIComponent(form.elements[i].value);
}
$.ajax({
url: form.action,
data: parameters,
type : 'POST',
});
return false;
};
</script>
and this is the JavaScript function, I use it myself so it should work without a Problem :) It simulates your post request, but uses Ajax and therefore your page will not reload...
You need a simple Ajax Call like the following and modify the form create so that it does not post automatically.
$ajax->form(array('type' => 'post',
'options' => array(
'model'=>ChatForm,
//'update'=>'UserInfoDiv',
'url' => array(
'controller' => 'chatforms',
'action' => 'quick_request'
)
)
));

Ajax driven content using CodeIgniter

I'm making an web that is a single-page website interacting with the server through Ajax in CodeIgniter. The general coding is of the following type:
controller (user.php):
public function get_user_content() {
$id = $this->input->post('id');
$hits = $this->user_model->user_data($id);
$s = '';
foreach ($hits as $hit) {
$s .= $hit->name;
$s .= $hit->age;
}
echo $s;
}
model(user_model.php):
function user_data($id) {
//do sql operation
return $query->result();
}
view:
...
...
Click here for user details
...
...
javascript:
('.user-data').click(get_user_data);
....
....
function get_user_data(response) {
return $.ajax({
type: "POST",
url: "<?php echo base_url();?>index.php/user/get_user_content",
data: { id: this.id },
success: function(response) {
$("#somediv").append(response);
$(".someclass").click(another_function);
},
error: function(error) {
alert("Error");
}
});
}
So, looking at the above javascript, there are separate functions for all actions that send some data to the server and the particular html content is updated via Ajax.
I had the following questions (I'm just new to this stuff):
1. Is there any better way of doing ajax in javascript than my implementation.
2. I'm not using the concept of views in CodeIgniter. I just `echo` results through my controller functions that gets embedded in javascript. This is because I want dynamic update in my app. It is a single page and there is no concept of new-page/new-tab. Is there any better way?
I'm not aware of any open-source projects that might make it easier/more optimized.
For making code more simplified, readable & with great coding standard answer will be yes for both to improve your javascript code & way you are getting a response from the Ajax call.
Improve Javascript :
You might have one common js included in you header portion, if not create & include one. This common jar contains only common functions throughout the application. Create one function with the name may be like sendAjaxRequest() in that common.js. This function will have some parameters like divId (refresh div id), url(post url), options(array of options) & function will look like this:
function sendAjaxRequest(strDivId, strRequestUrl, options) {
options = options || {};
var defaultOptions = {url: strRequestUrl, type: 'POST', beforeSend: function(request,options){showLoadingImage(strDivId);}, success: function(html){$('#'+strDivId).html(html); removeLoadingImage(strDivId); }};
options = $.extend({},defaultOptions,options);
$.ajax(options);
}
Call this function from where ever required on application.
like
('.user-data').click( function() { sendAjaxRequest('somediv', url,{data: { id: this.id }}) });
Benefit : This method is very useful in the future when you want to keep google analytics on ajax call also or want to track your ajax calls. It is always good to have common functions.
Resposnse from ajax call: You can load views in Controller->function in case of ajax call also, nothing need to change or configure for this. Use of this way is always good practice to maintain standardness & readablity in the code.
Note : Here in this case you might worry about using a second action on load of your first Ajax call, for this standard way is to write second action on load of view of that particular Ajax call view (Write second click code in that particular view only) like
('.someclass').click( function() { sendAjaxRequest('someOtherDiv', otherUrl,{data: { id: this.id }}) });
In short at the end user divide & conquer rule (Divide an html page into blocks & create the huge page) to create good applications. Its really fantastic way, as I am using this way in my codings overall.
1- There is other ways to do ajax calls , being better or not is based on your needs, This post clears this point
2- your way is good, still you could use some enhancements to your functions to be a complete web-services same as handling errors - in case - and to return the output data as json allowing you to control it from your JavaScript function for a better handling & representation.
3- from what i understood you're getting data for single user each time ,in this case using $query->row() would be make your life easier extracting the data than using $query->result() , but in case you are getting multiple records you could loop it withing your JavaScript function.
here's another approach to your example with little enhancements that might be helpful :
controller (user.php):
public function get_user_content($id) {
$output -> hit = $this -> user_model -> user_data($id);
if (!$output -> hit) {
$output -> msg = "NORECORDS";
} else {
$output -> msg = "SUCCESS";
}
echo json_encode($output);
}
model(user_model.php):
function user_data($id) {
//do sql operation
return $query -> row();
}
JavaScript :
function get_user_data(response) {
$.get("<?php echo base_url();?>index.php/user/get_user_content/" + this.id, function(data) {
if (data.msg != 'SUCCESS') {
alert(data.msg);
return;
}
var hit = data.hit;
$("#somediv").append("Name: " + hit.name + "Age: " + hit.age);
$(".someclass").click(another_function);
}, "json");
}
First Answer:
The ajax request seems fine, you can add dataType option also to expect particular type of response,
As you are using post you can use jquery.post as an alternative
Example
$.post( "<?php echo base_url();?>index.php/user/get_user_content", function(data) {
alert( "success" );
}, 'html') // here specify the datatype
.fail(function() {
alert( "error" );
})
You can also use done callback instead of success
Second answer:
Controller
public function get_user_content() {
$id = $this->input->post('id');
$hits = $this->user_model->user_data($id);
$user_array = array();
foreach ($hits as $hit) {
$temp_array = array();
$temp_array = array('name' => $hit->name);
$temp_array = array('age' => $hit->age);
$user_array = array($temp_array);
}
$this->load->view('user', $user_array);
}
Modal
Remains the same
View (user.php)
example say user.php
<?php
echo "<div class='somediv'>";
if (sizeof($user_array)) {
for ($row = 0; $row < sizeof($user_array); $row++ ) {
echo "User Details: Name - " . $user_array[$row]['name'] . ", Age - " . $user_array[$row]['age'];
echo "<br/>";
}
} else {
Click here for user details
}
echo "</div>";
?>
Javascript
$('.user-data').on('click' function () { // better to use event delegation as content is loaded dynamically
get_user_data();
});
function get_user_data() {
$.post( "<?php echo base_url();?>index.php/user/get_user_content", function(data) {
alert( "success" );
$("#somediv").append(data);
$(".someclass").click(another_function);
}, 'html') // here specify the datatype
.fail(function() {
alert( "error" );
});
}
Reference
stackoverflow.com/questions/18471627/codeigniter-load-a-view-using-post-and-ajax

Categories

Resources