How to pass javascript var into a ajax remoteFunction? - javascript

I have a view where ill have 3 divs:
Div 1: List of Brands with checkboxs.
Div 2: List of Categories with checkboxs.
Div 3: List of Items.
This last div will be refreshed with the all the items according to what is selected in the first two divs. At beginning it shows all the items, after we select some of the brands and/or categories and press refresh i'll want to refresh the div 3.
In Javascript I can get which of the categories/brands are selected and my biggest doubt is on how to refresh the last div...
Heres what I was trying:
function refresh() {
var brands= /*<code where i get all the brands selected (this will be a js array)>*/
var categories = /*<code where i get all the categories selected (this will be a js array)>*/
<?php echo $ajax->remoteFunction(array('url' => array('controller' => 'items',
'action' => 'men', brands, categories),
'update' => 'itemsContent')); ?>
}
My problems are:
- How do I pass the js vars into the php method?
- How do I receive an js array in a cakephp action? Because brands and categories will be used to filter the query that produce results for the div 3...

You won't be able to use the $ajax helper here, since it just outputs a static script which can't be changed/influenced at "run-time" in the browser. It just wasn't made for something more complex than it is.
So, you'll have to roll your own JS, which shouldn't be that hard though. All you need is:
a Cake action that outputs a list of items based on the data it receives (shouldn't be hard)
a bit of JS that figures out which brands and categories are selected (which you already have)
another bit of JS that packages that data and sends it to the Cake action
another bit of JS that updates the site with the list of items you received back
I'd take a look at jQuery's AJAX functions to accomplish #3. If you POST the data in a format like this, it's very easily accessible in $this->data in Cake:
{
'data[ModelName][categories]' : categories,
'data[ModelName][brands]' : brands
}
Regarding your question:
"How do I pass the js vars into the php method?"
You don't. PHP runs on the server and is already finished by the time the Javascript runs in the browser. The only "communication" between JS and PHP is via standard HTTP GET and POST requests, and there it doesn't matter whether the request comes from a standard browser or JS or Flash or whatnot.
The $ajax helper just has a bunch of pre-fabricated Javascript snippets it can put into your page, but your JS will not be able to "talk to" the $ajax helper in any way.

I had a similar scenario to yours, and I found a few methods on the Javascript helper that are applicable. I used codeBlock() to wrap a chunk of javascript, and event() to wire up the click event, but I'm not sure how much clearer this is than just writing the raw Javascript.
I found the AJAX section of the CakePHP manual to be really helpful for getting the basic set up. Then I took the generated Javascript and made it more dynamic.
In this example, I'm calling the add_topic action whenever the user clicks the link. Every time it gets called, I increment the topicIndex variable and pass it as a parameter in the AJAX call. The AJAX call returns a few rows that are inserted in the table above the link that the user clicked.
<tr id="add_topic_row"><td colspan="3">
<a id="add_topic_link" href="javascript:void(0);">New Topic
<?php echo $html->image('icons/add32.png');?></a></td></tr>
</table>
</fieldset>
<?php
echo $form->end('Submit');
$addTopicUrl = $html->url(array('action' => 'add_topic')) . '/';
$script = <<<EOS
var topicIndex = $index;
var addTopicUrl = '$addTopicUrl';
addTopic = function()
{
new Ajax.Updater(
'add_topic_row',
addTopicUrl + topicIndex,
{
asynchronous:true,
evalScripts:true,
insertion:Insertion.Before,
requestHeaders:['X-Update', 'add_topic']
});
topicIndex++;
}
EOS;
echo $javascript->codeBlock($script);
echo $javascript->event('add_topic_link', 'click', 'addTopic();')
?>

Related

Is it possible to use Ajax to call an internal function?

completely new to PHP, so this is a complete first for me. Right now, I want to try dynamically update a drop down list from 1-10 based on a previous drop down list.
The first drop down list is a table selection, which allows you to choose tables 1-35, and the second drop down list is a seat selection from 1-10. I wish to have it so that 1-10 will update depending on the table to say who has booked the seats on the table already.
I've already found a way to populate the list properly, however I'm having some issues when I try to update it upon the first drop down changing.
I've researched lots of Ajax calls to different files of PHP, however my code is dependent on where the PHP is in the index.php file to populate the drop down. I have a function currently which populates the list when it firsts loads, and I have a small Ajax call towards an internal function inside the same file.
This is the PHP code roughly that fully works (There's a bit more that I left out as it's irrelevant)
<?php
function populateDropdown2(){
for ($i=1; $i<=10; $i++)
{
if ($row[1] == $_POST['TableNum'] && $row[2] == $i)
{
$result = $i . ' - ' . $row[0];
break;
}
}
?>
<option value="
<?php echo $result;?>
"
<?php if(strlen($result) > 2){echo "Disabled";}?>
>
<?php echo $result;?>
</option>
And this is my attempt at the Ajax call:
$(document).ready(function(){
$('#Tabl').change(function(){
console.log("CLICKED");
$.ajax({
url: "index.php",
type: "post",
success: function(response){
populateDropDown2(response);
}
});
});
});
I've read quite a lot about Ajax, however is it possible to call a function that exists within the same file as it inside a different code block? Thanks.
Edit: The function I'm calling has to be in the position it is right now in the PHP file as it's just below all the other input fields for the form
Edit2: I'm getting my values from a CSV file for the PHP.
PHP and JavaScript (your AJAX function) are entirely separate and you can not directly call PHP from within JavaScript:
PHP: Runs on the web server and returns data via HTTP.
JavaScript: Runs locally in the client's browser.
Your AJAX call will have to call specific PHP code, which will then return data to JavaScript, which you can then use to modify the HTML currently being displayed.
If you create HTML in your PHP code, which is then returned to your JavaScript function, you can inject it into your DOM with $.html().
Preferably you'd want to return the data of interest as JSON (see json_encode()) tho and then use that to manipulate your DOM in JavaScript accordingly (see JSON.parse()).
Be sure to return your JSON wrapped into an object instead of arrays for security, see this post regarding the vulnerability.

Delete previous row in database show the next row in database by clicking button

I need Help on this, base on what I already did: In the output every time I click the button it shows the row (comments) in database. But I want that If I click the next button it will show the row (comments) in the database and when I click it again It will delete the previous row (comments) in the database and show the next row (comments).
Here is the code:
<?php
include 'dbh.php';
$commentNewCount = $_POST['commentNewCount'];
$sql = "SELECT * FROM comments LIMIT $commentNewCount";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
echo $row['id'];
}
} else {
echo "There are number!";
}
?>
This is for the button:
<script>
//jQuery code here!
$(document).ready(function() {
var commentCount = 0;
$("button").click(function() {
commentCount = commentCount + 1;
$("#comments").load("load-comments.php", {
commentNewCount: commentCount
});
});
});
</script>
You have AJAX tagged in your question, so I am assuming that you are somewhat familiar with the term. This can indeed be done by AJAX, but I don't see any AJAX attempts in your code?
Also, when you say delete, do you mean specifically delete by the literal sense, or simply that your comment display works as sort of a sliding function, removing the previous comment from display, showing the next comment in queue? I am going by the literal sense in my example, since that's what I have to assume really.
What you could do, is to have a file that handles all the comments, and displays them however you like. For instance,
<?php
$sql="SELECT * FROM comments ORDER BY id DESC";
$result_set=mysqli_query($conn, $sql);
while ($row=mysqli_fetch_assoc($result)) {
/*
html construction of displaying comments,
echo'ing the row value that displays the comments.
echo $row['comments']; as a guess
*/
}
?>
Let's call that PHP file comments.php for the sake of referencing later on. Also note, that I chose to make an ORDER BY in a descending order. Assuming your comment id is an auto increment, then this will always display the newest comments first, since the highest id's will be the latest entries.
Then, in another file, display-comments.php as an example, you could make a document.ready function, that loads your comments into an element, <div> element for example.
The AJAX function could look like this:
$( document ).ready(function() {
function loadCommentsAjax()
{
$.ajax({
type : "POST",
url : "comments.php",
data : { },
success: function (html) {
$("#commentContainer").html(html);
}
})
}
});
What I do here, is that I encapsulate an AJAX function in a document.ready function. What this does, is that when the document is ready, it fires the AJAX function.
How the AJAX function works, is that we declare a data type. The most common are probably POST and GET. You can look up the different data types, how to handle them, and what they mean specifically. The main difference between POST and GET for instance, is that GET displays its values as parameters in the URL. Since we aren't parsing any data, we could use a GET just fine, since it will have no influence. However, should you ever need to parse sensitive data, where you don't want the user to mingle with the data, then you should use POST.
We then tell the AJAX function, which page/file it should work with. In our example, it will be the comments.php that we created earlier. It will then in the success function, paste the html content into a container that we defined. In this case, commentContainer. Note that it's an id specific targeting, which means our container element needs to have that specific id. Note, that the container is in our main file, the display-comments.php file.
An example of the container could be the following:
<div id="commentContainer"></div>
This div element will then contain the comments and html logic that we made in our comments.php file.
In your button, you can then have another AJAX function, handling the comment deletion, and call our loadCommentsAjax() function on success, to reload our comments in the appropriate fashion.
The AJAX function handling the deletion of comments, would then again have a PHP file that will perform the delete. We'll call this delete-comments.php in our example.
example of our delete AJAX function:
function deleteNewestComment() {
$.ajax({
type : "POST",
url : "delete-comments.php",
data : { },
success: function (html) {
loadCommentsAjax();
}
})
}
Our delete-comments.php will look something like this:
<?php
/*
since you are deleting the latest entry each time, what we could do,
is make an SQL query that deletes the max id from the comments table
*/
$sql="DELETE FROM comments WHERE id=(SELECT max(id) FROM comments)";
$result=mysqli_query($conn, $sql);
?>
We will then have our button call the delete function like so:
<button onclick="deleteNewestComment();">Delete latest comment</button>
Let me know if this is what you were looking for at all, or whether you really just wanted a sliding kind of logic, where you simply iterate through your comments, displaying one at a time.
But in case you did mean literally delete, then wouldn't it be better to have delete buttons linked to each comment, so that you can delete them seperately, and independantly?

Call a PHP Link with Onclick

This isn't a duplicate question by any means and I have tried a lot finding solutions.So, please read it before down voting.
Background:
This application is like a note-taking web app where you can post/delete your notes.
Each item in the list has an id which is needed when making a delete call.
In my application, I have to delete individual items from a list which is generated by looping over a JSON response (by a REST API) using PHP.The JSON response can be obtained after successful login.
Question:
To implement delete functionality I have to send id of each of the items as a parameter to the rest api delete call.
So, for this I have to generate dynamic links of the form :
http://localhost/myfolder/api/notes/:id
which should be passed to the delete.php function (Which I have implemented in CURL).
I searched for possible ways :
Using a PHP function: It seems to be complex, however if there is some way to invoke a PHP function (the delete code using CURL) on click of a link (Which I found not possible as per some answers ?) this could be a great solution.
Using Javascript: I have to call a function upon click of link that sets a variable $_SESSION["id"] to the current item["id"] and then goes to delete.php where I use the $_SESSION variable to first set up the link and then use the CURL code.
I tried basic implementation using the second approach but I have hit a roadblock in this issue. It would be great if you could tell with a bit of code which approach should be followed or any other way to do this ?
This functionality is present in twitter/facebook and almost every such service, how do they implement this, the basic approach should be the same, right: Generate dynamic links and pass them to a php script on click ?
Basic Javasript approach :
<script>
<script>
var el = document.getElementById('del1');
el.onclick = del1;
function del() {
// I have to set $_SESSION here
return false;
}
</script>
echo "<a href=\"delete.php\" title=\"Delete\" id=\"del1\">";
//Here, I have to pass the item["id"] to the javascript function.
I had tried some other ways but I have modified the code a lot so, I can't post them. Thanks for your help.
Regarding #2, you can't access the user's session from Javascript, so that will not work.
My preferred way (if using jquery) is to put the id in a data attribute of the delete button (or the block as a whole). Then in the delete onclick function do something like
<div class="block" data-itemid="<?=$item['id']?>">
...
<div class="delete_button">Delete</div>
</div>
...
$('.delete_button').on('click',function(event) {
block = $(event).target.parent('.block');
itemid = block.data('itemid');
$.post('delete.php',[itemid: itemid]...);
});

Factorize HTML generation code between PHP and Javascript

I have a website entirely coded with PHP. Let's consider the simple example in which a PHP script generates HTML/CSS code from data about a list of fruits, fetched in a MySQL data base :
<?php
function displayFruit( $fruit ) {
echo('<div>');
echo('<span class="fruit-color">Coulor : '.$fruit['color'].'</span>');
...
// display some other parameters of the fruit, with maybe some complex styles, etc.
...
echo('</div>');
}
// Get infos from dabase
$fruits = getAllFruitsFromDatabase();
// Display infos
foreach( $fruits as $fruit ) {
displayFruit( $fruit );
}
?>
Now, I want to add interactivity and to allow the user to filter according to some fruits characteristics (color, etc.) so that only the corresponding fruits are displayed.
So I add some controls and link them to Javascript AJAX queries. These queries will return the same type of data (even though not the same format) as what getAllFruitsFromDatabase() returned, and I want this data to be displayed the same way displayFruit() displayed it.
However, the issue here is that the display/styling process will now have to occur on the client side and not anymore on the server side.
Is there a technical way to factorize the PHP code (the one of displayFruit() ) and the Javascript code that will have to be used, so that there only exists one place where the HTML display code is written (and not once in PHP, and once again in JS) ?
What you describe is a very common problem for interactive web apps and there is not really one 'correct' solution for it. : )
It really depends on what you want in terms of PHP-vs-JS balance, but here are two possible solutions that avoid duplication of the HTML rendering code:
1. Always create the mark-up in Javascript, even on the initial page load
This works well if you want the bulk of your code to be on the client-side. In this solution, you wouldn't have a displayFruit($fruit) function in PHP, but you'd have the equivalent in your Javascript. You would render your page 'frame' on page load, and then do your AJAX call on the document-ready event.
2. Always create the mark-up in PHP, even on the filter-AJAX calls
This is perhaps a more balanced approach and has the advantage that you could design your code such that it's possible to run even if the client has Javascript disabled.
One way to do this is to pass an optional parameter to your page rendering function (in the PHP code) that will make it render only the data part, e.g. something like this:
function renderPage($filters = false, $dataOnly = false)
{
if (!$dataOnly) {
// Output the top of the page
}
// Output the data
// If $filters is not false, the getFruitsFromDatabase call will return filtered data
$fruits = getFruitsFromDatabase($filters);
foreach( $fruits as $fruit ) {
displayFruit($fruit);
}
if (!$dataOnly) {
// Output the bottom of the page
}
}
When your PHP script is called via AJAX, you pass your filters to the first argument of the renderPage function and true to the second argument.
Note on front-end frameworks:
exussum and Michael Chaney have mentioned Javascript frameworks. While I haven't used any of those myself, they look fantastic!
So If you're ready to invest time in re-writing your display logic in JS, then go for it. However, if you don't have much time and would like to re-use as much of your original PHP code as possible, then I would go for solution number 2. The decision probably also depends on the size and design of your existing code.
EDIT: had forgotten to add a $filters argument to the example function
EDIT 2: comment on front-end frameworks mentioned by others in comments

Execute javascript inside the target of an Ajax Call Drag and Drop Shopping Cart without Server language

Well i wanna create an Ajax Drag and Drop Shopping cart using only javascript and ajax. Currently i'm using the example in this page as a stepping stone. Right now it's only with local jquery and it works fine but i want to make the cart work with ajax calls. Note that i do not want to use a server side language( like php, rubby, asp etc), only html and javascript.
My initial thought was that at the $(".basket").droppable i should add an ajax call to another html page containing the "server logic" in javascript, execute in that file all the necessary steps( like reading the get variables (product name, product id and quantity), set a cookie and then return an ok response back. When the server got the "ok" response it should "reload" the cart div with the updated info stored inside the cookie.
If this was with php i would know how to do it. The problem is that as far as i know, you can execute javascript once it reaches the DOM, but how can you execute that js from inside the page that isbeing called upon ? ( thanks to Amadan for the correction)
I've thought about loading the script using $.getScript( "ajax/test.js", function( data, textStatus, jqxhr ).. but the problem with that is that the url GET variables i want to pass to the "server script" do not exist in that page.
I havent implemented all the functionality yet as i am stuck in how to first achieve javascript execution inside an ajax target page.
Below is a very basic form of my logic so far
// read GET variables
var product = getQueryVariable("product");
var id = getQueryVariable("id");
var quantity= getQueryVariable("quantity");
//To DO
//--- here eill go all the logic regarding cookie handling
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
alert('Query Variable ' + variable + ' not found');
}
Any help regarding this matter will be appreciated.
Note: Logic in simple words:
1)have an html page with products+cart
2)Have an "addtocart.html" with the "Cart Server Logic"( being the target of the ajax call when an item is dropped into the product.)
If you have some other idea on this, please enlighten me :)
thanks in advance
Foot Note-1:
if i try loading the scipt using
$("#response").load("ajax/addtocart.html?"+ $.param({
product: product,
id: id,
quantity:quantity
})
);
i get the alert about not being able to find the url parameters( something that i thing is normal as because the content is being loaded into the initial page, from which the request is started, there are no get parameters in the url in the first place)
The problem is that as far as i know, you cannot execute javascript contained in the target of an ajax call, as that page never reaches the browser interpreter.
This is either incorrect or misleading. The browser will execute any JavaScript that enters DOM. Thus, you can use $.load to load content and execute code at the same time. Alternately, you can use hacked JSONP to both execute code and also provide content as a JSON document.
EDIT: Yes, you can't get to the AJAX parameters from JavaScript. Why do you want to? Do you have a good reason for it, or is it an XY problem?
The way I'd do it is this:
$('#response').load(url, data, function() {
onAddedToCart(product, id, quantity);
});
and wrap your JS code in your HTML into the onAddedToCart function.
Depending on what exactly you're doing, it could be simplified even further, but this should be enough to cover your use case.

Categories

Resources