Dynamic Optgroup in PHP - php

This is my current SQL Table I'm using to grab data for my php dropdown. The main goal of this is to turn this into a dropdown that has an optgroup with the members below and so on...
+-----------+------------+-----------+
| GroupName | MemberName | ValueName |
+-----------+------------+-----------+
| 1st Team | Joe Bob | Joe |
| 1st Team | Catherine | Kat |
| 2nd Team | Tommy | Tom |
| 3rd Team | John Razks | John |
+-----------+------------+-----------+
Table name: Members
Basically at the end result is such of the code below. It will be a dropdown with an optgroup called "1st Team" and have the members below ect. for 2nd Team and 3rd Team and so on.
<optgroup class="1st Team">
<option value="Joe">Joe Bob</option>
<option value="Kat">Catherine</option>
</optgroup>
<optgroup class="2nd Team">
<option value="Tom">Tommy</option>
</optgroup>
<optgroup class="3rd Team">
<option value="John">John Razks</option>
</optgroup>
Right now, this is how I get information from my SQL table. This works fine, but if I want to add a new GroupName then I would have to add a new code to my main page and I don't want to do that.
Trying make it dynamic so if the SQL table gets updated with a new GroupName, then a new optgroup class will appear in the dropdown and the members will be below.
<optgroup class="1st Team">
<?php
$conn = mysqli_connect("#connect_to_sql");
if(!$conn){
die("Connection Failed".myslqi_connect_error());
}
$result = mysqli_query($conn, "SELECT distinct MemberName from Members where GroupName = "1st Team" order by MemberName ASC");
while ($row = mysqli_fetch_assoc($result)){
unset($membername, $groupname);
$groupname = $row['GroupName'];
$membername = $row['MemberName'];
echo '<option value="'.$membername.'">'.$membername.'</option>';
}
?>
</optgroup>
I'm not positive at all on what to do. I've looked at other people's examples, but not sure how to approach this step.

First get all records from the database. create an array with keys as group name. Loop the new array to generate the desired output.
// query to get all records from database table
$result = mysqli_query($conn, "SELECT distinct MemberName,GroupName,ValueName from Members order by MemberName ASC");
while ($row = mysqli_fetch_assoc($result)){
// generate an array with keys as group name
$array[$row['GroupName']][] = $row;
}
// loop the array to create optgroup
foreach($array as $key=>$value){
// check if its an array
if(is_array($value)){
// create optgroup for each groupname
echo "<optgroup class='".$key."'>";
foreach($value as $k=>$v){
echo "<option value='".$v['membername']."'>'".$v['membername']."'</option>";
}
echo "</optgroup>";
}
}
I have not tested this but sure this will help you. And you can make improvements.

It's not the most elegant way, but you could build your group this way, what it's doing is checking the name of the group and changes that to a new optgroup each time the name changes, the $first var is just there so it doesn't add a closing tag the first time around.
I'm sure you can improve on this, but it should get you going.
It does kind of rely on a consistent naming convention for the group name, so as I say, I'm sure you could improve on it. I've also not included the connection checks as you've done that already in your example
$result = mysqli_query($conn, "SELECT * FROM Members ORDER BY GroupName");
$groupName = '';
$first = true;
echo '<select>';
while ($row = mysqli_fetch_assoc($result)){
if ($row['GroupName'] != $groupName) {
$groupName = $row['GroupName']; // Just set the new group name
if (!$first) { // Add a closing tag when we change the group, but only if we're not in the first loop
echo '</optgroup>';
} else {
$first = false; // Make sure we don't close the tag first time, but do after the first loop
}
echo '<optgroup label="' . $groupName . '">';
}
// We want to echo the options every loop so it's outside the if condition
echo '<option value="' . $row['MemberName'] . '">' . $row['ValueName'] . '</option>';
}
echo '</select>';

Related

How can i use the id from one table item to connect another tables item

I am pretty new to php and sql and am learning as i create a web app so i'm wondering how this would be possible, if at all, or if there are better practices for this sort of task.
just as an example:
Say i have a database with 2 tables
one is author, the other book
author table
-----------
id | author
1 | jones
2 | jane
book table
----------
id | title | author
1 | Learning php | 1 <- i want this to reference the author from author table
2 | Foobar | 1
3 | How to give a proper high five | 2
i have a form that gets the authors name from a query as a select tag and i want to assign the id as the value for author in the book table when i submit the form
$authorQuery = mysqli_query($con, "SELECT * FROM author");
<form id="bookForm" action="books.php" method="POST">
<label for="title">Book Title</label>
<input type="text" name="title">
<label for="author">Author</label>
<select id="author" name="author">
<?php
while($row = mysqli_fetch_array($authorQuery)) {
//display as an array in a drop down list
echo '<option>' . $row['author'] . '</option>';
}
?>
</form>
How would i go about this?
I will make the options values as the authors Ids, change this
echo '<option>' . $row['author'] . '</option>';
to this
echo '<option value="' . $row['id']. '">' . htmlspecialchars($row['author']) . '</option>';
Now, when this form is submitted , at the server you will receive the id of the author in the $_POST['author'] variable, so you can make your update query using the id instead of the name of the author.
$query = "update book set author_id = ? where title = ?";
$stmt = $con->prepare($query);
$stmt->bind_param("is", $_POST['author'], $_POST['title']);
$stmt->execute();
suggestions:
this scheme means that your relationship is 1:m (1 author can write many books, but 1 book is must be written by only 1 author), this is not correct, as many books are written by many authors, so you need to use a third conjunction table to represent the many to many relationship m:m
The search on MySQL is case insensitive by default, however it's better to make a <select> for the books instead of <input> and assign the IDs of the books to the <option>s instead of typing the title (unless you have too much books to fit in a select), so you make sure you avoid any typos in the title of the book when you need to fill the form to assign an author to a book
The easiest way will be to
<?php $stmt = $conn->prepare("SELECT * from book")
$stmt->execute();
foreach($stmt as $row){
$id = $row['author'];
$stmt = $conn->prepare("SELECT * from author WHERE id='$id'")
$stmt->execute();
foreach($stmt as $row){
$name = $row['author'];
?><option value="<?php echo $name;?>"><?php echo $name;?></option>
}
}
The Complex Method is
$stmt = $conn->prepare("SELECT *, book.author AS bookauthor FROM book LEFT JOIN author ON author.id=book.id");
$stmt->execute();
foreach ($stmt as $row) {
?><option value="<?php echo $row['bookauthor'];?>"><?php echo $row['bookauthor'];?></option>
}

Merge column entries in mysql

PeterM helped me with this question, but i dont want to create new one, thats why im editing this one.
I got another problem, sorry, im just new with sql.
This is my code that output all the information I need from the database.
What i want:
I created table with name "customers" with columns "id and customername".
Then i created simple script with INSERT INTO "customers", yes, its script like admin page.
The idea is: I want to add new orders from a separate page, for example: admin.php so I don't have to do it from a file.
How to easily do this?
I have admin.php file with: INSERT INTO customers (customername) VALUES (customername) and its working, i can add new order to database, when i fill html form, it doesn't show my new added order.
<?php
$output = "SELECT *, SUM(enddate - startdate) AS time FROM employees GROUP
BY id";
$result = mysqli_query($conn, $output);
WHILE ($row = mysqli_fetch_assoc($result)) {
$EMPLOYEE = $row['employee'];
$CUSTOMER = $row['customername'];
$WORKDATE = $row['workdate'];
$WORKTYPE = $row['worktype'];
$DAYHOURS = $row['startdate'];
$ENDDATE = $row['enddate'];
$TOTAL = $row['time'];
echo "
<tr>
<td>$EMPLOYEE</td>
<td>$CUSTOMER</td>
<td>$WORKDATE</td>
<td>$WORKTYPE</td>
<td>$DAYHOURS</td>
<td>$ENDDATE</td>
<td>$TOTAL</td>
</tr>";
}
?>
My html form:
<div class='row'>
<div class='col-25'>
<label for='customers'>Choose OrderName</label>
</div>
<div class='col-75'>
<select name='customername'>
<?php
$customers = "SELECT customername FROM customers";
$result = mysqli_query($conn, $customers);
WHILE ($row = mysqli_fetch_assoc($result)) {
$customer = $row['customername'];
echo "<option value=''>$customer</option>";
}
?>
</select>
</div>
</div>
You should change your query into something like this:
SELECT *, SUM(`enddate` - `startdate`) AS time FROM `employees` GROUP BY `employee`;
First you need to subtract the startdate from the enddate then get the sum of all the grouped results, hence the SUM part.
This should give you a result somewhat similar to this
Results:
| id | employee | startdate | enddate | time |
|----|----------|-----------|---------|------|
| 8 | David | 8 | 22 | 17 |
The time column is the one you need.
I made a fiddle where you can see and test how it works, http://sqlfiddle.com/#!9/40a959/5

output sql query in php

I'm a noob at php so I need a bit of help. I have a table with a list of hotels, the columns are
name | address | city | stars | price
so far I've made a dynamic drop-down menu where the user selects a city from the table, this is shown in the code below:
<?php
connection stuff blah blah
?>
<?php
$sql = "SELECT city FROM hotels";
$result_db = $db->query($sql);
if (!$result_db) {
echo $db->error . ' Error perform query!';
} else {
echo '<select name="value">';
echo '<option value="">-Select from below-</option>';
while ($row = $result_db->fetch_object()) {
echo '<option city="' . $row->city . '">';
echo $row->city;
echo '</option>';
}
echo '</select>';
}
?>
How would I now create a table where all the details of hotels in the selected city are outputted? I'm assuming I need another sql query, arrays (perhaps?) which then I echo into a table? :S But I have no idea how to.....
you need to use jquery to add event to your dropdown second in your table you should have an ID field..
You're table should be
Id | name | address | city | stars | price
next you need to create a query that will fetch the id and name fields and put it on a dropdown.
next you need to use jquery to add event to dropdown.
$(function() {
$("#hotel").change(function() {
});
})

(PHP) Categorize into an html opgroup based on mysql value

Basically I have a database with 66 bible books; some from old testament some from new. The bname value is the NAME of the book, while bsect has a value of O or N(new or old), how can I make my dropdown box dynamically display a book into an old or new optgroup based on whether its' bsect is O or N? My teacher said I have to make some array, but i have no idea how to do it. Any thoughts?
My database sample:
+-----------+-------+
| bname | bsect |
+-----------+-------+
| Genesis | O |
| Exodus | O |
| Leviticus | O |
+-----------+-------+
I don't want to have to rely on manually setting opgroups based on the NUMBER OF THE ENTRY, I want it to be dynamic based on value of bsect.
Right now I just have the following query with a select dropdown which puts the book into old or new based on its record number, but It will break if more books were to be added
$query = $mysqli->query("select distinct bname as Name from kjv");
?>
<select name="book">
<?php
$i=1;
while($option = $query->fetch_object()){
if($i==1) echo "<optgroup label='Old Testament'>";
else if($i==40) echo "<optgroup label='New Testament'>";
echo "<option value='$i'>".$option->Name."</option>";
$i++;
}
?>
Simply order by bsect and display different optgroups dynamically
<?php
$query = $mysqli->query("SELECT DISTINCT bsect, bname AS Name FROM kjv ORDER BY bsect");
?>
<select name="book">
<?php
$i = 1;
$bsect = "";
while($option = $query->fetch_object()){
if($bsect != $option->bsect) {
$bsect = $option->bsect;
echo "<optgroup label='{$bsect}'>";
}
else if($i==40) echo "<optgroup label='New Testament'>";
echo "<option value='$i'>".$option->Name."</option>";
$i++;
}
?>
Of course, then your books may be out of order. So what you would want to do is add a book-order column (border) that stores a number defining how to order the books in a given group, e.g.
ALTER TABLE kjy
ADD COLUMN border INT U?NSIGNED NOT NULL DEFAULT 0;
Then you can update the data to have the proper book order and do a query like this:
SELECT DISTINCT bsect, bname AS Name FROM kjv ORDER BY bsect, border;
Of course, this being the Bible, you aren't going to be adding books, so you can probably just define a static Book ID that defines the ordinality of each book. Then you could just sort by ID and know that "Old" and "New" books are coming out in the right order.
ALTER TABLE kjy
ADD COLUMN id INT UNSIGNED NOT NULL PRIMARY KEY BEFORE (bname);
This is how you can create 2 arrays in php,
$query = $mysqli->query("select distinct bname,bsect from kjv");
while($option = $query->fetch_object()){
if ($option->bsect == 'O'){
$books_old[] = $option->bname;
} elseif ($option->bsect == 'N'){
$books_new[] = $option->bname;
} else {
# Error collection - bsect not 'O' or 'N'
}
}
now you have 2 arrays which are lists of books; $books_old and $books_new.
I'd use the name as the value rather than an arbitrary index;
echo "<optgroup label='Old Testament'>";
foreach($books_old as $this_book){
echo "<option value=\"$this_book\">$this_book</option>";
}
echo "<optgroup label='New Testament'>";
foreach($books_new as $this_book){
echo "<option value=\"$this_book\">$this_book</option>";
}

dropdown from two tables, php mysql

Say I have the two following tables:
country_table:
---------------------------------
|ID|country_code|country_name |
|01|CA |Canada |
|02|US |United States |
---------------------------------
user_table:
----------------------------------------------
|id|user_id|country_code|email_address |
|01|oswalsh|CA |blah#hotmail.com |
|02|jlong |US |blah2#hotmail.com |
----------------------------------------------
I am creating my user signup/edit account forms, and have a drop down for country. Originally I had simply stored the country_name in the user_table instead of using a country_code, however I have also decided to implement a map script...which is a massive mess of javascript files which make use of the country_code.
Thus I created the country_table so I could match the country_code and the country_name so I could map user interactions...However I am not sure how to go about creating the sql statement for the drop down.
What I have so far:
<?php
include ('../../connect.php');
$account_panel = mysql_query("SELECT * FROM user_table WHERE id=1")
or die(mysql_error());
while($row1 = mysql_fetch_array( $account_panel ))
{
?>
<select name="event_country" id="event_country" required />
<option selected="selected" value="<?php echo $row1['user_country']; ?>"><?php echo $row1['user_country']; ?></option>
<?php
$countries = mysql_query("SELECT * FROM country_table")
or die(mysql_error());
while($row = mysql_fetch_array( $countries ))
{
echo "<option value='". $row['value'] ."'>". $row['name'] ."</option>";
}
echo "</select>";
?>
<?php
}
mysql_close($connection);
?>
So as you should be able to see from above what is happening, is that the list is populated from the country_table, but I am trying to get the selected value from the user table. This does seem to work, but my problem is that the country code is what is stored and being displayed. So say I am grabbing the info for oswalsh...me...the country returned is CA, and I would like it to display Canada.
If I understood you right, you need to familiarize yourself with SQL Joins
To join those two tables and get the country_name along with the user data from the user_table, you'd need an SQL statement like this:
SELECT ut.*, ct.country_name
FROM user_table ut
INNER JOIN country_table ct
ON ut.country_code = ct.country_code
In your case, this would result in the following:
1 oswalsh CA blah#hotmail.com Canada
2 jlong US blah2#hotmail.com United States
Also, you should consider using mysqli_ and stop using mysql_ functions. Here is a discussion on this topic on SA.

Categories