I am currently building an internal tool for viewing and editing SQL-like tables via the web. I have some PHP and html written that generates these tables and jQuery written that does this, so far:
Delete Rows
Add New Rows
Output form value after entry
The ultimate goal, of course, is to generate a SQL statement using INSERT, UPDATE, DELETE, etc on the modified data. I have a grasp on how to concatenate the results into such a statement, but could use help targeting columns for it.
My main concern is modifying the form value output function so that I can store any updated entries in an array and output them as a CSV string. I've read about .each, .map, .push, and .serializeArray. I'm not sure exactly how to use/combine these methods to accomplish the desired result. Here are some code snippets:
The current jQuery:
$('#add_row').on('click', function(){
$('<tr><td id="data"><input class ="new_row"></td><td id="data"><input class ="new_row"></td><td id="data" style="text-align:center;"><input class ="new_row"></td><td id = "Delete_Button"><button class="rmv_row">-</button></td></tr>').appendTo('#SQLdata');
});
$("table").on('keyup', 'input', function(){
$('#output').text($(this).val());
});
$('table').on('click', '.rmv_row', function(){
$(this).closest('tr').remove();
});
});
and the PHP/HTML:
<table id="SQLdata">
<tr style="background-color: margin-left:#6b685c;">
<td style="background-color: margin-left:#6b685c; font-family:tahoma,arial,verdana,sans-serif"; colspan="3">
<form style="color:black;" method="post" action="WebEventsStructureColumnTool.php">
Select your table name:
<select method="post" name="table_name" id="picker">
<option>Removed For Security</option>
</select>
<input type="submit" value="Go" name="submit">
</form>
</td>
<td><button id="add_row">Add a Row</button></td>
</tr>
$tableName = $_POST['table_name'];
$statementObject = $pdo->prepare("SELECT a, b, c FROM tab WHERE _id =?");
$statementObject->bindParam(1, $tableName, PDO::PARAM_STR);
$statementObject->execute();
$statementObject->bindColumn('a', $Col1);
$statementObject->bindColumn('b', $Col2);
$statementObject->bindColumn('c', $Col3);
while ($statementObject->fetchAll(PDO::FETCH_BOUND)){
// Gets an array from the CSVs in the column :
$Column1 = explode(",", $Col1);
$Column2 = explode(",", $Col2);
$Column3 = explode(",", $Col3);
}
//Fetches the total number of values from each exploded array:
$Count1 = count($Column1);
$Count2 = count($Column2);
$Count3 = count($Column3);
//Establishes the total length/height of the table:
$largest = $Count1;
if ($Count2 > $largest){
$largest = $Count2;
}
if ($Count3 > $largest){
$largest = $Count3;
}
echo '
<tr>
<th>a</th>
<th>b</th>
<th style="text-align: center">c</th>
<th>delete row</th>
</tr>';
for($i = 0; $i < $largest; $i++){
$tableRows[] =
"<tr>
<td id='data'>
<input type='text' value='" . $Column1[$i] . "'>
</td>" .
"<td id='data'>
<input type='text' value='" . $Column2[$i] . "'>
</td>" .
"<td id = 'data' style='text-align:center;'>
<input type='text' value='". $Column3[$i]. "'>
</td>
<td id = 'Delete_Button'><button class='rmv_row'>-</button></td>";
}
foreach ($tableRows as $row){
echo $row;
}
echo '</table><div><table><tr id="output" colspan="4"></tr></table>'
If anyone also has advice/recommendations on existing code, feel free to criticize. I am a young developer just starting out and could use all the help I can get. Thanks!
I added this bit this morning and am now successfully getting CSVs:
var string = new Array()
function updateString(){$('#output').text(string);}
$('input').each(function(){
string.push($(this).val());
});
Working on creating three different arrays for each data manipulation option and limiting printing to conditionals.
Related
I recently ran into a problem I wasn't quite sure how to solve. Sharing it here in case it helps someone else.
Use Case: User enters a string in a search box on a PHP page. On submit, the page queries the database and then posts results to a table on the same page. User then selects a single record with a radio button and needs to post only that record to a different PHP page. The second page does not have access to the database.
I took the actual page and created a sample page for clarity and testing, since the original had about 15 table columns.
<div class="container">
<div class="row" style="margin-top: 1rem;">
<div class="col-sm">
<form action="" method="post">
<table class="fit" id="entry">
<tr>
<td class="fit"><label for="start">Planet (try <strong>Caprica</strong> or <strong>Picon</strong>): </label></td>
</tr>
<tr>
<td class="fit"><input type="test" id="planet" name="planet" required autofocus /></td>
</tr>
</table>
<input class="btn btn-primary" type="submit" value="Get Characters" />
</form>
</div>
</div>
</div>
<div class="container" style="margin-top: 2rem;">
<div class="row">
<div class="col-sm">
<?php
require_once('./resources/pdo.php');
if ( isset($_POST['planet']) ) {
$planet = strtolower($_POST['planet']);
$pdo = new myPDO('phppostpost');
try {
$stmt = $pdo->prepare('CALL devCharacters(?)');
$stmt->bindParam(1, $planet, PDO::PARAM_STR);
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
die("Error occurred: " . $e->getMessage());
}
?>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="thead-light">
<tr>
<th class="fit">Select</th>
<th class="fit" scope="col">Customer First</th>
<th class="fit" scope="col">Customer Last</th>
<th class="fit" scope="col">Planet</th>
</tr>
</thead>
<tbody>
<?php while ($r = $stmt->fetch()): ?>
<tr>
<?php echo "<td class='fit'><input type='radio' id='cust-" . $r['customer_id'] ."' name='cust-id' value='". $r['customer_id'] . "' </td>"; ?>
<?php echo "<td class='fit'>" . $r['first_name'] . "</td>"; ?>
<?php echo "<td class='fit'>" . $r['last_name'] . "</td>"; ?>
<?php echo "<td class='fit'>" . $r['origin_planet'] . "</td>"; ?>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
<input class="btn btn-primary" onclick="getSelectedRowData();" type="submit" value="Send" />
<?php } ?>
</div>
</div>
</div>
As a relatively new developer, I couldn't figure out how to (1) grab just the selected row and (2) post data on submit from just that row, rather than from the the original search form.
After much Googling, as well as a kick in the pants from a Stack Overflow user who reminded me I needed to actually research for more than 20 minutes (thank you!), I was able to solve it.
I'll post the answer below for anyone else who runs into a similar problem.
To solve this, I used JavaScript to grab the selected row. In order to efficiently grab the correct record, I updated each TD element to have a unique, dynamically-generated ID:
<?php echo "<td class='fit' id='fname-" . $r['customer_id'] ."'>" . $r['first_name'] . "</td>"; ?>
<?php echo "<td class='fit' id='lname-" . $r['customer_id'] ."'>" . $r['last_name'] . "</td>"; ?>
<?php echo "<td class='fit' id='planet-" . $r['customer_id'] ."'>" . $r['origin_planet'] . "</td>"; ?>
I also gave the table body an ID so I could grab it quickly without grabbing a parent, then children, etc.:
<tbody id="results-body">
Finally, here's the JavaScript.
function getSelectedRowData() {
const tableRowArray = Array.from([document.getElementById('results-body')][0].rows);
let custFirst;
let custLast;
let custPlanet;
tableRowArray.forEach((tableRow, i) => {
cellButton = tableRow.getElementsByTagName('input');
if (cellButton[0].checked == true ) {
const rowID = cellButton[0].id.split('-').pop();
custFirst = document.getElementById('fname-' + rowID).innerHTML;
custLast = document.getElementById('lname-' + rowID).innerHTML;
custPlanet = document.getElementById('planet-' + rowID).innerHTML;
}
});
/* Build a hidden form solution to prep for post.
Source: https://stackoverflow.com/questions/26133808/javascript-post-to-php-page */
let hiddenForm = document.createElement('form');
hiddenForm.setAttribute('method', 'post');
hiddenForm.setAttribute('action', 'newpage.php');
hiddenForm.setAttribute('target', 'view');
const fieldCustFirst = document.createElement('input');
const fieldCustLast = document.createElement('input');
const fieldCustPlanet = document.createElement('input');
fieldCustFirst.setAttribute('type', 'hidden');
fieldCustFirst.setAttribute('name', 'custFirst');
fieldCustFirst.setAttribute('value', custFirst);
fieldCustLast.setAttribute('type', 'hidden');
fieldCustLast.setAttribute('name', 'custLast');
fieldCustLast.setAttribute('value', custLast);
fieldCustPlanet.setAttribute('type', 'hidden');
fieldCustPlanet.setAttribute('name', 'custPlanet');
fieldCustPlanet.setAttribute('value', custPlanet);
hiddenForm.appendChild(fieldCustFirst);
hiddenForm.appendChild(fieldCustLast);
hiddenForm.appendChild(fieldCustPlanet);
document.body.appendChild(hiddenForm);
// Post
window.open('', 'view');
hiddenForm.submit();
}
This worked for me, but I'm sure there's a better way to do this. Hopefully this (1) helps someone else and (2) a better solution is posted!
Here's a working demo: https://postfrompost.paulmiller3000.com/
Full source here: https://github.com/paulmiller3000/post-selected-from-post
I've created a dropdown list that is populated by data from my mysql db and programmed using php. What I need to do is populate a text field based on the selection made in the dropdown. Unfortunately, my question differs from the others asked on this forum because most are simply typing all of their options into a html form. Mine are contained within a table and I do not want to save the content in the text field to my database...it will be used for user reference only.
I've read a plethora of forum posts on this site and numerous others and have tried using jquery, javascript, and ajax scripts, but for some reason the only thing I've been successful in getting to appear in the text field is the id of the corresponding item selected from the dropdown list. I think it is important to know that both fields come from the same table in the db, so I can't figure out why it is so difficult to automatically populate the field. I would like to use javascript because I want everything in this one file.
This is the code in the php form:
<?php
'<div id="trxdetailstable">';
echo '<table align="center" width="750px" cellspacing="0" border=".5px" ! important><tr>
<th>Movie Title</th><th>Category</th><th>Price</th></tr>';
echo '<td align="left" width="8%" height="25px">';
$ddlquery4 = "SELECT id, title, categoryname FROM dvd ORDER BY title ASC";
$ddlresult4 = mysqli_query($dbc, $ddlquery4) or die("Bad SQL: $ddlquery4");
echo '<select class="dropdown" name="dvdid" id="dvdid" size="1" onchange="updatecat()">';
while($ddlrow4=mysqli_fetch_array($ddlresult4, MYSQLI_ASSOC)){
$categoryname = $ddlrow4['categoryname'];
echo "<option data-categoryname='' value='".$ddlrow4['id']."'>" . $ddlrow4['title'] . "</option>";
} //End while statement
echo "</select>";
echo '</a></td>';
echo '<td align="left" width="10%">';
echo '<input required id="categoryname" name="categoryname" type="text" readonly="readonly">';
echo '</a></td>';
This is the code I currently have in the html head:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
This is the code that is currently generating no results (text field is left blank after a dropdown item is selected):
$('#dvdid').change(function(e){
var optionChange = $('#dvdid option:selected').text();
$('#categoryname').val(optionChange);
});
</script>
And this is the code that actually gave me the primary key (id) for the item selected in the dropdown list (I want it to be the categoryname):
<script>
function updatecat(id){
if (id === "") {
$("input[name=categoryname]").val("");
} else {
$("input[name=categoryname]").val(id);
}
}
</script>
I have about 3 other scripts I've tried, but they all left the text (category) field blank.
Any advice would be appreciated. Please keep in mind all of my data is generated from a database not manually entered. Thanks.
You have repeated rows and do not use ID atrribute with them , you can use class like this :
$('select.dropdown').change(function(e){
var optionChange = $(this).find('option:selected').text();
$(this).closest("tr").find(".categoryname").val(optionChange);
});
and your php code should be something like this :
<?php
'<div id="trxdetailstable">';
echo '<table align="center" width="750px" cellspacing="0" border=".5px" ! important>
<tr>
<th>Movie Title</th>
<th>Category</th>
<th>Price</th>
</tr>';
echo '<tr>
<td align="left" width="8%" height="25px">';
$ddlquery4 = "SELECT id, title, categoryname FROM dvd ORDER BY title ASC";
$ddlresult4 = mysqli_query($dbc, $ddlquery4) or die("Bad SQL: $ddlquery4");
echo '<select class="dropdown" name="dvdid" id="dvdid" size="1" onchange="updatecat()">';
while($ddlrow4=mysqli_fetch_array($ddlresult4, MYSQLI_ASSOC)){
$categoryname = $ddlrow4['categoryname'];
echo "<option data-categoryname='' value='".$ddlrow4['id']."'>" . $ddlrow4['title'] . "</option>";
} //End while statement
echo "</select>";
echo '</a></td>';
echo '<td align="left" width="10%">';
echo '<input required class="categoryname" id="categoryname" name="categoryname" type="text" readonly="readonly">';
echo '</a></td></tr>';
For others using html/php and searching for a way to auto populate a text field based on the selection made in a dropdown fed from data held in their mysql db (and only use one file) here is what FINALLY worked for me:
In html head:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
In html/php portion:
echo '<td align="left" width="8%" height="25px">';
$ddlquery4 = "SELECT id, title, categoryname FROM dvd ORDER BY title ASC";
$ddlresult4 = mysqli_query($dbc, $ddlquery4) or die("Bad SQL: $ddlquery4");
echo '<select type="text" class="dropdown" name="dvdid" id="dvdid" size="1" onchange="updatecat()">';
while($ddlrow4=mysqli_fetch_array($ddlresult4, MYSQLI_ASSOC)){
echo "<option value='".$ddlrow4['id']."' data-categoryname='".$ddlrow4['categoryname']."'>" . $ddlrow4['title'] . "</option>";
} //End while statement
echo "</select>";
echo '</a></td>';
echo '<td align="left" width="10%">';
echo '<input type="text" id="categoryname" name="categoryname" readonly="readonly" value="">';
echo '</a></td>';
In HTML area at end of file:
<script>
$('#dvdid').change(function() {
selectedOption = $('option:selected', this);
$('input[name=categoryname]').val( selectedOption.data('categoryname') );
});
</script>
I sincerely hope this prevents someone else from having to go the days of trial and error and endless searching and reading that I went through.
Hi ! I used mysqli for my connection in database.
My problem is the second and the following rows is not affected whenever I select new option in .
Can you guys please help me to solve this.
$(document).ready(function ()
{
$('#dealer').change(function ()
{
$("#tt").val($(this).val());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<body>
<table>
<tr>
<th>USERNAME</th>
<th>PASSWORD</th>
<th>CURRENT USER TYPE</th>
<th>CHANGE USER TYPE</th>
<th>UPDATE</th>
<th>DELETE</th>
</tr>
<?php
while($row= mysqli_fetch_array($records))
{
//echo "<tr><form action='super_admin_function_edit.php' method='post'>";
echo "<tr><form action=super_admin_function_edit.php method=post>";
echo "<td><input type=text name=emp_username value='".$row['emp_username']."'></td>";
echo "<td><input type=text name=emp_password value='".$row['emp_password']."'></td>";
echo "<td><input type=text name=emp_type id=tt value='".$row['emp_type']."'></td>";
//echo "<td><input type='text' id='tt' </td>";
echo " <td><select name='dealer' id='dealer'>
<option value='0'>---- select Dealer -----</option>
<option value='1'>---- select Dealer1 -----</option>
<option value='2'>---- select Dealer2 -----</option>
</select>
</td>";
echo "<input type=hidden name=emp_id value='".$row['emp_id']."'></td>";
echo "<td><input type=submit></td>";
echo "<td><input type=submit value=Delete></td>";
echo "</form></tr>";
}
?>
</body>
Id's cannot be duplicated on an HTML page. You have id="tt" and id="dealer" on each row and browsers only see the first of each on the page. The reason for this is that browsers have a fast-lookup dictionary, that contains one DOM element per key (per id)
Change it to use a tt class and dealer class and find the closest one to the .dealer select that changes (e.g. based on the tr/row).
eg. using:
$(function ()
{
$('.dealer').change(function ()
{
$(this).closest('tr').find(".tt").val($(this).val());
});
});
notes:
$(function ().. is just the preferred shortcut for $(document).ready(function()...
Your generated markup will contain multiple id attributes with the same value, which is not valid HTML. So this jQuery code:
$("#tt").val($(this).val());
will only pick the first occurrence of the id. To fix this, replace id=tt with class='tt' and id='dealer' with class='dealer'.
Similarly, your jQuery code to:
$('.dealer').change(function ()
{
$(this).parent().find('.tt').val($(this).val());
});
I'm still new with yii
and now I want to add a Javascript code that can append dropdown list to the table, when I click the button.
Here is my table:
<table class="table table-hover" id="table-add-more">
<tr>
<th style="width:50px;">No</th>
<th style="width:200px;">Name</th>
<th style="width:50px;">Count</th>
<th style="width:30px;"></th>
</tr>
<tbody>
</tbody>
</table>
Here is my button:
<a id="btn-add-more" class="btn btn-sm btn-success">Add More</a>
Here is my script:
<script>
$(document).ready(function(){
var number = 1;
var product = <?php $product = Product::model(); echo $form->dropDownList($product,'ID', CHtml::listData(Product::model()->findAll(), 'ID', 'name')); ?>;
$('#btn-add-more').click(function() {
var more_field = "<tr>"+
"<td>"+number+"</td>"+
"<td>"+
<?php echo "product"; ?>
+"</td>"+
"<td><input type='number'/></td>"+
"<td><input type='checkbox'/></td>"+
"</tr>"
$('#table-add-more').append(more_field);
number = number + 1;
});
});
</script>
I got an error message:
"unexpected token <"
near the var product = <select name="Product[ID]" id="Product_ID">
but I can't found the mistake yet.
Please help..
I think the better way is to have dropdown list with display: none at initialization and when you click that button, you can change display to block. But If you want to append dropdown to your table, I think you have tow problem in your javascript function:
1.You need to wrap this php code into "".
var product = "<?php $product = Product::model(); echo $form->dropDownList($product,'ID', CHtml::listData(Product::model()->findAll(), 'ID', 'name')); ?>";
I think you need to have <?php echo $product; ?>, instead of <?php echo "product"; ?>
My question might be confusing, basically I have two tables in my ordering, one which is connected to a mysql database displaying the items i have in stock and the other (empty) table is where all my selected items go.
pic: http://tinypic.com/r/o89pn5/8
Now, everytime i click the button beside each row on the top table, it transfers the rows to the lower table
pic: http://tinypic.com/view.php?pic=290sfw2&s=8#.U7LMjpSSzTo
Now notice on the lower table I have another column named "Quantity". Can anyone show me how to fill this column with textboxes? Thanks a lot to anyone who can help me. I'm just staring to learn Javascript/JQuery.
Please feel free to ask me more questions in case my question is not clear.
Code for the tables:
<!-- Table 1(inventory table) -->
<?php
$con=mysqli_connect("localhost","root","","purchasing");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM tbl_inventory");
echo "<table id='table1' class='inventory' border='3'>
<tr>
<th>Check</th>
<th>ID</th>
<th>Product Name</th>
<th>Price</th>
<th>Stock</th>
</tr>";
while($row = mysqli_fetch_array($result)) {
echo "<tr>";
echo "<td> <button class='btn'>order</button> </td>";
echo "<td>" . $row['prod_id'] . "</td>";
echo "<td>" . $row['prod_name'] . "</td>";
echo "<td>" . $row['price'] . "</td>";
echo "<td>" . $row['stock'] . "</td>";
echo "</tr>";
}
echo "</table>";
mysqli_close($con);
?>
<br/><br/>
<!-- Table 2(ordered items table) -->
<table id="table2" class="inventory" border="3">
<tr>
<th>Check</th>
<th>ID</th>
<th>Product Name</th>
<th>Price</th>
<th>Stock</th>
<th>Quantity</th>
</tr>
<tbody>
</tbody>
</table>
The scripts:
<script>
$(".btn").click(function () {
// get the row containing this link
var row = $(this).closest("tr");
// find out in which table it resides
var table = $(this).closest("table");
// move it
row.detach();
if (table.is("#table1")) {
$("#table2").append(row);
}
else {
$("#table1").append(row);
}
// draw the user's attention to it
row.fadeOut();
row.fadeIn();
});
</script>
After this line:
$("#table2").append(row);
just append textbox in last tr last td like this:
$("#table2").find("tr:last").find("td:last").append('<input type="text" class="quantity" />');
JQuery gives you a few different ways to dynamically add elements to the page. In this case, if you wanted to add a text input to a td element you could do something simple like this:
<script>
$('table#table2 td.quantity').append('<input type="text" name="quantity" id="quantity" value="0" />");
</script>
You can also build elements using various JQuery methods and then append the the JQuery object directly:
<script>
var inputObj = $('<input />');
inputObj.attr('type','text').val('0').attr('name','quantity').attr('id','quantity');
$('table#table2 td.quantity').append( inputObj );
</script>
Hopefully, this may work, but it won't remember whichever value has been put in the text box if a user removes the row from #table2 and put it back later on.
if (table.is("#table1")) {
row.append('<td><input type="text" class="quantity" /></td>');
$("#table2").append(row);
}
else {
row.find('td:last').remove();
$("#table1").append(row);
}
If you have good html5 support, you should be able to use inputs of type number instead of a plain text box.
As an extra, you probably want to have the fadeout/fadein happen around the row move. You may implement it as follow:
var row = $(this).closest('tr');
var table = $(this).closest('table');
row.fadOut(300, function(){
row.detach();
if (table.is("#table1")) {
row.append('<td><input type="text" class="quantity" /></td>');
row.find('.btn').html('remove');
$("#table2").append(row);
}
else {
row.find('td:last').remove();
row.find('.btn').html('order');
$("#table1").append(row);
}
row.fadeIn(300);
});