My first thought was to set the input checked = "javascript function() true/false" is this possible?
What I am trying to do is a select all checkbox for my forum mailbox system.
I am useing a table to display the inbox and placed the select all checkbox inside.
<form action="" method = "post">
<table rules="all">
<tr>
<th>
<input type="checkbox" id = "setchecked" name="smessgage"value="deleteall" onclick="get_checked()"/>
</th>
<th>From</th>
<th>Subject</th>
<th>Date</th>
</tr>
I use
onclick="get_checked()
to call this javascript function which sets the other checkboxes checked attribute.
<script>
function get_checked()
{
if(document.getElementById("setchecked").checked)
{
for(var i = 0; i < 100;++i)
{
var check_id = "smessage"+i;
if(document.getElementById(check_id))
document.getElementById(check_id).checked = true;
}
}
else
{
for(var i = 0; i < 100;++i)
{
var check_id = "smessage"+i;
if(document.getElementById(check_id))
document.getElementById(check_id).checked = false;
}
}
}
</script>
The php to set the table up looks like this.
$i = 0;
while($row = mysqli_fetch_assoc($result))
{
if(isset($row['to_']) && $row['to_'] == $_SESSION['user_name'])
{
$id_ = isset($row['id']) ? $row['id'] : '';
$top_ = isset($row['subject']) ? $row['subject'] : '';
$auth_ = isset($row['from_']) ? $row['from_'] : '';
$date_ = isset($row['date']) ? $row['date'] : '';
echo '<tr id = "cat_" name = "cat_1">
<td style = "margin:0 auto; text-align:center;"><input type="checkbox" id = "smessage'.$i.'" name="smessgage" value="'.$id_.'"/></td>
<td style = "margin:0 auto; text-align:center;"><a href = "mail?from='.$auth_.'&mail_id='.$id_.'&mail_name='.$top_.'">'.
$auth_.'</a></td>
<td style = "margin:0 auto; text-align:center;"><a href = "mail?from='.$auth_.'&mail_id='.$id_.'&mail_name='.$top_.'">'.
$top_.'</a></td>
<td style = "margin:0 auto; text-align:center;"><a href = "mail?from='.$auth_.'&mail_id='.$id_.'&mail_name='.$top_.'">'.
time_elapsed_string($date_,true).'</a></td></tr>';
++$i;
}
}
This works as expected but seems a bit overkill. I just want to know if there is a more relastic approach or something that I missed while looking over input types?
Here is your improved version. Basically you just need to use same class for all checkbox before each line of your message, so that you can use jQuery.each() function to select all and toggle the checked property based on your main checkbox, which has id "setchecked"
Hope this help,
KD Quality
function checkAll(bx) {
var cbs = jQuery(".checkbox_class").each(function() {
jQuery(this).prop('checked', jQuery('#setchecked').prop('checked'));
});
}
var e = document.getElementById('setchecked'); e.onclick = checkAll;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form action="" method="post">
<table rules="all">
<tr>
<th>
<input type="checkbox" id="setchecked" name="smessgage" value="deleteall" />
</th>
<th>From</th>
<th>Subject</th>
<th>Date</th>
</tr>
<tr>
<td>
<input type="checkbox" name="messgage[]" value="message_1" class="checkbox_class" />
</td>
<td>Message 1</td>
<td>Message 1</td>
<td>Some Date</td>
</tr>
<tr>
<td>
<input type="checkbox" name="messgage[]" value="message_2" class="checkbox_class" />
</td>
<td>Message 1</td>
<td>Message 1</td>
<td>Some Date</td>
</tr>
<tr>
<td>
<input type="checkbox" name="messgage[]" value="message_3" class="checkbox_class" />
</td>
<td>Message 1</td>
<td>Message 1</td>
<td>Some Date</td>
</tr>
</table>
</form>
You could do something like this
// The important code
function selectAll(e) {
var nodes = document.querySelectorAll('form input[type=checkbox]');
for(var i = 0; i < nodes.length; i++) {
nodes[i].checked = e.target.checked;
};
}
// This is only code to genereate input elements
var form = document.getElementById('foo');
for (var i = 0; i < 15; i++) {
var input = document.createElement('input');
input.type = "checkbox";
form.appendChild(input);
}
<input id="selectall" type="checkbox" onclick="selectAll(event)" />
<label for="selectall">Select all</label>
<hr />
<form id="foo"></form>
Related
I have this html table and 2 textboxes:
<table id="myTbl">
<thead>
<tr>
<th>A</th>
<th>B</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
</tr>
</tbody>
</table>
<input type="text" name="txt" id="txt" >
<input type="text" name="txt" id="txt2" >
I want when reload the page, the values 1 and 2 must display in each textbox. How can I do it?
I have tried this js code but wrong and I want it auto display, not to click it:
var cells = document.querySelectorAll('#myTbl tbody ');
Array.from(cells).forEach(function (elem) {
elem.addEventListener('click', function () {
document.getElementById('txt').value = this.textContent;
})
})
var tbody = document.getElementsByTagName('tbody')[0]
var input1 = document.getElementById('txt')
var input2 = document.getElementById('txt2')
input1.value = tbody.getElementsByTagName('td')[0].textContent
input2.value = tbody.getElementsByTagName('td')[1].textContent
I have a table with three columns: id, price and a checkbox. I want to parse the table to JSON but only include rows with a checked checkbox. However, my code throws Uncaught TypeError: Cannot read properties of undefined (reading 'type') in this line: if (ele[i].type == 'checkbox' && ele[i].checked == true). Where am I going wrong?
const btn = document.getElementById("click");
btn.addEventListener("click", function() {
tableToJson(table);
})
let table = document.getElementById("myTable");
function tableToJson(table) {
let data = [];
const ele = document.querySelectorAll(".myCheckbox");
// first row needs to be headers
let headers = [];
for (i = 0; i < table.rows[0].cells.length; i++) {
headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi, '');
}
// go through cells
for (i = 1; i < table.rows.length; i++) {
if (ele[i].type == 'checkbox' && ele[i].checked == true) {
let tableRow = table.rows[i];
let rowData = {};
for (j = 0; j < tableRow.cells.length; j++) {
rowData[headers[j]] = tableRow.cells[j].innerHTML;
}
data.push(rowData);
}
}
console.log(data);
return data;
}
<body>
<button id="click">Click</button>
<table id="myTable">
<thead>
<tr>
<th>Id</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>AAA</td>
<td>12.81</td>
<td><input type="checkbox" class="myCheckbox" checked></td>
</tr>
<tr>
<td>BBB</td>
<td>1.06</td>
<td><input type="checkbox" class="myCheckbox" checked></td>
</tr>
<tr>
<td>CCC</td>
<td>1.89</td>
<td><input type="checkbox" class="myCheckbox" checked></td>
</tr>
<tr>
<td>DDD</td>
<td>1.94</td>
<td><input type="checkbox" class="myCheckbox" checked></td>
</tr>
<tr>
<td>EEE</td>
<td>3.61</td>
<td><input type="checkbox" class="myCheckbox" checked></td>
</tr>
</tbody>
</table>
</body>
As you're iterating on ele.length you should use ele[i].type == 'checkbox'.
Other than that, since you have 5 checkboxes and 6 rows, when you read tableRow you need to add a + 1 otherwise you'll select the wrong row.
In your current code, if you select the first element (index 0) you get the header row (index 0) while you should take index 1 instead.
let tableRow = table.rows[i+1];
const btn = document.getElementById("click");
btn.addEventListener("click", function() {
tableToJson(table);
})
let table = document.getElementById("myTable");
function tableToJson(table) {
let data = [];
const ele = document.querySelectorAll(".myCheckbox");
// first row needs to be headers
let headers = [];
for (i = 0; i < table.rows[0].cells.length; i++) {
headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi, '');
}
// go through cells
for (i = 0; i < ele.length; i++) {
if (ele[i].type == 'checkbox' && ele[i].checked == true) {
let tableRow = table.rows[i+1];
let rowData = {};
for (j = 0; j < tableRow.cells.length; j++) {
rowData[headers[j]] = tableRow.cells[j].innerHTML;
}
data.push(rowData);
}
}
console.log(data);
return data;
}
<body>
<button id="click">Click</button>
<table id="myTable">
<thead>
<tr>
<th>Id</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>AAA</td>
<td>12.81</td>
<td><input type="checkbox" class="myCheckbox" checked></td>
</tr>
<tr>
<td>BBB</td>
<td>1.06</td>
<td><input type="checkbox" class="myCheckbox" checked></td>
</tr>
<tr>
<td>CCC</td>
<td>1.89</td>
<td><input type="checkbox" class="myCheckbox" checked></td>
</tr>
<tr>
<td>DDD</td>
<td>1.94</td>
<td><input type="checkbox" class="myCheckbox" checked></td>
</tr>
<tr>
<td>EEE</td>
<td>3.61</td>
<td><input type="checkbox" class="myCheckbox" checked></td>
</tr>
</tbody>
</table>
</body>
first I do not know where you aré importing your js.
Second javascript Is faster than the dom so by the time you r js gets into if (ele[i].type == 'checkbox' && ele[i].checked == true) your dom Is not rendered yet. Thats y it breaks you need to wait for your dom to be rendered.
document.addEventLidtener("DOMContentLoaded", e=>{
// Add your code here
});
i have a list of rows and columns. basically the first_value and second_value column is an input type where the user can enter and the total column is a span. how can i add the first_value and second_value column to its specific row?
ID| first_value | second value | total
1 0 50 50
2 20 0 20
3 10 0 10
4 20 10 30
5 10 0 10
here is my html/php code
<table class="table table-striped" id="user_set_goal_table" width="100%">
<thead>
<tr>
<th>#</th>
<th>First_value</th>
<th>Second_value</th>
<th>total</th>
</thead>
<tbody>
for($i=1;$i<=16;$i++){
?>
<tr>
<td><?php echo $i; ?></td>
<td><?php echo "<input type='text' class='navigate_TD_ID' id='first_value".$i."' "; ?></td>
<td><?php echo "<input type='text' class='navigate_TD_ID' id='second_value".$i."' "; ?></td>
<td><?php echo "<span id='total".$i." '></span>"?></td>
</tr>
<?php
}
</tbody>
javascript code:
$('.navigate_TD_ID').on('change', function() {
var input_id = $(this).attr('id');
alert(input_id);
});
i can already get which id the user click on TD but i dont know how will i implement this calculations, i mean how can i calculate and display to its specific position in row. any help would be really appreciated.
To achieve this you can use jQuery's DOM traversal methods to find the span relative to the input that raised the event. Specifically, use the this reference along with closest() and find().
Also note that it's better practice to use common classes on repeated content, instead of generating dynamic id attributes. Try this:
$('.first, .second').on('input', function() {
var $tr = $(this).closest('tr');
var f = parseFloat($tr.find('.first').val()) || 0;
var s = parseFloat($tr.find('.second').val()) || 0;
$tr.find('.total').text(f + s);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-striped" id="user_set_goal_table" width="100%">
<thead>
<tr>
<th>#</th>
<th>First_value</th>
<th>Second_value</th>
<th>total</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td><input type="text" class="navigate first" /></td>
<td><input type="text" class="navigate second" /></td>
<td><span class="total"></span></td>
</tr>
<tr>
<td>2</td>
<td><input type="text" class="navigate first" /></td>
<td><input type="text" class="navigate second" /></td>
<td><span class="total"></span></td>
</tr>
</tbody>
</table>
Quick example with vanilla js and without PHP
<table class="table table-striped" id="user_set_goal_table" width="50%">
<thead style="text-align:left;">
<tr>
<th>#</th>
<th>First_value</th>
<th>Second_value</th>
<th>total</th>
</thead>
<tbody>
</tbody>
</table>
<script>
// table body
let tbody = document.querySelectorAll('table tbody')[0];
// trs
let rows = tbody.children;
// fill table body
for(let j = 0; j < 16; j++)
{
tbody.innerHTML += `
<td>${j}</td>
<td><input type="text" class="first"></td>
<td><input type="text" class="second"></td>
<td><span></span></td>
`;
}
for(let i = 0; i < rows.length; i++)
{
let firstInput = rows[i].children[1].firstElementChild;
let secondInput = rows[i].children[2].firstElementChild;
let total = rows[i].children[3].firstElementChild;
[firstInput, secondInput].forEach((elem) => {
elem.addEventListener('input' ,(e) => {
let first = e.target.value;
let second = (e.target.className == "first") ? secondInput.value : firstInput.value;
total.innerText = parseFloat(first) + parseFloat(second);
});
});
}
Result:
I have a row click event. Recently had to add a checkbox to each row. How can I identify the clicked cell on row click event?
Or prevent row click when clicked on the checkbox.
Attempts: this.parentNode.cellIndex is undefined on the row click event.
function pop(row){
alert(row.cells[1].innerText);
}
<table style="width:100%">
<tr>
<th>Select</th>
<th>Site</th>
</tr>
<tr onclick="pop(this);">
<td><input type="checkbox" id="123456" /></td>
<td>Lonodn</td>
</tr>
</table>
Do you want something like this? You can just check the type attribute of the source element of the event and validate whether to allow it or not, you can stop the event using e.stopPropagation();return;.
function pop(e, row) {
console.log(e.srcElement.type);
if(e.srcElement.type === 'checkbox'){
e.stopPropagation();
return;
}else{
console.log(row);
alert(row.cells[1].innerText);
}
}
<table style="width:100%">
<tr>
<th>Select</th>
<th>Site</th>
</tr>
<tr onclick="pop(event, this);">
<td><input type="checkbox" id="123456" /></td>
<td>Lonodn</td>
</tr>
</table>
You should pass in the event details to your function and check the target property:
function pop(e){
// If the target is not a checkbox...
if(!e.target.matches("input[type='checkbox']")) {
alert(e.target.cellIndex);
}
}
<table style="width:100%">
<tr>
<th>Select</th>
<th>Site</th>
</tr>
<tr onclick="pop(event)">
<td><input type="checkbox" id="123456" /></td>
<td>Lonodn</td>
</tr>
</table>
Note: If you have nested elements inside the <td>, you might want to check e.target.closest("td") instead.
Note 2: You might need a polyfill for the matches method depending on which browsers you're supporting.
Here is an example if you don't want to attach a listener on every row :
document.getElementById("majorCities").addEventListener("click", function(e){
if(e.target.type === 'checkbox'){
var checked = e.target.checked;
var tr = e.target.parentElement.parentElement;
var city = tr.cells[1].innerHTML;
console.log(city+":checked="+checked);
}
});
<table id="majorCities" style="width:100%">
<tr>
<th>Select</th>
<th>Site</th>
</tr>
<tr>
<td><input type="checkbox"/></td>
<td>London</td>
</tr>
<tr>
<td><input type="checkbox"/></td>
<td>Paris</td>
</tr>
<tr>
<td><input type="checkbox"/></td>
<td>New-York</td>
</tr>
</table>
window.pop = function(row){
console.log('here');
var parent = row.parentNode;
Array.from(row.parentNode.querySelectorAll('tr')).forEach(function(tr, index){
if (tr === row) {
alert(index)
}
})
}
https://jsfiddle.net/sz42oyvm/
Here is for the pleasure, another example with an object containing the cities' names and a method to draw the table with ids corresponding to the name of the clicked city, so getting the clicked name is easier.
(function () {
var mySpace = window || {};
mySpace.cities = {};
mySpace.cities.pointer = document.getElementById("majorCities");
mySpace.cities.names = ["Select","City"];
mySpace.cities.data = [{"name":"Paris"},{"name":"New Delhi"},{"name":"Washington"},{"name":"Bangkok"},{"name":"Sydney"}];
mySpace.cities.draw = function(){
this.pointer.innerHTML="";
var html = "";
html+="<tr>"
for(var i=0;i < this.names.length;i++){
html+="<th>"+this.names[i];
html+="</th>"
}
html+="</tr>"
for(var i=0;i < this.data.length;i++){
html+="<tr>"
html+="<td><input id='"+this.data[i].name+"' type='checkbox'/></td>"
html+="<td>"+this.data[i].name+"</td>"
html+="</tr>"
}
this.pointer.innerHTML=html;
}
mySpace.cities.draw();
mySpace.cities.pointer.addEventListener("click", function(e){
if(e.target.type === 'checkbox'){
var checked = e.target.checked;
var city = e.target.id;
console.log(city+":checked="+checked);
}
});
})();
table {width:25%;background:#ccc;border:1px solid black;text-align:left;}
td,tr {background:white;}
th:first-of-type{width:20%;}
<table id="majorCities">
</table>
How to modify the code to add row in the table dynamically by using javascript?
This is my existing code which is having other functionality. Need one button below the table to add row. I don't need a pop-up which will say how many rows do you want to add. Every single hit will add extra row.
Javascript
var editing = false;
function catchIt(e) {
if (editing) return;
if (!document.getElementById || !document.createElement) return;
if (!e) var obj = window.event.srcElement;
else var obj = e.target;
while (obj.nodeType != 1) {
obj = obj.parentNode;
}
if (obj.tagName == 'INPUT' || obj.tagName == 'A') return;
while (obj.nodeName != 'TD' && obj.nodeName != 'HTML') {
obj = obj.parentNode;
}
if (obj.nodeName == 'HTML') return;
var x = obj.innerHTML;
var y = document.createElement('input');
var z = obj.parentNode;
z.insertBefore(y, obj);
z.removeChild(obj);
y.value = x;
y.className = 'inp-edit';
y.onblur = saveEdit;
y.focus();
editing = true;
}
function saveEdit() {
var area = this;
var y = document.createElement('TD');
var z = area.parentNode;
y.innerHTML = area.value;
z.insertBefore(y, area);
z.removeChild(area);
editing = false;
}
document.onclick = catchIt;
HTML
<table border=1 class="display">
<thead>
<tr class="portlet-section-header results-header">
<th class="sorting">Operator ID</th>
<th class="sorting">Status</th>
<th class="sorting">First Name</th>
<th class="sorting">Last Name</th>
<th class="sorting">Email</th>
<th class="sorting">Role</th>
<th class="sorting_disabled">Select All
<br />
<input type="checkbox" onclick="checkAll(this);" name="check" />
</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Test1</td>
<td>Active</td>
<td>wsrc</td>
<td>wsrc</td>
<td>aa#aa.com</td>
<td>SE Admin</td>
<td>
<input type="checkbox" value="3" onclick="checkAllRev(this);" name="deleteItem" />
</td>
</tr>
<tr class="even">
<td>Test2</td>
<td>Inactive</td>
<td>EAI</td>
<td>SUBSYSTEM</td>
<td>aa#aa.com</td>
<td>API</td>
<td>
<input type="checkbox" value="4" onclick="checkAllRev(this);" name="deleteItem" />
</td>
</tr>
<tr class="odd">
<td>Test3</td>
<td>Inactive</td>
<td>Dunning</td>
<td>Portal</td>
<td>aa#aa.com</td>
<td>API</td>
<td>
<input type="checkbox" value="5" onclick="checkAllRev(this);" name="deleteItem" />
</td>
</tr>
</tbody>
</table>
You can make a template html for your row to be added, and append that html on click of the button.
For example, the row to be added contained two columns and looked some thing like this:
<tr>
<td>Test</td>
<td>Active</td>
</tr>
You can save this template in a variable. For example:
var template = "<tr><td>Test</td><td>Active</td></tr>";
Now append function of jQuery can be used to add row dynamically.
Since you need to add the row to tbody, following code can be used:
$("tbody").append(template);
A similar approach can be used to achieve your desired task.