C# MVC Deactivate (Disable) table row on click - javascript

I have a table whose values are looped in and a button in each row that I am attempting to use to deactivate that row if clicked:
<table id="categoryList" class="table">
<thead>
<tr>
<th>Category ID</th>
<th>Category Name</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Categories)
{
<tr>
<td>#item.id</td>
<td>#item.name</td>
<td><button class="btn btn-default pull-left" id="btn-deactivate">Deactivate</button></td>
</tr>
}
</tbody>
</table>
The rows are clickable at this point due to this javascript:
$("#categoryList > tbody > tr").click(function (event) {
$("#categoryModal #categoryId").val($(event.target).parent().children()[0].innerText);
$("#categoryModal #categoryName").val($(event.target).parent().children()[1].innerText);
$("#categoryModal .deleteButton").attr("href", $("#colDelUrl").val() + "?categoryId=" + $(event.target).parent().children()[0].innerText);
$("#categoryModal .deleteButton").show();
$("#categoryModal").modal({ show: true, backdrop: true });
});
The goal is to have the button deactivate (disable so it won't be clickable) the selected row when clicked and then reactivate the row on the second click.

Add active class at table rows.
<table id="categoryList" class="table">
<thead>
<tr>
<th>Category ID</th>
<th>Category Name</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Categories)
{
<tr class="active">
<td>#item.id</td>
<td>#item.name</td>
<td><button class="btn btn-default pull-left" id="btn-deactivate">Deactivate</button></td>
</tr>
}
</tbody>
</table>
make click on row active only if row has class="active":
$("#categoryList > tbody > tr.active").click(function (event) {
$("#categoryModal #categoryId").val($(event.target).parent().children()[0].innerText);
$("#categoryModal #categoryName").val($(event.target).parent().children()[1].innerText);
$("#categoryModal .deleteButton").attr("href", $("#colDelUrl").val() + "?categoryId=" + $(event.target).parent().children()[0].innerText);
$("#categoryModal .deleteButton").show();
$("#categoryModal").modal({ show: true, backdrop: true });
});
siwitch on/off click on rows by changing tr class:
$("#btn-deactivate").click(event)
{
var target = $( event.currentTarget );
var targetRow= target.closest( 'tr' );
if (targetRow.hasClass( "active" ))
{
targetRow.removeClass( "active" ).addClass( "inactive" );
}
else
{
targetRow.removeClass( "inactive" ).addClass( "active" );
}
}

Related

how to show table cell using js

description cells will starts as hide. The row that I click, will show the description and if i click another row will the current row description and hide the other description
var getTable = document.querySelector("tbody");
var cells = getTable.getElementsByTagName("td");
for (let item of document.getElementsByClassName("desc")) {
item.style.display = "none";
}
for (var i = 0; i < cells.length; i++) {
cells[i].addEventListener("click", function () {
var selectedRow =
getTable.getElementsByTagName("tr")[this.parentNode.rowIndex];
if (!this.parentNode.rowIndex) {
$(selectedRow).find(".desc").css("display", "none");
} else {
$(selectedRow).find(".desc").css("display", "block");
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tblInventory">
<thead>
<tr>
<th>UPC</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>987456</td>
<td>Product Blanks</td>
<td class="desc">Unfinished template for parts 1000222 to 1000299</td>
</tr>
<tr>
<td>654123</td>
<td>Threaded Rods</td>
<td class="desc">Rods threaded at both ends for Support Brackets</td>
</tr>
</tbody>
</table>
Try this in vanilla:
document.querySelector('#tblInventory').addEventListener('click', (e) =>
{
// Hide other descriptions
document.querySelectorAll('#tblInventory td.desc span').forEach(span => {
span.style.display = 'none';
});
// Show clicked row description
if (e.target.tagName === 'TD') {
e.target.parentNode.querySelector('td.desc span').style.display = 'inline';
}
});
#tblInventory td.desc span {
display: none
}
<table id="tblInventory">
<thead>
<tr>
<th>UPC</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>987456</td>
<td>Product Blanks</td>
<td class="desc"><span>Unfinished template for parts 1000222 to 1000299</span></td>
</tr>
<tr>
<td>654123</td>
<td>Threaded Rods</td>
<td class="desc"><span>Rods threaded at both ends for Support Brackets</span></td>
</tr>
</tbody>
</table>
Or with jQuery:
$('#tblInventory').on('click', 'td', (e) => {
// Hide other descriptions
$('#tblInventory td.desc span').hide();
// Show clicked row description
$(e.target).closest('tr').find('td.desc span').show();
});
#tblInventory td.desc span {
display: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<table id="tblInventory">
<thead>
<tr>
<th>UPC</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>987456</td>
<td>Product Blanks</td>
<td class="desc"><span>Unfinished template for parts 1000222 to 1000299</span></td>
</tr>
<tr>
<td>654123</td>
<td>Threaded Rods</td>
<td class="desc"><span>Rods threaded at both ends for Support Brackets</span></td>
</tr>
</tbody>
</table>
Using span is a suggestion, but you can fix the selectors to show/hide the td elements directly as well;
If you don't want to hide previous clicked descriptions, just remove the related code.

Get table row value based on button click using Jquery/Javascript

I need to get the table row value from onclick event. Below the table, I am using
Group name|Manage group
Test 1 | Button
Test 2 | Button
If I click 'Button' from the table row, I need to get the respective group name value from the table row.
Below the script, I am trying. But it is printing only the first group name value "Test 1" for both buttons.
var table = document.getElementById("user_table");
var rows = table.rows;
for (var i = 1; i < rows.length; i++) {
rows[i].onclick = (function (e) {
var rowid = (this.cells[0].innerHTML);
var j = 0;
var td = e.target;
while( (td = td.previousElementSibling) != null )
j++;
alert(rows[1].cells[j].innerHTML);
});
}
alert(rows[1].cells[j].innerHTML) printing group name value Test 1 and if I click second row button it is showing Test 1 only.But I need to get Test 2 if I click second row button.
Html file
<table id="user_table" style='overflow-x:scroll;overflow-y:scroll;width:100%;height:auto' class="table table-bordered" >
<thead>
<tr class="info">
<th>Group Name</th>
<th>User Group</th>
</tr>
</thead>
<tbody id="table_body">
<br>
<% #array.each do |user| %>
<tr>
<td >
<%=user['group_name']%>
</td>
<td>
<button id='manageusrbtn' name="button" type="button" class="editbtn" onclick="manageUserGroups()" style="background-color: #008CBA; color: white; border-radius: 6px;" >Manage User Groups</button>
</td>
<% end %>
</tr>
</tbody>
</table>
I would suggest to attach the click event handler to the button and not to each cell.
For this you can use:
querySelectorAll
forEach
addEventListener
closest
The snippet:
var table = document.querySelectorAll('#user_table tr button');
table.forEach(function(ele) {
ele.addEventListener('click', function (e) {
var rowid = (this.closest('td').previousElementSibling.innerHTML);
console.log(rowid);
})
});
<table id="user_table">
<tr>
<th>Group name</th>
<th>Manage group</th>
</tr>
<tbody>
<tr>
<td>Test 1</td>
<td><button>Button</button></td>
</tr> <tr>
<td>Test 2</td>
<td><button>Button</button></td>
</tr>
</tbody>
</table>

C# MVC Textbox on the specific table row (disable) when the button is clicked

I have a table whose values are looped with my product list and I have a textbox for 'Quantity' and a button for 'Add to Cart'. I am trying to do when I click on 'Add to Cart' button, it will check the Quantity value if it has value or not then the 'Quantity' textbox will get disabled for that specific row only.
Product.cshtml
<table id ="productList" class="table table-dark">
<tr>
<th>Product ID</th>
<th>Title</th>
<th>Description</th>
<th>Quantity</th>
<th>Add to cart</th>
</tr>
#foreach (var item in Model)
{
<tr class="active">
<td>#item.Id</td>
<td>#item.Title</td>
<td>#item.Description</td>
<td>#Html.TextBox("Quantity", "0", new { #class = "form-control" })</td>
<td><button class="btn btn-default pull-left" onclick="disableText(Quantity);" id="btn-addToCart">Add To Cart</button></td>
</tr>
}
</table>
javascript
function disableText(QtyVal) {
if(QtyVal.value == '')
{
document.getElementById("Quantity").value = 1;
}
}
Currently the output of my project is everytime I click any submit button, it will always update the first row (which is incorrect).
The goal is it will update the Quantity and disable it for that specific row
Your problem lies in this button definition:
<button class="btn btn-default pull-left" onclick="disableText(Quantity);" id="btn-addToCart">Add To Cart</button>
The foreach loop generates duplicate id attribute values for all buttons, which builds invalid HTML and causing undesired behavior. Since your table also contains <input> tag, you should use for loop instead of foreach and put distinct class name to the button, e.g. buttonadd:
<!-- assumed that #model List<Product> is used -->
<table id ="productList" class="table table-dark">
<tr>
<th>Product ID</th>
<th>Title</th>
<th>Description</th>
<th>Quantity</th>
<th>Add to cart</th>
</tr>
#for (int i = 0; i < Model.Count; i++)
{
<tr class="active">
<td>#Model[i].Id</td>
<td>#Model[i].Title</td>
<td>#Model[i].Description</td>
<td>#Html.TextBox("Quantity", "0", new { #class = "form-control" })</td>
<td><button type="button" class="btn btn-default pull-left buttonadd">Add To Cart</button></td>
</tr>
}
</table>
Then you can reference buttonadd class as selector to find out which row the button contained, and setting <input> state to readonly (not disabled because you want to send quantity values on form submit; all inputs with disabled attribute are not included during submit) as in example below:
$(document).on('click', '#productList .buttonadd', function () {
var row = $(this).closest('tr');
// find quantity text box in the same row as clicked button
var qty = row.find('input');
// set quantity value and prevent user input
qty.val(parseInt(qty.val()) + 1);
qty.attr('readonly', 'readonly');
});
Note: If you want to use strongly-typed helper, use #Html.TextBoxFor:
#Html.TextBoxFor(m => m[i].Quantity, new { #class = "form-control" })
Live example: .NET Fiddle
Since all of your textboxes have the same Id you cannot specify which one you are trying to update in your js. Try giving a unique ID to your TextBox then when you getElementById("UniqueID") you can ensure you are selecting the correct text box.
You just need to add bellow code at button click event
(this).prev('input').attr("disabled", "disabled")
Use a partial view, save some headache.
<table id ="productList" class="table table-dark">
<tr>
<th>Product ID</th>
<th>Title</th>
<th>Description</th>
<th>Quantity</th>
<th>Add to cart</th>
</tr>
#foreach (var item in Model)
{
#Html.Partial("~/Views/_OrderRowPartial.cshtml", item)
}
</table>
_OrderRowPartial.cshtml:
#model item
<tr class="active">
<td>#item.Id</td>
<td>#item.Title</td>
<td>#item.Description</td>
<td>#Html.TextBoxFor(m => m.Quantity, new { #class = "form-control quantity" })</td>
<td><button class="btn btn-default pull-left" onclick="disableText();">Add To Cart</button></td>
</tr>
Javascript:
function disableText(t, el) {
var qty = el.parentElement.previousElementSibling.getElementsByTagName('input')[0];
mytd.style.border = "1px solid #00FF00";
console.log(qty.value);
if (qty.value == '') {
qty.value = 1;
}
}
Here is an example where I set borders on stuff to make it obvious what is going on. Unclear if you want to disable input or button so I did both.
function disableText(t, el) {
el.style.border = "2px solid #FF0000";
var mytd = el.parentElement;
mytd.style.border = "1px solid #00FF00";
var mytr = mytd.parentElement;
var qtytd = mytd.previousElementSibling;
var qty = qtytd.getElementsByTagName('input')[0];
qtytd.style.border = "2px solid orange";
qty.style.border = "2px solid cyan";
console.log(qty.value);
if (qty.value == '') {
qty.value = 1;
}
// disable button
el.setAttribute("disabled", "disabled");
qty.setAttribute("disabled", "disabled");
}
<table id="productList" class="table table-dark">
<tr>
<th>Product ID</th>
<th>Title</th>
<th>Description</th>
<th>Quantity</th>
<th>Add to cart</th>
</tr>
<tr class="active">
<td>1234d</td>
<td>Cherry Pie</td>
<td>Gooey cherry pie</td>
<td><input type="text" class="form-control quantity" value="2" .>
<td><button class="btn btn-default pull-left" onclick="disableText('',this);">Add To Cart</button></td>
</tr>
<tr class="active">
<td>1234hd</td>
<td>Hot Dog</td>
<td>Dog, With mustard</td>
<td><input type="text" class="form-control quantity" /></td>
<td><button class="btn btn-default pull-left" onclick="disableText('',this);">Add To Cart</button></td>
</tr>
</table>

How to clone the Highlighted Row of one table to another Table by pressing Enter key

I have an HTML <table> with data. Upon clicking the table rows, I can add the clicked row to another table. But I want to highlight the row with arrow keys and, on pressing the Enter key on the highlighted row, add the data of the highlighted row to the new table.
How can I do that?
What I have tried so far:
$(document).ready(function(){
$('#myTable').focus();
});
function highlight(tableIndex) {
if ((tableIndex + 1) > $('#myTable tbody tr').length) //restart process
tableIndex = 0;
if ($('#myTable tbody tr:eq(' + tableIndex + ')').length > 0) {
$('#myTable tbody tr').removeClass('highlight');
$('#myTable tbody tr:eq(' + tableIndex + ')').addClass('highlight');
}
}
$('#goto_first').click(function() {
highlight(0);
});
$('#goto_prev').click(function() {
highlight($('#myTable tbody tr.highlight').index() - 1);
});
$('#goto_next').click(function() {
highlight($('#myTable tbody tr.highlight').index() + 1);
});
$('#goto_last').click(function() {
highlight($('#myTable tbody tr:last').index());
});
$(document).keydown(function(e) {
switch (e.which) {
case 38:
$('#goto_prev').trigger('click');
break;
case 40:
$('#goto_next').trigger('click');
break;
}
});
$(document).ready(function() {
var items = [];
$("#myTable tr").on('click', function(e) {
var newTr = $(this).closest("tr").clone();
items.push(newTr);
newTr.appendTo($("#cloneTable"));
});
})
<html><head><title>dynamictable</title>
<style>
table { cursor: pointer; }
.highlight { background-color: lightgreen; }
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<table id="myTable" border="1px" style="width: 30%;">
<thead>
<tr>
<th>##</th>
<th>Name</th>
<th>code</th>
<th>unit</th>
<th>rate</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>aaa</td>
<td>aa1</td>
<td>aa</td>
<td>111</td>
</tr>
<tr>
<td>1</td>
<td>aaa</td>
<td>aa1</td>
<td>aa</td>
<td>111</td>
</tr>
</tbody>
</table>
<br>
<br>
<br>
<input type="button" id="goto_first" value="first" class="btn btn-success">
<input type="button" id="goto_prev" value="prev" class="btn btn-secondary">
<input type="button" id="goto_next" value="next" class="btn btn-secondary">
<input type="button" id="goto_last" value="last" class="btn btn-success">
<br>
<br>
<br>
<table id="cloneTable" border="1px" style="width: 30%; float :left;"><!--new table to clone data-->
<thead>
<tr>
<th>##</th>
<th>Name</th>
<th>code</th>
<th>unit</th>
<th>rate</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</body>
</html>
Here you go
// highlight first row default
$("#myTable tbody tr:first-child").addClass("highlight");
document.onkeydown = moveAndAdd;
function moveAndAdd(e) {
e = e || window.event;
if (e.keyCode == "38") {
// up arrow
activeRow = $("tr.highlight"); /* get highlighted row */
activeRow.focus();
prevRow = activeRow.prev('tr'); /*very previous siblings*/
if (prevRow.length>0) {
activeRow.removeClass("highlight"); /*remove highlight from active class */
prevRow.addClass("highlight"); /* make very prev row highlighted*/
}
} else if (e.keyCode == "40") {
// down arrow
activeRow = $("tr.highlight"); /* get highlighted row */
activeRow.focus();
nextRow = activeRow.next('tr'); /*very previous siblings*/
if (nextRow.length>0) {
activeRow.removeClass("highlight");
nextRow.addClass("highlight");
}
}
else if (e.which == 13 || e.which == 32) {
// Enter or Spacebar - edit cell
e.preventDefault();
cloneRow = $(".highlight").clone(true); /*clone highlighted row*/
$("#cloneTable").append(cloneRow.removeClass("highlight")); /*append cloned row but remove class */
}
}
table {
color:black;
background-color:white;
}
.highlight{
color:White;
background-color:green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable" border="1px" style="width: 30%;">
<thead>
<tr >
<th>##</th>
<th>Name</th>
<th>code</th>
<th>unit</th>
<th>rate</th>
</tr>
</thead>
<tbody>
<tr>
<td >1</td>
<td>aaa</td>
<td>aa1</td>
<td>aa</td>
<td>111</td>
</tr>
<tr>
<td>2</td>
<td>bbb</td>
<td>bb2</td>
<td>bb</td>
<td>222</td>
</tr>
<tr>
<td>3</td>
<td>ccc</td>
<td>cc3</td>
<td>cc</td>
<td>333</td>
</tr>
<tr>
<td>4</td>
<td>ddd</td>
<td>dd1</td>
<td>dd</td>
<td>444</td>
</tr>
</tbody>
</table>
<table id="cloneTable" border="1px" style="width: 30%; float :left;">
<thead>
<tr>
<th>##</th>
<th>Name</th>
<th>code</th>
<th>unit</th>
<th>rate</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
I was going to write a custom response but check this out, it addresses your issue: Use arrow keys to navigate an HTML table
You're also missing a closing quotation mark around your "width: 30%" for your opening parent div

How to do show/hide of table rows multiple times per page?

I'm fairly new to programming and JS so I would like some pointers in terms of how I would go about this. I want to use that code for multiple instance of toggle per page.
I want by default table only shows 3 rows and when some click on view more it shows the rest of the rows and it should be toggle on click
$(document).ready(function(){
// toggle rows
$( ".viewSection a" ).click(function() {
var $self = $(this);
var $nextUl = $self.parent().next();
$(this).parent().next().slideToggle("fast");
});
})
HTML:
<div class="block">
<div class="tabWrapper">
<div class="tabContainer">
<div class="tabContent" style="display: none;">
<div class="childTable">
<table class="tableSeconday">
<thead>
<tr>
<th colspan="2">TOTAL BACKLOG: 20</th>
</tr>
</thead>
<tbody>
<tr>
<td>Lotus Greens Enviro City</td>
<td>15</td>
</tr>
<tr>
<td>Lotus Greens Enviro City</td>
<td>15</td>
</tr>
</tbody>
</table>
<!--/tableSeconday-->
</div>
<!--/childTable-->
</div>
<!--/tabContent-->
<div class="tabContent" style="display: block;">
<div class="childTable">
<table class="tableSeconday">
<thead>
<tr>
<th colspan="2">TOTAL BACKLOG: 30</th>
</tr>
</thead>
<tbody>
<tr>
<td>Gaursons Yamuna City Plots</td>
<td>15</td>
</tr>
<tr>
<td>Gaursons Yamuna City Plots</td>
<td>15</td>
</tr>
<tr>
<td>Gaursons Yamuna City Plots</td>
<td>15</td>
</tr>
<tr>
<td>Gaursons Yamuna City Plots</td>
<td>15</td>
</tr>
<tr>
<td>Gaursons Yamuna City Plots</td>
<td>15</td>
</tr>
<tr>
<td>Gaursons Yamuna City Plots</td>
<td>15</td>
</tr>
<tr>
<td>Gaursons Yamuna City Plots</td>
<td>15</td>
</tr>
<tr>
<td>Gaursons Yamuna City Plots</td>
<td>15</td>
</tr>
<tr>
<td>Gaursons Yamuna City Plots</td>
<td>15</td>
</tr>
</tbody>
</table>
<!--/tableSeconday-->
</div>
<!--/childTable-->
</div>
<!--/tabContent-->
</div>
</div>
<div class="viewSection"> view more
</div>
</div>
JSfiddle: http://jsfiddle.net/s9L128g9/
I don't want to have to work with manually adding separate IDs to the JS to activate the toggle. All I want to do is have multiple toggle areas on the same page, and use a class in the JS to work them all.
I think DOM Traversal is the way forwards. It's the only way to work on children of an element selected by class, where the element may be present multiple times on a page (AFAIK).
Small HTML change to put the 'show more/less' link in to the parent table div... JS is:
$('.tableSeconday').each(function () {
$(this).find('tr:gt(3)').hide();
});
$(".viewSection a").click(function () {
var $table = $(this).parent().prevAll('div').find('table');
$table.find('tr:gt(3)').toggle();
$(this).html($(this).html() == 'view more' ? 'view less' : 'view more');
});
http://jsfiddle.net/daveSalomon/rnwr07ar/6/
Try this :
// get all tr from second table with class="tableSeconday:eq"
var rows = $(".tableSeconday:eq(1) tr");
// slice after 4th row as first row include header part and hide them all
$(rows).slice(4,rows.length).each(function(index, element) {
$(this).hide();
});
// toggle rows
$( ".viewSection a" ).click(function() {
// show all tr from table
$(".tableSeconday:eq(1) tr").show();
});
Demo
EDIT - to work same for multiple table with class="tableSeconday" and toggle show / hide rows, use below query :
var showingLess = false;
var showLess = function(){
$(".tableSeconday").each(function(){
var rows = $(this).find("tr");
$(rows).slice(4,rows.length).each(function(index, element) {
$(this).hide();
});
});
showingLess = true;
}
// call showLess() for first time
showLess();
// toggle rows
$( ".viewSection a" ).click(function() {
if(showingLess)
{
$(".tableSeconday tr").show();
showingLess = false;
}
else
{
showLess();
}
});
Demo
Building on the previous answer (nice work btw) this Demo version will toggle the rows visibility as well as change the text to "view more/less".
// toggle rows
$( ".viewSection a" ).click(function() {
$(rows).slice(4,rows.length).each(function(index, element) {
if ($(this).is(":visible")) {
$(this).hide();
$("#showRows").html("view more");
} else {
$(this).show();
$("#showRows").html("view less");
}
});
});
Bhushan did the heavy lifting here but i don't have enough rep to add this as a comment sorry

Categories