I'm writing a Vanilla JS program in codesandbox environment as shown below:
function Game() {
alert("hi");
}
body {
font-family: sans-serif;
}
table {
border-collapse: collapse;
}
td {
border: 1px solid black;
}
td:first-child {
border-left-width: 0px;
}
td:last-child {
border-right-width: 0px;
}
table tr:nth-child(1) td {
border-top-width: 0px;
}
table tr:nth-child(3) td {
border-bottom-width: 0px;
}
<!DOCTYPE html>
<html>
<head>
<title>Tic-Tac-Toe</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="app">
<table width="300" height="300" onclick="Game();">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</div>
</body>
</html>
When I execute the above code snippet in codesandbox.io then it gives below error:
ReferenceError Game is not defined
Not sure why the execution environment of codesandbox is unable to detect the Game function. If I write the alert statement outside the function then it gets called successfully on page load:
alert("hi");
function Game() {
}
I've linked the external JS and CSS files correctly in the head tag of the HTML page.
You need to define the function as a variable attached to the global window object. Try defining the function like this:
window.Game = function() {
alert("hi");
}
Alternatively, instead of an inline onclick event handler try giving the table element an id such as game-table and then add an event listener:
document.querySelector('#game-table').addEventListener('click', Game);
Related
For example my code is like below.
I would like to classchange by clicking and hovering.
But it didn't work.
I would like to know,
① How to check the wrong point?
② How to fix such wrong point?
I tried console.log,but I would like to know whether the function is correctly mapped and
correctly work.
Thanks
var $ = jQuery;
const $days = $(this).find('.day');
function register() {
function clicked() {
$(this).toggleClass(is-clicked);
}
function hoverRange(){
$(this).addClass(is-hover);
}
$days.on({
click: clicked,
hover: hoverRange,
});
}
$("#calendar").each(register);
td{
padding:10px;
border:solid black 1px;}
table{
border-collapse:collapse;}
is-clicked{
background-color:aqua;
}
is-hover{
background-color:yellow;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<div id=calendar>
<table>
<tr>
<td class=day>1</td>
<td class=day>2</td>
<td class=day>3</td>
</tr>
</table>
</div>
you're using wrong code in the click event
you should have . in your css class.
you should use this when event is triggered, you were trying to trigger by using $days which is not correct.
for hover you don't need to write a method for that, I have updated the code.
var $ = jQuery;
const $days = $(this).find('.day');
function register() {
function clicked() {
alert("clicked");
$(this).toggleClass('is-clicked');
}
$(this).on({
click: clicked
});
}
$("#calendar").each(register);
td {
padding: 10px;
border: solid black 1px;
}
table {
border-collapse: collapse;
}
.is-clicked {
background-color: aqua;
}
td:hover {
background-color: yellow;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<div id=calendar>
<table>
<tr>
<td class=day>1</td>
<td class=day>2</td>
<td class=day>3</td>
</tr>
</table>
</div>
I have a table with multiple lines, e.g.:
<table>
<tr id="line1"><td>Line</td><td>1</td></tr>
<tr id="line2"><td>Line</td><td>2</td></tr>
<tr id="line3"><td>Line</td><td>3</td></tr>
</table>
Now, in javascript (based on a radio input field) I want to remove (e.g.) #line3 by adding a visibility:collapse, something like:
document.getElementById("line3").style = "visibility:collapse";
The special thing about #line3 is that it has a border-top:
<style>
table {
border-collapse: collapse;
}
#line3 {
border-top:1px solid black;
}
</style>
The problem I have with that: When I "collapse" #line3 the border persists, eventhough the element "does not exist". I guess this should be due to the border-collapse in the table style "inheriting" a border element on the previous tr element? How can I fix that issue?
EDIT: I'd like to keep the javascript like that. Of course I could remove/readd the style element but there should be a different way to solve this?!
Of course I could remove/readd the style element
I think this means you don't want to mess with the border-top property when changing the row's visibility, correct?
In that case, it looks like your only option is to use display:none instead of visibility:collapse[1], which is unfortunate because then your table might have the wobbly effect that visibility:collapse was designed to prevent.
[1] https://drafts.csswg.org/css-tables-3/#visibility-collapse-track-rendering is not crystal clear, but looks like the spec prescribes the behavior you don't want. And chrome and firefox act a bit differently in the visibility:collapse case. https://jsfiddle.net/dgrogan/gLqo9s4w/2
let visible = 1;
toggle.onclick = function() {
line3.style.visibility = visible ? "collapse" : "visible";
//line3.style.display = visible ? "none" : "table-row";
visible = !visible;
}
table {
border-collapse: collapse;
}
td {
border: 1px solid lime;
}
#line3 {
border-top: 2px solid black;
}
<table>
<tr id="line1">
<td>Line</td>
<td>1</td>
</tr>
<tr id="line2">
<td>Line</td>
<td>2</td>
</tr>
<tr id="line3">
<td>Line</td>
<td>3</td>
</tr>
</table>
<br><br>
<button id=toggle>toggle</button>
<P>
https://drafts.csswg.org/css-tables-3/#visibility-collapse-track-rendering
</P>
Have you tried "display: none"?
document.getElementById("line3").style = "display: none";
Or maybe you could try setting the border-top to 0 which should hide it.
document.getElementById("line3").style = "visibility:collapse; border-top: 0";
.cssText
You can edit the whole inline [style] attribute by using .cssText:
document.getElementById("line3").style.cssText = "visibility:collapse; border-top:0px";
This allows you to set visibility and border properties (and more if you want) in one line.
Demo
document.getElementById("line3").style.cssText = "visibility:collapse; border-top:0px";
table {
border-collapse: collapse;
}
#line3 {
border-top: 1px solid black;
}
<table>
<tr id="line1">
<td>Line</td>
<td>1</td>
</tr>
<tr id="line2">
<td>Line</td>
<td>2</td>
</tr>
<tr id="line3">
<td>Line</td>
<td>3</td>
</tr>
</table>
You have several solutions to do this, with Jquery:
$('#line1').hide();
//OR
$('#line1').css('visibility','collapse');
//OR
$('#line1').css('display','none');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr id="line1"><td>Line</td><td>1</td></tr>
<tr id="line2"><td>Line</td><td>2</td></tr>
<tr id="line3"><td>Line</td><td>3</td></tr>
</table>
You can also use Javascript directly with the getElementById property:
document.getElementById("line1").style.display = "none";
Or
document.getElementById("line1").style.visibility = "collapse";
As you can see after you run the code, i have multiple tables, let us assume they were dynamically created with PHP. I try to hide/show the entire tbody of a table if i click at it's thead.
I could just give each table it's own id and write the jquery code for each table... but since the tables are dynamically created, i can't solve it like this.
The current version of my jquery script toggles all tbody's if i click on a thead, instead of only the thead of the table which i actually clicked.
My only idea to solve this would be to also create the jquery code dynamically (but im not sure if this will actually work), but before i try this, does someone know if there is an easier solution?
I thought about something like this:
$("this tbody").css("display","none");
So that it only selects the tbody of the thead which i actually clicked on.
var main = function()
{
$toggle = true;
$("thead").click
(
function()
{
if ($toggle)
{
$toggle = false;
$("tbody").css("display","none");
}
else
{
$toggle = true;
$("tbody").css("display","");
}
}
);
}
$(document).ready(main);
table, td {
border: 1px solid black;
}
td {
color: red;
display: block;
max-width: 120px;
white-space: nowrap;
overflow-x: auto;
background-color: blue;
}
th {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr><th id="here1">First Table</th></tr>
</thead>
<tbody>
<tr><td>A</td></tr>
<tr><td>B</td></tr>
<tr><td>C</td></tr>
</tbody>
</table>
<table>
<thead>
<tr><th id="here1">Second Table</th></tr>
</thead>
<tbody>
<tr><td>A</td></tr>
<tr><td>B</td></tr>
<tr><td>C</td></tr>
</tbody>
</table>
First, instead of using $('tbody'), use this
Second, instead of managing variables for visibility, use toggle function
var main = function() {
$("thead").on("click", function() {
$(this).parents("table").find("tbody").toggle();
});
}
$(document).ready(main);
table,
td {
border: 1px solid black;
}
td {
color: red;
display: block;
max-width: 120px;
white-space: nowrap;
overflow-x: auto;
background-color: blue;
}
th {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th id="here1">First Table</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
</tr>
<tr>
<td>B</td>
</tr>
<tr>
<td>C</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th id="here1">Second Table</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
</tr>
<tr>
<td>B</td>
</tr>
<tr>
<td>C</td>
</tr>
</tbody>
</table>
try with
$(this).parent().find('tbody').css("display","none");
you can use .next() https://api.jquery.com/next/
$(this).next("tbody").css("display","none");
or better yet use toggle https://api.jquery.com/toggle/
$(this).next("tbody").toggle();
<table class="table" id="item"style="display:none;">
<tbody style="height:0px;width:82%; display:table;"></tbody>
</table>
and using script
<script>`enter code here`
document.getElementById("item").style.display = "block";
</script>
Question:
I'm having a little trouble with jQuery:
Consider this HTML, where I want to left-click on "https", change it's value and then click ok. On OK, it should remove the textbox, and re-attach the onclick handler.
This is does, but onclick is already issued by the current click...
Why ? And how to do this correctly ?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Tabelle editieren</title>
<!--
<script src="jquery-1.4.4.min.js" type="text/javascript"></script>
-->
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.js"></script>
<style type="text/css" media="all">
html {margin: 0px; padding: 0px; height: 100%;}
body {margin: 0px; padding: 0px; height: 100%;}
input{margin: 0px; padding: 0px; }
tr:nth-child(2n+1) {background-color: #F0F0F0;}
tr:nth-child(2n) {background-color: #FEFEFE;}
td
{
margin: 0px; padding: 0.5cm; padding: 0px; text-align: left;
}
</style>
<script type="text/javascript" language="javascript">
function hello(me) {
//alert("hello");
var str = $(me).text();
//alert(str);
$(me).html("<input id=\"my1\" type=\"text\" style=\"width: 198px; height: 100%;\" value=\"" + str + "\" /><input id=\"my1confirm\" type=\"button\" onclick=\"bye(this);\"style=\"width: 35px;\" value=\"" + "OK" + "\" />");
$(me).attr('onclick', '').unbind('click');
return false;
}
function bye(me) {
var objTR = $(me).parent();
//var tb = $(me).closest('table');
var tb = objTR.find('input');
var str = tb.val();
tb.remove();
objTR.text(str);
alert("TODO: sending change event with { id : \"" + objTR.attr('id') + "\", str : \"" + str + "\" } to server");
/*
objTR.click(function () {
alert("hi");
return false;
});
*/
objTR.attr('onclick', '').bind("click", function (e) {
e.preventDefault();
alert("it shouldn't execute this in this click, but it does... ");
//hello(this);
//event.stopImmediatePropagation();
});
return false;
}
$(document).ready(function () {
//$('#myDataTable').dataTable().makeEditable();
});
</script>
</head>
<body style="margin: 0.5cm;">
<h1>Application configuration</h1>
<!--
-->
<table border="1" style="border-collapse: collapse;" >
<thead>
<tr style="background-color: Black; color:White; font-weight: bold; text-transform: capitalize;">
<th style="width: 235px; text-align: left;">key</th>
<th style="width: 235px; text-align: left;">value</th>
</tr>
</thead>
<tfoot>
<tr style="background-color: Black; color:White; font-weight: bold; text-transform: capitalize;">
<th style="text-align: left;">key</th>
<th style="text-align: left;">value</th>
</tr>
</tfoot>
<tbody>
<tr>
<td>Environment</td>
<td id="server">testing</td>
</tr>
<tr>
<td>Protocol</td>
<td id="Protocol" onclick="hello(this);">https</td>
</tr>
<tr>
<td>UserHashMode</td>
<td id="UserHashMode">true</td>
</tr>
<tr>
<td>Logo</td>
<td id="Logo">LogoFileCustomerN.png</td>
</tr>
</tbody>
</table>
</body>
</html>
It seems that inline event handlers cannot be unbound by jQuery: Unbinding inline onClick not working in jQuery?
So I'm not sure if it'll work, but instead of using:
.attr("onclick", "")
try:
.removeAttr("onclick")
Let us know if that changes anything.
UPDATE:
I made a jsFiddle to show you how it could function "easier": http://jsfiddle.net/S2ARR/3/
A lot of it depends on certain things, such as using my structure - putting a span inside of the column instead of using the column for everything. I didn't use the id of elements for jQuery selecting because I wasn't sure why you weren't - if you set the id of elements and you need to access them, you might as well use the id selector in jQuery. So you wouldn't need to use .parent() or .find() in my example if you just used the id. Hopefully this is what you were looking for. I think the important thing was the .stopPropagation() call, otherwise it didn't seem to work.
i changed your event to delegate, removed onclick from the table and called it using jquery. However i'm not sure if what i get is your desire behavior.
jsfiddle
Update
Hi, i updated with the desired behavior.
Solution
Instead of binding the event via the onclick attribute, you can bind it to the table cell with jquery.
$(function(){
$("#Protocol").click(function(){
// your content
});
});
Then, you can guarantee that you can unbind the event with unbind later on.
Copy/paste this html code snippet and try it out in IE7. When you toggle the hidden columns it leaves a gap between the columns. In Firefox it works fine, the columns touch when minimized. Haven't tried IE8 yet, would be curious to hear how it works there. Any ideas? I've tried a bunch of things in the CSS like table-layout:fixed but no luck.
Note: Not looking for a different toggling method because the table I'm really dealing with is 50+ columns wide and 4000+ rows so looping/jquery techniques are too slow.
Here's the code - if someone can re-post a working version of it I'll instantly give them the check and be forever in your debt!
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<script>
function toggle() {
var tableobj = document.getElementById("mytable");
if (tableobj.className == "") {
tableobj.className = "hide1 hide2";
}
else {
tableobj.className = "";
}
}
</script>
<style>
table { border-collapse: collapse; }
td, th { border: 1px solid silver; }
.hide1 .col1 { display: none; }
.hide2 .col2 { display: none; }
</style>
</head>
<body>
<input type="button" value="toggle" onclick="toggle();" />
<table id="mytable">
<tr>
<th>A</th>
<th colspan="2">B</th>
<th colspan="2" class="col1">B1</th>
<th colspan="2">C</th>
<th colspan="2" class="col2">C1</th>
</tr>
<tr>
<td>123</td>
<td>456</td>
<td>789</td>
<td class="col1">123</td>
<td class="col1">456</td>
<td>789</td>
<td>123</td>
<td class="col2">456</td>
<td class="col2">789</td>
</tr>
</table>
</body>
</html>
Here's a solution that uses JQuery to toggle the column headers (see my other answer for the rationale). Apart from the JQuery stuff, the rest of the html page is the same.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min.js" type="text/javascript"></script>
<script>
function toggle() {
var tableobj = document.getElementById("mytable");
if (tableobj.className == "") {
tableobj.className = "hide1 hide2";
$('th[class^=col]').hide();
}
else {
tableobj.className = "";
$('th[class^=col]').show();
}
}
</script>
<style>
table { border-collapse: collapse; }
td, th { border: 1px solid silver; }
.hide1 .col1 { display: none; }
.hide2 .col2 { display: none; }
</style>
</head>
<body>
<input type="button" value="toggle" onclick="toggle();" />
<table id="mytable">
<tr>
<th>A</th>
<th colspan="2">B</th>
<th colspan="2" class="col1">B1</th>
<th colspan="2">C</th>
<th colspan="2" class="col2">C1</th>
</tr>
<tr>
<td>123</td>
<td>456</td>
<td>789</td>
<td class="col1">123</td>
<td class="col1">456</td>
<td>789</td>
<td>123</td>
<td class="col2">456</td>
<td class="col2">789</td>
</tr>
</table>
</body>
</html>
Don't yet have an explanation of why IE is doing this, but here's what's happening and here's how to work around it.
1) If you set the table class to 'hide1 hide2' in the html, then the table will render properly (no gap). Therefore, the problem seems to be related to the way that IE handles changes to a table via styles.
2) The gap between the columns is the width of the spanned column header.
3) If you eliminate column spanning (and the extra columns), then everything works fine.
I've found two workarounds. The first is to use code to toggle the display, but you've rejected that option.
The alternative is to eliminate the colspans. There are a variety of ways to do that. One is to convert the group of cells to be spanned into an embedded table (that is, instead of two TD elements, you'll have one TD which contains a TABLE with one TR and two TDs). Or you can use SPANs for cleaner code (with, say, a BORDER-RIGHT for all cells but the last).
Try this doctype declaration:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">