I am trying to get to the logic of the Tic Tac Toe game which I almost have made a logic, but I am stuck while pushing the Data to the array. Here is a fiddle that I have created.
http://jsfiddle.net/afzaal_ahmad_zeeshan/6bgjp/1/
Let me explain the whole thing to you!
I am trying to use the 9 td of the table as the 8 rows of the possible win. For that I have given some of the tds a className depending on their location in the table.
The HTML is simple
<div class="vicvacvoe">
<table>
<tr>
<td class="line1 line4 line7"></td>
<td class="line1 line5"></td>
<td class="line1 line6 line8"></td>
</tr>
<tr>
<td class="line2 line4"></td>
<td class="line2 line5 line7 line8"></td>
<td class="line2 line6"></td>
</tr>
<tr>
<td class="line3 line4 line8"></td>
<td class="line3 line5"></td>
<td class="line3 line6 line7"></td>
</tr>
</table>
</div>
Just a simple table with 9 tds, the CSS is not relative to this so leave it I guess.
jQuery for this also simple one. But I am not able to push the data to the Array.
var vic = $('.vicvacvoe table tr td');
var player = 1;
var tick = '✓';
var cross = 'X';
var user1 = [];
var user2 = [];
vic.click(function () {
var className = $(this).attr('class');
if (className != 'dead') {
// A new board place to write on...
// Now do the processes here...
if (player == 1) {
// First player!
var cArray = className.split(' ');
for (i = 0; i < cArray.length; i++) {
for (j = 0; j < user1.length; j++) {
// check for each class
if (user1[j] != cArray[i]) {
user1.push(cArray[i]);
}
}
}
} else {
/* code for second player, the same */
}
$(this).text('Works!');
$(this).attr('class', 'dead');
}
});
This is the entire jQuery script. Actually when I run the code, it really does go to the end of the stack (to the class attribute change script) and it locks the td for further process and it write Works! in the td too. But I am not able to get the classNames inside the Array for that user. I want to save the line number for each user and then check whether he has 3 spots filled or not. I need help with the Array part.
Thanks!
I prefer simplicity so you could use indexOf to check whether the class is already in the users' array like so:
if (player == 1) {
// First player!
var cArray = className.split(' ');
for (i = 0; i < cArray.length; i++) {
if(user1.indexOf(cArray[i]) == -1) {
user1.push(cArray[i]);
} else {
// css class is already in the array
}
}
}
Your issue is here:
for (j = 0; j < user1.length; j++) {
The only place you add to the user1 array is within this loop. Now the array is initially empty, so clearly this loop will never iterate as user1.length is always 0.
I think your intent with this bit of code was to check if the value was already in the array in which case I suggest using $.inArray.
Related
I want to detect the last table row cell of a table which doesn't have any value (text).
var all_product_cell = document.getElementsByClassName("product-cell");
for (var i = 0; i < all_product_cell.length; i++) {
var td = all_product_cell[i];
alert(all_product_cell.length);
}
This code returns the table rows length... but I don't know how to check the last row which is clean and put there a message "hello!"...
UPDATE :
With this code system find last cell and put HELLO, but how I check the last cells who haven't text value and put the Hello there?
var all_local_cell = document.getElementsByClassName("product-cell");
for (var i = 0; i < all_local_cell.length; i++) {
var td = all_local_cell[i];
total_rows = all_local_cell.length-1;
all_product_cell[total_rows].value = "HELLO";
const productTable = document.querySelector(".your-product-table"); // get the table
const textOnLastCell = productTable
.rows[productTable.rows.lenght -1] // get last row
.cells[productTable.rows[productTable.rows.lenght -1].cells.lenght -1] // get last cell of last row
.innerText // get inner text
You can get last row of table by using below line :
var product_table = document.getElementsByClassName("product-cell");
console.log(product_table);
for (var i = 0; i < product_table.length; i++) {
total_rows = product_table[i].rows.length;
last_row = product_table[i].rows[total_rows-1];
last_row_length = last_row.cells.length;
last_column = last_row.cells[last_row_length-1]; // directly get last cell
If(last_column.innerHTML() == “”){
last_column.innerHTML = “Hello friend”;
}
console.log(last_column.innerHTML);
for(var j =0;j<last_row.cells.length;j++){ // you can find through loop using which cells is empty
console.log(last_row.cells[j]);
}
// console.log(last_row);
}
If you give html code will help better way.
https://codepen.io/aviboy2006/pen/ZEYBWWE
Here's a table with two empty TD'S.
The function will get an array of all TD's with the class product-cell and loop through each cell and check if innerHTML is empty, and then it will set lastTD to the last empty TD and set its innerHTML to "Hallo"
setTextLastEmptyCell()
function setTextLastEmptyCell(){
let tds = document.getElementsByClassName('product-cell')
for(let td of tds){
if(td.innerHTML === '') lastTD = td
}
lastTD.innerHTML = 'HALLO'
}
<table>
<tr>
<td class="product-cell">ABC</td>
<td class="product-cell">DEF</td>
<td class="product-cell">CBA</td>
</tr>
<tr>
<td class="product-cell"></td>
<td class="product-cell">CDA</td>
<td class="product-cell">ACB</td>
</tr>
<tr>
<td class="product-cell">ABC</td>
<td class="product-cell"></td>
<td class="product-cell">DEF</td>
</tr>
</table>
I want to add numbers in <td></td> below via JavaScript. For example using the following description:
<td id='last'> + formatNumber(data.tickers[key].last) + </td>
<td id='high'> + formatNumber(data.tickers[key].high) + </td>
<td id='low'> + formatNumber(data.tickers[key].low) + </td>
How do I change the text of table data elements via JavaScript?
<td id='new1'> = + <td id='last'> + <td id='high'> + </td>
<td id='new2'> = + <td id='high'> + <td id='loww'> + </td>
Try this:
// these target the cell elements
let last = document.getElementById("last");
let high = document.getElementById("high");
let low = document.getElementById("low");
let new1 = document.getElementById("new1");
let new2 = document.getElementById("new2");
// now we convert cell content to numbers, add them and make them 2 decimal places.
new1.textContent = (parseFloat(last.textContent) + parseFloat(high.textContent)).toFixed(2);
new2.textContent = (parseFloat(high.textContent) + parseFloat(low.textContent)).toFixed(2);
td {
border: solid 1px;
}
<table>
<tr>
<th>last</th>
<th>high</th>
<th>low</th>
<th>new1</th>
<th>new2</th>
</tr>
<tr>
<td id='last'> 23.40 </td>
<td id='high'> 28.20 </td>
<td id='low'> 22.10 </td>
<td id='new1'></td>
<td id='new2'></td>
</tr>
</table>
First I'm going to make your life a bit easier. Instead of using document.getElementsByTagName('tr')[3].getElementsByTagName('td')[2] to get the fourth tr element's third td element ([0] = first, [2] = third, etc) this will help make your code much much easier to read. You don't need id attributes on every element if you know how reliable code and order are by default.
function tag_(t)
{//Example: tag_('body')[0];
return (document.getElementsByTagName(t)) ? document.getElementsByTagName(t) : false;
}
Object.prototype.tag_ = function(t)
{//Example: id_('unique_id').tag_('td')[0];
return (this.getElementsByTagName && this.getElementsByTagName(t) && this.getElementsByTagName(t).length > 0) ? this.getElementsByTagName(t) : false;
}
Secondly the easiest way to both read and write data to any element is to use textContent.
Read the fourth td on the third tr:
//Read an element's text node:
console.log(tag_('tr')[2].tag_('td')[5].textContent);
//Write to an element's text node:
tag_('table')[0].tag_('tr')[2].tag_('td')[5].textContent = '1,234');
JavaScript is a bit strict when it comes to types. So if you need to do some math with text content that you just read you need to convert it:
Number(tag_('tr')[1].tag_('td')[5].textContent);//'123' becomes `123`
Number(tag_('tr')[2].tag_('td')[2].textContent);//'a123' becomes `NaN` (Not a Number)
If I recall correctly I recently used the following to strip non-numeric text from a string:
var my_number = Number('String or replace with object reference'.replace(/\D/g,''));
Now that you're getting the read/write aspects and overcoming some of the more oddities associated with it I'll iterate over...iteration! You may already know this though I'm presuming a full answer is more desirable than a partial answer for not just you though also others reading this in the future.
var table = tag_('table');
for (var i = 0; i < table.length; i++)
{
console.log(table[i]);
var tr = table[i].tag_('tr');//Whatever table[i] is and it's table rows.
for (var j = 0; j < tr[i].length; j++)
{
console.log(tr[j]);
var td = table[i].tag_('tr')[j].tag_('td');//All the table data elements.
for (var k = 0; k < td.length; k++)
{
//apply read/write conditions here.
//potentially call a second global function to keep your code reusable.
}
}
}
That should help you get far enough with specific and iteral targeting of table data elements to help you learn and achieve your goals.
I am getting a Table from a database like this (row numbers may vary):
|Player 1|Player 2|
-------------------
|Danny |Danny |
|John |John |
|Mary |Mary |
I want to select two names, one from each Player column, and store them in two variables, say player1_id and player2_id which I will later use to insert data into the database. I also want to highlight the names when they are clicked. The highlight and the associated variable value should change when I click on another name.
For example, let's say I click on Danny and John from Player 1 and Player 2 respectively. These two names should get highlighted and the variables should get player1_id = "Danny" and player2_id = "John". If I change my mind and click on Mary on the Player 2 column, Mary should get highlighted, John should lose its highlight and player2_id should change to "Mary"
So far I managed to sort of getting only the highlight part (but when I click more than one names all stay highlighted). Could anyone point me to a correct direction, please?
Here is the JSFiddle code of what I have so far
try this: https://jsfiddle.net/dunsondog109/behcgwLf/7/
function inputClickHandler(e){
e = e||window.event;
var all = document.getElementsByTagName("td");
var tdElm = e.target||e.srcElement;
var tdIndex = tdElm.cellIndex;
var numberOfColumns = 2;
if(tdElm.style.backgroundColor == 'rgb(46, 204, 64)'){
tdElm.style.backgroundColor = '';
} else {
for (var i=0;i<all.length;i++) {
if (i%numberOfColumns==tdIndex%numberOfColumns) {
// It is in the same column
all[i].style.backgroundColor = '';
}
}
tdElm.style.backgroundColor = '#2ECC40';
}
}
You need to reset all the tds in your column first and then set the td that was clicked
maybe it will not help you, but this is what I created for fun ...
As I'm jQuery user I find it difficult to list the table for any actions using plain javascript ... I would prefer having list of players in some object, draw the table based on that list. Instead of adding css to table cell i would add class like active and then just easily remove / move that class to different player. Maybe even adding some classes or other data-attributes to the table cells to help identify correct row / cell ... Anyway, everything is possible, but with this design you will not get far with your project I think. Good luck.
var Game = function() {
var players = {};
var table = document.querySelector('#myTable');
var rows = table.querySelectorAll('tr');
function uncheckPlayers(col) {
for ( var i=0; i<rows.length; i++ ) {
var tds = rows[i].querySelectorAll('td');
for ( var x=0; x<tds.length; x++ ) {
if ( col === x ) {
tds[x].style.backgroundColor = '';
}
}
}
}
for ( var i=0; i<rows.length; i++ ) {
var tds = rows[i].querySelectorAll('td');
for ( var x=0; x<tds.length; x++ ) {
tds[x].addEventListener('click', function() {
var id = x;
return function() {
uncheckPlayers(id);
players[id] = new Player(id, this.innerText);
this.style.backgroundColor = 'red';
console.log(players);
}
}(x));
}
}
}
var Player = function(id, name) {
this.name = name;
this.id = id;
this.score = 0;
console.log(this);
};
var Game = new Game();
<html>
<head>
<title>Find table cell value on cell (table) click using JavaScript</title>
</head>
<body>
<center>
Click on table below to select Players.
<br />
<br />
</center>
<table align="center" id="myTable" border="1" style="cursor: pointer;">
<tr>
<th>Player 1</th><th>Player 2</th>
</tr>
<tr>
<td>Danny</td><td>John</td>
</tr>
<tr>
<td>John</td><td>Danny</td>
</tr>
<tr>
<td>Mary</td><td>Mary</td>
</tr>
</table>
<br />
</body>
</html>
I am trying to delete multiple columns from html table using javascript.
The logic it is using is that it searches in top row for tag "" and then deletes that column.
The problem is if only one cell in top row is having '', then it deletes that columns fine, but if there are multiple columns it throws error.
Here is my code
<!DOCTYPE html>
<html>
<body>
<table style="width:100%" border='1' id='Just_for_california'>
<tr>
<td><span></span></td>
<td>S</td>
<td><span></span></td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</table>
</body>
<script>
var dataTable_length = document.getElementById('Just_for_california').rows[0].cells.length;
var count_rows = document.getElementById('Just_for_california').rows.length;
var column_array = [];
for(var i=0; i<dataTable_length; i++)
{
var str = document.getElementById("Just_for_california").rows[0].cells[i].innerHTML;
if(str.search("<span></span>") != -1)
{
column_array.push(i);
}
}
var len = column_array.length;
for(var i=count_rows-1 ; i>=0;i--)
{
rows_number = document.getElementById('Just_for_california').rows[i];
console.log("row_number:"+i);
for(var j=0; j<len;j++)
{
rows_number.deleteCell(column_array[j]);
}
}
</script>
</html>
It happens because you calculate indexes incorrectly when you delete cells. I refactored you code (making it clearer) and it seems to work now:
var table = document.getElementById('Just_for_california'),
rows = table.rows;
for (var i = 0; i < rows[0].cells.length; i++) {
var str = rows[0].cells[i].innerHTML;
if (str.search("<span></span>") != -1) {
for (var j = 0; j < rows.length; j++) {
rows[j].deleteCell(i);
}
}
}
The problem is that you are trying to remove cells "horizontally" in the row. So say you want to delete cells at indexes 1 and 3 and there are 4 columns in the table. When you delete the first cell 1 it works fine. However then you move to the right and try to remove cell at index 3. This fails because since you have already removed cell 1, there is no cell with index 3 anymore. The maximum index now is 2. Hence the error.
In my improved code I'm removing columns "vertically", so such an issue can't happen.
Demo: http://jsfiddle.net/t2q60aag/
I have the following table generated by a cgi script:
<table>
<tr id='vfipbb'><td>col 1,0</td><td>col 1,1</td></tr>
<tr id='vfipbb.alipbb'><td>col 2,0</td><td>col 2,1</td></tr>
<tr id='vfipbb.esipbb'><td>col 3,0</td><td>col 3,1</td></tr>
<tr id='vfipbb.esipbb.esipbb_madrid'><td>col 4,0</td><td>col 4,1</td></tr>
<tr id='vfipbb.esipbb.esipbb_barcelona'><td>col 5,0</td><td>col 5,1</td></tr>
</table>
This is just a sample of what it would look like, but the important bit to note is the id.
when the webpage first loads all rows are collapsed except for the root context (vfipbb). I want to enable functionality when the root context is clicked it will expand all child rows listed under this, for example (alipbb), (esipbb) and if one of the child rows is clicked it will expand all grandchildren rows, for example (esipbb_madrid) (esipbb_barcelona).
Is there any efficient way of doing this in javascript based on ID? Any pointer in the right direction would be greatly welcome!
Not a working code, but something to get you started
// add click handlers to all tr
var tr0 = document.getElementsByTagName("tr");
for (var i = 0; i < tr0.length; i++) {
tr0[i].addEventListener("click", openChild);
}
function openChild() {
var id = this.id;
//regex that matches a string beginning with
//the id followed by dot and some other words
var regex = new RegExp("^" + id + ".[a-z_]+$", "g");
var tr1 = document.getElementsByTagName("tr");
//browse through the tr(s)
for (var i = 0; i < tr1.length; i++) {
//Learn regex test function!
if (regex.test(tr1[i].id)) //if a match found
//display children
document.getElementById(tr1[i].id).style.visibility = "visible";
}
}