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.
Related
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!
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)
I'm looking to change the font color of a div using jquery where the div is populated by the output of a SQL query.
I have:
$(document).ready(function(){
$('#foo').each(function(){
if ($(this).text() == 'bar') {
$(this).css('color','orange');
}
});
});
From a SO search which works fine when the div contains text.
But as this is SQL i'm populating the div with: ".$row['result']."
And this now does not work. I'm guessing this is because the sql, although being a varchar field is a $variable and isn't 'text' as such?.
I'm sure this is something simple, but i'm struggling to phrase this in google to return anything useful.
Many thanks.
edit
The whole thing is rather long and before i've tried to add the jquery was all working fine, so i'll just post the additions.
This is within the head:
echo "<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js'></script>";
echo "<script type='text/javascript'>";
echo "$(document).ready(function(){ $('#foo').each(function(){ if ($(this).text() == 'bar') { $(this).css('color','orange');}});});";
Then i echo each row in a while loop:
$sql = "SELECT...";
$result = mysql_query($sql)or die(mysql_error());
while($row = mysql_fetch_array($result)){
echo "<div id='foo'>".$row['result']."</div>";
}
The whole document is wrapped in PHP but its not the source of the issue as if i change the div to contain text rather than ".$row['result']." then the jquery executes on it just fine.
You are giving every div the same id ("foo"). An id has to be unique in HTML, you would be better off using a class for this. The way you have it now the .each() function would only be called on one element, possibly the first.
Change the HTML output like this:
echo "<div class='foo'>".$row['result']."</div>";
Then, adapt your selector in jQuery accordingly:
$('.foo').each(function(){
// ...
}
Do you use a $.ajax call or just emmbed the value via PHP on page load?
If you use PHP to print the value, I guess you forgott to echo the value:
".<?php echo $row['result']?>."
Not just:
".$row['result']."
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...
I have a 2 field database (daynumber & datavalue), the data of which I am retrieving with php then creating and passing variables into jquery for use with a graph.
I am not doing this as an array because I need to apply a formula to the datavalue field. The formula can be altered by the user.
In jquery, I need to be able to do this:
cday_1 = <?php echo $day_1?>;
cday_2 = <?php echo $day_2?>;
tday_1 = (<?php echo $day_1 ?> * formula1 / formula2;
tday_2 = (<?php echo $day_2 ?> * formula1 / formula2;
The cday series and the tday series will be plotted separately on the graph.
My problem is that I could manually name each var in php, ie:
$day_1=mysql_result($result,$i,"datavalue");
but I have 30 rows and I'd prefer to do it with a loop. So far, I've got this far:
$i=0;
while ($i < $num) {
$datavalue=mysql_result($result,$i,"datavalue");
echo "\$day_";
echo $i;
echo " = ";
echo $datavalue;
echo "<br>";
$i++;
}
So there are a couple of problems I'm having with this.
The first problem is that while everything is echoing, I'm not sure how to actually create variables like this(!).
The second problem is that there are only 30 rows in the db, but 34 are actually outputting and I can't work out why.
I'm self-taught, so apologies for clumsy coding and/or stupid questions.
You could just store them in a PHP-side array:
$days = array(
'cday' => 'the cday value',
'dday' => 'the dday value',
etc...
);
and then via json_encode() translate them to a Javascript array/object automatically. This object could be sent to your page as an AJAX response, or even embedded into the page directly:
<script type="text/javascript">
var days = <?php echo json_encode($days) ?>;
</script>
after which you just access the values as you would any other array in JS.
Have ended up doing this:
$i=0;
while ($i < $num) {
${"day_$i"}=mysql_result($result,$i,"datavalue");
$i++;
}
I have a feeling this was a basic issue and I just didn't explain myself properly. I am unable to use an array as I needed to fiddle with formulas so this solution worked fine.