Ajax function returning echo instead of value - javascript

I need to update a span element with a value from an update PHP function (that performs mySQL queries), triggered after a button click. I used jQuery/Ajax to achieve this, via a function in another file.
Apparently PHP logs in this case require the following form:
echo '<script> console.log("My message"); </script>';
So I put these in my PHP function file, which looks like the following:
if(isset($_POST['myAction'])) {
if ($_POST['myAction'] == "right_action") {
echo '<script> console.log("ENTERED"); </script>';
update(...)
...
}
}
function init()
{
...
echo '<script> console.log("Successfully connected to database"); </script>';
return ...;
}
function fetch(...) {
init();
...
echo '<script> console.log("Database fetch successful"); </script>';
echo '<script> console.log(' . result . '); </script>'; // equals 49
return ...;
}
function update(...) {
init();
...
echo '<script> console.log("Database update successful"); </script>';
return fetch(...);
}
On the one hand, the logs appear properly while the PHP is executing.
However it seems that the return value of the update PHP function, from the perspective of the Ajax function, contains all the logs. Here is the Ajax function:
$.ajax({
method: "POST",
url: "my_php_file.php",
data: { myAction: 'myAction',
(params) },
success: function(result) {
console.log("Success at Ajax transfer-to-PHP");
console.log("RESULT: " + result);
spanElement.load(result);
},
error: function(error) {
console.log("Error at Ajax transfer-to-PHP: " + error);
}
});
And the Ajax log:
RESULT
<script> console.log("ENTERED"); </script><script> console.log("Successfully connected to database"); </script><script> console.log("Database update successful"); </script><script> console.log("Successfully connected to database"); </script><script> console.log("Database fetch successful"); </script><script> console.log(49); </script>
The same behavior happens when I print in Ajax the content of the span element, initially filled with the result from the fetch PHP function. It prints all the logs; but then it does print the value (while the update mechanic above doesn't even).

I think you are approaching this very unusually, and making things quite hard for yourself. I've never seen PHP returning Javascript to do console.log() before. I'm sure it works, and maybe it really suits what you need, but it seems very Rube Goldberg-ish to me.
If you want to generate logs of what your PHP is doing, just do it in PHP on the server. You can then monitor your application log on the server.
If you want a response from your PHP that your browser can handle and use to update your page, just return the response as text, or better yet as JSON, so you can include eg a status as well as a message. If you really want to pass log messages back to the browser, you could structure the response to include a log element which will be logged to the console, along with a message element to display to the user. You might want to include a status or success element, which is true or false.
There are thousands of examples here on SO, here's a highly ranked one, here's a simpler one, but searching for anything like "php ajax example" will turn up plenty more for inspiration.
As to why your result includes multiple msgs, just trace through what your PHP is doing - each step echoes a message, one after the other. They're all part of the content returned to your Javascript.
I see one bug in your Javascript - .load() loads content from the specified URL. You've already loaded content with your .ajax(), and result is not a URL, so that isn't doing what you expect and won't work.
Here's some clunky pseudo-code which skips over some specifics but gives you a general idea. If you want to keep a running log of each step as you are currently, you'll have to pass your $response array around to/from your functions, or if this is a PHP class make it a class property to avoid that. If you just log to the server you can avoid that, since you only need the final result of your update().
$response = [];
if(isset($_POST['myAction'])) {
if ($_POST['myAction'] == "right_action") {
// If you really want to return log msgs to the browser
$response['log'][] = 'ENTERED';
// More appropriate might be to just log them in PHP. How you do that is
// up to you, eg if you are using a library or just your own simple fopen(),
// fwrite() etc. Though you might not want this level of detail after initial
// development.
// myLogger('Entered');
// In this pseudo-code you'll have to include $response as parameter passed
// to your functions so they can update it, and they'll have to return it
update(...)
...
}
}
// Return your response as JSON which is easy for JS to work with
header('Content-Type: application/json');
echo json_encode($response);
function init()
{
...
$response['log'][] = 'Successfully connected to database';
// myLogger('Successfully connected to database')
return ...;
}
function fetch(...) {
init();
...
$response['log'][] = 'Database fetch successful';
$response['message'] = $result;
// myLogger('Database fetch successful')
return ...;
}
function update(...) {
init();
...
$response['log'][] = 'Database update successful';
// myLogger('Database update successful')
return fetch(...);
}
Then your Javascrtipt can do something like:
$.ajax({
method: "POST",
url: "my_php_file.php",
data: {
myAction: 'myAction',
(params)
},
success: function(result) {
console.log("Success at Ajax transfer-to-PHP");
// Log your log msgs
console.log("RESULT:");
console.dir(result.log);
// .load() will load the specified remote content, similar to .ajax()
// spanElement.load(result);
// You can use .html() or .text() to update your span
// https://api.jquery.com/html/
spanElement.html(result.message);
},
error: function(error) {
console.log("Error at Ajax transfer-to-PHP: " + error);
}
});

Related

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.

Call a php from another php using ajax

I'm trying to call a php from ajax, so I wrote this on my first page (index.php):
<script type="text/javascript">
function valid(id) {
var element = document.getElementById(id);
$.ajax({
url: 'valid.php',
type:'POST',
data:
{
url: element.children[0].childNodes[0].nodeValue
},
success: function(msg)
{
console.log('done 1');
}
});
}
</script>
and here is my second one (valid.php):
<script type="text/javascript">
console.log('done 2');
</script>
<?php
if (isset($_GET['url']))
{
try
{
$bdd = new PDO('mysql:host=host;dbname=dbname;charset=utf8', 'id', 'password');
$bdd->exec("INSERT INTO sometable (url)
VALUES (".$_GET['url'].");");
}
catch (Exception $e)
{
die();
}
}
?>
But when I call my function, it doesn't seem to call valid.php even if the console show "done 1", "done 2" doesn't appear anywhere by the way and the database stay unchanged, like valid.php just doesn't run.
How may I fix that? Thank you!
Since you are using POST, you need to retrieve your data using $_POST rather than $_GET.
In valid.php if you are expecting isset($_GET['url']) which is a GET parameter but your AJAX request is sent via POST. You should change that to isset($_POST['url']).
Regarding the console.log('done 2'); on valid.php it won't get executed unless you append that to the body of index.php and evaluate that specific script but it is redundant because console.log('done 1'); refers to the completion of valid.php request.
Edit: On your insertion query you have $_GET['url'] and it should be $_POST['url'].

phpword send generated doc to frontend

I am trying to generate docFiles on my webapp. First i was thinking of using some tool in the Frontend like Markswindolls 'jquery.wordexport.js' tool. But since there are not much functions like setting Header or Footer or aligning, I started to work with 'phpword'.
My Problem now is, that the docFile is saved on the server. Is there any possibility of sending the file via ajax to the Frontend so the User can get the File after pushing on my 'download as .doc' button?
Any other recommendations are welcome too.
jquery:
$('#word-button').on('click', function() {
$.ajax({
type: "POST",
url: "phpWORD/gendocx.php",
success: function (msg, string, jpXHR) {
console.log('AJAX SUCCESS');
},
complete : function(data, textStatus, jqXHR){
console.log('AJAX COMPLETE');
},
error: function(xhr, desc, err) {
console.log(xhr);
console.log("Details: " + desc + "\nError:" + err);
}
});
})
gendocx.php:
<?php
require_once 'PHPWord.php';
$PHPWord = new PHPWord();
$section = $PHPWord->createSection();
// Create a new PHPWord Object
$PHPWord = new PHPWord();
// Every element you want to append to the word document is placed in a section. So you need a section:
$section = $PHPWord->createSection();
// After creating a section, you can append elements:
$section->addText('Hello world!');
// You can directly style your text by giving the addText function an array:
$section->addText('Hello world! I am formatted.', array('name'=>'Tahoma', 'size'=>16, 'bold'=>true));
// If you often need the same style again you can create a user defined style to the word document
// and give the addText function the name of the style:
$PHPWord->addFontStyle('myOwnStyle', array('name'=>'Verdana', 'size'=>14, 'color'=>'1B2232'));
$section->addText('Hello world! I am formatted by a user defined style', 'myOwnStyle');
// You can also putthe appended element to local object an call functions like this:
$myTextElement = $section->addText('Hello me!');
// At least write the document to webspace:
$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007');
$objWriter->save('helloWorld.docx');
?>
This is what I use for PHP Excel, sorry about fragmentation, but this is from a large service file:
$this->generateXls();
$this->writeToVariable();
if ($response instanceof Response) {
$this->setHeaders($response->getHeaders());
}
$response->setContent($this->getXlsContent());
This is where the file content is stored to a variable instead of a file:
protected function writeToVariable()
{
ob_start();
$this->getWriter()->save('php://output');
$xlsContent = ob_get_clean();
$this->setXlsContent($xlsContent);
}
And just set the headers before returning your response
protected function setHeaders(Headers $headers)
{
$headers->addHeaderLine('Content-Type', $this->getFileMimeType());
$headers->addHeaderLine('Content-Disposition', "attachment; filename=\"{$this->getFullFileName()}\"");
$headers->addHeaderLine('Accept-Ranges', 'bytes');
$headers->addHeaderLine('Content-Length', strlen($this->getXlsContent()));
}
This is done in zf2 so headers are injected in to response object but in your case just add them to whatever generates your output.
Oh, btw, mime type for excel looks like this:
$this->setFileMimeType('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
So try to find the one for the ms word format you want to output, that is in this format.
For a simplified non-OO approch:
$writer = \PHPExcel_IOFactory::createWriter($this->getWorkbook(), $type);
//<---GENERATE YOUR DOCUMENT HERE
ob_start();
$writer->save('php://output');
$document = ob_get_clean();
//<---SET OUTPUT HEADERS LIKE FOR ANY OTHER FILE TYPE HERE
echo $document;
die;

Passing values from jQuery to PHP in same page instantly

I have written a PHP program to confirm deletion of data through jQuery confirm message (Refer: http://rathur.fr/jQuery/MsgBox/) and record the result back to the same page itself instantly. If the page refreshes, it'll return back its state to previous.
The part of line is below:
print "
<script type='text/javascript'>
$(document).ready(function(){
$.msgbox('<br/>Are you sure you want to delete the selected record from the database?', {
type : 'confirm'
}, function(result){
$('#output').text(result);
var output = result;
});
});
</script>";
I want to get the result of the action button to PHP variable instantly, like below (just a trial):
$x = $_SESSION['output']; OR
$x = $_POST['output']; OR
$x = print "<div id=\"output\"></div>"; OR
$x = some_function(output);
Please help me, or suggest if there is other better options.
Here is a simple Ajax call to a Php File by an event : Click on a button.
Javascript client side :
$("body").on("click", "#mybutton", function() {
var mydata = $("#form").serialize();
$.ajax({
type: "POST",
url: "/api/api.php",
data: {data : mydata},
timeout: 6e3,
error: function(a, b) {
if ("timeout" == b) $("#err-timedout").slideDown("slow"); else {
$("#err-state").slideDown("slow");
$("#err-state").html("An error occurred: " + b);
}
},
success: function(a) {
var e = $.parseJSON(a);
if (true == e["success"]) {
$("#action").html(e['message']);
// here is what you want, callback Php response content in Html DOM
}
}
});
return false;
});
Next in your Php code simply do after any success function :
if ($result) {
echo json_encode(array(
'success' => true,
'msg' => "Nice CallBack by Php sent to client Side by Ajax Call"
));
}
You should use jQuery to POST the data to a PHP script using AJAX if you want to use the second pass.
http://api.jquery.com/category/ajax/ has many functions and tutorials on writing AJAX functions and handling return data. In particular, look at the post() function.

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