Linked list with PHP and AJAX - php

I'm having troubles when making a linked list in HTML, let me explain:
In HTML I have this two selects:
<!-- This select WORKS and read the opened projects from de database -->
<select name="project" id="project">
<option value="0">Select a project</option>
<?php if (isset($result2)): ?>
<?php foreach ($result2 as $res): ?>
<option value=<?php echo $res['c_project_id'] ?>><?php echo $res['d_name'] ?></option>
<?php endforeach ?>
<?php endif ?>
</select>
<!-- This doesn't work, but I want: When I select a project, the project's categories go here -->
<select name="category" id="category">
</select>
The REAL DATA are the next: Table PROJECT
c_project_id | d_name | d_description | n_budget | d_state
1 | Test | Test Project | 100 | Open
2 | Web | Web APP | 3000 | Open
3 | C Test |Closed Project | 100 | Closed
4 | Certif.| Certificates | 2500 | Open
Table Categories (conected with table project)
c_category_id | d_name | d_description | c_project_id
1 | General| General cat | 1
2 | Test | Test cat | 1
3 | General| General cat | 2
4 | General| General cat | 3
5 | Nothing| Nothing cat | 3
6 |Program | Programming | 2
...
I have a SELECT in html that takes the project name and ID, this works in the select nÂș1
$statement2 = $conexion->prepare("SELECT c_project_id, d_name FROM project WHERE d_state= 'Open'");
$statement2->execute();
$resultado2 = $statement2->fetchAll();
Now I want: When I "click" in the first select, the second select make the statement and fulfill the second select. For testing, I just wrote a simple option. I tried with AJAX and PHP but the 2nd option is empty:
AJAX:
$( "#project" ).change(function() {
var select = $( "#project option:selected" ).val();
console.log(select); //just for testing that I took the value.
$.ajax({
type: "POST",
url: "phpPage.php",
data: { selectedProject : select }
}).done(function(data){
console.log("Done");
$("#category").html(data);
});
});
AND PHP:
if(isset($_POST["selectedProject"])){
$proy = $_POST["selectedProject"];
$output = "<option value='100'> Select your category </option>";
if($proy != 0){
$output.= "<option>" . $proy . "</option>";
}
echo $output;
}
But this return me nothing, all is empty.
FINALLY, when I tried to debug, I noticed that in one of the PHP responses, the HTML code () is been written at start of the page (in the response):
<option value='100'> Select your category </option><option>1</option>
<!DOCTYPE html>
<html lang="es">
<head>
<title>
...
Sorry for that huge question, but I'm wasting a lot of time with that and I don't know what could happen.
Thanks you!

Lets look at the breakdown of what you have and want to do. First, you have an empty select element:
<select name="category" id="category">
// empty
</select>
Then, you are tripping off an ajax call which returns data from your PHP. This ajax is simply taking all the returned html from the PHP and putting it in the middle of that above select:
$("#category").html(data);
Your PHP is where you are creating too much information on output. This is usually where its a good idea to isolate your "ajax php scripts" from normal full html build php scripts. So that you are only outputting what you need for that specific ajax call.
In your above PHP, you have:
if(isset($_POST["selectedProject"])){
$proy = $_POST["selectedProject"];
$output = "<option value='100'> Select your category </option>";
if($proy != 0){
$output.= "<option>" . $proy . "</option>";
}
echo $output;
}
// you must have more page generation below this based on your Q (?)
You can either isolate the above code into a new ajax response script (include any needed db actions and pull of data from the database based on the POST arg value, etc).... OR, you can add exit; after your echo $output;... so long as no other extra html was being output BEFORE this if block.
if(isset($_POST["selectedProject"])){
$proy = $_POST["selectedProject"];
$output = "<option value='100'> Select your category </option>";
if($proy != 0){
$output.= "<option>" . $proy . "</option>";
}
echo $output;
exit; // <-- halt so none of the other following html spills out
}

Related

getting only certain entries of the database

The code bellow gets a few domains from my database and outputs them in a dropdown list. I need some help as I can't get this change i want to make work.
I want to show only the domains where in the database premium_only is set to 6, nothing else. If I try to change the if statement to $shortUrlDomain['premium_only'] == 6 I can't see any domains appear in the list which has premium_only set to 6 in the database. Why?
Database layout:
id | domain | premium_only | status | date_created
---+-------------+--------------+---------+-------------------
1 | exaple.com | 0 | enabled | 2020-03-02 08:13:0
2 | exaple2.com | 6 | enabled | 2021-03-02 08:13:0
PHP code:
<div>
<label for="shortUrlDomain"><?php echo t("short_url_domain", "Short Url Domain"); ?>:</label>
<select id="shortUrlDomain" name="shortUrlDomain" style="width: 100%;">
<?php
foreach ($shortUrlDomains AS $k => $shortUrlDomain) {
// active domains only
if ($shortUrlDomain['status'] != 'enabled') {
continue;
}
$lastPremiumOnly = $shortUrlDomain['premium_only'];
echo '<option value="' . (int)$k . '"';
// selected option
if ($k == (int)$_REQUEST['shortUrlDomain']) {
echo ' SELECTED';
}
echo '>';
'</option>';
}
echo '</optgroup>';
?>
</select>
</div>
// get base urls
$shortUrlDomains = getShortUrlDomains();
static function getShortUrlDomain($domainId)
{
// get base urls
$shortUrlDomains = getShortUrlDomains();
if(!isset($shortUrlDomains[$domainId]))
{
return _CONFIG_SITE_PROTOCOL.'://'._CONFIG_SITE_FULL_URL;
}
return _CONFIG_SITE_PROTOCOL.'://'.$shortUrlDomains[$domainId]['domain'];
}
It's a bit hacky, but you might add this statement earlier in your code.
Ideally you'd alter the database query further down the stack, but you question doesn't include any mention of how you set $shortUrlDomains.
<?php
// somewhere before you render the HTML as in the snippet from your Q.
/**
* This makes shortUrlDomains into a subset of the original array,
* showing only those who have a `premium_only` key with a value of `6`.
*/
$shortUrlDomains = array_filter($shortUrlDomains, function($domain) {
return (int) $domain['premium_only'] === 6;
});
See more of array_filter here, at the PHP docs.

Personalized content

I would like to, clicking on a link, showing a content personalized.
<div class="tab_event">
<?php
do{
echo'
<table class="preview_event">
<td class="date_event">
'.$row["Date"].'
</td>
<td class="title_event">
<p>'.$row["Title"].'<br></p>
Read more !
</td>
</table>
';
} while ($row = $query->fetch(PDO::FETCH_ASSOC));
?>
My program consist at doing a "preview" of some articles from the database.
And when you click on "read more" i would like that, automatically, you get a page where the all article is written.
But I don't have any ideas about how to do it, bcs i don't want to create a page manually for each article.
Does anyone have any idea about how to do ?
Thanks
To achieve what you want, you need to generate a href to another/same PHP powered page along with a query parameter with some value which uniquely identifies the article in your database.
Assuming your database table structure is similar to
| Id | Date | Title |
|----|------------|------------------------|
| 1 | 0000-00-00 | Some catchy post title |
| 2 | 0000-00-00 | Yet another post title |
| 3 | 0000-00-00 | Some other title? |
I will use $row["Id"] using the above table structure
<div class="tab_event">
<?php
do {
echo '
<table class="preview_event">
<td class="date_event">
'.$row["Date"].'
</td>
<td class="title_event">
<p>'.$row["Title"].'<br></p>
Read more !
</td>
</table>';
} while ($row = $query->fetch(PDO::FETCH_ASSOC));
?>
Now access the aid parameter on your linked script (showArticle.php) to fetch the article from databse
<?php
if (!empty($_GET['aid']) {
// escape and verify value of `$_GET['aid']`
// fetch and return article from database using the `$_GET['aid']` parameter
} else {
// tell the user no `Id` was provided
}
?>
It's quite an easy task, first of all, you need to modify your table page, and edit the read more link this :
Read more !
Where article_idis whatever record's identification you wanna use to store that information when clicking the link, for example the article's id field in the database, now you create a read.php page, which will change its content based on the article's id in the link, so you only need to create that and not one page for each article.
Then in read.php you retrieve that information from the URL so that you can query the database with the correct article's ID and show its content:
...
...
$article_id = $_GET['article'];
// then you query the database using that variable (using whatever method you prefer, this in just an example)
$query = $db->prepare("SELECT title, date, content FROM articles WHERE articles.id = " . $article_id);
$query->fetch(PDO::FETCH_ASSOC);
This way you can retrieve the single's article information and show them on the read.php page , creating only one page which changes its content based on which link you click.
Also, worth mention that you should remove that do...while, for and foreach loops are way more elegant.
One example would be (assuming that the variable containing the results is called $rows) :
<table> <!-- table tag outside of the loop, otherwise for each article a table is created, which is wrong -->
<tbody>
<?php
foreach($rows as $article) {
echo "<tr>"; // since we need one row for each article, we include the tr tag in the loop
echo "<td>".$article['title']."</td>";
echo "<td>".$article['date']."</td>";
echo "<td>".$article['author']."</td>";
...
...
echo "</tr>"; // and we close the row
}
?>
</tbody>
</table>

Prevent page refreshes updating a table in PHP - via <a> link and not a form

I have some client code that uses 3 php pages to:
offer a long list of <a> links to the end user,
updates a database based on the link selected (and the passed params), and
confirms the update
Now, ignoring the fact that yes this isn't using a form, and yes, using a get to update a table is inherently wrong, there is an issue with multiple updates.
+----------+ +----------+ +----------+
| 1 \ | | 2 \ | | 3 \ |
| \| | \| | \|
| | ----> | | -----> | |
| list.php | | book.php | | conf.php |
| | | | | |
| | | | | |
| | | | | |
+----------+ +----------+ +----------+
|
|
v
+-----------+
| Update DB |
+-----------+
Due to the nature of the DB (it's FileMaker) the booking page (book.php) can take a while to update. Understandable impatience on the part of the users is causing them to refresh the page after clicking the link on list.php, and therefore multiple updates (in fact new records) in the table before getting to a cons.php.
What I can't get my head around is how to prevent this.
I've tried all sorts of approaches, (and the gotcha here is that I can't use forms!) and the one that I think would work best would be to pass a random key in from list.php in the params, and then start a session in book.php check that the key wasn't already in a session variable, and if it was ignore it, if it wasn't set it in the session variable, and then run the update. However, I can't seem to get it to work.
Any ideas oh great stackoverflow-ers?
UPDATE
Turns out code I wrote works locally on Apache but not on IIS !!?
list.php
<?php
// list.php
session_start();
$key = time();
echo "<h2>List of Urls</h2>";
echo '<p>Book 1</p>';
echo '<p>Book 2</p>';
echo '<p>Book 3</p>';
echo '<p>Book 4</p>';
echo "<p>Time page rendered was $key</p>";
echo "<pre>";
print_r($_SESSION);
echo "</pre>";
?>
book.php
<?php
// book.php
session_start();
if( isset($_SESSION['key']) && $_SESSION['key'] == $_GET['key'] ) {
header('Location: conf.php?error=doubleclicked');
} else {
if( isset($_GET['key']) ) {
$_SESSION['key'] = $_GET['key'];
}
header('Location: conf.php?key='.$_GET['key'].'&booking='.$_GET['booking']);
}
?>
conf.php
<?php
// conf.php
session_start();
echo "<pre>";
print_r($_GET);
echo "</pre>";
?>
Given all the restrictions to do not fix it properly, I would go with AJAX and modal overlay on list.php page to prevent users clicking on book.php links unless they reload list.php first.
Something like:
$("a").on("click", function(){
$("#dialog").show();
$.ajax({url: $(this).attr('href')})
.done(function() {window.location.href="conf.php"})
return false;
});
with #dialog overlay saying something like "Please wait, don't reload."
If you can use jquery, you can try the following:
On top of list.php:
<style>
.loading
{
width:100%;
height:100%;
position:fixed;
z-index:200;
background-image: url('http:// droppicture.com/images/loading/loading-03.jpg');
background-position: center top;
background-repeat: repeat;
opacity: 0.2;
}
<div class="loading" style="display: none" id="loading" ></div>
At the bottom of the page:
$('#YOUR_LINK_ID').click(function(e){
$('#loading').attr('style','display: block');
});

user chose css file as theme for webpage using SESSION

I'm building a webpage that allows a user to choose a theme for it. How can I build that based on this suggestion (I have to use SESSION):
<link rel="stylesheet" type="text/css" href="<?php echo $_SESSION['style']?>" />
I've try to make table named 'theme' on mysql database like this:
id | th_name | link
1 | blue | style.css
2 | back | black.css
3 | pink | pink.css
.................
And my code (not work):
<?php
echo "<form>";
echo "<select>";
$sql = "select * from theme";
foreach ($dbh->query($sql) as $row)
{
?>
<option value="<?php $row['link'] ?>"><?php echo $row['th_name'] ?></option>
<?php
}
echo "</select>";
echo "</form>";
?>
The 1st code is the key. Do you have any solution for this? (using jquery or something....?)
Why would you want to use mysql database? You can give a variable the same name css file. And use cookies. This is an implementation example
Just be careful to secure it well!
You could do it the way that you showed above, but for security's sake you would probably want to do it a little different (your way would allow significant opportunity for XSS).
Essentially, you will need to set the $_SESSION global variable to have the style, and that should come directly from the database. If it were me, I would do this:
<?php
echo "<form>";
echo "<select name=\"theme\" id=\"select-theme\">";
$sql = "select * from theme";
foreach ($dbh->query($sql) as $row)
{
?>
<option value="<?php $row['id'] ?>"><?php echo $row['th_name'] ?></option>
<?php
}
echo "</select>";
echo "</form>";
?>
Then, on your postback script, do this:
<?php
if (isset($_POST['theme']) {
// Perform query here to get the link's file, using PDO - watch out for XSS
// Note - you may have to call session_start()
// depending on your php.ini's settings
$_SESSION['style'] = $link;
}
If you are wanting to do this on the fly with jQuery, you can see the information here: How do I switch my CSS stylesheet using jQuery?
In addition, you would want to persist your changes like this:
<script type="text/javascript">
$("#select-theme").on("change", function() {
$.post({
url:'yoururl.php',
data: {
theme: $(this).find("option:selected").value()
});
});

How to create conditional button in HTML based on MySQL data?

I am trying to create a button that will either say "Follow" or "Unfollow", depending on whether or not the current user follows another user.
If John followed Tim, but not Sarah, the web view would look as follows, according to John's view:
_________________________________
| | |
| Tim | (unfollow) |
|________________|______________|
| | |
| Sarah | (follow) |
|________________|______________|
Where (" ") denotes a button.
I have a database that indicates who follows whom, but how would I display the correct button based upon validation with said database?
Assuming you have three fields "name_id","name" and "followed" where "name_id" is the id of the person, "name" is a string signifying the name of the person, and "followed" is a boolean:
<script type="text/javascript">
function toggleFollowing(name_id) {
window.location = 'toggleFollowing.php?name_id='+name_id;
}
</script>
...
<?php
...
while ($row = $result->fetch_assoc()) {
echo '<tr>';
echo '<td>'.$row['name'].'</td><td><a href=""><button type="button" onclick="toggleFollowing('.$row['name_id'].')">'.($row['followed']==1 ? 'Unfollow':'Follow').'</button></td>';
echo '</tr>';
}
...
?>
You would have toggleFollowing.php receive the variable $_GET['name_id'] to toggle on the database and come back to this page. I'm assuming you have the current user's ID stored as a session variable or by other means since you would need that as a primary reference to update the record. If you're passing that from page to page by some other means, then you would want to pass that variable as well.
Apparently, this is more truncated code, but a better method would be to use AJAX to perform the toggling on the DB, and DOM manipulation (JQuery?) for a "real-time" update.
Hard to answer without examples of your code, but something like this?
<?php
if(follow){
echo '<input type="button" value="Follow" />';
} else {
echo '<input type="button" value="Unfollow" />';
}
?>

Categories