Adding a table stops js show/hide from working - javascript

I have a show/hide function on a web page where I want to improve the layout, but when I added a new table to put in headers for the data, the show/hide stopped working.
A snippet of the original code is:
<table id="cart-list">
<div class="col-sm-12 col-md-12 col-lg-12 col-xl-12">
<tr class="cl-group">
<td class="cl-sh" title="Show [+] or Hide [-] this lists' products"> </td>
<td colspan="2">Cart List One:
<table id="cl-chg-1" class="cl-other cl-chg">
<tr>
<td>List Name:</td>
<td><input type="text" name="group_name[1]" value="Cart List One" maxlength="255" /></td>
</tr>
<tr>
<td>List Comments:</td>
<td><input type="text" name="group_comments[1]" maxlength="255" /></td>
</tr>
<tr>
<td><button type="button" onclick="cancelGroupEdit();">Cancel</button></td>
<td><button type="submit" name="change" value="1">Go</button></td>
</tr>
</table>
</td>
</tr>
</div>
<tr>
<td>Stuff Here</td>
</tr>
<tr>
<td>Stuff Here</td>
</tr>
</table>
And the js used is
var groups = document.getElementsByClassName("cl-sh");
if (groups) {
for (var i = 0; i < groups.length; i++) {
groups[i].onclick = function() {
this.classList.toggle('cl-a');
var productsDisplay = '';
if (this.classList.contains('cl-a')) {
productsDisplay = 'none';
}
var nextRow = this.parentNode.nextElementSibling;
while (nextRow) {
if (nextRow.classList.contains('cl-group')) {
break;
}
nextRow.style.display = productsDisplay;
nextRow = nextRow.nextElementSibling;
}
}
}
}
A fiddle can be seen here: https://jsfiddle.net/65j1nvpq/1/
The broken function with the additional table code added can be seen here: https://jsfiddle.net/cmgqeLf7/
I don't really understand why having an additional table is breaking the function.
Any suggestions on a fix for this?

What does your JS function do when you click on the +/- cell?
Firstly, it toggles whether the clicked cell contains the cl-a class. Then, it runs through all remaining rows in the same table, showing or hiding them as appropriate, until it finds a row with the class cl-group, or hits the end of the rows in that table.
Note the word same in the last paragraph.
In your first fiddle, you have one table. In your second fiddle, you have two, and the rows you wish to toggle the display of are not in the same table as the toggle button. This is why they are not showing/hiding when you click the toggle button.
I'm not sure exactly what your requirements for showing/hiding rows are, so I'm not going to propose a fix. However, understanding what the problem is may help you to find a fix for yourself.

Related

Click elsewhere and checkbox is ticked/unticked [duplicate]

This question already has answers here:
What do querySelectorAll and getElementsBy* methods return?
(12 answers)
Closed 1 year ago.
So I have a piece of code to create a table with some data in it. The first column contains checkboxes, other columns are just regular data.
What I want is that when I click anywhere on a random row (except for header), that entire row's background is turning into yellow (initially white) and the checkbox in that row is ticked. If I click again, everything in the row back to its normal (white row and unticked checkbox).
When I click right at the checkbox, everything acts as expected. However, when I click elsewhere, only the background is changed. I have checked the checked attribute of the checkbox and it is changed whenever I click (which is like normal). I don't know why this happens. I have looked through many posts with similar issues but it is not helped. I am only a beginner at Javascript and HTML. Please help me with this. Thank you very much!
function changeColorRow(number) {
var elem = document.getElementsByTagName("tr")[number]
var curr_check = document.getElementsByClassName("checkbox").checked
if (!curr_check) {
elem.style.backgroundColor = "yellow"
document.getElementsByClassName("checkbox").checked = true
} else {
elem.style.backgroundColor = "white"
document.getElementsByClassName("checkbox").checked = false
}
}
<h1>List of companies</h1>
<table id="company">
<tr>
<th>Choose</th>
<th>ID</th>
<th>Company</th>
<th>Website</th>
</tr>
<tr onclick="changeColorRow(1)">
<td><input type="checkbox" class="checkbox"></td>
<td>1</td>
<td>ECOPRO Co., Ltd</td>
<td>http://www.ecoprovn.com</td>
</tr>
<tr onclick="changeColorRow(2)">
<td><input type="checkbox" class="checkbox"></td>
<td>2</td>
<td>WAVINA.COM</td>
<td>http://www.wavina.com</td>
</tr>
</table>
document.getElementsByClassName returns an array like structure, You have to use index to get that particular element at that index.
document.getElementsByClassName("checkbox")
You can get the index of the clicked row as
index = number - 1
const allCheckbox = document.getElementsByClassName("checkbox");
function changeColorRow(number) {
const index = number - 1;
var elem = document.getElementsByTagName("tr")[number]
var curr_check = document.getElementsByClassName("checkbox")[index].checked
if (!curr_check) elem.style.backgroundColor = "yellow"
else elem.style.backgroundColor = "white"
allCheckbox[index].checked = !allCheckbox[index].checked
}
[...allCheckbox].forEach(cb => {
cb.addEventListener("change", (e) => changeColorRow(parseInt(e.target.dataset.index)))
})
tr {
cursor: default;
user-select: none;
}
<h1>List of companies</h1>
<table id="company">
<tr>
<th>Choose</th>
<th>ID</th>
<th>Company</th>
<th>Website</th>
</tr>
<tr onclick="changeColorRow(1)">
<td><input type="checkbox" class="checkbox" data-index="1"></td>
<td>1</td>
<td>ECOPRO Co., Ltd</td>
<td>http://www.ecoprovn.com</td>
</tr>
<tr onclick="changeColorRow(2)">
<td><input type="checkbox" class="checkbox" data-index="2"></td>
<td>2</td>
<td>WAVINA.COM</td>
<td>http://www.wavina.com</td>
</tr>
</table>

How do I highlight a table row when checkbox is selected? Angular 7

So let's skip the the table headers to my table body. I have a populated table:
HTML:
<tbody>
<tr *ngFor="let e of emails; let i = index">
<td <input type="checkbox" id="email-checkbox" (change)="addToSelectedList($event, e)"></input></td>
<td id="subject-{{i}}">{{e.sender}}</td>
<td id="subject-{{i}}">{{e.subject}}</td>
<td id="subject-{{i}}">{{e.date}}</td>
</tbody>
I want the table whole row to display a CSS class when the user checks the checkbox. And then the color should go back to normal when the user deselects. Just UI stuff to show the user that an email has been selected. I currently have an empty CSS and .ts file.
The way you have done it here is more involved because presumably you have some logic inside addToSelectedList event that will add/remove the email depending on the checked state. The easiest way is to add a property on the email entity isSelected, and do this:
<input ... [checked]="e.isSelected" >
On your tr add the ngclass binding as suggested by others as follows:
<tr [ngClass]="{ 'selectedcssclass' : e.isSelected }"...
Other observation in your code there isn't a closing tr that should be wrapping around all the tds.
Not an Angular expert, but you can achieve just that using a JS onchange event bound to your checkbox:
$(".box").on("change", function() {
$(this).parents("tr").toggleClass("highlight");
});
.highlight {
background-color: #ffff00;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>Label 1</td>
<td><input type="checkbox" class="box"/></td>
</tr>
<tr>
<td>Label 2</td>
<td><input type="checkbox" class="box"/></td>
</tr>
</table>

Change button text of a cloned element

Making an food ordering app. There is a first table with all items you can choose. Each item have a button. On this button click it clones the line and put it in a second table containing your chosen items. I would like to change the text content of the button when the element go to the second table. Like "+" in the first table become "-" in the second table (to next delete the item of the second table on "-" click)
HTML
<h1>CHOOSE</h1>
<table id="starters">
<tr>
<th>PRODUCT</th>
<th>PRICE</th>
<th>ADD TO CART</th>
</tr>
<tr>
<td>Cherry</td>
<td>6</td>
<td><button class="item_button">+</button></td>
</tr>
<tr>
<td>Peach</td>
<td>8</td>
<td><button class="item_button">+</button></td>
</tr>
<tr>
<td>Strawberry</td>
<td>12</td>
<td><button class="item_button">+</button></td>
</tr>
</table>
<h1>YOUR CHOICE</h1>
<table id="products_cart">
</table>
JS
let basket = document.getElementById("products_cart")
let buttons = document.querySelectorAll('.item_button');
for (button of buttons) {
button.addEventListener('click', cloneLine);
}
function cloneLine(e) {
let td = e.target.parentNode;
let tr = td.parentNode;
let clone = tr.cloneNode(true);
basket.appendChild(clone);
}
I tried different things like to get (querySelectorAll) the buttons and change their innerHTML (or textContent or innerText) with no success. I also tried to create another button and to replace the former by the newer.

Clone a <tr> and modify the clone's content in JavaScript / jQuery

I'm stuck with a problem. I currently have a simple <table> that looks like this:
<table class="table">
<tbody>
<tr id="kc_keychain_1">
<td class="td-kc-id"> kc_keychain_1 </td>
<td class="td-kc-name"> Keychain 1 </td>
<td>
<p>my key</p>
<p>my second key</p>
</td>
</tr>
<tr id="kc_keychain_10">
<td class="td-kc-id"> kc_keychain_10 </td>
<td class="td-kc-name"> Keychain 10</td>
<td>
<p>ma clé</p>
<p>Clé 005V</p>
</td>
</tr>
</tbody>
</table>
I also have some JavaScript code, that aims at cloning a specific row, modifying the .tc-kc-id and .tc-kc-name cells of the cloned row, and finally adding the cloned and modified row to the table:
var clonedTr = document.querySelector('#' + id).cloneNode(true);
//$(clonedTr).find(".td-kc-id").innerText = "test";
//$(clonedTr).find(".td-kc-name").innerText = "test";
document.querySelector('tbody').appendChild(clonedTr);
It clones and adds the cloned row without any problem. But the commented code doesn't work. What I try in the commented code is to get specific cells thanks to their classname, and then change their innerText property.
But the innerText of the cells remain unchanged. Can anyone help me? Thanks
Thanks to #ChrisG, a possible working solution is:
$(clonedTr).find(".td-kc-id").text("test");

jquery cloned button action not working

i have a table with add/remove buttons, those buttons add and remove rows from the table, the buttons are also added with each new row
here what i have as html
<table>
<tr>
<th>catalogue</th>
<th>date</th>
<th>add</th>
<th>remove</th>
</tr>
<- target row ->
<tr id="cat_row">
<td>something</td>
<td>something</td>
<td><input id="Add" type="button" value="Add" /></td>
<td><input id="Remove" type="button" value="Remove" /></td>
</tr>
</- target row ->
</table>
JavaScript:
$("#Add").click(function() {
$('#cat_row').after('<- target row with ->'); // this is only a notation to prevent repeatation
id++;
});
$("#Remove").click(function() {
$('#cat_'+id+'_row').remove();
id--;
});
Please note that after each addation of a new row the id is also changed for example here after clicking the button "Add" 1 time
<table>
<tr>
<th>catalogue</th>
<th>date</th>
<th>add</th>
<th>remove</th>
</tr>
<tr id="cat_row">
<td>something</td>
<td>something</td>
<td><input id="Add" type="button" value="Add" /></td>
<td><input id="Remove" type="button" value="Remove" /></td>
</tr>
<tr id="cat_1_row">
<td>something</td>
<td>something</td>
<td><input id="Add" type="button" value="Add" /></td>
<td><input id="Remove" type="button" value="Remove" /></td>
</tr>
</table>
now the new added Buttons has no actions i must always click on the original buttons - add/remove
after this i want to make the Remove Button removes ONLY the row where it is clicked on
for example if i click the button in row 2, row 2 will be deleted
Info:
I use web2py 2.2.1 with python 2.7 with the last version of jQuery
I think it would be better instead of:
$('#cat_'+id+_row').remove();
Do this in your onclick event:
$(this).parent().parent().remove();
You can't have two buttons with the same id (you're using duplicates for both "Add" and "Remove"). id values must be unique on the page.
You might look at using a class instead, and also look at event delegation. For instance, assuming this is the only table on your page (if not, just make the selector more specific), if you change your buttons to have classes "add-btn" and "remove-btn" instead of id values, then you can use delegate:
$("table").delegate(".add-btn", "click", function() {
// An add button was pressed, you can find out which
// row like this:
var row = $(this).closest('tr');
});
...and similarly for the .remove-btn button.
Alternately, some prefer to use on (note the order of arguments is slightly different):
$("table").on("click", ".add-btn", function() {
// An add button was pressed, you can find out which
// row like this:
var row = $(this).closest('tr');
});
Which you use is currently a matter of style. I prefer delegate for clarity, but the jQuery team love to hyper-overload their functions. So far they haven't deprecated delegate, though they do call it "superceded."

Categories