I am new to Angular. Here I am trying to format JSON data being displayed on a table. Here is what I am trying to achieve, for empty rows, instead of being blank , I fill them with a hyphen, values greater than 25 I fill there individual cells background with red color, values between 20 and 25 i fill them with yellow color, but for some weird reason my table is not being formatted completely, it is like it is not detecting the ngAfterViewInit() function, also when i try to get the average of all the columns i am getting the result as NaN for all columns.
My component.ts file
#ViewChild('myTable', {static: false}) myTable: ElementRef;
ngAfterViewInit() {
var table = this.myTable.nativeElement;
var row;
var cell;
var j = 1;
var r = 0;
var t = 0;
//console.log(table);
if (table !== null) {
while (row = table.rows[r++]) {
var c = 0;
while (cell = row.cells[c++]) {
var cellValue = cell.innerHTML;
//cell.innerHTML='[Row='+r+',Col='+c+']'; // do sth with cell
if (c === 5 && cellValue > 25) {
cell.style.background="#FF0000";
} else if (c === 5 && cellValue >= 10 && cellValue < 25) {
cell.style.background="#FFFF00";
}
}
}
//getting the average value of each column
var colL = table.rows.length - 1;
//console.log(table.rows[1].cells.length);
for (j = 1; j < table.rows[1].cells.length; j++) {
var sumVal = 0;
for (var i = 1; i < table.rows.length; i++) {
if (i < colL) {
//console.log(table.rows[i].cells[1].innerHTML);
if (Number.isInteger(parseInt(table.rows[i].cells[j].innerHTML)) === true) {
sumVal = sumVal + parseFloat(table.rows[i].cells[j].innerHTML);
} else {
table.rows[i].cells[j].value = "-";
table.rows[i].cells[j].style.backgroundColor = "#FFFF00";
}
}
// console.log(table.rows[colL].cells[table.rows.length - 1].innerHTML);
}
//Setting the last cell with the avirrage value
if (table.rows[colL].cells[j] !== table.rows[colL].cells[table.rows[1].cells.length - 2]) {
var ans = (sumVal / (table.rows.length - 2)).toFixed(2);
table.rows[colL].cells[j].innerHTML = ans;
} else
table.rows[colL].cells[j].innerHTML = sumVal;
//Taking out all cells with zore totals
if (parseFloat(ans) === 0) {
for (t = 0; t <= colL; t++) {
table.rows[t].cells[j].style.display = 'none';
}
}
}
}
}
}
My beginning of the Table
<div class="panel-body" >
<div class="table-responsive">
<table class="table table-hover" #myTable>
<thead>
My beginning of the rows
<tr class="even gradeC" style="text-align:center" ng-repeat="home in homeurban"
*ngFor="let home of homeurban">
<td class="infos" style="position: absolute; top: auto; width: 100.5px;">{{home.teamNumber}}</td>
What I am doing wrong?
Thanks in advance
Related
I've created a table dynamically, but now I want to create a dropdown row on demand. I have an onclick handler for each row. Upon clicking, this row should drop something downward (like a hidden div but unfortunately these cannot be easily created in a dynamic setting, as there's not a way to assign a unique id at row creation. Is this even possible in Javascript/jQuery? or, preferably, twitter bootstrap?
function buildHtmlTable(portalData, tablename) {
var columns = [];
var headerTr$ = $('<tr/>');
var n = 0;
if (tablename == "order-table") {
document.getElementById("dist-name").innerText = JSON.parse(JSON.stringify(portalData[0], null, 2))["Company Name"];
n = 1;
}
for (var i = 0 ; i < portalData.length ; i++) {
var rowHash = portalData[i];
for (var key in rowHash) {
if ($.inArray(key, columns) == -1) {
columns.push(key);
headerTr$.append($('<th/>').html(key));
}
}
}
$('#' + tablename).append(headerTr$);
for (i = 0 ; i < portalData.length ; i++) {
var row$ = $('<tr/>');
for (var colIndex = n ; colIndex < columns.length ; colIndex++) { // n is how many columns to drop, based on table name
var cellValue = portalData[i][columns[colIndex]];
if (cellValue == null) {
cellValue = "";
}
row$.append($('<td/>').html(cellValue));
}
$('#' + tablename).append(row$);
}
// Drop unnecessary columns
for(i = 0 ; i<n; i++) {
$("#order-table").find('td,th').first().remove();
}
if (tablename == "order-table") {
var tablerows = document.getElementsByTagName('tr');
for (var x in tablerows) {
tablerows[x].classList.add("clickable");
tablerows[x].setAttribute(data-toggle,"collapse");
tablerows[x].setAttribute(data-target,"");
}
}
}
I am not getting the grid cell value.It's always empty. How can i get the cellvalue?
Code:
function VallidRcvQuantity (txtcurrentrcved) {
var grid = document.getElementById("<%=gvGoodReceived.ClientID%>");
var txtcurrentrcvamount = txtcurrentrcved;
for (var i = 0; i < grid.rows.length - 1; i++) {
var cellValue = $("#gvGoodReceived").find("tr:eq(" + i + ")").find("td:eq(2)").text();
if (Number(txtcurrentrcvamount) > Number(cellValue)) {
alert("Receive quantity must be less or equal PO quantity");
return false;
}
}
return true;
}
The reason you are not getting a cell value is because for the row with index 0, there are no td elements but only th elements within a tr element. This row is the header row.
So, you must either skip the first row in your original code or use code like below.
function getGridViewCellValue() {
var grid = document.getElementById("<%=gvGoodReceived.ClientID%>");
for (var i = 0; i < grid.rows.length - 1; i++) {
var cell = $("#<%=gvGoodReceived.ClientID%>").find("tr:eq(" + i + ")").find("td:eq(2)");
if (cell.length > 0) {
var cellValue = cell.text();
return cellValue;
}
}
return null;//means no cell value was found
}
I am building a table and I want the background color of the selected cell to change. Then when i select a different cell (and apply the same change to this new cell), I want the change to revert in the first (no longer selected) cell. What is the best approach to this? Here is my code:
var table = '';
for (var r = 0; r < rows; r++) {
table += '<tr>';
for (var c = 0; c < cols; c++) {
if (c == 0) {
if (r == 0) {
var cellID = r.toString();
cellID += letterArray[c - 1];
table += '<td style="min-width:50px; height:25px;">' + '</td>';
}
else {
var cellID = r.toString();
cellID += letterArray[c - 1];
table += '<td style="min-width:50px; height:25px">' + r + '</td>';
}
}
else if (r == 0 && c > 0) {
var cellID = r.toString();
cellID += letterArray[c - 1];
table += '<td style="min-width:50px; height:25px">' + letterArray[c - 1] + '</td>';
}
else {
var cellID = r.toString();
cellID += letterArray[c - 1];
table += '<td id="' + cellID + '" style="min-width:50px; height:25px;" onclick="selectCell(this)">' + '</td>';
}
}
table += '</tr>';
}
Writing the table to the document:
document.write('<table id="table" border=1>' + table + '</table>');
selectCell function:
function selectCell(x) {
alert("Row = " + x.parentNode.rowIndex + " Col = " + String.fromCharCode((x.cellIndex - 1) + 65));
x.style.backgroundColor = 'purple';
}
This is where i encounter my problem. As I click the first cell, my alert shows me the info of which cell i have selected, and then changes the background color. Then when i select a different cell, it alerts me with the new cell row and column info, and changes the color.
What is the best way to revert the color change of the previously selected cell?
Thank you for your time and energy!
You should make a CSS class that applies the background color and add/remove it in your function. Your function can check for an element that already has the class, like this:
CSS:
.selected {
background-color: purple;
}
JS:
function selectCell(x) {
var currentSelection = document.querySelector('.selected');
if (currentSelection) {
currentSelection.classList.remove('selected');
}
x.classList.add('selected');
}
I agree with #Rishat Muhametshin that you should avoid using document.write. And I liked how #skyline3000 solved it so I put everything together into a snippet for you to see a cleaner way to code this.
I even went so far as to give you true headers on the top and the side and then added extra CSS to make them look more like headers.
var rows = 7;
var cols = 8;
var table = document.createElement('table');
var selecedTd;
table.id = "table";
table.border = 1;
table.cellSpacing = 0;
table.cellPadding = 4;
document.body.appendChild(table);
for (var r = 0; r < rows; r++) {
var tr = document.createElement('tr');
if (r > 0) {
tr.id = "row"+r;
}
table.appendChild(tr);
for (var c = 0; c < cols; c++) {
var cell;
var char = String.fromCharCode(c+64);
if (c===0 || r===0) {
cell = document.createElement('th');
cell.setAttribute('style', 'min-width:50px; height:25px;');
} else {
cell = document.createElement('td');
}
tr.appendChild(cell);
if (c == 0 && r > 0) {
cell.textContent = r;
}
else if (r == 0) {
if (c > 0) {
cell.textContent = char
cell.id = "col"+c;
}
}
else {
cell.id = r+char;
cell.addEventListener('click', selectCell);
//cell.textContent = cell.id;
}
}
}
function selectCell(event) {
var x = event.target;
var currentSelection = document.querySelector('.selected');
if (currentSelection) {
currentSelection.classList.remove('selected');
}
x.classList.add('selected');
}
.selected {
background-color: purple;
color: white;
}
th {
background-color: #DDD;
}
td {
cursor: pointer;
}
UPDATE
Below is code that will allow editing of the selected field. It needs work before it could be used in production and you would want to save the data in some array or object as well as in the cells, but it should get you going.
var rows = 7;
var cols = 8;
var table = document.createElement('table');
var selecedTd;
var inputField = document.createElement('input');
table.id = "table";
table.border = 1;
table.cellSpacing = 0;
table.cellPadding = 4;
document.body.appendChild(table);
inputField.className = "roving-input";
for (var r = 0; r < rows; r++) {
var tr = document.createElement('tr');
if (r > 0) {
tr.id = "row"+r;
}
table.appendChild(tr);
for (var c = 0; c < cols; c++) {
var cell;
var char = String.fromCharCode(c+64);
if (c===0 || r===0) {
cell = document.createElement('th');
} else {
cell = document.createElement('td');
}
tr.appendChild(cell);
if (c == 0 && r > 0) {
cell.textContent = r;
}
else if (r == 0) {
if (c > 0) {
cell.textContent = char
cell.id = "col"+c;
}
}
else {
cell.id = r+char;
cell.addEventListener('click', selectCell);
cell.textContent = cell.id;
}
}
}
function selectCell(event) {
var x = event.target;
var currentSelection = document.querySelector('.selected');
if (x !== currentSelection && x.localName === 'td') {
if (currentSelection) {
currentSelection.textContent = inputField.value;
currentSelection.classList.remove('selected');
}
x.classList.add('selected');
inputField.value = x.textContent;
x.appendChild(inputField);
inputField.style.width = (x.clientWidth-2)+'px';
inputField.focus();
inputField.select();
}
}
.selected {
position: relative;
}
th {
background-color: #DDD;
height:25px;
min-width:50px;
}
td {
cursor: pointer;
}
.roving-input {
background-color: #FDF;
border: none;
bottom: 0;
display: inline-block;
left: 0;
outline: none;
position:absolute;
right: 0;
top: 0;
}
I am making a game of tic tac toe 5 in a row. I have the grid where whenever you click on a square, it records a "coordinate" of [row,column] in the certain color of the dot. I'm currently not sure how to use the 'coordinates' to detect a five in a row of either color and just prints out a message.
Note: If 5 in a row gets tedious with the copy and pasting of previous code or such, a 3 in a row will also work for me and I will just modify it into a 5 in a row. Also when viewing the code snippet below, use the full screen mode.
Code I have so far:
var white=true;
function generateGrid( rows, cols ) {
var grid = "<table>";
for ( row = 1; row <= rows; row++ ) {
grid += "<tr>";
for ( col = 1; col <= cols; col++ ) {
grid += "<td></td>";
}
grid += "</tr>";
}
return grid;
}
$( "#tableContainer" ).append( generateGrid( 10, 10) );
$( "td" ).click(function() {
$(this).css('cursor','default');
var index = $( "td" ).index( this );
var row = Math.floor( ( index ) / 10) + 1;
var col = ( index % 10) + 1;
var $td = $(this);
if ($td.data('clicked'))
return;
if (white===true){
var whi=[row,col];
console.log("white coord is "+whi);
} else {
var bla=[row,col];
console.log("black coord is "+bla);
}
$td.data('clicked', true);
$td.css('background-color', white ? 'white' : 'black');
white = !white;
});
html{
background-color:#7189ea;
}
td {
border: 1px solid;
width: 25px;
height: 25px;
border-radius:100%;
}
table {
border-collapse: collapse;
}
<link type="text/css" rel="stylesheet" href="stylesheet.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="tableContainer"></div>
I've written a function that checks whether the last move wins the game. It basically loops the squares in every direction (and backwards) and looks for 5 in a row (the required length of a line).
var board = new Array();
var boardSize = 5;
var requiredLineLength = 5;
for (var r = 0; r < boardSize; r++) {
board[r] = new Array();
for (var c = 0; c < boardSize; c++) {
board[r][c] = 0;
}
}
var lineDirections = [
[0, 1], //horizontal
[1, 0], //vertical
[1, -1], //diagonal 1
[1, 1] //diagonal 2
];
//example usage:
board[0][0] = 1;
board[1][0] = 1;
board[2][0] = 1;
board[3][0] = 1;
board[4][0] = 1;
console.log(checkWin(1, [0, 0]));
// an empty square is marked with 0
// the players are marked with 1 and 2
// pl is the id of the player: either 1 or 2
// lastMove is an array of size 2, with the coordinates of the last move played, for example: [3, 1]
function checkWin(pl, lastMove) {
var boolWon = false;
for (var i = 0; i < lineDirections.length && !boolWon; i++) {
var shift = lineDirections[i];
var currentSquare = [lastMove[0] + shift[0], lastMove[1] + shift[1]];
var lineLength = 1;
while (lineLength < requiredLineLength && legalSquare(currentSquare) && board[currentSquare[0]][currentSquare[1]] === pl) {
lineLength++;
currentSquare[0] += shift[0];
currentSquare[1] += shift[1];
}
currentSquare = [lastMove[0] - shift[0], lastMove[1] - shift[1]];
while (lineLength < requiredLineLength && legalSquare(currentSquare) && board[currentSquare[0]][currentSquare[1]] === pl) {
lineLength++;
currentSquare[0] -= shift[0];
currentSquare[1] -= shift[1];
}
if (lineLength >= requiredLineLength)
boolWon = true;
}
return boolWon;
}
function legalSquare(square) {
return square[0] < boardSize && square[1] < boardSize && square[0] >= 0 && square[1] >= 0;
}
It's not fully tested so let me know if you encounter any problems or if you need any clarification on how this works.
I'm creating a heatmap for some results I have based on some simple thresholds. I'm using JavaScript to create, set up the value and the background color. The expected result is a heatmap using some blue different tonalities. However, nothing is being colored, and by analysing the DOM I found:
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
Thus, the bgcolor="#" is not setup. I have used both bgcolor and setAtribute, but the result it is the same: nothing is being colored. My function is posted below:
function makeTable(data)
{
var row = new Array();
var cell = new Array();
var row_num = 26;
var cell_num = 44;
var tab = document.createElement('table');
tab.setAttribute('id', 'newtable');
tab.border = '1px';
var tbo = document.createElement('tbody');
for(var i = 0; i < row_num; i++){
row[i] = document.createElement('tr');
var upper = (i+1)*44;
var lower = i*44;
for(var j = lower; j < upper; j++){
cell[j] = document.createElement('td');
if(data[j] != undefined){
var index = document.createTextNode(data[j].diff);
cell[j].appendChild(index);
/* specify which color better suits the heatmap */
if(index >= 0 || index <= 100){
cell[j].bgcolor = "#ADDDE6";
}
else if(index > 100 || index <= 1000){
cell[j].bgcolor = "#00BFFF";
}
else if(index > 1000 || index <= 4000){
cell[j].bgcolor = "#6495ED";
}
else if(index > 4000 || index <= 6000){
cell[j].bgcolor = "#00008B";
}
else{
cell[j].bgcolor = "#0000FF";
}
row[i].appendChild(cell[j]);
}
}
tbo.appendChild(row[i]);
}
tab.appendChild(tbo);
document.getElementById('mytable').appendChild(tab);
}
Any ideas?
Thanks
cell.style.backgroundColor="red"
You need a capitalized C in bgcolor property -> bgColor.