I am trying to develop a pretty simple and straight forward website. I have a table and a user can fill information in the input="text" fields. I add rows with the plus button that triggers the insertRow() function and remove rows with removeRow() function dynamically. The wipe button removes every text from input="text" fields. When I click the proceed button, the function proceed() is triggered which rebuilds the above table in a new one below. After the rebuild, I add the text from the fields and then, run the removeButtons() function to remove all the buttons from the right side of the tables.
The problem is that I run the removeButtons() inside the proceed() function but the removeButtons() does not get executed. I can not seem to find what is wrong even though I spend quite some time trying to solve the problem, that is why I am requesting help from people with much more experience than me. I know probably the problem is in the proceed() function but I tried several things from which none solved my problem.
My code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
.btndiv {
position: relative;
top: -20px;
}
.btn {
position: absolute;
right: -30px;
width: 20px;
height: 20px;
background-image: url(minus.jpg);
cursor: pointer;
}
.btnPlus {
position: absolute;
right: -60px;
width: 20px;
height: 20px;
background-image: url(plus.jpg);
cursor: pointer;
}
.hideP {
display: none;
}
table,
td,
th {
border: 1px solid #ddd;
}
table {
border-collapse: collapse;
}
</style>
<script>
function insertRow() {
//>>> Inserting a row and a div that holds the buttons on every last cell in each row
var table = document.getElementById("myTable");
var count = document.getElementById("myTable").rows.length;
var row = table.insertRow(count);
var cell = 0;
while (cell <= 6) {
var cl = row.insertCell(cell);
cl.innerHTML = "<input type='text' />";
if (cell == 6) {
cl.innerHTML = "<input type='text' /><div class='btndiv'><div class='btn' onclick='deleteRow(this.id)'></div><div class='btnPlus' name='plus' onclick='insertRow()'></div></div>";
}
cell++;
}
hidePlus();
resetIds();
}
function deleteRow(theId) {
//>>> Deleting a row
var count = document.getElementById("myTable").rows.length;
if (count == 3) {
alert("The table must have at least one row!");
} else {
theId++;
theId++;
document.getElementById("myTable").deleteRow(theId);
hidePlusDelete();
resetIds();
}
}
function resetIds() {
//>>> Resetting the ids of my buttons dynamically (when inserting or removing row)
var count = document.getElementById("myTable").rows.length;
var x = document.getElementsByClassName("btn");
var y = 0;
var temp;
while (y <= count) {
temp = x[y];
temp.setAttribute("id", y);
y++;
}
}
function hidePlus() {
//>>> Hiding all plus buttons in every row except the last one on the right side of the minus button
var count = document.getElementById("myTable").rows.length;
if (count > 3) {
var x = document.getElementsByClassName("btnPlus");
var xlength = x.length;
var xlengthnew = xlength - 1;
var y = 0;
var temp;
while (y < xlengthnew) {
temp = x[y];
temp.setAttribute("class", "hideP");
y++;
}
}
}
function hidePlusDelete() {
var count = document.getElementById("myTable").rows.length;
if (count >= 3) {
var x = document.getElementsByClassName("hideP");
var xlength = x.length;
var xlengthnew = xlength - 1;
var y = 0;
var temp;
if (y === xlengthnew && count < 3) {
temp = x[y];
temp.setAttribute("class", "btnPlus");
}
}
}
function clearTable() {
//>>> Clear all input="text" fields
var inp = document.getElementsByTagName('input');
for (var i in inp) {
if (inp[i].type == "text") {
inp[i].value = "";
}
}
}
function proceed() {
//>>> Get text from text boxes and store them in the text variable
//>>> Counter variable to get the number of input="text" fields
var text = "";
var count = 0;
var inp = document.getElementsByTagName("input");
for (var i in inp) {
if (inp[i].type == "text") {
text += inp[i].value;
text += ";";
count++;
}
}
//>>> Store the HTML code from myTable in data variable
//>>> Put the HTML code in newTable
var data = document.getElementById("myTable").innerHTML;
document.getElementById("newTable").innerHTML = data;
//>>> Splitting my text in parts
//>>> Put the text in the input="text" of newTable
var temp = 0;
var counter = 0;
var tempor;
var temporary;
var values = text.split(";");
var p2inp = document.getElementsByTagName("input");
for (var c in p2inp) {
if (p2inp[c].type == "text") {
temp = counter + count + 2;
tempor = p2inp[temp];
temporary = values[counter]
tempor.value = temporary;
//inp[temp].setAttribute("readonly", "readonly");
//inp[temp].setAttribute("disabled", "disabled");
counter++;
}
}
//>>> Hiding buttons from the tables
//>>> The buttons are divs modified to look like buttons with css
removeButtons();
}
function removeButtons() {
//>>> Adding the css class hideP (display="none")
alert("in remove buttons");
var divcount = document.getElementsByClassName("btndiv").length;
alert(divcount);
var divcounter = 0;
var divtemp = 0;
var divinp = document.getElementsByClassName("btndiv");
while (divcounter <= divcount) {
divtemp = divinp[divcounter];
divtemp.setAttribute("class", "hideP");
divcounter++;
}
}
window.onload = insertRow;
</script>
</head>
<body>
<table id="myTable" style="width: 50%">
<col>
<colgroup span="2"></colgroup>
<colgroup span="2"></colgroup>
<tr>
<th colspan="1" rowspan="2">Name, strength and form of medicine</th>
<th colspan="1" rowspan="2">What it's for</th>
<th colspan="4" scope="colgroup">How much to take, when</th>
<th colspan="1" rowspan="2">Extra instructions</th>
</tr>
<tr>
<th scope="col">Breakfast</th>
<th scope="col">Midday meal</th>
<th scope="col">Evening meal</th>
<th scope="col">Bed Time</th>
</tr>
</table>
<br/>
<input type="image" src="whipe.png" onclick="clearTable()" width="50px" height="50px" />
<input type="image" src="go.png" onclick="proceed()" width="50px" height="50px" />
<br/>
<br/>
<br/>
<table id="newTable" style="width: 50%"></table>
</body>
</html>
Your problem (maybe) is this loop, if you comment it out, the desired function will run, so start search for an error here, or from the used variables in your loop:
for (var c in p2inp) {
if (p2inp[c].type == "text") {
temp = counter + count + 2;
tempor = p2inp[temp];
temporary = values[counter]
tempor.value = temporary;
//inp[temp].setAttribute("readonly", "readonly");
//inp[temp].setAttribute("disabled", "disabled");
counter++;
}
}
And as others said, always check for errors in the console.
Also I recommend to try start to debug your javascript.
Related
I have a dynamic table. Data comes from inputs by Create button click.
If at least one row includes current input ID-field value (not inserted yet) program should forbid row insertion.
I tried to add checkId() logic but it didn't work for me:
checkId = () => {
var isDuplicate = false;
var idVal = inputs[0].value;
if (textbox.value.includes(idVal)){
isDuplicate = true;
row.remove();
alert("Pease, enter unique ID")
}
return isDuplicate;
}
Is there any way to implement this logic within existing code (no jQuery)?
Here are both html and js:
let headerArr = new Array();
headerArr = ['ID', 'Fname', 'Lname', 'Age'];
//console.log(headerArr.length)
//inputs
var div = document.getElementById('enter');
var inputs = div.getElementsByTagName('input')
var count = 0;
createTable = () => {
let storage = document.createElement('table');
storage.setAttribute('id', 'storage'); //set the table ID
let row = storage.insertRow(-1);
for (let h = 0; h < headerArr.length; h++) { //table header
let headCols = document.createElement('th');
headCols.innerHTML = headerArr[h];
row.appendChild(headCols);
}
let div = document.getElementById('dynamicTable');
div.appendChild(storage); //add the table to the page
}
/* checkId = () => {
var isDuplicate = false;
var idVal = inputs[0].value;
//textbox = document.createElement('input')
if (textbox.value.includes(idVal)){
isDuplicate = true;
row.remove();
alert("Pease, enter unique ID")
}
return isDuplicate;
} */
//add a new row to the table
addEnd = () => {
let table = document.getElementById('storage');
var rowCount = table.rows.length; //get table row count
var row = table.insertRow(rowCount)
var textbox;
// if((!checkId()) && rowCount > 1){
for (let c = 0; c <= headerArr.length - 1; c++) {
var cell = document.createElement('td');
cell = row.insertCell(c);
textbox = document.createElement('input');
textbox.setAttribute('type', 'text');
textbox.setAttribute('readonly', true);
textbox.setAttribute('value', inputs[c].value);
cell.appendChild(textbox);
}
// }
}
let createBtn = document.getElementById('create-btn');
createBtn.addEventListener('click', addEnd, false);
<!DOCTYPE html>
<html>
<head>
<title>Table</title>
<style>
table {
width: 100px;
border-spacing: 10px;
padding: 10px;
}
table,
th,
td {
border: 1px solid gray;
border-collapse: collapse;
padding: 2px 3px;
text-align: left;
}
.enter {
display: block;
float: right;
margin-bottom: 10px
}
}
</style>
</head>
<body onload="createTable()">
<div id="dynamicTable"></div>
<div id="enter" class="enter">
<p>ID:<br>
<input class="enter__id" type="text" id="id"></input>
<br>
<p>First name:<br>
<input class="enter__name type=" text " id="name "></input>
<br>
<p>Last name:<br>
<input class="enter__surname type="text" id="surname"></input>
<br>
<p>Age:<br>
<input class="enter__age" type="text" id="age"></input>
<br>
<button id="create-btn">Create</button>
<button id="update-btn">Update</button>
</div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
Please, help me to find the right way to solve it.
if (textbox.value.includes(idVal))
Your condition isn't valid, because you try to get .value from a variable that is undefined in your context.
I fix your js code :
let headerArr = new Array();
headerArr = ['ID', 'Fname', 'Lname', 'Age'];
//console.log(headerArr.length)
//inputs
var div = document.getElementById('enter');
var inputs = div.getElementsByTagName('input')
var count = 0;
createTable = () => {
let storage = document.createElement('table');
storage.setAttribute('id', 'storage'); //set the table ID
let row = storage.insertRow(-1);
for (let h = 0; h < headerArr.length; h++) { //table header
let headCols = document.createElement('th');
headCols.innerHTML = headerArr[h];
row.appendChild(headCols);
}
let div = document.getElementById('dynamicTable');
div.appendChild(storage); //add the table to the page
}
checkId = () => {
var idVal = inputs[0].value;
for (var i = 0; i < document.getElementsByClassName('id_cells').length; i++) {
let el_id = document.getElementsByClassName('id_cells');
if (el_id.value = idVal) {
alert("Pease, enter unique ID");
return true
}
}
return false;
}
//add a new row to the table
addEnd = () => {
let table = document.getElementById('storage');
var rowCount = table.rows.length; //get table row count
var row = table.insertRow(rowCount)
if ((!checkId()) && rowCount > 1) {
for (let c = 0; c <= headerArr.length - 1; c++) {
var cell = document.createElement('td');
cell = row.insertCell(c);
textbox = document.createElement('input');
textbox.setAttribute('type', 'text');
textbox.setAttribute('readonly', true);
textbox.setAttribute('value', inputs[c].value);
if (c == 0) {
textbox.setAttribute('class', 'id_cells');
}
cell.appendChild(textbox);
}
}
}
let createBtn = document.getElementById('create-btn');
createBtn.addEventListener('click', addEnd, false);
When you create your cells, if it's the first of the row (where the id should be displayed), I add a class to the cell to keep a reference. When you need to check for duplicate id, you get all the tag with the class i set beforehand and check their id in a loop.
I hope it solved your issue
I'm trying to accomplish the following.
I have a "grid" in which each cell can be 'owned' by a user.
To 'own' some new cells, the user should be able to click on two points (in a straight line) on the grid and then confirm by clicking on a button or cancel by clicking on another button, which updates the state of the grid. When both points are clicked, the cells between the two clicked ones must change color.
I should mention that I would like to achieve this only by using plain Javascript / PHP, if possible.
What I've done so far:
I have stored the 'grid' in a DB, having a record for each cell, containing position (i, j), owner and some other feature.
I query the DB using PHP, I save everything in memory (2D array - the grid is supposed to be small) and represent the grid by generating an HTML table
I'm trying to use JS to change the color of the cells when clicking, but I'm having problems (I'm new to JS and web programming in general).
I'm sure there's some kind of pattern to do what I want to do (surely is not rocket science), and would completely agree the following is pure Spaghetti code, but that's the only way I thought of doing it given my very very limited experience.
I do the following.
I have an HTML page with a named div in which I represent the table
<div id="Vis_table"> <?php echo $table ?> </div>
At the end of the body I have a script, which I report in its essential elements
var click = 0;
var grid = <?php echo json_encode($grid); ?>;
var Y_grid = <?php echo Y_g; ?>;
if (click == 0) { //first click
var cells = document.getElementsByTagName("th"); //take all cells
for (var i = 0; i < cells.length; i++) { // all rows
var row = parseInt(i / (Y_grid)); //dimensions
var col = i % (Y_grid);
cells[i].onclick = (function (xr, yc, index) {
return function () {
if (click == 0) { //first click, start
var tab = "<table>";
for (var x = 0; x < grid.length; x++) {
tab += "<tr>";
for (var y = 0; y < grid[0].length; y++) {
if (x == xr && y == yc) { //if it's the cell i clicked on
tab += "<th class = 'clicked'>" + x + " " + y + "</th>";
} else {
tab += "<th class = 'free'> </th>";
}
}
tab += "</tr>";
}
tab += "</table>";
click = 1;
document.getElementById("Vis_table").innerHTML = tab;
}
};
})(row, col, i);
}
}
Now, this works just fine, and the clicked cell changes color according to the CSS rules. The problem is that I don't know how to go on (ie color the cells between the first and the second clicked cells).
Do you have any suggestion?
Table prepared via JS(to do this in PHP is your task).
Area marking in JS :)
I've split the task in small steps to its easier to understand. If you got questions, feel free to ask!
/* This is generated by PHP (for testing i do it with js here) >>> */
var rows = 5;
var cols = 10;
var $table = $('#myTable');
for( let row = 1; row <= rows; row++ ) {
$row = $('<tr>');
for( let col = 1; col <= cols; col++ ) {
$col = $('<td>');
$col.text(row + "|" + col);
$col.attr('data-row', row);
$col.attr('data-col', col);
$row.append($col);
}
$table.append($row);
}
/* <<< */
var cells = [];
$('#myTable').click(function(e) {
$cell = $(e.target);
cells.unshift($cell);
if(cells.length > 2) {
cells.pop();
}
resetCells();
markActiveCells();
if ( cells.length == 2 ) {
fillArea();
}
});
function resetCells() {
$('#myTable td').removeClass('active');
$('#myTable td').removeClass('area');
}
function markActiveCells() {
$(cells).each(function() {
$(this).addClass('active');
});
}
function fillArea() {
if( cells.length < 2 ) return;
start_row_cell = (cells[0].data('row') <= cells[1].data('row'))?0:1;
start_col_cell = (cells[0].data('col') <= cells[1].data('col'))?0:1;
start_row = cells[start_row_cell].data('row');
end_row = cells[(start_row_cell+1)%2].data('row');
start_col = cells[start_col_cell].data('col');
end_col = cells[(start_col_cell+1)%2].data('col');
for( let row = start_row; row <= end_row; row++ ) {
for( let col = start_col; col <= end_col; col++ ) {
$('#myTable td[data-row=' + row + '][data-col=' + col + ']').addClass('area');
}
}
}
td {
font-size: 10px;
width: 25px;
height: 25px;
background-color: #EEE;
text-align: center;
}
td.active {
background-color: #FA0 !important;
}
td.area {
background-color: #FDA;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable" cellspacing=0></table>
I'm making a Javascript Tic Tac Toe Game, and I'm having trouble with the reset button. I believe that in my clickHandler function, I should be calling the blankPattern function. It's not working, though.
<!doctype html>
<html>
<head>
<title>Tic Tac Toe</title>
<style>
#stage {
position:relative;
}
.cell {
position:absolute;
border:3px solid black;
background-color:white;
font-size: 300px;
text-align: center;
color: red;
}
#reset {
font-family: "Lucida Console", Monaco, monospace;
color: white;
height: 100px;
width: 150px;
background-color:black;
top: 45%;
left: 50%;
position: absolute;
font-size: 30px;
}
</style>
</head>
<body>
<div id="stage"></div>
<button id = "reset">Reset</button>
<script>
var reset = document.querySelector("#reset");
reset.style.cursor = "pointer";
reset.addEventListener("click", clickHandler, false);
// GRAB A REFERENCE TO THE STAGE
var stage = document.querySelector("#stage");
// THE SIZE AND SPACE OF EACH CELL
var SIZE = 290;
var SPACE = 0;
// THE ARRAY DIMENSIONS - TRY CHANGING THESE TO GET LARGER OR SMALLER GRAPHS
var MAXROWS = 3;
var MAXCOLS = 3;
// THE 2D ARRAY THAT DEFINES THE PATTERN
var pattern = blankPattern();
// CREATE THE DIVS and POSITION THEM IN THE STAGE... BUT DON'T WORRY ABOUT COLORING THEM HERE!!!!
for (var row = 0; row < MAXROWS; row++) {
for (var col = 0; col < MAXCOLS; col++) {
// CREATE A DIV HTML ELEMENT CALLED CELL
var cell = document.createElement("div");
// SET ITS CSS CLASS TO CELL
cell.setAttribute("class", "cell");
// GIVE EACH OF THE CREATED DIVS A UNIQUE ID
// BASED ON THE ROW# AND COL#
// EXAMPLE : <div id="c-1-2" class="cell"></div>
// In this example, row = 1 and col = 2
cell.setAttribute("id", "c-" + row + "-" + col);
// !!!!! ADD A CLICK HANDLER TO EACH OF THE INDIVIDUAL DIVS
cell.addEventListener("click", cellClick, false);
// ADD THE DIV HTML ELEMENT TO THE STAGE
stage.appendChild(cell);
// POSITION THE CELL IN THE CORRECT PLACE
// WITH 10 PIXELS OF SPACE AROUND IT
cell.style.width = SIZE + "px";
cell.style.height = SIZE + "px";
cell.style.top = row * (SIZE + SPACE) + "px";
cell.style.left = col * (SIZE + SPACE) + "px";
}
}
colorPattern();
// ***********************************************************************************************
// ***********************************************************************************************
// ***********************************************************************************************
// FUNCTION DECLARATIONS
// ***********************************************************************************************
// ***********************************************************************************************
// ***********************************************************************************************
// ***********************************************************************************************
function blankPattern() {
// ***********************************************************************
// This function creates a new 2D array based on the size of the MAXROWS and MAXCOLS
// All cells of the array are initialized to 0
// The function RETURNS this new 2D array back to the calling function
// ***********************************************************************
// CREATE A LOCAL VARIABLE TO HOLD THE 2D ARRAY
var newPattern = [];
// LOOP THROUGH ALL THE ROWS
for (var row = 0; row < MAXROWS; row++) {
// EACH ROW OF THE ARRAY.. .IS ALSO AN ARRAY... SO INITIALIZE IT TO BE ONE
newPattern[row] = [];
// LOOP THROUGH ALL THE COLUMNS OF THE ARRAY
for (var col = 0; col < MAXCOLS; col++) {
// INITIALIZE ALL THE CELL VALUES TO BE 0
newPattern[row][col] = 0;
}
}
// RETURN THIS NEW ARRAY BACK TO THE CALLING FUNCTION
return newPattern;
}
function colorPattern() {
// ***********************************************************************
// This function uses the GLOBAL VARIABLE "pattern" to color the divs
// ***********************************************************************
for (var row = 0; row < MAXROWS; row++) {
for (var col = 0; col < MAXCOLS; col++) {
var cell = document.querySelector("#c-" + row + "-" + col);
// COLOR THE CELL IF IT'S ARRAY VALUE IS "1"
if (pattern[row][col] === 0) {
cell.innerHTML = "";
} else if (pattern[row][col] === 1) {
cell.innerHTML = "X";
} else if (pattern[row][col] === 2) {
cell.innerHTML= "O";
}
}
}
}
function cellClick() {
// RIP APART THE DIV ID THAT WAS CLICKED ON
// WERE HIDING THE ROW AND COLUMN IN THE ID
// THE FORMAT OF THE ID IS "C-ROW#-COL#"
// EXAMPLE : <div id="c-1-2" class="cell"></div>
// In this example, row = 1 and col = 2
var zpos;
thisid = "0-1"
// THE "this" KEYWORD RETURNS THE HTML ELEMENT THAT WAS CLICKED ON
var thisid = this.id;
zpos = thisid.indexOf("-");
thisid = thisid.substr(zpos+1);
zpos = thisid.indexOf("-");
var thisRow = thisid.substr(0,zpos);
var thisCol = thisid.substr(zpos+1);
// now that we have the row and column for this div... change the array
if (pattern[thisRow][thisCol] === 0) {
pattern[thisRow][thisCol] = 1;
}
else if (pattern[thisRow][thisCol] === 1) {
pattern[thisRow][thisCol] = 2;
}
else {
pattern[thisRow][thisCol] = 0;
}
colorPattern();
}
function clickHandler ()
{
pattern = blankPattern();
}
</script>
</body>
</html>
This worked for me.
function clickHandler() {
pattern = blankPattern();
colorPattern();
}
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;
}
Please see the below code, the table should change the number of rows based on input selected in the selected id option below, but only the first value of select id is read, and the number of rows are not changing based on the selection, can you please point out the mistake in my code ?
http://jsfiddle.net/uTY6n/14/
HTML:
<div id="scrollingDiv">
<select id="read">
<option value="1">1</option>
<option value="2">2</option></select>
<table id="contentTable" border="1">
<!-- Fill table programmatically -->
</table>
</div>
JAVASCRIPT:
function buildTable()
{
var myTable =document.getElementById("contentTable");
var j=document.getElementById("read").value;
var rows = [];
var cells = [];
for( var i = 0; i < j; i++ )
{
rows[i] = myTable.insertRow(i);
if(i%3==2)rows[i].addClass("everyrow");
cells[i] = [];
for( var x = 0; x < 3 ; x++ )
{
cells[i][x] =document.createElement((x==0)?"th":"td");
cells[i][x].innerHTML = (x==0)?"<input>":"<input>";
rows[rows.length - 1].appendChild(cells[i][x]);
}
}
}
buildTable();
CSS:
#scrollingDiv
{
border: 1px groove black;
height: 350px;
width: 350px;
background: #ffffff;
overflow: auto;
}
#contentTable
{
height: 350px;
width: 350px;
}
.every3rdrow{
border-bottom:3px solid black;
}
See this demo.
First, you need to attach an event listener to the <select>:
document.getElemenyById('read').addEventListener('change', buildTable);
Then, you need to make sure the table is emptied before it's rebuilt every time buildTable() is called:
function buildTable() {
var myTable =document.getElementById("contentTable");
var j=document.getElementById("read").value;
var rows = [];
var cells = [];
while (myTable.hasChildNodes()) {
myTable.removeChild(myTable.lastChild);
}
...
}
Hope this helps!
try
function buildTable() {
var myTable =document.getElementById("contentTable");
myTable.innerHTML = "";
var j=document.getElementById("read").value;
var rows = [];
var cells = [];
var myHtml = "";
for( var i = 0; i < j; i++ ) {
myHtml += "<tr>";
for( var x = 0; x < 3 ; x++ ){
myHtml += "<td></td>"
}
myHtml += "</tr>";
}
myTable.innerHTML = myHtml;
}
thats the general idea, also be sure to call this onChange of your select.