Function name is not defined at HTMLTableCellElement.onclick - javascript

I want to make X and O game , So the first function i did it has loop and condition that when i click on any cell(td) in the table and if all cells in the table are empty wrote X in the cell which I clicked it , but I have here 2 problem ,
First one The console wrote (Sample1.html:53 Uncaught SyntaxError: Unexpected token '<') it refers to for loop, so I don't know what is the problem there.
the second problem console wrote also that my function name is not define , although the function name is correct so can anyone help me.
the JS codes is
<script >
/*var lastGame;*/
var TR=0;
var table = document.getElementById('tb');
function CheckAllEmpty(idClicked){
for(var x=0, x < table.rows.length; x++){
if(!table.rows[x])
{
TR++;
}
else{}
}
if(TR==9)
{
document.getElementById(idClicked).innerHTML="X";
}
else {}
}
</script>
And the HTML :
<table id="tb">
<tr>
<td id="td1" onclick="CheckAllEmpty(this.id);"></td>
<td id="td2"></td>
<td id="td3"></td>
</tr>
<tr>
<td id="td4"></td>
<td id="td5"></td>
<td id="td6"></td>
</tr>
<tr>
<td id="td7"></td>
<td id="td8"></td>
<td id="td9"></td>
</tr>
</table>

There seems to be other problems with your code, but your two specific problems should be fixed. Also I don't see why you need to check if every cell is empty, but then again I can't see the rest of your code. Feel free to ask any questions in the comments.
var TR = 0;
var table = document.getElementById('tb');
function CheckAllEmpty(idClicked) {
for (var x = 0; x < table.rows.length; x++) {
if (!(table.rows[x].value == "")) {
TR++;
console.log(TR);
}
}
if (TR == 3) {
document.getElementById(idClicked).innerHTML = "X";
}
}
CheckAllEmpty('td1');
<table id="tb">
<tr>
<td id="td1" onclick="CheckAllEmpty(this.id)"></td>
<td id="td2"></td>
<td id="td3"></td>
</tr>
<tr>
<td id="td4"></td>
<td id="td5"></td>
<td id="td6"></td>
</tr>
<tr>
<td id="td7"></td>
<td id="td8"></td>
<td id="td9"></td>
</tr>
</table>

Related

If I apply the excel file to the html table, I want to give each td a different id

Sign up and first question. I keep looking to solve my problem but haven't found an answer yet. The question is, like the title, I want to load an excel file into an html table and give each td a different ID.
Currently, I have succeeded in assigning an id, but I know that the id value must not be the same. So I want to solve this problem with vanilla JavaScript. Below are the scripts I've completed so far and the results shown in the Chrome Developer Tools.
SCRIPT:
document.getElementById("ex_file").onchange = (evt) => {
var reader = new FileReader();
reader.addEventListener("loadend", (evt) => {
var table = document.getElementById("importexcel");
table.innerHTML = "";
var workbook = XLSX.read(evt.target.result, {type: "binary"}),
worksheet = workbook.Sheets[workbook.SheetNames[0]],
range = XLSX.utils.decode_range(worksheet["!ref"]);
for (let row=range.s.r; row<=range.e.r; row++) {
let r = table.insertRow();
for (let col=range.s.c; col<=range.e.c; col++) {
let c = r.insertCell(),
xcell = worksheet[XLSX.utils.encode_cell({r:row, c:col})];
c.innerHTML = xcell.v;
c.setAttribute('id', 'excel' + numbering)
var numbering = 0;
numbering++;
}
}
});
reader.readAsArrayBuffer(evt.target.files[0]);
};
Chrome Developer Tools:
<table id="importexcel" class="table">
<tbody>
<tr>
<td id="excelundefined">STYLE</td>
<td id="excel1">XS 90</td>
<td id="excel1">X 95</td>
<td id="excel1">M 100</td>
<td id="excel1">L 105</td>
<td id="excel1">XL 110</td>
<td id="excel1">XXL 115</td>
<td id="excel1">TOTAL</td>
</tr>
<tr>
<td id="excel1">hgfhgfhgf</td>
<td id="excel1">3</td>
<td id="excel1">4</td>
<td id="excel1">0</td>
<td id="excel1">4</td>
<td id="excel1">0</td>
<td id="excel1">4</td>
<td id="excel1">15</td>
</tr>
</tbody>
</table>
Below is the result I want:
<table id="importexcel" class="table">
<tbody>
<tr>
<td id="excelundefined">STYLE</td>
<td id="excel1">XS 90</td>
<td id="excel2">X 95</td>
<td id="excel3">M 100</td>
<td id="excel4">L 105</td>
<td id="excel5">XL 110</td>
<td id="excel6">XXL 115</td>
<td id="excel7">TOTAL</td>
</tr>
<tr>
<td id="excel8">hgfhgfhgf</td>
<td id="excel9">3</td>
<td id="excel10">4</td>
<td id="excel11">0</td>
<td id="excel12">4</td>
<td id="excel13">0</td>
<td id="excel14">4</td>
<td id="excel15">15</td>
</tr>
</tbody>
</table>
The script used another developer's script. If there is a problem, I would like to get help. Please feel free to comment if you need a little more information for an accurate answer!

How to loop through a table and get the td elements to follow a condition

I just want make so it the tr hides when the td does not follow the requirements, tried with jQuery and JavaScript, don't know what's wrong.
$(document).ready(function(){
$("td").each(function() {
var id = $(this).attr("price_search");
if (id > value4 && id < value5) {
$(this).hide;
}
else {
$(this).hide;
}
});
});
You can do this.
Hope this will help you.
$(document).ready(function() {
var value4 = 2;
var value5 = 4;
$("td").each(function() {
var id = $(this).attr("price_search");
if (id > value4 && id < value5) {
$(this).hide();
} else {
$(this).show();
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td price_search="3">10</td>
<td price_search="2">20</td>
<td price_search="3">30</td>
</tr>
</table>
I am going to go out on a limb here and make broad assumptions on content not in the question.
Your .hide; is invalid syntax
You are missing value for two variables value4 and value4 which frankly are not well named variables at all. I will make an assumption that those are better named and that they come from somewhere during the page rendering.
I make an assumption that you have something you want to filter/hide by those upper/lower price points.
I make the assumption the attribute might contain values that need to be parsed (not a number as they are)
var lowerPricePoint = .45;
var upperPricePoint = 5.25;
$(function() {
$("td").filter('[price_search]').each(function() {
// parse out a price from perhaps formatted values
let price = Number.parseFloat($(this).attr("price_search").replace(/\$|,/g, ''));
// toggle visibility of the row
$(this).closest('tr').toggle(price > lowerPricePoint && price < upperPricePoint);
});
});
td {
border: solid black 1px;
padding: 0.4em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<table>
<tr>
<td>Wear it</td>
<td price_search="123.13">Shoes</td>
</tr>
<tr>
<td>Drive it</td>
<td price_search="$23,123.13">Car</td>
</tr>
<tr>
<td>Drink it</td>
<td price_search="3.13">Beet Juice</td>
</tr>
<tr>
<td>Eat it</td>
<td price_search="12.13">Can of expensive corn</td>
</tr>
<tr>
<td>Cheap</td>
<td price_search="35">Radish</td>
</tr>
<tr>
<td>Use it</td>
<td price_search="1.45">Paper towel</td>
</tr>
<tr>
<td>Plain</td>
<td price_search="$1.87">Butter</td>
</tr>
<tr>
<td>Herb</td>
<td price_search="$2.45">Butter</td>
</tr>
<tr>
<td>Cheap</td>
<td price_search="15">Gum</td>
</tr>
</table>

Loop through elements in a HTML table

I am learning Javascript, in a school assignment we have to by using a loop count how many games was made in 2014.
It does not return anything in the console, where have I gone wrong?
var allGames = document.getElementsByTagName('td');
var array = Array.prototype.slice.call(allGames, 0)
var games14 = 0;
for (var i = 0; i < array.length; ++i) {
if (array[i] == 2014) {
games14++;
console.log(games14)
}
}
<table id="games">
<thead>
<tr>
<th>Titel</th>
<th>Genre</th>
<th>Årstal</th>
</tr>
</thead>
<tbody id="games_tbody">
<tr class="horror">
<td class="title">Outlast</td>
<td>Horror</td>
<td>2013</td>
</tr>
<tr class="rpg">
<td class="title">Dragon Age: Inquisition</td>
<td>Role-playing Game</td>
<td>2014</td>
</tr>
<tr class="rpg">
<td class="title">Skyrim</td>
<td>Role-playing Game</td>
<td>2011</td>
</tr>
<tr class="horror">
<td class="title">Amnesia: The Dark Descent</td>
<td>Horror</td>
<td>2010</td>
</tr>
<tr class="simulator">
<td class="title">Scania Truck Driving Simulator</td>
<td>Simulator</td>
<td>2012</td>
</tr>
<tr class="horror">
<td class="title">Five Nights at Freddy’s</td>
<td>Horror</td>
<td>2014</td>
</tr>
<tr class="simulator">
<td class="title">Sims 4</td>
<td>Simulator</td>
<td>2014</td>
</tr>
<tr class="rts" id="last">
<td class="title">Warcraft III: Reign of Chaos</td>
<td>Real-time Strategy</td>
<td>2002</td>
</tr>
</tbody>
</table>
You need to check for its text:
var allGames = document.getElementsByTagName('td');
...
if (array[i].innerHTML == '2014') {
OR,
if(array[i].innerText == '2014' || array[i].textContent == '2014'){
No need to do Loop through elements in a HTML table.. You can simply use regular expressions to count all occurrences within the games_tbody:
var games14 = document
.getElementById('games_tbody')
.innerText
.match(/2014/g)
.length;
console.log('Games made in 2014:', games14);
<table id="games">
<thead>
<tr><th>Titel</th><th>Genre</th><th>Årstal</th></tr>
</thead>
<tbody id="games_tbody">
<tr class="horror"><td class="title">Outlast</td><td>Horror</td><td>2013</td></tr>
<tr class="rpg"><td class="title">Dragon Age: Inquisition</td><td>Role-playing Game</td><td>2014</td></tr>
<tr class="rpg"><td class="title">Skyrim</td><td>Role-playing Game</td><td>2011</td></tr>
<tr class="horror"><td class="title">Amnesia: The Dark Descent</td><td>Horror</td><td>2010</td></tr>
<tr class="simulator"><td class="title">Scania Truck Driving Simulator</td><td>Simulator</td><td>2012</td></tr>
<tr class="horror"><td class="title">Five Nights at Freddy’s</td><td>Horror</td><td>2014</td></tr>
<tr class="simulator"><td class="title">Sims 4</td><td>Simulator</td><td>2014</td></tr>
<tr class="rts" id="last"><td class="title">Warcraft III: Reign of Chaos</td><td>Real-time Strategy</td><td>2002</td></tr>
</tbody>
</table>
array[i] == 2014
Everything in the array will be an HTML Table Data Cell Element object.
Nothing in the array will be the Number 2014.
You need to read the text content from the element and then compare that.
I think this is a better way.
var table = document.getElementById("games");
count = 0;
for (let i = 0; row = table.rows[i]; i++) {
if (row.cells[2].innerHTML === "2014"){
count++;
}
/*
for (let j = 0; col = row.cells[j]; j++) {
if (col.innerHTML === "2014"){
count++;
}
}
*/
}
console.log(count);
The commented code is for checking every item on a single row.

merging <td> rows in one column of html table

I have a requirement, if i have same data in column1 of 's with same id then i need to merge those cells and show their respective values in column2.
i.e., in fiddle http://jsfiddle.net/7t9qkLc0/12/ the key column have 3rows with data 1 as row value with same id and has corresponding different values in Value column i.e., AA,BB,CC. I want to merge the 3 rows in key Column and display data 1 only once and show their corresponding values in separate rows in value column.
Similarly for data4 and data5 the values are same i.e.,FF and keys are different, i want to merge last 2 rows in Value column and dispaly FF only one time and show corresponding keys in key column. All data i'm getting would be the dynamic data. Please suggest.
Please find the fiddle http://jsfiddle.net/7t9qkLc0/12/
Sample html code:
<table width="300px" height="150px" border="1">
<tr><th>Key</th><th>Value</th></tr>
<tr>
<td id="1">data 1</td>
<td id="aa">AA</td>
</tr>
<tr>
<td id="1">data 1</td>
<td id="bb">BB</td>
</tr>
<tr>
<td id="1">data 1</td>
<td id="cc">CC</td>
</tr>
<tr>
<td id="2">data 2</td>
<td id="dd">DD</td>
</tr>
<tr>
<td id="2">data 2</td>
<td id="ee">EE</td>
</tr>
<tr>
<td id="3">data 3</td>
<td id="ff">FF</td>
</tr>
<tr>
<td id="4">data 4</td>
<td id="ff">FF</td>
</tr>
<tr>
<td id="5">data 5</td>
<td id="ff">FF</td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="3" style="padding-left: 0px; padding-right: 0px; padding-bottom: 0px">
</td>
</tr>
</table>
Building on tkounenis' answer using Rowspan:
One option to implement what you need would be to read all the values in your table after being populated, then use a JS object literal as a data structure to figure out what rows/columns are unique.
A JS object literal requires a unique key which you can map values to. After figuring out what rows/columns should be grouped, you can either edit the original table, or hide the original table and create a new table (I'm creating new tables in this example).
I've created an example for you to create a new table either grouped by key or grouped by value. Try to edit the examples provided to introduce both requirements.
Let me know if you need more help. Best of luck.
JSFiddle: http://jsfiddle.net/biz79/x417905v/
JS (uses jQuery):
sortByCol(0);
sortByCol(1);
function sortByCol(keyCol) {
// keyCol = 0 for first col, 1 for 2nd col
var valCol = (keyCol === 0) ? 1 : 0;
var $rows = $('#presort tr');
var dict = {};
var col1name = $('th').eq(keyCol).html();
var col2name = $('th').eq(valCol).html();
for (var i = 0; i < $rows.length; i++) {
if ($rows.eq(i).children('td').length > 0) {
var key = $rows.eq(i).children('td').eq(keyCol).html();
var val = $rows.eq(i).children('td').eq(valCol).html();
if (key in dict) {
dict[key].push(val);
} else {
dict[key] = [val];
}
}
}
redrawTable(dict,col1name,col2name);
}
function redrawTable(dict,col1name,col2name) {
var $table = $('<table>').attr("border",1);
$table.css( {"width":"300px" } );
$table.append($('<tr><th>' +col1name+ '</th><th>' +col2name+ '</th>'));
for (var prop in dict) {
for (var i = 0, len = dict[prop].length; i< len; i++) {
var $row = $('<tr>');
if ( i == 0) {
$row.append( $("<td>").attr('rowspan',len).html( prop ) );
$row.append( $("<td>").html( dict[prop][i] ) );
}
else {
$row.append( $("<td>").html( dict[prop][i] ) );
}
$table.append($row);
}
}
$('div').after($table);
}
Use the rowspan attribute like so:
<table width="300px" height="150px" border="1">
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr>
<td id="1" rowspan="3">data 1</td>
<td id="aa">AA</td>
</tr>
<tr>
<td id="bb">BB</td>
</tr>
<tr>
<td id="cc">CC</td>
</tr>
<tr>
<td id="2" rowspan="2">data 2</td>
<td id="dd">DD</td>
</tr>
<tr>
<td id="ee">EE</td>
</tr>
<tr>
<td id="3">data 3</td>
<td id="ff">FF</td>
</tr>
<tr>
<td id="4">data 4</td>
<td id="ff">FF</td>
</tr>
<tr>
<td id="5">data 5</td>
<td id="ff">FF</td>
</tr>
</table>
http://jsfiddle.net/37b793pz/4/
Can not be used more than once the same id. For that use data-id attribute
HTML:
<table width="300px" height="150px" border="1">
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr>
<td data-id="key1">data 1</td>
<td data-id="valaa">AA</td>
</tr>
<tr>
<td data-id="key1">data 1</td>
<td data-id="valbb">BB</td>
</tr>
<tr>
<td data-id="key1">data 1</td>
<td data-id="valcc">CC</td>
</tr>
<tr>
<td data-id="key2">data 2</td>
<td data-id="valdd">DD</td>
</tr>
<tr>
<td data-id="key2">data 2</td>
<td data-id="valee">EE</td>
</tr>
<tr>
<td data-id="key3">data 3</td>
<td data-id="valff">FF</td>
</tr>
<tr>
<td data-id="key4">data 4</td>
<td data-id="valff">FF</td>
</tr>
<tr>
<td data-id="key5">data 5</td>
<td data-id="valff">FF</td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="3" style="padding-left: 0px; padding-right: 0px; padding-bottom: 0px"></td>
</tr>
</table>
JQ:
//merge cells in key column
function mergerKey() {
// prevents the same attribute is used more than once Ip
var idA = [];
// finds all cells id column Key
$('td[data-id^="key"]').each(function () {
var id = $(this).attr('data-id');
// prevents the same attribute is used more than once IIp
if ($.inArray(id, idA) == -1) {
idA.push(id);
// finds all cells that have the same data-id attribute
var $td = $('td[data-id="' + id + '"]');
//counts the number of cells with the same data-id
var count = $td.size();
if (count > 1) {
//If there is more than one
//then merging
$td.not(":eq(0)").remove();
$td.attr('rowspan', count);
}
}
})
}
//similar logic as for mergerKey()
function mergerVal() {
var idA = [];
$('td[data-id^="val"]').each(function () {
var id = $(this).attr('data-id');
if ($.inArray(id, idA) == -1) {
idA.push(id);
var $td = $('td[data-id="' + id + '"]');
var count = $td.size();
if (count > 1) {
$td.not(":eq(0)").remove();
$td.attr('rowspan', count);
}
}
})
}
mergerKey();
mergerVal();
Use below snippet of javascript. It should work fine for what you are looking.
<script type="text/javascript">
function mergeCommonCells(table, columnIndexToMerge){
previous = null;
cellToExtend = null;
table.find("td:nth-child("+columnIndexToMerge+")").each(function(){
jthis = $(this);
content = jthis.text();
if(previous == content){
jthis.remove();
if(cellToExtend.attr("rowspan") == undefined){
cellToExtend.attr("rowspan", 2);
}
else{
currentrowspan = parseInt(cellToExtend.attr("rowspan"));
cellToExtend.attr("rowspan", currentrowspan+1);
}
}
else{
previous = content;
cellToExtend = jthis;
}
});
};
mergeCommonCells($("#tableId"), 1);
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>

How Do I wrap only selected elements in jQuery

In a badly designed table like this:
<table id="bow-me">
<td class="show-me">Pet is Great</td>
<td class="show-me">Pete is Greate</td>
<td class="go-me">Met is Great</td>
<td class="go-me">Mete is Greate</td>
<td class="show-me">Latte is Great</td>
<td class="show-me">Lattus is Greate</td>
<td class="low-me">Bet is Great</td>
<td class="low-me">Bette is Greate</td>
<td class="go-me">Rat is Great</td>
<td class="go-me">Rate is Greate</td>
</table>
I need to add the <tr> tag after every 2 <td> tags using jQuery. To make things clear, I have separated 2 <td>s in above question.
At first I did:
$('.show-me').wrapAll('<tr class="know-me"> </tr>');
$('.go-me').wrapAll('<tr class="know-me"> </tr>');
$('.low-me').wrapAll('<tr class="know-me"> </tr>');
But the messes up the structure.
Then I tried wrap('<tr></tr>'), which wraps every td with tr.
I also tried with before() and after() methods, but wasn't successful with it too.
My ideal output should be:
<table id="bow-me">
<tr class="know-me">
<td class="show-me">Pet is Great</td>
<td class="show-me">Pete is Greate</td>
</tr>
<tr class="know-me">
<td class="go-me">Met is Great</td>
<td class="go-me">Mete is Greate</td>
</tr>
<tr class="know-me">
<td class="show-me">Latte is Great</td>
<td class="show-me">Lattus is Greate</td>
</tr>
<tr class="know-me">
<td class="low-me">Bet is Great</td>
<td class="low-me">Bette is Greate</td>
</tr>
<tr class="know-me">
<td class="go-me">Rat is Great</td>
<td class="go-me">Rate is Greate</td>
</tr>
</table>
Is there anyway I can do this with jQuery?
The JSFiddle
You can do:
var tds = $('#bow-me td');
for (var i = 0; i < tds.length; i += 2) {
tds.slice(i, i + 2).wrapAll('<tr class="know-me"></tr>');
}
Updated Fiddle
As #Blazemonger suggestion, you can use unwrap() to remove the auto-generated tr here:
$('.know-me').unwrap();
Updated Fiddle
HTML (the original source code) is not the same as the DOM (the page as your browser and jQuery understand it). When your browser reads the original HTML, it considers it invalid and automatically adds <tr> tags around all the table cells.
You ought to alter your original HTML, or else use div elements and CSS to add display: table-cell as needed. HTML:
<div id="bow-me">
<div class="show-me">Pet is Great</div>
<div class="show-me">Pete is Greate</div>
<div class="go-me">Met is Great</div>
<div class="go-me">Mete is Greate</div>
<div class="show-me">Latte is Great</div>
<div class="show-me">Lattus is Greate</div>
<div class="low-me">Bet is Great</div>
<div class="low-me">Bette is Greate</div>
<div class="go-me">Rat is Great</div>
<div class="go-me">Rate is Greate</div>
</div>
CSS:
#bow-me {
display: table;
}
.know-me {
display: table-row;
}
.show-me, .go-me, .low-me {
display: table-cell;
}
And now this slightly unorthodox jQuery will do what you want:
$('.show-me,.go-me,.low-me').each(function() {
var klass = $(this).attr('class');
if (!$(this).closest('.know-me').length) { // not already wrapped in a row
$(this).nextUntil(':not(".'+klass+'")').addBack()
.wrapAll('<div class="know-me">');
};
});
http://jsfiddle.net/mblase75/QhKP7/
I don't think you can wrap 2 dom nodes...
I suspect you will have to do something like:
$('#bow-me').find('td:nth-child(2n+1),td:nth-child(2n+2)').wrapAll('<tr class="know-me"></tr>');
Hope someone improves and finds a better way but for now thats all I got
You can use following code;
var length = $("#bow-me td").length;
for (var i = 0; i <= length; i += 2) {
$("#bow-me td:eq(" + i + "), #bow-me td:eq(" + (i+1) + ")").wrapAll('<tr class="know-me"></tr>');
}
Here is a working fiddle: http://jsfiddle.net/cubuzoa/WNQ3d/4/
You could do something like this:
var els = $('td'),
trow;
for (var i = 0; i < els.length; i++) {
if (i%2 === 0) {
trow = $('<tr class="know-me" />');
$(els[i]).before(trow);
trow.append(els[i]);
trow.append(els[i + 1]);
}
}
Code snippet:
var els = $('td'),
trow;
for (var i = 0; i < els.length; i++) {
if (i % 2 === 0) {
trow = $('<tr class="know-me" />');
$(els[i]).before(trow);
trow.append(els[i]);
trow.append(els[i + 1]);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="bow-me">
<td class="show-me">Pet is Great</td>
<td class="show-me">Pete is Greate</td>
<td class="go-me">Met is Great</td>
<td class="go-me">Mete is Greate</td>
<td class="show-me">Latte is Great</td>
<td class="show-me">Lattus is Greate</td>
<td class="low-me">Bet is Great</td>
<td class="low-me">Bette is Greate</td>
<td class="go-me">Rat is Great</td>
<td class="go-me">Rate is Greate</td>
</table>

Categories

Resources