Updating multiple rows with select option - php

Database:
+------+------+
| id |status|
+------+------+
| 50 | 2 |
+------+------+
| 51 | 0 |
+------+------+
| 52 | 1 |
+------+------+
As you can see there is a column named id and another column named status which indicates the current status of sth (2=done, 1=in work, 0 = open)
So I have done a little GUI where you can choose the current status through an select option input field, it also preselects the current record for status.
function generateSelect($name = '', $options = array(), $default = '') {
$html = '<select name="'.$name.'">';
foreach ($options as $option => $value) {
if ($value == $default) {
$html .= '<option value='.$value.' selected="selected">'.$option.'</option>';
} else {
$html .= '<option value='.$value.'>'.$option.'</option>';
}
}
$html .= '</select>';
return $html;
}
As I have mentioned each number in the database stands for a text with its status
$statusArray=array("Done" => "2", "In Work" => "1","Open" => "0");
This is what the generation of all the select option fields for every id looks like:
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$strStatus = generateSelect("stat", $statusArray, $row['status']);
echo '<tr><td>' . $row['id']. '</td><td>'.$strStatus.'</td></tr>';
What I am trying to do right now is that when the submit button is pressed it updates all status records.
What I have tried:
1.getting the selected one
function getSelected(){
$value="";
if($_POST['status']=="0")
$value="0";
else if($_POST['status']=="1")
$value="1";
else if($_POST['status']=="2")
$value="2";
else if($_POST['status']=="3")
$value="3";
return $value;
}
2. SQL statement where probably the problem is
$tmp = getSelected();
$sql = "UPDATE form SET status='$tmp' WHERE *";
Another option would be just saving the one edited, maybe with the onchange method from the select field?
Really appreciate every help I can get :) ty in advance for taking time to look throught the code.
UPDATE
ty for the quick answer and Extra Update #MarioZ
However it still doesnt seem rly to work. :/ maybe you can help me out there ^^
first worked fine with just $row['id'] because I want to be able to update more fields i have added ."['status']"
$strStatus = generateSelect($row['id']."['status']", $statusArray, $row['status']);
and also tried this for person, with no success then.
$personArray=array("Zivildiener" => "4", "Schmikl" => "3", "Poier" => "2","Dirnböck" => "1","Tom" => "0");
$strPerson = generateSelect($row['id']."['person']", $personArray, $row['person']);
and I have also added this which also worked fine, however only for status :/
foreach($_POST as $key => $value) {
$sql = "UPDATE form SET status='$value' WHERE id = $key";
$result = $conn->query($sql); }
Idk I honestly didnt really understand the foreach loop, but it worked somehow, you maybe need to know that there are more columns in the database which I didnt listen, but despite all this the first answer you gave worked perfectly, no clue how though :x so I would really appreciate your help again if you have some time :)

You need to pass the id of each row as the name of each select:
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$strStatus = generateSelect($row['id'], $statusArray, $row['status']);
echo '<tr><td>' . $row['id']. '</td><td>'.$strStatus.'</td></tr>';
So, when you retrieve the $_POST data you have the id as key and the value of the option as value:
foreach($_POST as $key => $value) {
$sql = "UPDATE form SET status='$value' WHERE id = $key";
}
You can adapt your function getSelected() in that loop to ge sure no other value is injected in the query.
FINAL UPDATE:
This is a way to do what you want to do, I've wrote to be easy to understand and apply to your code:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<form name="tasks" action="<?php $_SERVER['PHP_SELF']; ?>" method="post">
<?php
// Names of fields
$status_list[] = "open";
$status_list[] = "in work";
$status_list[] = "done";
$person_list[] = "John";
$person_list[] = "Bran";
$person_list[] = "Edd";
$task_list[50] = "Kill enemies";
$task_list[51] = "Avenge father";
$task_list[52] = "Sleep";
// Database conection
$db = new mysqli("localhost", "root", "", "test");
// Update database only if post
if(!empty($_POST)) {
foreach($_POST as $key => $value){
if($db->query("UPDATE change_status SET status = {$value['status']}, person = {$value['person']} WHERE id = $key ")) {
echo "<span>".$key." - UPDATED!</span>";
} else {
echo "<span>".$key." - FAILED!</span>";
}
}
}
// Get database
$query = $db->query("SELECT * FROM change_status");
// Draw the HTML content
$form = "";
while($result = $query->fetch_array()) {
$form .= '<div>';
$form .= '<span>'.$task_list[$result['id']].'</span>';
$form .= ' - ';
$form .= '<select name="'.$result['id'].'[status]">';
foreach($status_list as $key => $value) {
$form .= '<option value="'.$key.'"';
$form .= $result['status'] == $key? " selected" : "";
$form .= '>'.$value.'</option>';
}
$form .= '</select>';
$form .= '<select name="'.$result['id'].'[person]">';
foreach($person_list as $key => $value) {
$form .= '<option value="'.$key.'"';
$form .= $result['person'] == $key? " selected" : "";
$form .= '>'.$value.'</option>';
}
$form .= '</select></div>';
}
echo $form; // display html content
?>
<input type="submit">
</form>
</body>
</html>

Related

Php: Group and add missed field

I have in a array a table like this:
cid plugin lang_id name father
1 Newspage 1 Actualidad 1
1 Newspage 2 News 1
2 Newspage 1 Tecnologia 1
2 Newspage 2 Tech 1
3 Newspage 1 Deportes 1
3 Newspage 2 Sports 1
4 Newspage 1 Ocio 1
In this example there are two languages (1:Spanish and 2:English) but admin can add more languages
I want do a "modify category" section and group it by CID with input boxes for each language if language its missed i want display a empty input for add the missed language.
Something like this:
http://i.imgur.com/fGCUgKc.png
My actual bad code its this:
$content = "<div class='catlist'>";
$content .= "<p>{$LANGDATA['L_NEWS_MODIFIED_CATS']}</p>";
$query = $db->select_all("categories", array ("plugin" => "Newspage", "lang_id" => 1));
while ($cat_grouped = $db->fetch($query)) {
$content .= "<form id='cat_mod' method='post' action=''>";
$content .= "<div>";
foreach ($langs as $lang) {
if ($lang['lang_id'] == $cat_grouped['lang_id']) {
$content .= "<label>{$lang['lang_name']}</label> <input type='text' name='{$lang['lang_id']}' value='{$cat_grouped['name']}' />";
} else {
$query2 = $db->select_all("categories", array ("plugin" => "Newspage", "cid" => "{$cat_grouped['cid']}", "lang_id" => "{$lang['lang_id']}"));
if($db->num_rows($query2) <= 0) {
$content .= "<label>{$lang['lang_name']}</label> <input type='text' name='{$lang['lang_id']}' value='' />";
} else {
$other_lang_cat = $db->fetch($query2);
$content .= "<label>{$lang['lang_name']}</label> <input type='text' name='{$lang['lang_id']}' value='{$other_lang_cat['name']}' />";
}
}
}
$content .= "<input type='hidden' name='cid' value='{$cat_grouped['cid']}' />";
$content .= "<input type='submit' name='ModCatSubmit' value='{$LANGDATA['L_NEWS_MODIFY']}' />";
$content .= "</div></form>";
}
$content .= "</div>";
This:
$db->select_all(...);
mean
$db->select_all("table", $WHERE, ...)
I want to retrieve all content in one query and do the work in php
My actual code its clearly very bad and assumed lang_id=1 exists for each entry and do few query's huh!
My old code use "GROUP BY cid" for the first query and not need to use "lang_id=1" but after a system upgrade that line give the error:
reported: Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column
and not want to use again that.
any idea the best way for do that?
I don't know what your database library is, so I'm writing a pseudo like code.
First, I would use a pagination to limit the database queries, for example 10/20 phrases for each page. So the query would be:
SELECT * FROM language_phrases WHERE cid IN (
SELECT DISTINCT cid FROM language_phrases WHERE plugin = 'Newspage'
LIMIT 0,10
)
then I would use the data from database first to get the cid values:
$cid = array();
$strings = array();
while($row = $db->fetch($result))
{
if(!in_array($cid,$row["cid"]))
{
$cid[] = $row["cid"];
}
$strings[]= array(
"cid" => $row["cid"],
"lang_id" => $row["lang_id"],
"name" => $row["name"],
"father" => $row["father"]
);
}
Then I would have the table and the distinct cid's in this page in my buffer. Then PHP will do the rest:
foreach($cid as $idx=>$key)
{
$values = array_filter($strings,function($d) use ($key) {
return $d["cid"] == $key;
});
// build the form with the $values array.
}
This problem give a headache but i made another version that work and only one query.
I will check later the Taha Paksu version/way (thanks!)
$content = "<div class='catlist'>";
$content .= "<p>{$LANGDATA['L_NEWS_MODIFIED_CATS']}</p>";
$query = $db->select_all("categories", array ("plugin" => "Newspage"), "ORDER BY cid");
$cats = [];
$catsids = [];
while ($cats_row = $db->fetch($query)) {
$cats[] = $cats_row;
$catsids[] = $cats_row['cid'];
}
$catsids = array_unique($catsids);
$foundit = 0;
foreach ($catsids as $catid) {
$content .= "<form id='cat_mod' method='post' action=''>";
$content .= "<div>";
foreach ($langs as $lang) {
foreach ($cats as $cat) {
if (($catid == $cat['cid']) && ($cat['lang_id'] == $lang['lang_id'])) {
$content .= "<label>{$lang['lang_name']}</label> <input type='text' name='{$lang['lang_id']}' value='{$cat['name']}' />";
$foundit = 1;
}
}
if ($foundit == 0) {
$content .= "<label>{$lang['lang_name']}</label> <input type='text' name='{$lang['lang_id']}' value='' />";
}
$foundit = 0;
}
$content .= "<input type='hidden' name='cid' value='$catid' />";
$content .= "<input type='submit' name='ModCatSubmit' value='{$LANGDATA['L_NEWS_MODIFY']}' />";
$content .= "</div></form>";
}

Split text from the database in two columns

I have a bootstrap based website with 2 columns(col-lg-6 and col-lg-6).
I have the ability to add text from an admin panel (articles).
How can I make it so it splits in the second div (col-lg-6) after a specific number of characters or after I insert a character or something that will represent the breakage?
I prefer a PHP solution, but Javascript/Jquery would do too
edit *
if(isset($_GET['chapter']) && !empty($_GET['chapter'])){
$chapterid = (int)$_GET['chapter'];
$chaptertitle = mysql_query("SELECT bookname FROM books WHERE id=$chapterid");
$chaptertitle = mysql_fetch_array($chaptertitle);
$chaptertitle = $chaptertitle[0];
$chapter = mysql_query("SELECT bookContent FROM books WHERE id=$chapterid");
$chapter = mysql_fetch_array($chapter);
$chapter = $chapter[0];
$bookcontent = mysql_query("SELECT * FROM books WHERE bookid=$id");
$bookcontainer = '';
while($row = mysql_fetch_array($bookcontent)){
$bookcontainer .= '<h2>'.$row['bookname'].'</h2>' . $row['bookContent'];
}
and this is the place where the code is printed
<div class="row">
<div class="col-lg-6" id="paragraphs">
<div style="width:100%;">
<?php
//if($errors == false){
echo $chapter;
//}
//else{
//echo 'erorr madarfaker';
//}
?>
</div>
</div>
<div class="col-lg-6"></div>
</div>
If anyone is interested in this: I made 2 fields in the admin panel and the variable that was being sent to the database was "field 1 + ' | ' + field 2" and then I used explode to display the content on 2 sides, separator being " | "
Choose an arbitrary character for your split, like "|". Based on your posted code, use this as your echo statement:
echo str_replace($chapter, "|", "</div></div><div class='col-lg-6' id='paragraphs'><div style='width:100%;'>");
I am not sure if this solves your problem, but you can try :
<?php
// An array with your database data :
$arr = array('val1', 'val2', 'val3', 'val4');
$col1 = "";
$col2 = "";
$flag=false;
for($i=0; $i<sizeof($arr); $i++){
//Break condition :
$flag = ($arr[$i] == "val3" || $flag != true ) ? true : false;
if(!$flag){
$col1 .= $arr[$i];
}
else{
$col2 .= $arr[$i];
}
}
$html = "";
if($col1 != ""){
$html .= "<div class='col-lg-6'>".$col1."</div>";
}
if($col2 != ""){
$html .= "<div class='col-lg-6'>".$col2."</div>";
}
// The two div with your content (if the break rule is found) :
echo $html;
?>
If anyone is interested in this: I made 2 fields in the admin panel and the variable that was being sent to the database was "field 1 + ' | ' + field 2" and then I used explode to display the content on 2 sides, separator being " | "

Make more than one database call in wordpress plugin (PHP CRUD)

I have 2 pieces of code from a simple plugin that work independently from each other but don't work together.
if(isset($_POST['submit'])){
if(has_presence($_POST['product_name'])){
insert_row_into_table('CAL_products');
show_errors();
if(has_presence($wpdb->last_query)) {
echo "Update Successful";
} else {
echo "Update Failed";
}
} else {
echo "The field 'Product Name' cannot be blank.";
}
}
And this one
$results_array = $wpdb->get_results("SELECT * FROM wpCMS_CAL_products ORDER BY id ASC");
echo build_table_from_results_array($results_array);
The functions are included at the bottom.
The problem I have is that when the page loads there is no $_POST so it skips over the if statement and builds the table. This table builds fine.
When the form is submitted the if statements come back true and the new value is added to the database successfully, but then the table doesn't build until the page is refreshed. If the code to build the table is put at the top above the if statement it builds fine but doesn't include the new value until the page is refreshed.
Is it possible to add a new item to the database table before the results are populated to the HTML table?
function insert_row_into_table($table_name){
global $wpdb;
$prefix = $wpdb->prefix; //Define the wordpress table prefix
$table = $prefix . $table_name; //Build the table name
unset($_POST['submit']);
echo print_r($_POST);
$data = $_POST; //collect the data from post
$wpdb->insert( $table, $data ); //insert data into the table
}
function show_errors(){
echo $wpdb->show_errors();
echo $wpdb->print_error();
}
function has_presence($value) {
return isset($value) && $value !== "";
}
function build_table_from_results_array($results_array) {
$out = "";
$out .= "<table class=\"widefat\">";
$out .= "<thead>";
foreach($results_array[0] as $key => $element) {
if($key == "id") {
$out .= "<th class=\"id-column\">";
$out .= strtoupper($key);
$out .= "</th>";
} else {
$out .= "<th>";
$out .= ucwords(str_replace("_", " ", $key));
$out .= "</th>";
}
}
$out .= "</thead>";
$out .= "<tbody>";
$i = 0;
foreach($results_array as $key => $element){
if($i % 2 === 0) $extraclass= "alternate";
$out .= "<tr class=\"$extraclass\">";
$i++;
$extraclass="";
foreach($element as $subkey => $subelement){
$out .= "<td>$subelement</td>";
}
$out .= "<td>EDIT</td>";
$out .= "</tr>";
}
$out .= "</tbody>";
$out .= "</table>";
return $out;
}
A general pattern for this type of page is Post-Redirect-Get. You could, for instance, pull the if(isset($_POST['submit'])) block out into a separate file called processForm.php. The form's action parameter is changed to processForm.php. The form sends $_POST data to processForm which inserts the new database records, and processForm in turn redirects the user back to the original page which gets the results.
If you want a one-page solution using the above code, add this code at the very top of the file, before you output anything at all. This starts the output buffer, which is usually necessary if you want to use the header() command to redirect.
ob_start();
Then edit the if(isset) block:
if(isset($_POST['submit'])){
if(has_presence($_POST['product_name'])){
insert_row_into_table('CAL_products');
show_errors();
if(has_presence($wpdb->last_query)) {
echo "Update Successful";
header("Location: index.php"); //change index.php to the current page
//header("Location: ".$from); //or use a variable
} else {
echo "Update Failed";
}
} else {
echo "The field 'Product Name' cannot be blank.";
}
}
Finally, add this at the very end of the script to close the output buffer:
ob_end_flush();
Essentially, this code refreshes the page on success after the new entries are inserted into the database. This should allow your table to include the new records.

Empty input type not being posted in html

I created a PHP function that will create a form for any table that you have in a database. This function allows you to specify the name of the table and a list of all the columns you want in your html form. Everything works great, if the user puts something in for the text inputs. If they don't, then strange things happen when trying to retrieve the column name. Please see the function below...
function generateSubmissionFromTable($db, $tablename, $rowstoinclude,$action)
{
$query = 'SHOW COLUMNS from '.$tablename;
$colsresult = mysql_query($query,$db);
$table = array();
while($row = mysql_fetch_array($colsresult))
{
array_push($table,$row[0]);
}
$finalcolumns = array();
foreach($table as $row)
{
foreach($rowstoinclude as $inc)
{
if($row == $inc)
{
array_push($finalcolumns,$row);
}
}
}
echo '<form name="loginy" method="post" action="'.$action.'">';
foreach($finalcolumns as $column)
{
echo 'Please enter the '.$column.'<br/>';
echo '<input type=text name=column['.$column.'] value="blah"/><br/>';
}
echo '<input type="hidden" name="tablename" value="'.$tablename.'" />';
echo '<button type="button" size="4" style="font-size:35px;" onClick="document.loginy.submit()">Submit</button>';
echo '</form>';
}
Now, comes the weird part... I have another function that will generate the query statement based off that automatic form generation.
function submitDataToTable($post)
{
$query = 'INSERT INTO '.$post['tablename'].'(';
$buf = "";
while($col = current($post['column']))
{
$query = $query.$buf.key($post['column']);
$buf=",";
next($post['column']);
}
$buf = "";
$query = $query.') VALUES (';
foreach($post['column'] as $val)
{
$query = $query.$buf.$val;
$buf = ",";
}
$query = $query.')';
echo 'QUERY='.$query;
}
Now for example I have a table that I want to input for 3 columns (name, link, descritpion) and I fill in the top 2 and not the bottom, the query gets generated as this...
QUERY=INSERT INTO LinksWebsites(name,link) VALUES (blah,blah,)
which as you can see, the query is missing the column (name,link,descritption) but what is weird if you take a look at the post...
POST =Array ( [column] => Array ( [name] => blah [link] => blah [description] => ) [tablename] => LinksWebsites )
which shows all the keys, but my PHP method of extracting the keys is not showing all the keys! (Might have something to do with the current($array) and key($array) calls?)
Try putting a java script in your html where you will put the php function that text inputs must not be blank before trying to submit it.
<script>
function validateForm()
{
if (inputbox==null || inputbox=="")
{alert("Input should not be empty");
return false;
}
}
</script>
Just include the onsubmit="return validateForm()" in the form tag.

How to split part of table into 2 columns over specific number of td's with PHP?

The site I'm working on wants data organized in a specific way. I need to split it into two columns if it's over 8 td's long. Here is my code right now. I've put it into an array as I had an idea about doing that and using the count to display data but I haven't figured out how to make that work.
$resultFound = false;
$prevWeek = -1;
$count = 0;
while($row = mysqli_fetch_array($result)) {
$adjustedWeek = dateToWeek($row['date']) - 35;
if($_GET['keywords'] != "") {
$id = search($row, $_GET['keywords']);
if($row['id'] == $id) {
if($validWeek) {
if($week == $adjustedWeek) {
include('test2.php');
}
}
else {
include('test2.php');
}
}
}
foreach($tableArray as $table) {
echo $table;
}
Here is my code for test2.php
$table = "";
if($prevWeek != $adjustedWeek) {
$table .= ('<th colspan=2>Week' . $adjustedWeek . '</th>');
$prevWeek = $adjustedWeek;
}
$table .= '<tr>';
$table .= ('<td colspan=12><a href="details.php?id=' . $row['id'] . '">'
. getGameTitleText($row) . '</a></td>');
$table .= '</tr>';
$resultFound = true;
$tableArray[] = $table;
$count++;
I need the code to do something like this:
If (all items of any week > 8)
write out 8 items to column one
then write the rest to column two
I've accounted for the total number of entries it's searching but not specific to a week, and I don't want to have to make lots of variables for that either to keep track.
How could I get the result like I want?
Warning!! the following code is to illustrate the idea only. Not tested on machine, but I think you can iron the possible error out.
pseudo code example:
$arr=array();
while($row = mysqli_fetch_array($result)) {
$arr[]['data']=$row['data'];
$arr[]['whatever']=$row['whatever'];
}
$columns=floor(count($arr)/8);
$output="<table>";
foreach ($arr as $i=>$a){
$output.="<tr>";
$output.="<td>{$arr[$i]['data']}</td>";
if ($columes>0){
for($j=0;$j<$columes;$j++){
$row_number=$i+($j+1)*8;
$output.="<td>{$arr[$row_number]['data']}</td>";
}
}
$output.="</tr>";
}
$output.="</table>";
This code will continue to add the third column if 2 is not enough.
You may still want to put a test for the end of array, so you don't get a bunch of warning when the $row_number is larger than count($arr)
This is how I ended up doing it. It's a bit "dirty" because it echo's out an extra /table and /tr at the beginning but it works for my purposes and is simpler than the code already posted. That was too complex for me
$table = "";
if($prevWeek != $adjustedWeek) {
$table .= '</tr></table><table class="vault_table">';
$table .= ('<tr><th>Week ' . $adjustedWeek . '</th></tr>');
$table .= '<table class="vault_table">';
$prevWeek = $adjustedWeek;
}
if($count % 2 == 0) {
$table .= '<tr>';
}
$table .= ('<td><a href="details.php?id=' . $row['id'] . '">'
. getGameTitleText($row) . '</a></td>');
$resultFound = true;
$tableArray[] = $table;
$count++;
The class is just for styling the table. Didn't have anything to do with how it's being layed out. other than each side of the table being 50% width of the container

Categories