This question is more about "good pratices" than a real problem; I just started with php and jquery, but I would know more in details what I'm doing and why.
What I'm trying to get: catch user request (with a form), query database and then show result in a table. All using ajax call and jquery.
Now, I have my controller.php:
class Controller {
public $model;
public function __construct() {
$this->model = new Model ();
}
public function run() {
$action = isset ( $_REQUEST ["action"] ) ? $_REQUEST ["action"] : $action = "home";
switch ($action) {
case "home" :
//doing stuff
break;
case "search" :
//this function will take arguments then perform a query and return results.
$result = $this->search();
//I put $result into a $prod field of my model.
$this->model->prod = $result;
//then I would display acquired data into a table.
echo include 'view/include/result-table.php';
break;
}
}
function search() {
//query DB etc..
}
}
And this is my table (view/include/result-table.php), I would like insert this into a div in my page.
<?php
if (isset ( $this->model->prod )) {
if (count ( $this->model->prod ) == 0) {
echo "<h4 class=\"info\"> No product find";
} else {
?>
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
<th>Descr</th>
<th>Qty</th>
</tr>
</thead>
<tbody>
<?php
foreach ( $this->model->prod as $p ) {
echo "<tr><td> $p->id </td>";
echo "<td>" . ucfirst ( $p->name ) . "</td>";
echo "<td>" . ucfirst ( $p->descr ) . "</td>"
// and so on..
}
?>
</tbody>
</table>
<?php
}
}
?>
Problem 1: the "echo include "view/include/....php" seems to echoes also a 1 (a digit) at the end of the page (or the div). Why?
"Problem 2": This is working pretty well, but I'm not sure that is the correct way to do this. Are there any other solutions to query a DB and display results in a div, with only jquery/ajax request? (I don't want a page refresh every time). Maybe something that can speed up responses and/or improves security.
Thank you very much!
For problem 1: include does not require an echo. Its including the content and the echos are inside the included php file. So the echo include is actualy echoing the result of include, which is true or 1 by success.
problem 2: You are right, ajax would be a solution without refreshing the whole page. All you need to do is to make an ajax request to your php script which returns just the html content you want to replace and append this result to your html dom. jQuery has lots of functions for both making ajax calls and appending the result in your html dom.
A good practice is not to return the raw html content and just append it to your site because if something went wrong you might receive error codes from php or warnings or even mysql errors which is bad to show on your website of course. So in order to tell your ajax request that the result is the expected one just send over a status flag with value true. A good way to do this is by sending the result as json encoded string like this:
{
status : true, //shows you your call was successfull
html : "your result html to place on your site"
}
Only if your ajax call returns the correct status (true) everything went well and you can insert it in your page.
I don't know how to add a comment and keep formatting... anyway:
Thanks for your reply.
I didn't understand the last part, right now I have my ajax call:
$('#submit-btn').click(function(event) {
event.preventDefault();
$.get("index.php", {action : "search" , data : mydata }).done(function(data) {
$('#result').html(data);
});
Removing echo the 1 disappeared, but I don't understand the flag you're talking about and what I should encode. The page I want to append? Only the result of query?
After querying DB, I update my model with new values (coming from db) and then I want to show updated table, in this way will I see the modified table?
I hope my question is clear... :)
Thanks a lot!
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am getting a very self explanatory error. However the index, as far as I can tell is not only 100% defined, it also contains a value. This is the latest of a series of silly problems that's driving me insane today.
Here is the code you've probably seen a million times that should work.
jQuery
$('#projects').click(function (e) {
alert(aid);
$.post('core/functions/projects.php', { aid: aid })
.done(function(data) {
alert(aid);
$('#home_div').hide();
$('#pcd').fadeIn(1000);
})
.fail(function(jqXHR, status, error) {
alert(error);
});
});
Which alerts me twice with the value of 6
PHP
<?php
require_once "$_SERVER[DOCUMENT_ROOT]/core/init.php";
if(isset($_POST)) {
$aid = $_POST['aid'];
echo $aid;
} else {
echo 'fail';
}
?>
I receive this error:
Notice: Undefined index: aid in C:\xampp\htdocs\core\functions\projects.php on line 5
So I added a little deeper check to my if else and it now looks like this
<?php
require_once "$_SERVER[DOCUMENT_ROOT]/core/init.php";
$account_id;
if(isset($_POST['aid'])) {
$aid = $_POST['aid'];
echo $aid;
} else {
echo 'fail';
}
and now it spits back fail. I already went here, to check out the error and it's exactly as I thought it was. That doesn't mean it makes any more sense to me why I'm getting it.
So lets review. My jQuery, is hitting the right PHP file because I am getting responses from that specific PHP file. My variable holds a value because jQuery alerts me twice with the value it holds of 6. However my PHP file is not receiving this value? Can someone please explain to me why?
EDIT
If I add a line to my jQuery I get another message verifying the data is being sent. Yet I STILL receive the error that the $_POST index is not set. This is crazy
$('#projects').click(function (e) {
alert(aid);
$.post('core/functions/projects.php', { aid: aid })
.done(function(data) {
alert(aid);
alert(data);
$('#home_div').hide();
$('#pcd').fadeIn(1000);
})
.fail(function(jqXHR, status, error) {
alert(error);
});
});
Now I get 3 Alert boxes holding the value 6.
1 alert box fires before the post is sent with the $aid variable information of '6'
1 alert box fires after the data is received again with the $aid variable '6'
1 alert box fires after the data is received now with the php response which is again '6'!
I mean WTF? Will this nightmare ever end? That means even the variable in php is being set from the post! How is this possible? I mean look at the php code all it echos is either 'fail' or $aid and $aid cant have a value unless its set by the post and furthermore it would NOT be giving me the error of Undefined index. I need to go take a break, I am gonna lose it.
FIREBUG
In firebug I see
I see POST ->
projects.php ->
POST ->
PARAMETERS ->
aid 6 ->
SOURCE -> aid=%0D%0A6
RESPONSE ->
There is nothing in the response, the brief time I posted a response here was because I left my 'require_once' off and I had my code commented out.
There is something odd in the source though. It says SOURCE aid=%0D%0A6 instead of the normal SOURCE aid = 6
2ND EDIT
I had a large section of code commented out to simplify this example. The code uses the variable and query's for data. Then returns a table created in php. If un-comment the code I can see the table in my RESPONSE in html form. If I go to HTML I can actually see the visual table. So Whats going on? Why is that response inflating my div and not the table? I will now post some more code to explain
<?php
require_once "$_SERVER[DOCUMENT_ROOT]/TrakFlex/core/init.php";
if(isset($_POST['aid'])) {
$aid = $_POST['aid'];
try {
$query_projectInfo = $db->prepare("
SELECT projects.account_id,
projects.project_name,
projects.pm,
//...more columns
FROM projects
WHERE account_id = ?
");
$query_projectInfo->bindValue(1, $aid, PDO::PARAM_STR);
$query_projectInfo->execute();
$count = $query_projectInfo->rowCount();
if ($count > 0) {
echo "<table class='contentTable'>";
echo "<th class='content_th'>" . "Job #" . "</th>";
echo "<th class='content_th'>" . "Project Name" . "</th>";
//...more table headers
while ($row = $query_projectInfo->fetch(PDO::FETCH_ASSOC)) {
echo "<tr>";
echo "<td class='content_td'>" . "<a href='#'>" . $row['account_id'] . "</a>" . "</td>";
echo "<td class='content_td'>" . $row['project_name'] . "</td>";
//.. more data
echo "</tr>";
}
echo "</table>";
}
} catch(PDOException $e) {
die($e->getMessage());
}
} else {
echo 'could not load projects table';
}
?>
So as you can see my full php file actually sends back a table of data. I can see this table in FireBug -> NET -> XHR -> HTML. I can also see all the php code in FireBug -> NET -> XHR -> RESPONSE. However the div that should hold the table only holds the else statement 'could not load projects table'. So I think I'm getting closer, but I'm still stuck. Any ideas?
POST -> aid 6 shows that the server is indeed receiving the data. Something else is clearing $_POST at some point before it reaches the if statement.
While you had require_once "$_SERVER[DOCUMENT_ROOT]/core/init.php"; commented out, your jQuery data contained the expected value. It was still commented out when you posted the Firebug info, hence the database connection error messages. Those messages, which you've since removed, indicates errors on line 7 of projects.php which tells me that your testing a file with more code than you posted here. It's not uncommon for people to show us a portion of their code, in fact, it's encouraged; however, in this case it's problematic because the error doesn't lie in the code you gave us.
Inorder to validate this finding and save your sanity, rename projects.php temporarily to projects.backup.php.
Create a new file called, "projects.php" and run the following code (and ONLY the following code) through AJAX:
<?php
if(isset($_POST['aid'])) {
$aid = $_POST['aid'];
echo $aid;
} else {
echo 'fail';
}
?>
Incidentally, %0D%0A is the Windows® newline combo, CRLF (carriage return + line feed)
Is it possible to create an HREF link that calls a PHP function and passes a variable along with it?
<?php
function sample(){
foreach ($json_output->object ){
$name = "{$object->title}";
$id = "{$object->id}";
print "<a href='search($id)' >$name</a>";
}
}
function search($id){
//run a search via the id provide by the clicking of that particular name link
}
?>
You can do this easily without using a framework. By default, anything that comes after a ? in a URL is a GET variable.
So for example, www.google.com/search.html?term=blah
Would go to www.google.com/search.html, and would pass the GET variable "term" with the value "blah".
Multiple variables can be separated with a &
So for example, www.google.com/search.html?term=blah&term2=cool
The GET method is independent of PHP, and is part of the HTTP specification.
PHP handles GET requests easily by automatically creating the superglobal variable $_GET[], where each array index is a GET variable name and the value of the array index is the value of the variable.
Here is some demo code to show how this works:
<?php
//check if the get variable exists
if (isset($_GET['search']))
{
search($_GET['search']);
}
function Search($res)
{
//real search code goes here
echo $res;
}
?>
Search
which will print out 15 because it is the value of search and my search dummy function just prints out any result it gets
The HTML output needs to look like
anchor text
Your function will need to output this information within that format.
No, you cannot do it directly. You can only link to a URL.
In this case, you can pass the function name and parameter in the query string and then handle it in PHP as shown below:
print "<a href='yourphpscript.php?fn=search&id=$id' >$name</a>";
And, in the PHP code :
if ($_GET['fn'] == "search")
if (!empty($_GET['id']))
search($id);
Make sure that you sanitize the GET parameters.
No, at least not directly.
You can link to a URL
You can include data in the query string of that URL (<a href="myProgram.php?foo=bar">)
That URL can be handled by a PHP program
That PHP program can call a function as the only thing it does
You can pass data from $_GET['foo'] to that function
Yes, you can do it. Example:
From your view:
<p>Edit
Where 1 is a parameter you want to send. It can be a data taken from an object too.
From your controller:
function test($id){
#code...
}
Simply do this
<?php
function sample(){
foreach ($json_output->object ){
$name = "{$object->title}";
$id = "{$object->id}";
print "<a href='?search=" . $id . "' > " . $name . "</a>";
}
}
if (isset($_REQUEST['search'])) {
search($_REQUEST['search']);
}
function search($id){
//run a search via the id provide by the clicking of that particular name link
}
?>
Also make sure that your $json_output is accessible with is the sample() function. You can do it either way
<?php
function sample(){
global $json_output;
// rest of the code
}
?>
or
<?php
function sample($json_output){
// rest of the code
}
?>
Set query string in your link's href with the value and access it with $_GET or $_REQUEST
<?php
if ( isset($_REQUEST['search']) ) {
search( $_REQUEST['search'] );
}
function Search($res) {
// search here
}
echo "<a href='?search='" . $id . "'>" . $name . "</a>";
?>
Yes, this is possible, but you need an MVC type structure, and .htaccess URL rewriting turned on as well.
Here's some reading material to get you started in understanding what MVC is all about.
http://www.phpro.org/tutorials/Model-View-Controller-MVC.html
And if you want to choose a sweet framework, instead of reinventing the MVC wheel, I highly suggest, LARAVEL 4
I am trying to build a db driven web site in which the user selects from a drop down menu a
value and some Information from a database are returned. I use an ajax post cause i dont want the page to get refreshed:
$("#button").click(function(){
var datastr = ($('#act').val());
var datastr1 = ($('#loc').val());
$.ajax({
type:'POST',
url:'activities_code.php',
data: {datastr:datastr, datastr1:datastr1},
success:function(response){
$("#msg").html(response);
} });});
In the url parameter I have the following php file (this is a part of the php file):
$query = "SELECT PK,title,Information from activities where Activities='$category'";
$result = mysqli_query($dbcon, $query) or die('no available data');
echo "<table>";
$num_results = 0;
$t = 0; //title counter for the id of each title
while ($row=mysqli_fetch_array($result, MYSQLI_ASSOC)) {
// Here the columns of title and information are printed
echo "<tr><td>";
echo "<a href='test.php' id=\"t\".$t onClick=\"test()\" target=\"_new\" >".$row['title']."</a>";
echo "<br>";
echo $x = $row['PK'];
echo "</td></tr>";
echo "<tr><td>";
echo $row['Information'];
echo "</td></tr>";
// Here I sum up the number of the results
$num_results=$num_results+1;
$t = $t+1;
}
}
As you can see, I have a while loop in which I echo each time a link with an id:
"<a href='test.php' id=\"t\".$t onClick=\"test()\" target=\"_new\" >".$row['title']."</a>";
What I want to do is to use this id of each link later in my code by doing something like this:
document.getElementById("t1").value
My question is, how can I return this id's to the client side? I think I should write something in the success function but I have no idea what.
If you dont understand some part of the code or I didn't explain everything clear, please ask me.
Thanks
D.
This is what I get when I alert(response) in the success function.
<!DOCTYPE HTML>
<table id="container"><tr><td><a href='test.php' id="t0" target="_new" class='pickanchor'>Rafting in Voidomatis</a><br>1</td></tr><tr><td>
<img src="m.jpg" class="textwrap" height="120px" width="120px">
<p style="text-align:left;">Our experienced rafting instructors will show you the best way to enjoy Voidomatis, the river with the most clear waters inSouth Europe. You can also cross the Vikos Gorge by following Voidomatis river in an attractive one and a half hour long walk. Alternatively you can ask for the more demanding Aoos river rafting.</p>
<br>
<br>
<hr></td></tr><tr><td><a href='test.php' id="t1" target="_new" class='pickanchor'>Rafting in Lousios</a><br>4</td></tr><tr><td><img src="raf.jpg" class="textwrap" height="120" width="120">
<p>You will be surprised to know that Greece hides numerous, densely vegetated rivers offering amazing rafting opportunities. In the whole mainland, there is a company base awaiting you, for an amazing � off the beaten track experience!</p>
<br>
<br>
<br>
<hr></td></tr><div id="r2" align="center" id="result_2">2 results for rafting were found!
</div></table> <!-- End of PHP code-->
First, There is problem with ID of your anchor tag. here is correction
"<a href='test.php' id=\"t".$t."\" onClick=\"test()\" target=\"_new\" >".$row['title']."</a>";
Second, Give id to your table like
<table id="container">
Third, give class to your anchor tag.
"<a href='test.php' class='pickanchor' id=\"t.$t\" onClick=\"test()\" target=\"_new\" >".$row['title']."</a>";
Now write following code into your success handle after .html() statement
NEW EDIT
$("a.pickanchor").each(function(i){
alert(this.id);
});
In line you presentd you made mistake. In wrong place you have added ".
echo "<a href='test.php' id=\"t\".$t onClick=\"test()\" target=\"_new\" >".$row['title']."</a>";
It should be
echo "<a href='test.php' id=\"t".$t."\" onClick=\"test()\" target=\"_new\" >".$row['title']."</a>";
As simplest solution you could add after the while loop
echo "<script> my_max_id_num=$t </script>"
This will give you knowledge about which ids are present on page. This should give your js script access to my_max_id_num variable. It's not considered best programming practice but is simple.
Second (better) way of solving problem could be returning json instead of html and rewriting your success method. This will be more work to be done:
Rewrite while loop so it returns something like:
{ "data":[
...
{ "id":"10", "target":"_new", "title":"one_of_your_link_titles" },
{ "id":"10", "target":"_new", "title":"one_of_your_link_titles" },
...
]}
Rewrite your ajax query so it will accept json, and rewrite success method so it will create your links on basis off data returned from server.
This way you will have both, ids and your links in one query. What's more in case of changing requirements it will be easier.
The simplest solution would be to give your elements a class, that way you don't need to select based on the elements id, but you can access it easily:
eg.
test 0
test 1
$('#msg').on('click', '.className', function() {
console.log(this.id);
});
I don't have enough rep points to ask for clarification, but what do you mean by 'return this id's to the client side'? Also what would the 'value' of the element 't1' be?
Lets say you wanted to get the link location it could be something like:
var value = $('#addButton').attr('href');
and then do something with the value (not sure what you mean by 'return this id's to the client side') but perhaps you want the value then to be visible to the client?
So if you have a div somewhere on the page where you want it to show you could populate it with you value, maybe something like:
HTML
<div id="valueBox"></div>
jQuery
$("#valueBox").html(value);
I have a personal message system in my website done simply with php/sql. Actually I am facing the trouble to display them using jquery. The db has as fields: message_id, message_from, message_to, message_topic, message_subject and message_status. The way I am showing the message_topic is repeating eight times the following:
echo '<table><tr><td>';
retrieve_msg_topic($result);
echo '</td></tr>'; //of course I won't make 8 tables!!!
the function called is:
function retrieve_msg_topic($result)
{
if($row = mysql_fetch_assoc($result))
{
echo $row['usernombre'];
$message_topic = stripslashes($row['message_topic']);
echo '<div id="msg'.$row['message_id'].'">';
echo $message_topic;
echo '</div>';
//this will return: <div id="msgN">message topic (title, commonly subject)</div>
}
} //end function retrieve msg topic
So far I have a list on a table with the last eight messages sent to the user. The following row is reserved for pagination (next/prior page) and, after that, another row showing the message I select from the list presented, like we see in Outlook. Here is my headache. My approach is to call another function (8 times) and have all of them hidden until I click on one of the messages, like this:
echo '<tr><td>';
retrieve_msg_content($result);
retrieve_msg_content($result); //repeat 8 times
echo '</td></tr></table>';
the function this time would be something like this:
function retrieve_msg_content($result)
{
if($row = mysql_fetch_assoc($result))
{
echo '<script type="text/javascript">
$(document).ready(function(){
$("#msg'.$row['message_id'].'").click(function(){
$(".msgs").hide(1000);
$("#'.$row['message_id'].'").show(1000);
});
});
</script>';
echo '<div class="msgs" id="'.$row['message_id'].'" style="display: none">'
.$row['message_subject'].
'</div>';
}
/* This function returns:
// <script type="text/javascript">
// $(document).ready(function(){
// $("#msgN").click(function(){
// $(".msgs").hide(1000);
// $("#N").show(1000);
// });
// });
// </script>
// <div class="msgs" id="N" style="display: none">Message subject (body of message)</div>
*/
} //end function retrieve msg content/subject
I could simply explain that the problem is that it doesn't work and it is because I do if($row = mysql_fetch_assoc($result)) twice, so for the second time it doesn't have any more values!
The other approach I had was to call both the message_topic and message_subject in the same function but I end up with a sort of accordion which is not what I want.
I hope I was clear enough.
The easiest way to fix your troubles would be to copy the results of the MySQL query into an array
while($row = mysql_fetch_assoc($result)) {
$yourArray[] = $row;
}
And then use that to build your tables.
edit: What I meant was more along the lines of this:
while($row = mysql_fetch_assoc($result)) {
$yourArray[] = $row;
}
echo '<table>';
foreach($yourArray as $i) {
retrieve_msg_topic($i);
}
echo '<tr><td>';
foreach($yourArray as $i) {
retrieve_msg_content($i);
}
echo '</tr></td></table>';
And then removing everything to do with the SQL query from those functions, like this:
function retrieve_msg_topic($result) {
echo '<tr></td>'$result['usernombre'];
echo '<div id="msg'.$result['message_id'].'">';
echo stripslashes($result['message_topic']);
echo '</div><td></tr>';
}
Right now you're doing some weird key mojo with ret[0] being the topic and $ret[1] being the message, which isn't a good practise. Also, I don't see the declaration of $i anywhere in that code.
The error suggests that the result is empty or the query is malformed. I can't be sure from the code I've seen.
A few other notes: it seems weird that you're using stripslashes() on data that's directly from the DB. Are you sure you're not escaping stuff twice when inserting content into the DB?
Always use loops instead of writing something out x times (like the 8 times you said in your question). Think of a situation where you have to change something about the function call (the name, the parameters, whatever). With loops you have to edit 1 place. Without, you need to edit 8 different places.
BTW, another solution to this problem would be using AJAX to load content into the last cell. If you're curious, I could show you how.
more edits:
For AJAX, build your message list as usual and leave the target td empty. Then, add a jQuery AJAX call:
$('MSG_LIST_ELEMENT').click(function() {
var msgId = $(this).attr('id').replace('msg','');
$.get(AJAX_URL+'?msgID='+msgId,function(data) {
$('TARGET_TD').html(data);
})
});
Replace the capitalized variables with the ones you need. As for the PHP, just echo out the contents of the message with the ID $_GET['msgID'].
However, make sure you authenticate the user before echoing out any messages, so that someone else can't read someone's messages by switching the id number. Not sure how authentication works on your site, but this can be done by using session variables.
I'm using template system in php, so my code is like that for example...
$template->addVar ( 'thenameoftemplate', 'thenameofsubtemplate',"what to output");
And this code i output in the html file like... {thenamefsubtemplate}..
But i have a problem, when i try to output from database something with in the template like the above example but from database, it isn't working, only 1 output from the rows, but when echo it outside of the template it works..
I tryed to output with, foreach,while eaven with for from the database and output it in the template but it's showing just one result.
How to fix that, i wan't to row all the result and output them .
Update
Actualy i don't know what is the template system, some script was gaved to me and.. everythingwas ok until the database output..
Here is my last try with the for..
if (check_group_access_bool('show_admin_panel_button')) {
$template->addGlobalVar('admin','<BR>виж Ñмъкваните пеÑни<BR><img src="/images/icons/edit-user-32x32.png" hspace="2" alt="редактирай" align="absmiddle">редактирай');
}
$sudtwo = $_SESSION['user']['id'];
$fvsmt = mysql_query("select * from fav where user_id=$sudtwo");
if(isset($_SESSION['user']['id'])){
while($rowings = mysql_fetch_array($fvsmt)) {
$template->addVar( 'userprofile', 'userprofiletwo',"<tr><th nowrap valign=\"TOP\" align=\"LEFT\"> ñòèë: ".$rowings['name']." <form method=\"post\"><input type=\"submit\" value=\"premahni ot liubimi\" name=\"del\"></form>></th></tr>");
if(isset($_POST['del']))
{
mysql_query("DELETE FROM fav WHERE name_id=".$rowings['name_id']."");
}
echo"".$rowings['name']."<br>";
}
}
This is in the php and here is the HTML
<template:tmpl name="userprofile">
{USERPROFILETWO}
</template:tmpl>
That's how it outputs..
In the php code, where is my echo it works, but here in the html outputs only one row.
edit: OK, you're using something called patTemplate, which hasn't been updated in a few years. I found some documentation though, and once you've set up your PHP correctly, this in your html should work:
<table>
<patTemplate:tmpl name="userprofile">
{userprofiletwo}
</patTemplate:tmpl>
</table>
BUT, your PHP is a bit of a mess. What you have is basically:
for () {
$rowings = ...;
//you are overwriting the variable each time here
$template->addVar('userprofile', 'userprofiletwo', $rowings);
}
And I think what you want is something like:
$rowings = array();
for () {
// make an array of your data
$rowings[] = ...;
}
// and call addVar *once*
$template->addVar('userprofile', 'userprofiletwo', $rowings);
Now {userprofiletwo} is an array, and you can loop over that in your template.
Also, I'm not sure what the purpose of this bit of code is:
if(isset($_SESSION['user']['id'])){
}
as it doesn't really do anything...