How to detect element and cut into group in html tables - javascript

I am working with HTML tables and need to achieve color change in a certain way.
My desired result is as described below.
Lower figure shows that assume current state is upper figure,then cell 1 is clicked,upper figure becomes like lower figure.
I would like to selectfirstelement,and then add 'aqua' class after5cells including first cell.
I achieved to select first cells among these clicked cells,But I couldn't figure out how to detect after 5 cells which has 'class'.
If someone has opinion,please let me know
Thanks
$("td").click(function() {
$(this).addClass("red");
$("td.aqua").removeClass("aqua");
$("td.red").first().addClass("aqua");
});
td {
transition-duration: 0.5s;
border: solid black 1px;
padding: 5px;
cursor:pointer;
}
table {
border-collapse: collapse;
}
.red {
background-color:red;}
.aqua{
background-color:aqua;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=calendar></div>
<script>
let html = ''
html += '<table>';
let i = 0;
for (let w = 0; w < 5; w++) {
html += '<tr>';
for (let d = 0; d < 10; d++) {
i=i+1;
html += '<td>'+ i+'</td>'
}
html += '</tr>';
}
html += '</table>'
document.querySelector('#calendar').innerHTML = html;
</script>

I'm not 100% sure I understand correctly what you need to do, but this will color the clicked cell in aqua and the following 5 cells in red. Even if it's not exactly what you need, it should guide you in the right direction.
$('body').on('click', "td", function() {
let _this = this;
let _index = -1;
$(this).parents('table').find('td').each(function(i, el){
if(el == _this){
_index = i;
}
if (_index > -1 && i > _index && i < (_index + 6)){
console.log(i);
$(el).addClass('red');
}
});
$(this).addClass("aqua");
});
On a logical level you need to loop through all your td elements and detect which one of them has been clicked, get the index if it and then add the class red to the following 5 elements. Apply class aqua to the clicked one either at the end or at the beginning.

Does this what you want?
$("table").on("click", "td", function(ev) {
$(this).removeClass("aqua").addClass("red");
let nextRowIdx = this.parentNode.rowIndex,
nextCellIdx = this.cellIndex + 5;
if (nextCellIdx >=10) {
nextRowIdx += 1;
nextCellIdx -= 10;
}
try {
let tbl = this.parentNode.parentNode,
cell = tbl.children[nextRowIdx].children[nextCellIdx];
$(cell).removeClass("red").addClass("aqua");
} catch (err) {
}
});
td {
transition-duration: 0.5s;
border: solid black 1px;
padding: 5px;
cursor:pointer;
}
table {
border-collapse: collapse;
}
.red {
background-color:red;}
.aqua{
background-color:aqua;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=calendar></div>
<script>
let html = ''
html += '<table>';
let i = 0;
for (let w = 0; w < 5; w++) {
html += '<tr>';
for (let d = 0; d < 10; d++) {
i=i+1;
html += '<td>'+ i+'</td>'
}
html += '</tr>';
}
html += '</table>'
document.querySelector('#calendar').innerHTML = html;
</script>

Related

How to build a table on HTML page which is pushed as list?

I am trying to show .csv content on a page as a table. The list includes unknown rows and columns that depends on the user. It is not a fixed type like 2x2 or 3x4.
But I got something like the following;
[
[
&
#
x
2
7
;
x
x
.......
I am redirecting a list and also tried json. The content of the list is not fixed. The length and column side are dependable. I am trying to pass data properly and show as table
return list;
return render(request, 'yuklenen.html', {'veriler': yuklenen, 'file': listx })
I want to show it as
<div id="contain"></div>
Here's the code:
<script>
var str = '<ul>';
var data1 = "{{file}}" ;
for(var x in at){
str+='<li>' + at[x] + '<li>';
}
str += '</ul>';
document.getElementById("contain").innerHTML = str;
</script>
Hope this will get you started:
function rand(min, max)
{
return Math.round(Math.random() * (max - min) + min);
}
function update()
{
const at = [];
for(let x = 0; x < rand(3, 10); x++)
{
const c = [];
for(let y = 0; y < rand(1, 10); y++)
{
c[y] = rand(0, 100);
}
at[x] = c;
}
var str = '<ul>';
for(var x in at){
str+='<li>';
for(var y in at[x])
str += "<span>" + at[x][y] + "</span>";
str+='</li>';
}
str += '</ul>';
document.getElementById("contain").innerHTML = str;
}
update();
ul
{
display: table;
border-collapse: collapse;
}
li
{
display: table-row;
}
li > span
{
border: 1px solid black;
vertical-align: middle;
text-align: center;
display: table-cell;
width: 2em;
height: 2em;
}
<button onclick="update()">update</button>
<div id="contain"></div>

Continuously adding arrays to a 2D array

Every time I click on a cell in a grid, it logs an array of [rows,column] of the cell into a variable, either bla (for black) or whi (for white). However, the next time I click on a cell, it changes the variable. For example, I click on a cell and variable whi is [1,2] then I click on another cell, variable bla is [2,2] and after that, I click on a third cell and variable whi is changed from [1,2] (from the original click) to [3,2]. (I made up random numbers for this). I want to create two 2D arrays, one for the variable bla and one for the variable whi. Using my example, one of the 2D arrays should be [[1,2],[3,2]] (for the white cells) and the other one should be [[2,2]] (for the black cells)
Test out the code:
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]; //I want to log the array for whi into a 2D array
console.log("white coord is "+whi);
} else {
var bla=[row,col]; //I want to log this array into another 2D array
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>
Initialize whi and bla as arrays and push [row,col] to them - see demo below:
var white = true;
var whi = [];
var bla = [];
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) {
whi.push([row, col]);
} else {
bla.push([row, col]);
}
$td.data('clicked', true);
$td.css('background-color', white ? 'white' : 'black');
white = !white;
});
$('#getarr').click(function(){
console.log("white arr: ", whi);
console.log("black arr: ", bla);
});
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>
<button id="getarr">Get array</button>

selecting multiple table row using shift key and control key is not working

hi i have a editable table which is created by using java script.here i use some code for selection process .i want select table row using control key and shift key . i get the code from
[1]: http://jsfiddle.net/g8Rpe/ here. this example shown for html table .but my table is daynamic one
the code is here:
/******for table**************/
$(function () {
function tableCreate() {
var body = document.body,
tbl = document.createElement('table');
tbl.style.width = '100%';
tbl.style.borderCollapse = 'collapse';
for (var i = 0; i < 30; i++) {
var tr = tbl.insertRow();
tr.setAttribute("data-id", i, 0);
for (var j = 0; j < 3; j++) {
var td = tr.insertCell();
td.appendChild(document.createTextNode(''));
}
}
$("body").append(tbl);
$("td").addClass("mainheading4")
$("tr").on("onmousedown=RowClick(this,false)")
}
tableCreate();
//******************for editable table*************************//
$('td').click(function () {
$('td').attr('contenteditable', 'true');
})
//************for multiple selection*****************//
var lastSelectedRow;
var trs = document.getElementById('table').tBodies[0].getElementsByTagName('tr');
// disable text selection
document.onselectstart = function () {
return false;
}
function RowClick(currenttr, lock) {
if (window.event.ctrlKey) {
toggleRow(currenttr);
}
if (window.event.button === 0) {
if (!window.event.ctrlKey && !window.event.shiftKey) {
clearAll();
toggleRow(currenttr);
}
if (window.event.shiftKey) {
selectRowsBetweenIndexes([lastSelectedRow.rowIndex, currenttr.rowIndex])
}
}
}
function toggleRow(row) {
row.className = row.className == 'selected' ? '' : 'selected';
lastSelectedRow = row;
}
function selectRowsBetweenIndexes(indexes) {
indexes.sort(function (a, b) {
return a - b;
});
for (var i = indexes[0]; i <= indexes[1]; i++) {
trs[i - 1].className = 'selected';
}
}
function clearAll() {
for (var i = 0; i < trs.length; i++) {
trs[i].className = '';
}
}
});
body{font-size:62.5%;}
td { padding: 0.2em 0.4em; }
.selected { background: lightBlue }
.mainheading4{
border: 1px solid;
border-color: lightgray;
width:33.3%;
height:17px;
font-size:15px;
padding-left: -5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
i use
$("tr").on("mousedown=RowClick(this,false)") <
for getting mouse event.
but its not taken.
There are couple of wrong doings.
1) Assign id to table without which you will not get table rows as in below line
var trs = document.getElementById('table').tBodies[0].getElementsByTagName('tr');
E.g. In your tableCreate method add below lines of code.
var body = document.body,
tbl = document.createElement('table'),
tableId = document.createAttribute('id');
tableId.value = "table";
tbl.setAttributeNode(tableId);
2) Second register mouse down event like suggested by feela,
$(document).on('click', 'tr', function () {
RowClick(this, false);
});
Hope it will resolve your issue.
This is not a valid syntax for on. See: http://api.jquery.com/on/
What you probably meant was:
$("tr").on("mousedown", function(event) {
RowClick(event.target, false);
});

How to create board NxN using JavaScript and jQuery

I am trying to create board game (like chess board game) with JavaScript.
When I tried to do it this is what happened:
The <tr> got closed immediately with </tr>, same thing with <table> </table>
I tried to replace the append() method with appendTo() or add() but it didn't help
This is my JavaScript code:
var boardSize = 5;
$(function() { //on load
printBoard(boardSize);
});
function printBoard(i_BoardSize) {
var maxRow = parseInt(i_BoardSize);
var maxCol = parseInt(i_BoardSize);
var num = 1;
$("#board").append("<table oncontextmenu=\"return false\">");
for(var row = maxRow - 1; row >= 0 ; row--) {
$("#board").append("<tr>");
for(var col = 0; col < maxCol ; col++) {
$("#board").append("<td>" + num + "</td>");
num++;
}
$("#board").append("</tr>");
}
$("#board").append("</table>");
}
CSS:
td {
width: 32px;
height: 32px;
cursor: pointer;
text-align: center;
border: 2px solid blue;
}
.redborder {
background-color: red;
color: white;
}
.blueborder {
background-color: blue;
color: white;
}
HTML:
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel='stylesheet' type='text/css' href='css/board.css' />
<script type="text/javascript" src="jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="Scripts/board.js"></script>
</head>
<body>
<p> <center><h3><font size="20" color="black"> Board Game</font></h3></center></p>
<div>
<div id="board">
<div class="cell">
</div>
</div>
</div>
</body>
</html>
This happens because jQuery append() method not supporting only closing tags and trying to close tags if they wasn't closed in provided param. To solve this you need to assign your append() result to some variable, for example:
var myTable = $("<table oncontextmenu=\"return false\"></table>").appendTo("#board");
and then append your rows to this var:
var myRow = $("<tr></tr>").appendTo( myTable );
Same with columns:
myRow.append("<td>" + num + "</td>");
By using appendTo method you will be able to get newly created elements.
So your final code should look like:
var boardSize = 5;
$(function() { //on load
printBoard(boardSize);
});
function printBoard(i_BoardSize) {
var maxRow = parseInt(i_BoardSize);
var maxCol = parseInt(i_BoardSize);
var num = 1;
var myTable = $("<table oncontextmenu=\"return false\"></table>").appendTo("#board");
for (var row = maxRow - 1; row >= 0; row--) {
var myRow = $("<tr></tr>").appendTo(myTable);
for (var col = 0; col < maxCol; col++) {
myRow.append("<td>" + num + "</td>");
num++;
}
}
}
The others have supplied you with why this is happening but I thought I might give an example of how you might make better use of css and more recent dom usage.
Fiddle: http://jsfiddle.net/np62shu6/1/
But the basic idea is to define the number of cells, then write out a series of divs that have a 20% float value. In the end you have a chess board with a cell data attribute.
HTML:
<div id="game">
</div>
CSS:
.cell{
width:20%;
float:left;
text-align:center;
}
.odd{
background:#eee;
}
JS (assumed you place this in a load handler):
var cells = 25;
var cell;
var h;
for(var i = 1; i <= cells; i ++)
{
cell = $('<div>').addClass('cell').attr('data-cell', i).text(i);
if(i % 2 == 1)
cell.addClass('odd');
$('#game').append(cell);
}
h = $('.cell:last-of-type').width();
$('.cell').css({height: h, lineHeight: h + 'px'});
As others have said, append is a sequential method, so calling it one after the other will just keep dropping things in the DOM. But you can create elements, then add things to those elements using append, then use append to add that whole group to another...
My example does not show this. My example is just an alternative to what you wrote. I would not do it the way you are doing it is all.
Another slight side note - chess boards have 64 cells (8 x 8), but I left it at 25 because your example did this.
When you append a tag with jQuery it doesn't work like appending text to a HTML string. Instead it creates the dom element. Try something like this instead, notice the absence of closing tags and td is appended directly to the latest tr:
var boardSize = 5;
$(function() { //on load
printBoard(boardSize);
});
function printBoard(i_BoardSize)
{
var maxRow = parseInt(i_BoardSize);
var maxCol = parseInt(i_BoardSize);
var num = 1;
$("#board").append("<table oncontextmenu=\"return false\">");
for(var row = maxRow - 1; row >= 0 ; row--)
{
$("#board table").append("<tr>");
for(var col = 0; col < maxCol ; col++)
{
$("#board tr:last").append("<td>" + num + "</td>");
num++;
}
}
}
The error is here:
function printBoard(i_BoardSize)
{
var maxRow = parseInt(i_BoardSize);
var maxCol = parseInt(i_BoardSize);
var num = 1;
$("#board").append("<table oncontextmenu=\"return false\">");
for(var row = maxRow - 1; row >= 0 ; row--)
{
#here
$("#board").append("<tr>");
for(var col = 0; col < maxCol ; col++)
{
#here
$("#board").append("<td>" + num + "</td>");
num++;
}
$("#board").append("</tr>");
}
$("#board").append("</table>");
}
You are appending each element to the #board instead of properly nesting them. try keeping the created elements in variables, and do nesting:
function printBoard(i_BoardSize)
{
var maxRow = parseInt(i_BoardSize);
var maxCol = parseInt(i_BoardSize);
var num = 1;
$tableelement = $("<table oncontextmenu=\"return false\"></table>");
$("#board").append($tableelement);
for(var row = maxRow - 1; row >= 0 ; row--)
{
#here
$rowelement = $("<tr></tr>");
$tableelement.append($rowelement);
for(var col = 0; col < maxCol ; col++)
{
#here
$rowelement.append("<td>" + num + "</td>");
num++;
}
}
}
Reason: certain browsers will immediately try to fix malformed HTML, and in the middle of the execution, the items are malformed while you insert it, and are wellformed after you finish. in the middle -this function's execution is not atomic- the code is malformed and the browser tries to fix it by closing the tags you add. That's why you need to add elements by nesting -opening and closing the tags for them beforehand-
$(function() { //on load
var boardSize = 5;
printBoard(boardSize);
});
function printBoard(i_BoardSize)
{
var maxRow = parseInt(i_BoardSize),
maxCol = maxRow;
var $table = $("<table oncontextmenu='return false'></table>").appendTo($("#board"));
for(var row = 1; row <= maxRow; row++)
{
var $row = $("<tr/>").appendTo($table);
for(var col = 1; col <= maxCol; col++)
{
$row.append("<td>" + (row*col) + "</td>");
}
}
}
td {
width: 32px;
height: 32px;
cursor: pointer;
text-align: center;
border: 2px solid blue;
}
.redborder {
background-color: red;
color: white;
}
.blueborder {
background-color: blue;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p> <center><h3><font size="20" color="black"> Board Game</font></h3></center></p>
<div>
<div id="board">
<div class="cell">
</div>
</div>
</div>
Side note: You don't have to append the closing tags manually...
This is way easier and cleaner if you just learn JavaScript and work in the DOM.
function makeBoardWithoutJQuery(xs, ys) {
var table = document.createElement('table');
var tbody = document.createElement('tbody');
for (var y=0; y<ys; ++y) {
var tr = document.createElement('tr');
for (var x=0; x<xs; ++x) {
var td = document.createElement('td');
td.innerHTML = (y*xs) + x;
tr.appendChild(td);
}
tbody.appendChild(tr);
}
table.appendChild(tbody);
return table;
}

How to change the content of a webpage without using document.write?

I have a .js file that creates a 4x4 table that way:
document.write('<div align="center"><table>');
for (var a = 0; a < 4; a++) {
document.write('<tr>');
for (var b = 0; b < 4; b++) {
document.write('<td align="center" id="t' +((4 * a) + b) + '"></td>');
}
document.write('<\/tr>');
}
What if I want to add one column and one row to that table after the page is loaded? In other terms, I'm looking for the same function but the "4" is a variable and I get its value from a checkbox.
(I didn't put that code in a proper function because every time I call document.write in a function, the page goes blank).
Maybe there is another way to use it in a function without document.write and that's what I'm looking for.
So I tried to concat all the '' strings and apply them to the .innerHTML of the table, but it didn't work. Any ideas why? And how can I correct the bug?
Thank you. (No jQuery answers please...)
You can use the standard document methods. Documentation can be found on MDN
CSS
table {
width: 100px;
height: 100px;
border-style: solid;
border-width: 3px;
}
td {
width: 25px;
height: 25px;
border-style: solid;
border-width: 1px;
}
Javascript
var table = document.createElement('table'),
tHead = document.createElement('thead'),
tBody = document.createElement('tbody'),
row,
cell,
a,
b;
table.align = 'center';
table.appendChild(tHead);
table.appendChild(tBody);
for (a = 0; a <= 3; a += 1) {
row = tBody.insertRow(-1);
for (b = 0; b <= 3; b += 1) {
cell = row.insertCell(-1);
cell.id = (4 * a) + b;
cell.align = 'center';
cell.appendChild(document.createTextNode(cell.id));
}
}
document.body.appendChild(table);
On jsFiddle
var main = document.getElementById("table");
document.write('<div align="center" id="table"><table>');
for (var a = 0; a < 4; a++) {
main.appendChild('<tr>');
for (var b = 0; b < 4; b++) {
main.appendChild('<td align="center" id="t' +((4 * a) + b) + '"></td>');
}
main.appendChild('<\/tr>');
}
I'm basically just switching document.write for appendChild(). Does that work for you?

Categories