I have an exiting PHP/javascript application that generates a table with some rows and corresponding child rows(there can be many of them, all are retrived from DB at once), which are hidden by default. Child rows are shown after user clicks button placed in table row.
It looks like this(one parent, two children):
http://i.imgur.com/hul9fT9.png
It is generated like this from php:
for($i = 0; $i < count($shipArr); $i++)
{
echo '
<tr>
<td><span>'.$shipArr[$i]["orderNo"].'</span></td>
</tr>
<tr>
<td>
<table id="details">
;'
for($j = 0; $j < count($shipDetailsArr[$i]); $j++)
{
echo '
<tr>
<td>
<p>
<span>Order Number: </span><span>'.$shipDetailsArr[$i][$j]["lineNo"].'</span>
</p>
</td>
</tr>
';
}
echo '</table>;'
}
Can I use somehow objects $shipArr and $shipDetailsArr populated from db to create the same effect using datatables plugin? How can I achieve this?
Thanks for any help.
I dont't think there is a database plugin which can automatically generate a table. You should use something like a table generator. You can program it yourself in e.g. PHP.
If this is hard for you there are already classes which can do this. Two examples are:
http://www.dyn-web.com/php/table_class/example.php
https://github.com/naomik/htmlgen
Good luck!
I know this question is quite old, but I thought I'd chime in with some support considering another answer here linked to my project.
To solve this problem, I wrote htmlgen, mirrored on packagist. It makes HTML generation with PHP quite nice, if I do say so myself !
use function htmlgen\html as h;
use function htmlgen\map;
$beeData = [
'pop' => 'yup',
'candy' => 'sometimes',
'flowers' => 'so much',
'water' => 'not really',
'sand' => 'indifferent',
'donuts' => 'most definitely'
];
echo h('table',
h('thead',
h('tr',
h('td', 'item'),
h('td', 'do bees like it?')
)
),
h('tbody',
map($beeData, function($value, $key) { return
h('tr',
h('td', $key),
h('td', $value)
);
})
)
);
Output (whitespace not included in actual output)
<table>
<thead>
<tr>
<td>item</td>
<td>do bees like it?</td>
</tr>
</thead>
<tbody>
<tr>
<td>pop</td>
<td>yup</td>
</tr>
<tr>
<td>candy</td>
<td>sometimes</td>
</tr>
<tr>
<td>flowers</td>
<td>so much</td>
</tr>
<tr>
<td>water</td>
<td>not really</td>
</tr>
<tr>
<td>sand</td>
<td>indifferent</td>
</tr>
<tr>
<td>donuts</td>
<td>most definitely</td>
</tr>
</tbody>
</table>
Related
Hopefully I am using the proper words in my title here.
What I am hoping to achieve is creating a link that varies automatically based on the value of a previously found class. Below is the code I am using, and I'd like the XXXX.jpg to change based on the numbers found in the Class directly before the link.
<?php
$crim_url = "<a href=../images/vinyl/crim/numbers/XXXX.jpg>Link</a>";
?>
<tbody>
<tr>
<td><? print $bluewhite ?></td><td class=num>0002</td><td>Name</td><td><? print $crim_url ?></td></tr><tr>
<td><? print $bluewhite ?></td><td class=num>0004</td><td>Name</td><td><? print $crim_url ?></td>
</tr>
</tbody>
So in this example, I'd like to have the $crim_url grab the data in the previously found < td class=num> and replace the XXXX.jpg with 0002.jpg and 0004.jpg respectively. I don't even know where to start with this. I have nearly 1000 links, and I'd like to automate this instead of writing code manually. I'm not sure if it's possible with the setup I'm using, but any tips in the right direction would be great!
Thank you!
Use a loop to create the HTML, so you can substitute the same number into both the <td> and $crim_url.
<?php
$numbers = ['0002', '0004'];
?>
<tbody>
<tr>
<?php
foreach ($numbers as $number) {
$crim_url = "<a href=../images/vinyl/crim/numbers/$number.jpg>Link</a>";
?>
<td><? print $bluewhite ?></td><td class=num><?= $number ?></td><td>Name</td><td><?= $crim_url ?></td></tr><tr>
<? php
} ?>
</tr>
</tbody>
Because you tagged Javascript in your question, here is a pure JS solution for you.
If you already have the table rows parsed in the DOM within the table, you can loop over the elements and get the textContent of each element and then find its closest parent element and query the target tr element that will hold the formatted link and then set its innerHTML to the formatted link. Format the link using a method that returns the textContent of the current iteration of the num element.
// function to return the link formatted with the proper address
// maybe you want to add more attributes like a class or a dataset
function parseLink(address, className) {
return `<a class="${className}" href=../images/vinyl/crim/numbers/${address}.jpg>Link - ${address}</a>`
}
// get all elements with a class of num
const nums = document.querySelectorAll('.num')
// loop over the elements with a class of num
nums.forEach(num => {
// get the closest parent row and query the 4th child to display the link
let val = num.closest('tr').querySelectorAll('td')[3]
// set the innerHTML of that 4th child to the formatted link
val.innerHTML = parseLink(num.textContent, 'blue-white link')
})
.blue-white:hover {
color: white;
background: blue;
}
.link {
text-decoration: none;
}
<table>
<tbody>
<tr>
<td>
<? print $bluewhite ?>
</td>
<td class='num'>0002</td>
<td>Name</td>
<td>
</td>
</tr>
<tr>
<td>
<? print $bluewhite ?>
</td>
<td class='num'>0004</td>
<td>Name</td>
<td>
</td>
</tr>
</tbody>
</table>
I've been working on a small project where I display multiple tables for a user on a web page. I would like for the users to be able to edit their tables and have that data update in the database. I'm using the jQuery tabledit plugin to achieve this.
I followed this tutorial Live editable tables and was able to successfully get this to work for one table.
The problem I'm having is this doesn't seem to be working for all my tables. I can only click into the first displayed table but I need to be able to edit all of them.
I've searched for anybody trying to achieve something similar but couldn't find much.
<?php
// ...
if ($resultCheck > 0) {
while ($row = mysqli_fetch_assoc($result)) {
?>
<table id="data_table">
<thead>
<tr>
<th>col1</th>
<th>col2</th>
<th>col3</th>
<th>col4</th>
</tr>
</thead>
<tbody>
<tr>
<td><?php echo $row ['col1_data']; ?></td>
<td><?php echo $row ['col2_data']; ?></td>
<td><?php echo $row ['col3_data']; ?></td>
<td><?php echo $row ['col4_data']; ?></td>
</tr>
</tbody>
</table>
<?php
}
}
$(document).ready(function () {
$('#data_table').Tabledit({
deleteButton: false,
editButton: false,
columns: {
identifier: [ 0, 'col1_data' ],
editable: [ [ 1, 'col2_data' ], [ 2, 'col3_data' ], [ 3, 'col4_data' ] ],
},
hideIdentifier: false,
url: 'includes/liveedit.inc.php',
})
})
I think this may be a problem with each table having the same identifier but I'm not sure. I return each table from the database with a unique identifier but I'm not sure how to use that with the plugin (it seems like I need to).
Sorry if this has an easy solution. I'm pretty new to php and jQuery.
Thanks in advance for any help and please let me know if I'm not being clear enough!
You have an id and it must be unique. Your while statement creates many tables with the same id.
Your JS always going to the first table with such id. Change it on class. Don't use id if you wanna apply your JS code at once.
$(document).ready(function() {
$('.data_table').Tabledit({
deleteButton: false,
editButton: false,
columns: {
identifier: [0, 'col1_data'],
editable: [[1, 'col2_data'], [2, 'col3_data'], [3, 'col4_data']]
},
hideIdentifier: false,
url: 'includes/liveedit.inc.php'
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery-tabledit#1.0.0/jquery.tabledit.min.js"></script>
<table class="data_table">
<thead>
<tr>
<th>col1</th>
<th>col2</th>
<th>col3</th>
<th>col4</th>
</tr>
</thead>
<tbody>
<tr>
<td>rew</td>
<td>ter</td>
<td>yrt</td>
<td>qwe</td>
</tr>
</tbody>
</table>
<table class="data_table">
<thead>
<tr>
<th>col1</th>
<th>col2</th>
<th>col3</th>
<th>col4</th>
</tr>
</thead>
<tbody>
<tr>
<td>data_column1</td>
<td>dat2a_column1</td>
<td>da3ta_column1</td>
<td>data_co5lumn1</td>
</tr>
</tbody>
</table>
Press ENTER in the snippet for saving the new value
I create a table with dynamic data from mysql. He seems to :
screen
When I click on the delete button from the second row, and make an alert js with the value of id, he save the id from the first row and not in the row where I cliqued.
My Views :
$('.Btrash').click(function() {
//var id_stream = $('#id_stream').val();
var id_stream = $('#id_stream').attr('value');
var id_compte = $('#id_compte').val();
alert(id_stream);
});
<div class="row" id="Tstream">
<table class="table table-striped table-bordered table-list">
<thead>
<tr>
<th>Feeds</th>
<th>Data request</th>
<th>Begin Stream</th>
<th>End Stream</th>
<th><em class="fa fa-cog"></em></th>
<th>Status</th>
<th>Access to Data</th>
</tr>
</thead>
<tbody >
<?php foreach ($aAllRequestByIdUser as $aRequestByIdUser) : ?>
<tr>
<td class="vert-align">
<input type="hidden" id="id_compte" value="<?= $iIdCompte ?>">
<input type="text" id="id_stream" value="<?= $aRequestByIdUser['id_Stream'] ?>">
...
My alert always show 74.
Can you help me to find a solution?
Thanks
First let me explain a bit about jquery selectors. This code of yours
var id_stream = $('#id_stream').attr('value');
selects all the items with the id of #id_stream, and returns the first value.
If you want to get the ID of the row clicked, then you should select the row first. But since you haven't shared the rest of your code, i can only assume the rest. There are several ways of doing so, and this is one of them.
1 ) Get the parent of $(this) >
2 ) Then get the first sibling of it
3 ) Finally find input and get val().
Or you can do it by Jquery's closest function. But as i said, first i need to see the rest of your code.
I currently have the following:
<table class="table table-striped">
<tr>
<th> Artikelbild </th>
<th> Artikelnummer </th>
<th> Name des Artikels </th>
<th> Beschreibung </th>
<th> Preis </th>
<th> Kategorie </th>
</tr> #foreach($products as $product)
<tr class='clickable-row' <?php if($product->stockCount === 0) echo "style='color:red;'";?>data-href="{{url('/product')}}
<?php echo '/'.$product->id;?>">
<td> <img src="/images/{{$product->imageUrl}}" class="productImageSmall" /> </td>
<td> {{$product->id}} </td>
<td> {{$product->name}} </td>
<td>
<?php if (strlen($product->description) > 30) { $productShortened = substr($product->description, 0, 30) . "[...]"; } else { $productShortened = $product->description; } echo $productShortened; ?> </td>
<td>
<?php echo number_format($product->price, 2, ',', '.');?>€ </td>
<td> {{$product->categoryName}} </td>
</tr> #endforeach
</table>
The $product thing is passed from my controller with the paginate() option.
Now I want that this table is sort-able by one column. So lets say, the user clicks on the "price" (or Preis in german) column on top of the table, then all results should be sorted by the price (from low to high or from high to low), same for the category, for the name and every other column.
How can I do this? Do I have to reload the page and get the data again from the db, but somehow sorted (if yes, how?). Or can I somehow just sort it without reloading it? How can I do this?
Thanks for any help
Building sortable tables is a pretty time-consuming task, so I'd recommend you to use some package. I use this package for building sortable tables.
If you still want to build this functionality by yourself, you can add arguments like ?price=desc to the URL and get these with the request() method. Just an example:
if (request()->has('price')) {
$query = $query->orderBy('price', request('price'));
}
And don't forget to append URL arguments to the pagination links:
{{ $products->appends(['price' => 'desc'])->render() }}
Here's my code :
<table class="table table-hover" id="mytable" >
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Print</th>
</tr>
<script type="text/javascript">
function initButtonPrint(){
var button = document.getElementById('button-print');
button.onclick = function(e){
print();
grayLine(1);
return false;
}
}
function grayLine(lineId){
var arrayLine = document.getElementById("mytable").rows;
arrayLine[lineId].style.backgroundColor = "silver";
}
</script>
</thead>
<tbody>
<br/>
<?php
for ($i=0; $i<$lineNumber; $i++)
{
?>
<tr>
<td><?php echo $mytable[$i]['Data']['Column 1']; ?></td>
<td><?php echo $mytable[$i]['Data']['Column 2']; ?></td>
<td><input type="button" id="button-print" value="Print"/></td>
</tr>
<?php
}
echo $this->Js->writeBuffer();
?>
</tbody>
</table>
<script type="text/javascript">
initButtonPrint();
</script>
What this code does ?
I put my data from a database into a html table using a for loop and I put a print button in each line. When I click the first print button, the print configuration page opens and the first line is colored grey
arrayLine[lineId].style.backgroundColor = "silver";
What I want to do ?
When I click on a print button, the line is colored grey (or silver here)
The main issue is that I don't know how to tell the javascript which button from which line was pressed. In my code the first line is colored grey because I passed the number 1 into the function
grayLine(1)
Another main issue is that only the first print button from the first line works (only one which opens the print configuration page)
Thanks for your help !
You must change the id='button-print' to class='button-print' because 'id' is unique in a document, the loop creat more than one id
please try the following code:
<html>
<head>
<script src="https://code.jquery.com/jquery-3.0.0.js" integrity="sha256-jrPLZ+8vDxt2FnE1zvZXCkCcebI/C8Dt5xyaQBjxQIo=" crossorigin="anonymous"></script>
</head>
<body>
<table class="table table-hover" id="mytable" >
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Print</th>
</tr>
</thead>
<tbody>
<br/>
<?php
$database = array(
'one' => array('name' => 'john' , 'city' => 'noida' , 'addr' => 'xyz','mail' => 'john#xyz.com'),
'two' => array('name' => 'jimi' , 'city' => 'india' , 'addr' => 'abc','mail' => 'jimi#abc.com'),
'three' => array('name' => 'foo' , 'city' => 'china' , 'addr' => 'pqr','mail' => 'foo#pqr.com'),
'four' => array('name' => 'apple' , 'city' => 'america' , 'addr' => 'lmno','mail' => 'apple#lmno.com'),
);
foreach($database as $row)
{
?>
<tr>
<td>Name : <?php echo $row['name']; ?></td>
<td>City : <?php echo $row['city']; ?></td>
<td><input type="button" onclick="change_color(this);" class="button-print" value="Print"/></td>
</tr>
<?php
}
?>
</tbody>
</table>
<script>
function change_color(obj){
$('.button-print').parent().parent().css('background-color' , 'white');
$(obj).parent().parent().css('background-color' , 'silver');
}
</script>
</body>
</html>
I agree with Sun Liren answer and you should accept it but I would also like to point out the title is somewhat misleading and could be reworded to show what you actually wanted to know( make the buttonclick aware of the row he is a child of). I would also remove the php tag since it's not relevant to the question and I would use dummy data instead of your php code to populate it, to make it easier to get your code to work on tools like jsfiddle. Sorry if that sounded arrogant, it wasn't my intention. Would have posted it as a comment but I don't have enough reputation
For a quick look, you can see this codepen
http://codepen.io/SLRXXX/pen/KrmRgE?editors=1111
The attribute 'id' means there's only one specific element with the id in the html DOM tree. So, in the html that you show us, there are many buttons with the same id, which is an improper way to use 'id', but the browser won't tell you. When you use the document.getElementById method, it only returns the first button.
So, what we should do is to bind event to every button in the table rows, when button clicked, find the row containing the button (in another word, look for the button's parent table row), then change its color.
To select all the buttons, we can use class instead of id attribute. Or if the page is simple enough, we can just use input[type="button"] to select.
Put the following script under your table element.
function initButtonPrint() {
var buttons = document.querySelectorAll('#mytable .button-print');
for (var i = 0; i < buttons.length; i++) {
buttons.item(i).onclick = function () {
var t = this;
while (true) { // find the row containing the button
t = t.parentElement;
if (t.nodeName === 'TR') {
break;
}
}
t.style.backgroundColor = "silver";
};
}
}
initButtonPrint();
As for your table, it may look like this:
<table class="table table-hover" id="mytable" >
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Print</th>
</tr>
</thead>
<tbody>
<?php
for ($i=0; $i<$lineNumber; $i++) {
?>
<tr>
<td><?php echo $mytable[$i]['Data']['Column 1']; ?></td>
<td><?php echo $mytable[$i]['Data']['Column 2']; ?></td>
<td><input type="button" class="button-print" value="Print"/></td>
</tr>
<?php
}
echo $this->Js->writeBuffer();
?>
</tbody>
</table>
Ok so I manage to solve my problem and it is ridiculously simple : I deleted the initButtonPrint() and grayLine(lineId) functions which were useless and instead I did this using jQuery (thanks to Gurpreet Janjua) :
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.button-print').click(function(){
$(this).parent().parent().css('background','grey');
print();
});
});
</script>
The problem was that I declared my button with id instead of class.
Big thank you to Sun Liren, N Muhammed Thamjeed and everyone who replied to me
may be it's help you :
<table class="table table-hover" id="mytable" >
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Print</th>
</tr>
</thead>
<tbody>
<br/>
<?php
for ($i=0; $i<$lineNumber; $i++)
{
?>
<tr>
<td><?php echo $mytable[$i]['Data']['Column 1']; ?></td>
<td><?php echo $mytable[$i]['Data']['Column 2']; ?></td>
<td><input type="button" class="button-print" value="Print"/></td>
</tr>
<?php
}
echo $this->Js->writeBuffer();
?>
</tbody>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.button-print').click(function(){
$(this).parent().parent().css('background','grey');
});
});
</script>
in this code,when you click on print button then that row background will be grey..