Select one data-attribute per table row and cell - javascript

I have the following html table:
<table border="1" cellpadding="5" class="test">
<tr>
<td class="talent-cell"><div class="btn7" data-value="0">aaa</div></td>
<td class="talent-cell"><div class="btn8" data-value="1">bbb</div></td>
<td class="talent-cell"><div class="btn9" data-value="2">ccc</div></td>
</tr>
<tr>
<td class="talent-cell"><div class="btn7" data-value="0">ddd</div></td>
<td class="talent-cell"><div class="btn8" data-value="1">eee</div></td>
<td class="talent-cell"><div class="btn9" data-value="2">fff</div></td>
</tr>
<tr>
<td class="talent-cell"><div class="btn7" data-value="0">ggg</div></td>
<td class="talent-cell"><div class="btn8" data-value="1">hhh</div></td>
<td class="talent-cell"><div class="btn9" data-value="2">iii</div></td>
</tr>
</table>
If you click on a "div attribute" inside a table cell I need to get the "data-value" of the clicked div attribute. After that I build a query string to use it with "URLSearchParams". This works so far.
Now I need a certain condition. It should be only allowed to select one div-attribute per table row and column. But I don't know how to implement this condition in my code.
This is the Fiddle and the code:
var btn7;
var btn8;
var btn9;
$('.btn7').click(function () {
if ($(this).attr('data-selected') === 'true') {
$(this).attr('data-selected', 'false');
$(this).removeClass('selected');
} else {
$(this).closest('tr').find('.btn7').not(this)
.removeClass('selected').attr('data-selected', 'false');
$(this).attr('data-selected', 'true');
$(this).addClass('selected');
params.set('var7', $(this).data("value"));
window.history.replaceState({}, '', `?${params}`);
}
});
$('.btn8').click(function () {
if ($(this).attr('data-selected') === 'true') {
$(this).attr('data-selected', 'false');
$(this).removeClass('selected');
} else {
$(this).closest('tr').find('.btn8').not(this)
.removeClass('selected').attr('data-selected', 'false');
$(this).attr('data-selected', 'true');
$(this).addClass('selected');
params.set('var8', $(this).data("value"));
window.history.replaceState({}, '', `?${params}`);
}
});
$('.btn9').click(function () {
if ($(this).attr('data-selected') === 'true') {
$(this).attr('data-selected', 'false');
$(this).removeClass('selected');
} else {
$(this).closest('tr').find('.btn9').not(this)
.removeClass('selected').attr('data-selected', 'false');
$(this).attr('data-selected', 'true');
$(this).addClass('selected');
params.set('var9', $(this).data("value"));
window.history.replaceState({}, '', `?${params}`);
}
});
const params = new URLSearchParams({
var7: btn7,
var8: btn8,
var9: btn9,
});

Idea
Mark each table cell with a data- attribute indicating its respective row and column, and maintain 2 arrays that hold the currently selected element (if any) for each of the columns and row.
Implementation
The following code implements the selection logic. Based on the arrays holding the currently active selections you can visit all relevant elements and assemble the parameters when you send a request to the server.
The specs of single cell/row selection implies that there will usually be rows and columns that do not carry a selection.
Note that the case of expressly deselecting a cell is not handled.
The code does not resort to jquery.
<!DOCTYPE html>
<html>
<head>
<title>SO _: 1-in-a-row, 1-in-a-col selection</title>
<style type="text/css">
.selected {
background: #333;
color: #fff;
}
</style>
<script type="text/javascript">
let a_colSelection = new Array(3)
, a_rowSelection = new Array(3)
;
document.addEventListener ( 'DOMContentLoaded', () => {
Array.from(document.querySelectorAll('div[data-row][data-col]')).forEach ( el => {
el.addEventListener ( 'click', eve => {
let c = parseInt(eve.target.getAttribute('data-col'))
, r = parseInt(eve.target.getAttribute('data-row'))
;
if (a_colSelection[c] !== undefined) {
document.querySelector(`div[data-col="${a_colSelection[c][1]}"][data-row="${a_colSelection[c][0]}"]`).classList.remove("selected");
}
if (a_rowSelection[r] !== undefined) {
document.querySelector(`div[data-col="${a_rowSelection[r][1]}"][data-row="${a_rowSelection[r][0]}"]`).classList.remove("selected");
}
a_colSelection[c] = [r, c];
a_rowSelection[r] = [r, c];
document.querySelector(`div[data-col="${a_colSelection[c][1]}"][data-row="${a_rowSelection[r][0]}"]`).classList.add("selected");
});
});
});
</script>
</head>
<body>
<table border="1" cellpadding="5" class="test">
<tr>
<td class="talent-cell"><div data-value="0" data-col="0" data-row="0">aaa</div></td>
<td class="talent-cell"><div data-value="1" data-col="1" data-row="0">bbb</div></td>
<td class="talent-cell"><div data-value="2" data-col="2" data-row="0">ccc</div></td>
</tr>
<tr>
<td class="talent-cell"><div data-value="0" data-col="0" data-row="1">ddd</div></td>
<td class="talent-cell"><div data-value="1" data-col="1" data-row="1">eee</div></td>
<td class="talent-cell"><div data-value="2" data-col="2" data-row="1">fff</div></td>
</tr>
<tr>
<td class="talent-cell"><div data-value="0" data-col="0" data-row="2">ggg</div></td>
<td class="talent-cell"><div data-value="1" data-col="1" data-row="2">hhh</div></td>
<td class="talent-cell"><div data-value="2" data-col="2" data-row="2">iii</div></td>
</tr>
</table>
</body>
</html>

Consider the following.
Fiddle: https://jsfiddle.net/Twisty/dzng31f5/39/
HTML
<table border="1" cellpadding="5" class="test">
<tr class="var7">
<td class="talent-cell">
<div class="btn" data-value="0">aaa</div>
</td>
<td class="talent-cell">
<div class="btn" data-value="1">bbb</div>
</td>
<td class="talent-cell">
<div class="btn" data-value="2">ccc</div>
</td>
</tr>
<tr class="var8">
<td class="talent-cell">
<div class="btn" data-value="0">ddd</div>
</td>
<td class="talent-cell">
<div class="btn" data-value="1">eee</div>
</td>
<td class="talent-cell">
<div class="btn" data-value="2">fff</div>
</td>
</tr>
<tr class="var9">
<td class="talent-cell">
<div class="btn" data-value="0">ggg</div>
</td>
<td class="talent-cell">
<div class="btn" data-value="1">hhh</div>
</td>
<td class="talent-cell">
<div class="btn" data-value="2">iii</div>
</td>
</tr>
</table>
I adjusted the HTML Structure, such that each Row has a Class that represents the Index name that will be used in the Object.
jQuery
$(function() {
function checkCol(colIndex, table) {
var result = true;
console.log("Col Index:" + colIndex)
$("tbody tr", table).each(function(i, el) {
result = result && !$("td:eq(" + colIndex + ") div.btn", el).hasClass("selected");
});
return !result;
}
function checkRow(target, row) {
var isInCol = checkCol($(target).parent().index(), $(row).closest("table"));
if (!isInCol) {
if ($(".selected", row).length) {
$(".selected", row).removeClass("selected");
$(target).addClass("selected");
} else {
$(target).addClass("selected");
}
}
}
var selected = {};
$('.btn').click(function(event) {
var row = $(this).closest("tr");
checkRow(this, row);
$(".test tbody tr").each(function(i, el) {
selected[$(el).attr("class")] = $(".selected", el).length ? $(".selected", el).data("value") : "";
});
console.log(selected);
var params = new URLSearchParams(selected);
console.log(params.toString());
});
});
You can now use selected as your Data in a POST or GET call.
Updated
I had missed that each Row and Column needed to be unique. Code is updated to use Functions to check both conditions.

"Now I need a certain condition. It should be only allowed to select one div-attribute per table row and column."
The versatility of jQuery is leveraged by the use of this because it narrows down from many objects (all <td> in <table>) to a single object (<td> the user clicked). The behavior needed is common with radio button groups called "mutual exclusive selection", using .not(this) makes it simple.
In HTML,
assign a common class to each <div> (ex. '.col', see Figure I)
assign a class to each <div> that corresponds to the value of it's [data-value] (ex. '.c0', see Figure I)
Figure I
<div class='col c0' data-value='0'>
I did not include the params part in OP since it's beyond the scope of the question (see beginning of this answer). The values are stored in object C and is easily accessible (ex. C.c0).
BTW, I hope that the logic is different with your real code. For example, there is no difference between .c0 2nd row and .c0 1st row.
Details are commented in example below
// Declare object to store [data-value]
let C = {};
// Any click on a .col calls the event handler
$('.col').on('click', function() {
// Flip .selected on this .col
$(this).toggleClass('selected');
// If this .col is flipped to be .selected...
if ($(this).is('.selected')) {
//... get this .col [data-value] (0, 1, or 2)...
let idx = $(this).data('value');
/*
... find all .c0, .c1, or .c2 BUT NOT this .col and
remove .selected from them...
*/
$('.c' + idx).not(this).removeClass('selected');
/*
... then find the closest <tr>, then find all .col of
<tr> BUT NOT this .col and remove .selected from them
*/
$(this).closest('tr').find('.col')
.not(this).removeClass('selected');
// set key 'c0', 'c1', or 'c2' of C to this .col [data-value]
C['c'+idx] = $(this).data('value');
}
console.log(C);
});
<table border="1" cellpadding="5" class="test">
<tr>
<td><div class="col c0" data-value="0">aaa</div></td>
<td><div class="col c1" data-value="1">bbb</div></td>
<td><div class="col c2" data-value="2">ccc</div></td>
</tr>
<tr>
<td><div class="col c0" data-value="0">aaa</div></td>
<td><div class="col c1" data-value="1">bbb</div></td>
<td><div class="col c2" data-value="2">ccc</div></td>
</tr>
<tr>
<td><div class="col c0" data-value="0">aaa</div></td>
<td><div class="col c1" data-value="1">bbb</div></td>
<td><div class="col c2" data-value="2">ccc</div></td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Related

Can't access element after drag and drop

I've made a drag and droppable table for sorting products.
My table looks like this:
<table class="table table-sortable" id="mytab">
<tbody>
[{foreach from=$mylist item=listitem}]
[{assign var="_cnt1" value=$_cnt1+1}]
<tr draggable="true" id="test_variant.[{$_cnt1}]">
<td class="idcount">[{$_cnt1}]</td>
<td class="[{$listclass}]">Productname</td>
<input id="sortcount[{$_cnt1}]" class="sortcount" type="hidden" value="[{$_cnt1}]"/>
</tr>
[{/foreach}]
</tbody>
</table>
My jQuery looks like this:
$(function() {
$('.table-sortable tbody').sortable({
handle: 'span'
});
$('.table-sortable tbody').sortable().bind('sortupdate', function(e, ui) {
function updateTable(){
var table = document.getElementById("mytab");
for (var i = 0, row; row = table.rows[i]; i++) {
$( row ).attr("id","test_variant."+i);
$( row ).find(".idcount").text(i);
$( row ).find(".sortcount").val(i+10);
}
}
setTimeout(updateTable, 100);
});
});
The problem is, after I drag and drop my items the dom or something doesn't exist anymore.
Like my system won't save the dragged and dropped entries (But the others which are updated but not dragged).
And what leads me here because I don't understand it is when i dragged an item and try to access it like this
document.getElementById("sortcount1").value = "200";
it just says
Uncaught TypeError: Cannot set property 'value' of null like it's not existing
I've no problem accessing the other items.
When I open the dom with clicking on elements in chrome devtools, then back to console and try it again its working again like it needs to initialize or something.
Hope someone can give me a hint.
Thank you!
You might consider the following example.
$(function() {
function updateTable(e, ui) {
var t = $(e.target).closest("table");
$("tbody tr", t).each(function(i, el) {
$(el).attr("id", "test_variant." + i);
$(".idcount", el).html(i);
$(".sortcount", el).val(i + 10);
});
}
$('.table-sortable tbody').sortable({
handle: 'span',
update: updateTable
});
});
This will reset the items in the table after the Sort has updated.
Update
$(function() {
function updateTable(e, ui) {
var t = $(e.target).closest("table");
$("tbody tr", t).each(function(i, el) {
var c = i + 1;
$(el).attr("id", "test_variant." + c);
$(".idcount", el).html(c);
$(".sortcount", el).val(c + 10);
});
}
$('.table-sortable tbody').sortable({
handle: 'span',
items: "> tr",
update: updateTable
});
});
table {
width: 340px;
}
table tr {
margin: 0 3px 3px 3px;
padding: 0.4em;
padding-left: 1.5em;
font-size: 1.4em;
height: 18px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<table class="table-sortable">
<thead>
<tr>
<td> </td>
<td>ID</td>
<td>Product Name</td>
</tr>
</thead>
<tbody>
<tr id="test_variant.1">
<td><span class="ui-icon ui-icon-arrowthick-2-n-s"></span></td>
<td class="idcount">1</td>
<td class="products">Item Name 1
<input id="sortcount-1" class="sortcount" type="hidden" value="11" />
</td>
</tr>
<tr id="test_variant.2">
<td><span class="ui-icon ui-icon-arrowthick-2-n-s"></span></td>
<td class="idcount">2</td>
<td class="products">Item Name 2
<input id="sortcount-2" class="sortcount" type="hidden" value="12" />
</td>
</tr>
<tr id="test_variant.3">
<td><span class="ui-icon ui-icon-arrowthick-2-n-s"></span></td>
<td class="idcount">3</td>
<td class="products">Item Name 3
<input id="sortcount-3" class="sortcount" type="hidden" value="13" />
</td>
</tr>
<tr id="test_variant.4">
<td><span class="ui-icon ui-icon-arrowthick-2-n-s"></span></td>
<td class="idcount">4</td>
<td class="products">Item Name 4
<input id="sortcount-4" class="sortcount" type="hidden" value="14" />
</td>
</tr>
<tr id="test_variant.5">
<td><span class="ui-icon ui-icon-arrowthick-2-n-s"></span></td>
<td class="idcount">5</td>
<td class="products">Item Name 5
<input id="sortcount-5" class="sortcount" type="hidden" value="15" />
</td>
</tr>
</tbody>
</table>
Tested the code and it appears to work properly.

How to change color of selected row on onmousedown event

I am trying to change the color of the selected row from a table on a onmousedown event and reset all others (or keep them the same) . Only one row can be red at a time while all others are green.
What I have tried:
function HighLight(id) {
var rows = $('#tbl > tbody > tr').each(function(elem) {
elem.style.background = 'green';
})
var tr = document.getElementById(id);
tr.style.background = 'red';
}
<table id="tbl">
<tr id="tr1" style="background-color:aquamarine" onmousedown="Highlight(e)">
<td>
v1
</td>
</tr>
<tr id="tr2" style="background-color:aquamarine" onmousedown="Highlight(e)">
<td>
v2
</td>
</tr>
<tr id="tr3" style="background-color:aquamarine" onmousedown="Highlight(e)">
<td>
v3
</td>
</tr>
</table>
Ideally I would like to store the old selected row so that I won't reset all others at each new selection, but in case I can't reset all would do it.
P.S I need to make due with the id that i am provided.I am using interop so the id is coming from the exterior. All my tr have that method injected in them.
The function name is wrong its Highlight not HighLight
To pass the id of the element on function call you cannot just pass any variable(e in your case). Use this.getAttribute('id') to get the id.
In the each() the argument elem represented the index of the element and not the element itself. Introduce another argument for index.
function Highlight(id) {
var rows = $('#tbl > tbody > tr').each(function(i,elem) {
elem.style.background = 'green';
})
var tr = document.getElementById(id);
tr.style.background = 'red';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tbl">
<tr id="tr1" style="background-color:aquamarine" onmousedown="Highlight(this.getAttribute('id'))">
<td>
v1
</td>
</tr>
<tr id="tr2" style="background-color:aquamarine" onmousedown="Highlight(this.getAttribute('id'))">
<td>
v2
</td>
</tr>
<tr id="tr3" style="background-color:aquamarine" onmousedown="Highlight(this.getAttribute('id'))">
<td>
v3
</td>
</tr>
</table>
Here is a quick example on how can you do that.
$("table tr").on('click', function(){
$(".highlighted").removeClass("highlighted");
$(this).addClass("highlighted");
});
table tr {
background: green;
}
table tr.highlighted {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tbl">
<tr id="tr1">
<td>
v1
</td>
</tr>
<tr id="tr2">
<td>
v2
</td>
</tr>
<tr id="tr3">
<td>
v3
</td>
</tr>
</table>
Here is how it works:
It binds a click event to every row in the table (tr),
Every time you click on a row, all elements that has a class called highlighted loose it and the row that you clicked gets the class highlighted,
In css you can change the default background color for all rows and the color after highlighting.
If you don't want to use a css, here is similar function but instead of adding and removing class it does the same with the inline css property.
$("table tr").on('click', function(){
$("table tr").css("background", "green");
$(this).css("background", "red");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tbl">
<tr id="tr1" style="background: green;">
<td>
v1
</td>
</tr>
<tr id="tr2" style="background: green;">
<td>
v2
</td>
</tr>
<tr id="tr3" style="background: green;">
<td>
v3
</td>
</tr>
</table>
But I do not recommend the second solution.
You can have two css classes; one for selected row and other for remaining rows.
On click of the row, you can add the "selected" class to that row.
$("#tbl tr").click(function(){
var $this = $(this);
//remove the previous row selection, if any
$("#tbl tr.selected").removeClass("selected");
//add selected class to the current row
$this.addClass("selected");
});
#tbl tr{
background-color: aquamarine;
}
#tbl tr.selected{
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tbl">
<tr id="tr1">
<td>
v1
</td>
</tr>
<tr id="tr2" >
<td>
v2
</td>
</tr>
<tr id="tr3" >
<td>
v3
</td>
</tr>
</table>
You can do like this.by using class you can carry out other operations
$("#tbl").on("click", "tr", function() {
$(' tr').removeClass("Red")
$(this).addClass("Red")
});
.Red {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tbl">
<tr id="tr1">
<td>
v1
</td>
</tr>
<tr id="tr2">
<td>
v2
</td>
</tr>
<tr id="tr3">
<td>
v3
</td>
</tr>
</table>
Several issues:
JS is case sensitive, so Highlight and HighLight (capital L) is not the same. I renamed the HighLight function to Highlight (lowercase l)
Use parameter this on function call in event handler attribute. This hands over the HTML element of the event handler attribute over to the event handler function (Highlight in your case)
Callback function of jQuery's each method has the index as a first parameter and the element as second
This makes your code work
function Highlight(tr) {
var rows = $('#tbl > tbody > tr').each(function(index, elem) {
elem.style.backgroundColor = 'green';
})
tr.style.background = 'red';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tbl">
<tr id="tr1" style="background-color:aquamarine" onmousedown="Highlight(this)">
<td>
v1
</td>
<td>
v1
</td>
<td>
v1
</td>
</tr>
<tr id="tr2" style="background-color:aquamarine" onmousedown="Highlight(this)">
<td>
v2
</td>
<td>
v2
</td>
<td>
v2
</td>
</tr>
<tr id="tr3" style="background-color:aquamarine" onmousedown="Highlight(this)">
<td>
v3
</td>
<td>
v3
</td>
<td>
v3
</td>
</tr>
</table>
There are some more things you can do to enhance your code
Don't use style in your JS code, but set classes for CSS
Don't use HTML onmousedown attributes, but JS addEventListeners
Replace jQuery code with VanillaJS
console.clear()
const rows = document.querySelectorAll('#tbl > tbody > tr');
for (row of rows) {
row.addEventListener('mousedown', Highlight)
}
function Highlight(e) {
e.preventDefault()
const tr = this
const rows = document.querySelectorAll('#tbl > tbody > tr');
for (row of rows) {
row.classList.remove('highlight')
row.classList.add('highlight-siblings')
}
tr.classList.remove('highlight-siblings')
tr.classList.add('highlight')
}
/* 1. */
tr {
background-color: aquamarine;
}
tr.highlight-siblings{
background-color: green;
}
tr.highlight{
background-color: red;
}
<table id="tbl">
<tr>
<td>
v1
</td>
<td>
v1
</td>
<td>
v1
</td>
</tr>
<tr>
<td>
v2
</td>
<td>
v2
</td>
<td>
v2
</td>
</tr>
<tr>
<td>
v3
</td>
<td>
v3
</td>
<td>
v3
</td>
</tr>
</table>

Selecting TD with specific classes from each TR and do math

I have a quite simple table.
Each TR with class "name-check" will be looped in php for as long as there are $name. Each new TR is getting a new class name with a counter, so basically the structures of the TR in this table looks like this:
Screenshot of table
<tr class="name-check name_1">
<tr class="name-check name_2">
<tr class="name-check name_3">
etc.
This is the content of each TR:
// Content of TR
<tr class="name-check name_1">
<td class="name">
<?php echo $name; ?>
</td>
<td class="check-date">
<label class="check-label"></label>
</td>
<td class="check-date">
<label class="check-label"></label>
</td>
<td class="check-date">
<label class="check-label"></label>
</td>
<td class="dont-count"></td>
<td class="check-date">
<label class="check-label"></label>
</td>
<td class="sum-up" align="center">
<span class="sum-up-span">0</span>
</td>
</tr>
This is the first TR which contains the TH:
// Table TH
<tr class="dates">
<th></th>
<th class="dat">1 </th>
<th class="dat">2 </th>
<th class="dat">3 </th>
<th class="dat">4 </th>
<th class="dont-count-th">Don't count</th>
</tr>
// Table TH End and after this tr comes:
<tr class="name-check name_1">...
<tr class="name-check name_2">
<tr class="name-check name_3">
When a user clicks on a TD with the class "check-date" that TD will get an extra class. Actually it is a click loop:
- 1 time click adds class .one,
- 2 time click adds class .two,
- 3 time click adds class .three.
What I want basically is, for each row, get the TD's which have any of these three classes and substract them from the number of TD's with the class of "check-date", or I could use the "TH" with class ".dat". The result should be displayed in the last td of each tr, the span with class ".sum-up-span".
I got that working for a single row, but multiple rows, it gets all the values.
var totalDays = $("tr.dates th.dat").length;
var daysOff = $("tr.name-check").each(function() {
$( "td.odsutan, td.godisnji, td.praznik" ).length;
var sum = totalDays - daysOff;
$(".sum-up-span").each(function () {
$(this).html("There " + sum + " from " + totalDays);
});
SOLVED
Both answers provided work great perfectly. Thank you guys for this.
Try this one,
$("td.check-date").click(function(e) {
if($(this).hasClass("one"))
$(this).removeClass("one").addClass("two");
else if($(this).hasClass("two"))
$(this).removeClass("two").addClass("three");
else if($(this).hasClass("three"))
$(this).removeClass("three");
else
$(this).addClass("one");
var tr = $(this).closest("tr");
var td_count = tr.find("td.check-date").length;
var clicked_td_count = tr.find("td.check-date.one, td.check-date.two, td.check-date.three").length;
tr.find("span.sum-up-span").text(td_count - clicked_td_count);
});
Your jQuery selectors are not limited to any container, so they search the entire page. What you need to do is limit them to the tr you clicked on.
Use the event e you get in a jQuery bound click function to do that:
function(e) {
var currentRow = jQuery(e.currentTarget);
var totalDays = $("tr.dates th.dat").length;
var daysOff = $("td.odsutan, td.godisnji, td.praznik", currentRow).length;
var sum = totalDays - daysOff;
$(".sum-up-span", currentRow).html("There " + sum + " from " + totalDays);
}
Note: if you don't have jQuery bound click events and need help with that, just ask.
$("table").on("click", "td.check-date", function() {
var row = $(this).closest("tr"),
checked = row.find(".one, .two, .three").length, // get the number of clicked/checked columns
toCheck = row.find(".check-date").length; // get number of columns to check
row.find(".sum-up-span").text(toCheck - checked); // print missing checks in "sum-up" column
});
// this only adds the "click" feature for a better visibility :D
(function() {
var classes = ["one", "two", "three", ""];
$("td.check-date").on("click", function() {
var td = $(this),
clicked = td.data("clicked") || 0;
td.data("clicked", clicked + 1);
this.className = "check-date " + classes[clicked % classes.length];
});
}())
td {
border: solid 1px black;
padding: 20px
}
.one { background-color: green }
.two { background-color: yellow }
.three { background-color: red }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr class="name-check">
<td class="name"></td>
<td class="check-date"></td>
<td class="check-date"></td>
<td class="check-date"></td>
<td class="dont-count"></td>
<td class="check-date"></td>
<td class="sum-up" align="center">
<span class="sum-up-span">0</span>
</td>
</tr>
<tr class="name-check">
<td class="name"></td>
<td class="check-date"></td>
<td class="check-date"></td>
<td class="check-date"></td>
<td class="dont-count"></td>
<td class="check-date"></td>
<td class="sum-up" align="center">
<span class="sum-up-span">0</span>
</td>
</tr>
</tbody>
</table>

Change cell color via ng-click

I have change color of my cell when I click in my button but when I click second time my color cell is not keep.
I wish that when I click a second time on another button my first cell keeps color
First click:
Second click:
HTML:
<table class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr class="warning">
<th>Key</th>
<th>Valeur version {{application.version}}</th>
<th></th>
<th>Valeur version {{applicationcible.version}}</th>
</tr>
</thead>
<tbody ng-repeat="group in groups">
<tr>
<td class="danger" colspan="4" ng-click="hideGroup = !hideGroup">
<a href="" ng-click="group.$hideRows = !group.$hideRows">
<span class="glyphicon" ng-class="{ 'glyphicon-chevron-right': group.$hideRows, 'glyphicon-chevron-down': !group.$hideRows }"></span>
<strong>{{group.name}}</strong>
</a>
</td>
</tr>
<tr ng-repeat-start="member in group.members" ng-hide="hideGroup">
<td rowspan="2">
{{ member.name }}
</td>
<td rowspan="2" ng-class="{selected: $index==selectedRowLeft}">{{ member.valueRef }}</td>
<td class="cube" >
<div ng-if="group.id != 1">
<button type="button" ng-click="moveLeft($index, group)" ><span class="glyphicon glyphicon-chevron-left"></span></button>
</div>
</td>
<td rowspan="2" ng-class="{selected: $index==selectedRowRight}">{{ member.valueCible }}</td>
</tr>
<tr ng-repeat-end ng-hide="hideGroup" >
<td class="cube" >
<div ng-if="group.id != 2">
<button type="button" ng-click="moveRight($index, group)"><span class="glyphicon glyphicon-chevron-right"></span></button>
</div>
</td>
</tr>
</tbody>
</table>
CSS:
.selected { background-color: #ffff05; }
JS:
scope.moveLeft = function (index, group) {
move(scope.properties, group.id, index, 'left');
};
scope.moveRight = function (index, group) {
move(scope.propertiescible, group.id, index, 'right');
};
var move = function (properties, groupId, origin, destination) {
unregister();
var value;
if (destination === 'right') {
scope.selectedRowRight = origin;
} else {
scope.selectedRowLeft = origin;
}
...
You might need to create an array to keep the cells that are selected thus background color is changed.
Also you will need to change the ng-click function to check the array, and implement the following logic "if there is a record for the clicked row as selected change it's bg-color to yellow"
You will need to do something like this
<td ng-repeat="group in groups" ng-class="{'selected': check == group.title}" ng-click="select(group)">{{group.title}}</li>
in css make sure you have this selected class defined
.selected {
background: 'red';
}
in controller
$scope.check = '';
$scope.select = function (group) {
$scope.check = group.title
};
See this plunker http://plnkr.co/edit/pLbLMWsJ7A6Zr1Z9uAmz?p=preview

Show hidden rows in table with dropdown

I have something that seems fairly simple but I'm stumped. I want a dropdown within a table that affects how many table rows are shown. By default, only 2 rows are shown. By selecting 4 in the dropdown, 4 rows should be shown. I am only seeing one of the hidden rows show up, and I've tried to wrap the 2 rows in a hidden div as well, no luck. Ideas?
<table border="1">
<tr>
<td class="noBG" colspan="3">
<select id="displayText" onchange="javascript:toggle();">
<option>2</option>
<option>4</option>
</select>Items
</td>
</tr>
<thead>
<tr>
<th>Dates</th>
<th>Time</th>
<th>Person</th>
</tr>
</thead>
<tr>
<td>12/3</td>
<td>12:45</td>
<td>John Doe</td>
</tr>
<tr>
<td>12/4</td>
<td>12:45</td>
<td>James Doe</td>
</tr>
<tr id="toggleText" style="display: none">
<td>12/4</td>
<td>12:45</td>
<td>Janey Doe</td>
</tr>
<tr id="toggleText" style="display: none">
<td>12/4</td>
<td>12:45</td>
<td>Janey Doe</td>
</tr>
</table>
<script language="javascript">
function toggle() {
var ele = document.getElementById("toggleText");
if(ele.style.display == "block") {
ele.style.display = "none";
}
else {
ele.style.display = "block";
}
}
</script>
​
Using display: block; doesn't work as the table rows will then displayed not in the right way. But you can toggle the visibility by adding and removing a class, which is defined with display: none;. So you must not switch display: none/block;, but the class.
This works (incl. jQuery): http://jsfiddle.net/Yuvvc/1/
You can use following code for JS function:
function toggle() {
$.each($('tr[name=toggleText]'), function() {
$(this).toggleClass("hiddenRow", $(this).attr('class') != "hiddenRow");
});
}
With the second parameter (bool) for .toggleClass you can add and remove the class.
EDIT
Here a non-jQuery version:
function toggle() {
var rows = document.getElementsByName("toggleText");
for(var i=0; i<rows.length; i++)
{
rows[i].className = (rows[i].className == "hiddenRow") ? "" : "hiddenRow";
}
}
Change all <tr id="toggleText" to <tr name="toggleText", and then change the toggle function to the following:
function toggle() {
var ele = document.getElementsByName("toggleText");
for (var i = 0; i < ele.length; i++) {
if (ele[i].style.display == "block") {
ele[i].style.display = "none";
}
else {
ele[i].style.display = "block";
}
}
}
You can toggle the hidden rows by giving each row an id like this:
<table class="table">
#foreach (var item in Model)
{
<tr>
<td onclick="toggle1(#item.ID)" colspan="3">
#Html.DisplayFor(modelItem => item.Name)
</td>
</tr>
<tr class="hidden" id="bluh_#item.ID">
<td>
#Html.DisplayFor(modelItem => item.Code)
</td>
<td>
#Html.DisplayFor(modelItem => item.Position)
</td>
</tr>
}
then use JavaScript to Hide and Show the Children Rows
<script>
function toggle1(something) {
$("#bluh_"+something).toggleClass('hidden');
}
</script>

Categories