Print button in Javascript - javascript

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..

Related

How can I optimally load a web page that is a big table, centering the viewport on a specific row of that table?

I would like to create a web page that is a giant table (a ranking table) with millions of rows.
The table attributes should be the row number, a little image, a username and another number (indicating a score).
When loading the page it should instantly center and starting to load the table from the row associated to the currently logged in user.
So here are my two questions:
What is the best way to center the starting viewport on the current logged in user row?
If an user is in a very low position he would have to wait until all the upper rows are ready, so what should i do to optimize the loading times? Maybe there is a way to load only the rows that are near the viewport of the user?
Here's an example of what I was trying to do (using Bootstrap for the table classes). I was simply putting the id="scrollpoint" on the current username row, so it is centered when i go to table.php#scrollpoint, this surely is not a nice solution, and I don't know at all how to solve the slow loading problems:
<table class="table">
<thead>
<tr>
<th class="sticky-top bg-success" scope="col">#</th>
<th class="sticky-top bg-success" scope="col">IMG</th>
<th class="sticky-top bg-success" scope="col">USERNAME</th>
<th class="sticky-top bg-success" scope="col">POINTS</th>
</tr>
</thead>
<tbody>
<?php
$i = 1;
while ($i <= $num_rows) {
if ($_SESSION['username'] == $row['username']) {
?>
<tr class="table-light" id="scrollpoint">
<th scope="row"><?php echo $i; ?></th>
<td><img src="img.png"></td>
<td><?php echo $row['username'] ?></td>
<td><?php echo $row['points'] ?></td>
</tr>
<?php } else { ?>
<tr>
<th scope="row"><?php echo $i; ?></th>
<td><img src="img.png"></td>
<td><?php echo $row['username'] ?></td>
<td><?php echo $row['points'] ?></td>
</tr>
<?php
}
$i++;
}
?>
</tbody>
</table>
Thanks for the help, and sorry if not very clear, english is not my primary language.

Having trouble getting jquery tabledit plugin to work on multiple tables

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

Uncaught TypeError: scrollIntoView is not a function

I can't figure out why, but scrollIntoView() function doesn't work. The browser displays an error: Uncaught TypeError: element.scrollIntoView is not a function at .... The element element is defined and displayed in console. I haven't been able to find any answer in the Internet. Below is simplified code:
[...]
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Surname</th>
</tr>
</thead>
<tbody>
<?php
if (is_array($array)) {
foreach ($array as $element) { ?>
<tr data-someid="<?= $element->some_id ?>">
<th><?= $element->id ?></th>
<td><?= $element->name ?></td>
<td><?= $element->surname ?></td>
</tr>
<?php }
} ?>
</tbody>
</table>
[...]
<script>
var element= document.querySelectorAll('[data-someid="' + someId + '"]');
console.log(element); // displays the element well
element.scrollIntoView();
</script>
[...]
Do somebody have any ideas why it doesn't work?
document.querySelectorAll() returns a list of DOM elements. Right now you're trying to access a method .scrollIntoView on the returned NodeList which of course doesn't exist.
You probably meant to use document.querySelector() which returns a single element.

jquery filter on table works first time but after that hides all rows

I've created a filter to show only rows containing td's with the value selected from a dropdown. The filter works fine first time but second time i run it, all rows dissapear and I cant figure out why.
This is my filter:
$(document).ready(function(){
$('select[name=selectedName]').change(function() {
$('tr').filter(function () {
return $(this).find('td.userName').filter(function () {
return $(this).text().indexOf($('select[name=selectedName]').val()) == -1;
}).length;
}).hide();
});
});
The drop down:
$query = "SELECT user_name FROM users";
$result = mysql_query($query); ?>
<select name="selectedName" id="userSelected">
<option value="" disabled selected>user name</option>
<?php while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) { ?>
<option value="<?php echo $line['user_name'];?>">
<?php echo $line['user_name'];?>
</option>
<?php } ?>
</select>
And finally the creation of the table:
<table class="table table-bordered table-hover" ng-controller="tableCtrl">
<thead>
<th>user name</th>
<th>script name</th>
<th>cron format<span class="glyphicon glyphicon-question-sign"></span></th>
<th>schedule last update</th>
<th>next execution time</th>
<th>script exec</th>
</thead>
<tbody ng-repeat="(user_id,script_id) in data">
<tr ng-repeat="(script_id, cron_format) in script_id">
<td class="userName">{{user(user_id)}}</td>
<td class="scriptName">{{script(script_id)}}</td>
<td class="cronFormat"><span contenteditable="true" ng-repeat="l in letters(cron_format) track by $index">{{l}}</span></td>
<td>{{compare(user_id,script_id,cron_format)[0]}}</td> <!--[0] represents scheduler last update-->
<td>{{compare(user_id,script_id,cron_format)[1]}}</td> <!--[1] represents next execution time-->
<td>{{compare(user_id,script_id,cron_format)[2]}}</td> <!--[2] represents script_exec-->
</tr>
</tbody>
</table>
Any idea why is it happening? Thanks for helping...
UPDATE
i added $('tr').show(); and function works except, how can i add value in dropdown to show the all table/cancel the filter?
You take care of hiding rows, but you never show them back. This is why your table sooner or later will have all rows invisible.

multiple child rows in datatable

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>

Categories