Passing a AJAX Variable to PHP - javascript

Hi wondering how to send a AJAX variable to php, I thought I had it but apparently not. In my console I get the error "Uncaught TypeError: Illegal invocation line 6"
Im taking it there is something wrong with my code straight after the alert?
(NOTE where it say "jquery" is in replace of $ simply because joomla does not like $ in scripts for some reason)
UPDATED, Pay attention to
Script to click and get rowID
<script language="javascript" type="text/javascript">
jQuery(document).ready(function()
{
jQuery("tr.getRow").click(function()
{
rowID = jQuery(this).find("td.idCell");
alert(jQuery(rowID).text());
//Send the row ID to ajaxupdate.php
jQuery.post("ajaxupdate.php", { submit: "update", ID_ID: rowID})
.done( function(data) {
var results = jQuery.parseJSON(data);
console.log( results );
})
.fail( function() {
console.log("AJAX POST failed.");
});
});
});
</script>
Load first table(the one thats being clicked)
<table border="",th,td, width="500", align="center">
<tr>
<th>TP ID</th> <th>Permit Deny</th> <th>Level</th> <th>Session</th> <th>Information Specialist</th>
</tr>
<?php foreach ($results as $row): ?>
<tr class="getRow">
<td class="idCell"><?php echo $row->TP_ID ?></td>
<td><?php echo $row->Permit_or_Deny ?></td>
<td><?php echo $row->Level ?></td>
<td><?php echo $row->Session ?></td>
<td><?php echo $row->Information_specialist ?></td>
</tr>
<?php endforeach ?>
<br>
</table>
Second table, the one that im trying to get to load
<?php
// In ajaxupdate.php file
if( (isset($_POST['ID_ID'])) || (isset($_POST['submit']))) //im Sure this part is wrong
{
$ID_ID =($_POST['ID_ID']); // pass JS var as a PHP var
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query
->select($db->quoteName(array('CV_ID', 'Classifier', 'Value', 'TP_ID')))
->from($db->quoteName('sessionta'))
->where($db->quoteName('TP_ID') . ' LIKE '. $db->quote('".$ID_ID."'));
$db->setQuery($query);
$results = $db->loadObjectList();
}
?>

3425742,
I rewrote your script and tested it with this JSfiddle. Try it out.
I see that you are using Joomla. Diving into Joomla as a novice is daunting. Within ajaxupdate.php the script is expecting to see a $_POST['submit'] variable. Either remove that requirement or add it like I did below. At the bottom of ajaxupdate.php add this line so that jQuery has something to test.
echo $results ? json_encode("succeeded") : json_encode("failed"); die();
Here is the jQuery ajax code:
//Send the row ID to ajaxupdate.php
$.post("ajaxupdate.php", { submit: "update", TP_ID: rowID})
.done( function(data) {
var results = $.parseJSON(data);
console.log( results );
})
.fail( function() {
console.log("AJAX POST failed.");
});
Edit "ajaxupdate.php" to the correct location of that file. If ajaxupdate.php is in a different directory you have to tell jQuery to look there. For example, if your $.post is in index.php in the root of your webserver and ajaxupdate is in the /js directory change "ajaxupdate.php" to "js/ajaxupdate.php".

you are passing rowID as an object, not as a single text-variable. You'd need
$.post("ajaxupdate.php", ({ TP_ID: rowID.attr('id') }), function( data )
...

Related

How to call a php function with parameters using Ajax and JQuery

Trying to delete a record by using JQuery/Ajax function so that my page will not reload everytime I delete. I have a Movie.php that serves as a model object for Movie and this is where I put the function called delete_movie to delete based on movieId parameter. I have tried to call it inside my Jquery call but it looks like it is not calling my function delete_movie(movieId).
This is my Movie.php
<?php
class Movie {
public static function delete_movie($movieId) {
$db = Database::getDB();
$query = 'DELETE FROM MOVIE
WHERE movieId = :movieId';
$statement = $db->prepare($query);
$statement->bindValue(':movieId', $movieId);
$statement->execute();
$statement->closeCursor();
}
}
?>
movielist.php
<tr class="delete_mem<?php echo $movie['movieId'];?>">
<td><?php echo $movie['title']; ?> </td>
<td><?php echo $movie['releaseYear']; ?></td>
<td><?php echo $movie['imdbId']; ?></td>
<td><?php echo $movie['description']; ?></td>
<td><button type="submit" class="btn btn-danger" id="<?php echo $movie['movieId'];?>">Delete</button></td>
</tr>
JQScript.js
$(document).ready(function() {
$('.btn-danger').click(function() {
var id = $(this).attr("id");
if (confirm("Are you sure you want to delete this?")) {
$.ajax({
type: "POST",
url: "model/Movie.php",
data: {
delete_movie : id
},
success: function() {
alert('Success deletion!');
}
});
} else {
return false;
}
});
});
When PHP is running movie.php, it's just processing the class. The PHP within the file doesn't actually say to do anything.
If you don't need classes, you could just change your movie.php to
$db = Database::getDB();
$query = 'DELETE FROM MOVIE
WHERE movieId = :movieId';
$statement = $db->prepare($query);
$statement->bindValue(':movieId', $movieId);
$statement->execute();
$statement->closeCursor();
If there's more in the file or you must use classes, then you need a controller that receives the url POST, and then calls Movie::delete_movie($id).
You appear to be following the MVC pattern, the model and view you have, and adding this controller to control the actions, would be the final part.
You cannot call PHP code from JavaScript (not easily, at least). Fortunately for you, you can do what you're trying to achieve because you're sending a POST message to Movie.php. All that you have to do now is to handle that POST message in Movie.php.
<?php
class Movie {
public static function delete_movie($movieId) {
$db = Database::getDB();
$query = 'DELETE FROM MOVIE
WHERE movieId = :movieId';
$statement = $db->prepare($query);
$statement->bindValue(':movieId', $movieId);
$statement->execute();
$statement->closeCursor();
}
}
// add this
if (isset($_POST["delete_movie"])) {
Movie.delete_movie($_POST["delete_movie"]);
}
?>
I suggest you don't forget to add authentication. Otherwise, anyone can delete any movie from your database. Try adding a session. That's outside the scope of this question, though.

how to change the text of a button in a Jquery on click event handler inside an ajax success function

I usually figure things out for myself but this one is giving me a really difficult time. I need to change the text value of a button in a table that is created by php from a database, after it gets clicked on.
<td id="order_num"><?php echo $order -> order_num; ?></td>
<td><?php echo $order -> data; ?></td>
<td><?php echo $order -> data; ?></td>
<td><?php echo $order -> data; ?></td>
<td><?php echo $order -> data; ?></td>
<td><?php echo $order -> data; ?></td>
<td><?php echo $order -> data; ?></td>
<td><?php echo $order -> data; ?></td>
<!-- **** this is the button. ******** -->
<td><button type="submit" class="accept_order" id ="row_<?php echo $order -> order_num; ?>"
data-row_id = "row_<?php echo $order -> order_num; ?>" data-current_user = "<?php echo $user_id; ?>"
data-order_num = "<?php echo $order -> order_num; ?>">Accept</button>
here is the big mess of an ajax call
$(document).ready(function () {
$('.shop').on('click', 'button', function(e){
var button = $(this).find('button'); //trying to put the value of the current button in a variable to pass to the ajax function.
var current_user = $(this).closest('.shop').find('.accept_order').data('current_user');
console.log(current_user);
var row_id = $(this).closest('.shop').find('.accept_order').data('row_id');
var accepted_order = $(this).closest('.shop').find('.accept_order').data('order_num');
console.log(accepted_order);
e.preventDefault();
$.ajax('url', {
type: "POST",
data: { order_id: accepted_order, user_id: current_user },
success: function(msg){
console.log(msg);
console.log(this);
//change the text of the button to something like "accepted"
***************this is where I have problems ***********************
$(this).html('accepted'); or
$(this).closest('.shop').find('button').html(msg); or
button.text(msg);
},
error: function(){
$(this).closest('.shop').find('.accept_order').html("failure");
}
});
});
});
</script>
I did use $('button').html(msg);
but that changes all of the buttons. It seems like I lose scope to the object when inside the success function. Any ideas or help will be greatly appreciated. Thanks in advance.
I believe I found your problem source but I'm not sure. And The problem came from this keyword because this in the ajax function direct to the ajax object not the button node object. So you can use bind function in the success and error functions to make this directs to the button. here is the modification:
and another thing the url in ajax function is a variable not a string as you wrote above.
$.ajax(url, {
type: "POST",
data: { order_id: accepted_order, user_id: current_user },
success: function(msg){
console.log(msg);
console.log(this);
//change the text of the button to something like "accepted"
***************this is where I have problems ***********************
$(this).html('accepted'); or
$(this).closest('.shop').find('button').html(msg); or
button.text(msg);
}.bind(this),
error: function(){
$(this).closest('.shop').find('.accept_order').html("failure");
}.bind(this)
});
I'm not sure from the solution because there is no demo for what you asked about.
I hope it works.
Maybe you can use the class to select the button
$.ajax('url', {
type: "POST",
data: { order_id: accepted_order, user_id: current_user },
success: function(msg){
console.log(msg);
console.log(this);
//change the text of the button to something like "accepted"
***************this is where I have problems ***********************
$("button.accept_order").html(msg);
},
error: function(){
$(this).closest('.shop').find('.accept_order').html("failure");
}
});
or better..
var button = $(this);
and inside your ajax call just use:
button.html(msg);

Getting callback results to send to AJAX from php and update table

I am updating a database table via AJAX and PHP right now, but I want my page to be more responsive and update my table in my file after the data has been inserted into the database table.
I am not sure how to send info from my php file to AJAX and then how to get AJAX to update the table. How can I call back the data from my PHP file in order to make my table interactive?
The table
Current Announcements
<table>
<tr>
<th>ID</th>
<th>Username</th>
<th>Message</th>
<th>Date</th>
</tr>
<?php
while ($row = $announcements_stmt->fetch()) {
?>
<tr>
<td><?php echo $announcements_id; ?></td>
<td><?php echo $announcements_username; ?></td>
<td><?php echo $announcements_messages; ?></td>
<td><?php echo $announcements_date; ?></td>
</tr>
<?php
}
?>
}
</table>
<?php
}
}
AJAX
$(document).ready(function(){
$("#submit_announcement").on("click", function () {
var user_message = $("#announcement_message").val();
//$user = this.value;
$user = $("#approved_id").val();
$.ajax({
url: "insert_announcements.php",
type: "POST",
data: {
"user_id": $user,
//"message": user_message
"user_message": user_message
},
success: function (data) {
// console.log(data); // data object will return the response when status code is 200
if (data == "Error!") {
alert("Unable to get user info!");
alert(data);
} else {
$(".announcement_success").fadeIn();
$(".announcement_success").show();
$('.announcement_success').html('Announcement Successfully Added!');
$('.announcement_success').delay(5000).fadeOut(400);
}
},
error: function (xhr, textStatus, errorThrown) {
alert(textStatus + "|" + errorThrown);
//console.log("error"); //otherwise error if status code is other than 200.
}
});
});
});
PHP file
$announcement_user_id= $_POST['user_id'];
$announcement_message= $_POST['user_message'];
$test = print_r($_POST, true);
file_put_contents('test.txt', $test);
//var_dump($announcement_user_id);
$con = mysqli_connect("localhost", "", "", "");
$stmt2 = $con->prepare("INSERT INTO announcements (user_id, message, date) VALUES (?, ?, NOW())");
if ( !$stmt2 || $con->error ) {
// Check Errors for prepare
die('Announcement INSERT prepare() failed: ' . htmlspecialchars($con->error));
}
if(!$stmt2->bind_param('is', $announcement_user_id, $announcement_message)) {
// Check errors for binding parameters
die('Announcement INSERT bind_param() failed: ' . htmlspecialchars($stmt2->error));
}
if(!$stmt2->execute()) {
die('Announcement INSERT execute() failed: ' . htmlspecialchars($stmt2->error));
}
//echo "Announcement was added successfully!";
else
{
echo "Announcement Failed!";
}
I think to do this, the following steps is what you need:
Write a new php script that gets the items form the database (like in 'the table' script) and echo these items in the table format you want. So when you call this script, it echo's only a table containing the rows.
Remove the dynamic rows part from the 'the table' script.
On success of your ajax request, make a new request to the new php script
Place the output of that script in the html using jQuery (.html(), insertAfter(), appendTo(), or anything like that).
`

use php variable inside javascript retuns null

I have the following code:
<?php
include('Connection.php');
$query = $conn->prepare("SELECT DISTINCT c.movieName, c.castName, c.movieImdbId, f.year, f.posterLink FROM cast_movie as c JOIN film_info as f ON c.ImdbId = f.ImdbId WHERE c.castName = :q");
$query->execute(array(':q' => $searchText ));
while($row = $query->fetch(PDO::FETCH_ASSOC)):
?>
<tr>
<td><?php echo $row['movieName']; ?></td>
<td>Add to list
</tr>
<?php
endwhile;
?>
<script type="text/javascript">
$('#add').on('click', function (e) {
var selectedOpts = "<?php echo $row['movieName']; ?>";
var obj = {
"movie_name":selectedOpts,
"movie_info": ""
};
parent.window.opener.addToBasket(selectedOpts); //addToBasket is a function that add selected movies to the basket.
});
</script>
My question:
When I click on "add to list" link, it add Nothing to the basket (I mean, the function addToBasket works fine, but the value of "selected" is null..
Could someone kindly let me know how should I use <?php echo $row['movieName']; inside my javascript code? I know I have to put it between "", but I think there should be another problem.. (maybe because this row is not known in javascript code, but I have no idea how to fix it..)
I add also this image to clarify the problem:
Thanks in advance,
Not tested code, but this should work for you :)
<?php
include('Connection.php');
$query = $conn->prepare("SELECT DISTINCT c.movieName, c.castName, c.movieImdbId, f.year, f.posterLink FROM cast_movie as c JOIN film_info as f ON c.ImdbId = f.ImdbId WHERE c.castName = :q");
$query->execute(array(':q' => $searchText ));
while($row = $query->fetch(PDO::FETCH_ASSOC)):
?>
<tr>
<td><?php echo $row['movieName']; ?></td>
<td>Add to list
</tr>
<?php
endwhile;
?>
<script type="text/javascript">
function addmovie(movieName) {
var obj = {
"movie_name":movieName,
"movie_info": ""
};
parent.window.opener.addToBasket(obj); //addToBasket is a function that add selected movies to the basket.
}
</script>
You could use the .prev() jquery option, that will return the dom object previous to your '#add td.
in this case the that olds the movie name, and get the value inside the previous as selectedOps
There are couple of issues I can see:
You have used id="add" for all the rows(movies) and then attaching click event to the id. Change id="add" to class="add".
put the movie name in a data attribute like:
<td>Add to list
Then change the javascript to :
<script type="text/javascript">
$('.add').on('click', function (e) {
var selectedOpts = $(e).data("movieName");
var obj = {
"movie_name":selectedOpts,
"movie_info": ""
};
parent.window.opener.addToBasket(selectedOpts); //addToBasket is a function that add selected movies to the basket.
});
</script>
This should work.
Your first mistake is you are using "id" to fetch the value
Add to list
and you have used while loop because of which your id is getting duplicated and as we all know "id" of element in js should be unique throughout the page.
There are many solutions available for your problem out of which following is one
while($row = $query->fetch(PDO::FETCH_ASSOC)):
?>
<tr>
<td><?php echo $row['movieName']; ?></td>
<td>Add to list
</tr>
<?php
endwhile;
?>
Javascript :
<script type="text/javascript">
$('.add').on('click', function (e) {
var selectedOpts = $(this).attr('lang');
var obj = {
"movie_name":selectedOpts,
"movie_info": ""
};
parent.window.opener.addToBasket(selectedOpts); //addToBasket is a function that add selected movies to the basket.
});
</script>
Suggession : Avoid direct use of php in javascript code instead try to use hidden () variables.

Update CakePhp View each time a record is inserted in the db table

Am making an application that will enable remote viewing of records and reports via a browser. I have used cakePHP to make the application and its working fine,but i have one little problem,since the application does not do any inserts its just reading the data,i want when a user has opened a view and a record has been inserted on the table,it should update all open clients, instead of the user refreshing the page to get the new records.
Is there a cakePHP websocket plugin that actually works?
Our webhost doesnt allow installing programs or adding apache modules so nodejs or similar solutions wont be applicable here.
Am looking for a purely php and javascript implementation where you
just upload your application files to the webserver and everything
runs. You dont have to run, install extras or do any configuration on apache or stuff... afteruploading your files
here is a function in one of my controllers(BooksController.php) that retrieves the data to the view
public function list_books()
{
$this->Books->recursive = 0;
$this->paginate = array('order' => array('Serial_No' => 'DESC'));
$this->set('All_Books', $this->paginate());
}
and here is one of my views(list_books.ctp) that displays the data in a table paginated.
<div class="row-fluid">
<div class="span12">
<?php echo $this->Session->flash() ?>
<h4><?php echo __('All Books') ?></h4>
<hr>
<table class="table table-bordered">
<thead>
<tr> <th><?php echo __('Serial No') ?></th>
<th><?php echo __('Title') ?></th>
<th><?php echo __('Author') ?></th>
<th><?php echo __('Publisher') ?></th>
<th><?php echo __('Category') ?></th>
<th><?php echo __('Section') ?></th>
<th><?php echo __('Available') ?></th>
</tr>
</thead>
<tbody>
<?php foreach( $All_Books as $book ){ ?>
<tr>
<td><?php echo $this->Html->link(__($book['Book']['Serial_No']),'/books/view/'.$book['Book']['Serial_No']) ?></td>
<td><?php echo $book['Book']['Title'] ?></td>
<td><?php echo $book['Book']['Author'] ?></td>
<td><?php echo $book['Book']['Publisher'] ?></td>
<td><?php echo $book['Book']['Category'] ?></td>
<td><?php echo $book['Book']['Section'] ?></td>
<td><?php echo $book['Book']['Available'] ?></td>
</tr>
<?php } ?>
</tbody>
</table>
<?php echo $this->Paginator->prev('« Previous', null, null, array('class' => 'disabled'));
echo $this->Paginator->numbers();
echo $this->Paginator->next('Next »', null, null, array('class' => 'disabled'));
echo $this->Paginator->counter(array(
'format' => 'Page {:page} of {:pages}, showing {:current} records out of
{:count} total, starting on record {:start}, ending on {:end}'
));
?>
</div>
</div>
What can i add on my view or controller or model, to make the view auto updating?
Can this be achieved using ajax?
You can use an AJAX poller, or (HTML5) websockets (using Pusher for instance) for push notification.
You've already mentioned it, AJAX. That's the easiest way to accomplish something like that, simply do a check in the background via AJAX, and if necessary reload the page, or update only the affected parts by again using an AJAX request.
Depending on the amount of data you could of course simply load the data directly instead of checking for updates first.
Update I've misunderstood the question, in case the inserts/udpates are made from an external source that you have no direct control over as described in the comments, the only options I could think of for checking whether updating the view is necessary, would be checking the UPDATE_TIME information schema (works on MyISAM only), using triggers for updating a custom information schema that could be checked, or counting the rows, however the latter would only cover inserts.
All methods would fetch the comparison value (update time or row count) in the controller action of the specific view, and pass that value to the view where it's then used in the AJAX call. The AJAX call invokes a controller method where the passed value is compared to the current time/count value in order to determine whether an update is necessary.
Please note that the examples are untested!
Information Schema
The easiest method would be checking the UPDATE_TIME information schema, however as mentioned this only works for MyISAM tables:
Model:
public function getUpdateTime()
{
$db = $this->getDataSource();
$result = $db->fetchAll('
SELECT
UNIX_TIMESTAMP(UPDATE_TIME) AS update_time
FROM
information_schema.tables
WHERE
TABLE_SCHEMA = ?
AND
TABLE_NAME = ?',
array
(
$db->config['database'],
$this->table
)
);
if(empty($result) || !isset($result[0][0]['update_time']))
{
return false;
}
return (int)$result[0][0]['update_time'];
}
Controller:
public function list_books()
{
$this->set('lastUpdate', $this->Books->getUpdateTime());
$this->Books->recursive = 0;
$this->paginate = array('order' => array('Serial_No' => 'DESC'));
$this->set('All_Books', $this->paginate());
}
public function checkForUpdate($time)
{
$updateNecessary = $this->Books->getUpdateTime() > (int)$time;
return new CakeResponse(array('body' => json_encode($updateNecessary)));
}
View:
<script>
jQuery(function($)
{
var lastUpdate = <?php echo $lastUpdate; ?>;
function checkForUpdate()
{
$.get('/books/checkForUpdate', {time: lastUpdate}, function(updateNecessary)
{
if(updateNecessary === true)
{
alert('update necessary');
// now reload the page or use an additional AJAX request for updating the content
}
else
{
queueUpdateCheck();
}
},
'json');
}
function queueUpdateCheck()
{
setTimeout(checkForUpdate, 5000);
}
queueUpdateCheck();
});
</script>
Using Triggers
Another option would be using triggers. You'd need an additional table that connects tables and time values using for example the table name, and two triggers, one for inserts, one for updates. These triggers could then update the custom information table.
Information Table
CREATE TABLE IF NOT EXISTS `table_stats` (
`table_name` varchar(255) NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`table_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `table_stats` (`table_name`, `update_time`)
VALUES ('books', NOW());
Triggers
CREATE TRIGGER `update_time_after_insert` AFTER INSERT ON `books`
FOR EACH ROW
UPDATE `table_stats` SET `update_time` = NOW() WHERE `table_name` = 'books';
CREATE TRIGGER `update_time_after_update` AFTER UPDATE ON `books`
FOR EACH ROW
UPDATE `table_stats` SET `update_time` = NOW() WHERE `table_name` = 'books';
Model:
public function getUpdateTime()
{
$db = $this->getDataSource();
$result = $db->fetchAll('
SELECT
UNIX_TIMESTAMP(update_time) AS update_time
FROM
`table_stats`
WHERE
`table_name` = ?',
array
(
$this->table
)
);
if(empty($result) || !isset($result[0][0]['update_time']))
{
return false;
}
return (int)$result[0][0]['update_time'];
}
Controller and View would be the same as in the previous example.
Counting rows
Now the last option would be comparing the row count, which would of course only work for inserts. In this example the Model would stay untouched.
Controller:
public function list_books()
{
$this->set('rowCount', $this->Books->find('count'));
$this->Books->recursive = 0;
$this->paginate = array('order' => array('Serial_No' => 'DESC'));
$this->set('All_Books', $this->paginate());
}
public function checkForUpdate($rowCount)
{
$updateNecessary = $this->Books->find('count') != (int)$rowCount;
return new CakeResponse(array('body' => json_encode($updateNecessary)));
}
View:
<script>
jQuery(function($)
{
var rowCount = <?php echo $rowCount; ?>;
function checkForUpdate()
{
$.get('/books/checkForUpdate', {rowCount: rowCount}, function(updateNecessary)
{
if(updateNecessary === true)
{
alert('update necessary');
// now reload the page or use an additional AJAX request for updating the content
}
else
{
queueUpdateCheck();
}
},
'json');
}
function queueUpdateCheck()
{
setTimeout(checkForUpdate, 5000);
}
queueUpdateCheck();
});
</script>
Retrieving data together with the update check
Of course you could also submit possible data together with the update check, in order to avoid additional requests. For example:
Model
public function checkForUpdate($time)
{
$data = '';
$updateAvailable = $this->Books->getUpdateTime() > (int)$time;
if($updateAvailable)
{
$this->set('books', $this->Books->find('all'));
// render /Elements/books.ctp in ajax.ctp layout and grab the rendered content
$this->viewPath = 'Elements';
$view = $this->render('books', 'ajax');
$data = $view->body();
}
$body = compact('updateAvailable', 'data');
return new CakeResponse(array('body' => json_encode($body)));
}
View
<script>
jQuery(function($)
{
var lastUpdate = <?php echo $lastUpdate; ?>;
function checkForUpdate()
{
$.get('/books/checkForUpdate', {time: lastUpdate}, function(response)
{
if(response.updateAvailable === true)
{
// the data is already available, so directly update the content
$('#content').html(response.data);
}
queueUpdateCheck();
},
'json');
}
function queueUpdateCheck()
{
setTimeout(checkForUpdate, 5000);
}
queueUpdateCheck();
});
</script>

Categories