Firefox cutting off bottom of table - javascript

Edit: Updated the code slightly based on your comments.
Edit 2: Live example: lachniet.com/chessboard
I'm trying to use a combination of HTML, CSS, and JS to draw out an empty chessboard. My code with CSS and JS inline is this:
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>TitaniumChess</title>
<style>
html,body {
margin: 0;
padding: 0;
}
#board {
border: 1px solid #000;
border-collapse: collapse;
float: left;
height: 50vw;
width: 50vw;
}
.tile-white {
height: 12.5%;
width: 12.5%;
}
.tile-black {
background-color: #000;
color: #fff;
height: 12.5%;
width: 12.5%;
}
</style>
</head>
<body>
<table id="board"></table>
<script>
var board = document.getElementById('board');
var draw = '';
var letters = 'abcdefgh';
for (var column = 8; column > 0; column--) {
draw += '<tr id="' + column + '">';
for (var row = 0; row < 8; row++) {
draw += '<td id="' + letters.charAt(row) + column + '" class="';
if ((row + column) % 2 == 1) {
draw += 'tile-black';
} else {
draw += 'tile-white';
}
draw += '">test</td>';
}
draw += '</tr>';
}
board.innerHTML = draw;
</script>
</body>
</html>
Now, this code works perfectly fine for me in Chrome 52. However, in Firefox 47, the bottom row is cut off. Surprisingly, this code works fine even in IE 11, and Edge 12 (All on Windows 10 Enterprise 64-Bit).
This seems to be a problem specific to Firefox. Does anyone have any idea why?

The problem is in hidden borders and paddings. Also browser recalculates height if the sum less than 100%. This is css which works for me in Edge, FF, and GC.
html, body {
margin: 0;
padding: 0;
}
#board {
float: left;
height: 50vw;
width: 50vw;
border: 1px solid #000;
border-collapse: collapse;
padding:0;
}
#board td{ /*All td are created equal*/
height: 10%; /*Let browser recalculate*/
width: 12.5%;
border:none 0px; /*remove borders explicitly */
padding:0;
}
.tile-white {
}
.tile-black {
background-color: #000;
color: #fff;
}
As a bonus, you don't need .tile-black and .tile-white classes.
/*Odd td in even tr and even td in odd tr*/
#board tr:nth-child(2n) td:nth-child(2n+1),
#board tr:nth-child(2n+1) td:nth-child(2n)
{
background-color: #000;
color: #fff;
}

Related

Front-end Interview Prompt: Box into Quarters

I had a front-end interview a few months ago with the following problem and guideline:
You are given the baseline CSS, HTML, and JS
You are not allowed to directly edit the predefined HTML or CSS
You are allowed to add new CSS classes and use whatever version of jQuery you want or Vanilla JS
Goal 1: When you click the #container, divide the box (which is 400px by 400px) into four equal sized boxes.
Goal 2: When you click one of the boxes that were created in Goal 1, said box also divides into 4 equal sized boxes as well.
My Problem
No matter what I do, the boxes do not divide perfectly. Not sure why inline-block isn't doing it's think, or what I can't append more than one node. Anyone have some expert tips?
var c = document.getElementById("container");
c.addEventListener("click", function(e) {
var node = document.createElement("div");
node.className = "boxxie";
c.appendChild(node);
c.appendChild(node);
c.appendChild(node);
c.appendChild(node);
})
*,
*:before,
*:after {
box-sizing: border-box;
}
#container {
border: 1px solid #2196f3;
width: 400px;
height: 400px;
}
.boxxie {
display: inline-block;
height: 50%;
width: 50%;
outline: 1px solid black;
}
<div id="container"></div>
Here is the jsfiddle
https://jsfiddle.net/drewkiimon/fvx632ab/
Thanks to #wbarton, I was able to get this answer to work without using flexbox. I was adamant without using flexbox since I was pretty confident that it would not need it. Long and behold, there is a solution without it. By using float: left, we can avoid the vertical align, and by creating a for-loop where we re-create a "new" node, we can just append it four times. I also used a class with my div instead of a direct CSS selector on the div.
Thank you for all the help everyone! Case closed.
document.getElementById("container").addEventListener('click', function(e) {
for (var i = 0; i < 4; i ++) {
var node = document.createElement("div");
node.className = "boxxie";
e.target.appendChild(node);
}
})
*,
*:before,
*:after {
box-sizing: border-box;
}
#container {
border: 1px solid #2196f3;
width: 400px;
height: 400px;
}
.boxxie {
outline: 1px solid tomato;
width: 50%;
height: 50%;
float: left;
}
<div id="container"></div>
My solution: https://jsfiddle.net/fvx632ab/106/
Added CSS:
div {
display: flex;
flex-grow: 0;
flex-shrink: 0;
outline: 1px solid #f33;
width: 50%;
flex-wrap: wrap;
}
Flexbox makes this easy for us, by defining some sensible layouts. We set the width of the child to 50%, and also enable wrapping so that we get two rows (since we're going to add four elements).
Then, in my JavaScript:
document.querySelector('body').addEventListener('click', (e) => {
if (!e.target.matches('div')) {
return;
}
for (let i=0; i<=3; i++) {
e.target.appendChild(document.createElement('div'));
}
});
We listen for clicks on the body (because we're going to be adding more divs later), but filter for only the selector we want, which is div. Then, we just add 4 children.
Nothing new from a JS perspective but to answer #drewkiimon "is possible without flex?"
This example uses floats.
document.querySelector('body').addEventListener('click', (e) => {
if (!e.target.matches('div')) {
return;
}
for (let i = 0; i < 4; i++) {
e.target.appendChild(document.createElement('div'));
}
})
*,
*:before,
*:after {
box-sizing: border-box;
}
#container {
border: 1px solid #2196f3;
width: 400px;
height: 400px;
}
/* ---------- */
#container div {
float: left;
width: 50%;
height: 50%;
outline: 1px solid tomato;
background-color: rgba(64, 224, 208, .1);
}
<div id="container"></div>
Here is my solution.
Using e.target allows you to keep drilling down.
vertical-align: top and line-height: 1px; address spacing issues you might find using inline-block per Get rid of space underneath inline-block image
const c = document.getElementById("container");
c.addEventListener("click", e => {
const target = e.target;
for (let i = 0; i < 4; i++) {
const child = document.createElement("div");
target.appendChild(child);
}
});
#container {
width: 400px;
height: 400px;
border: 1px solid blue;
box-sizing: border-box;
}
#container div {
border: 1px solid red;
display: inline-block;
box-sizing: border-box;
width: 50%;
height: 50%;
vertical-align: top;
line-height: 1px;
}
<div id="container"></div>

Making table cells same row and make it look like buttons

I have this code below that alerts the value of the cell whenever the user clicks on the row. The problem is that i want try to make the cells look like button and put them on the same roll i'm not really too sure if this is possible to accomplish. Any help would be greatly appreciated thanks!
var obj2 = {};
var key3 = "Cars";
obj2[key3] = ['Toyota', 'Audi', 'Mercedes', 'Ferrari', 'Jeep', 'Honda', 'Nissan', 'Lamborghini'];
var myArray3 = [];
myArray3.push(obj2);
var bodyString = '';
var headString = '';
$.each(obj2[key3], function(index) {
bodyString += ('<tr><td>' + obj2[key3][index] + '</td></tr>');
});
headString += ('<tr><th>' + 'Cars' + '</th></tr>');
$('.carsclass tbody').html(bodyString);
$('.carsclass thead').html(headString);
$(document).ready(function() {
$("#carsid td").click(function() {
getval(this);
});
});
function getval(cel) {
alert(cel.innerHTML);
}
.class {
font-family: Open Sans;
}
.center{
display:flex;
justify-content:center
}
.skillsTable th{
border-left: 1px solid #AAA5A4;
border-right: 1px solid #AAA5A4;
}
table{
float: left;
border-collapse: collapse;
width:70%
}
td {
border-left: 1px solid #AAA5A4;
border-right: 1px solid #AAA5A4;
padding-top: 8px;
padding-left: 11px;
font-size: 15px;
}
th {
font-weight: normal;
border-bottom: 1px solid #AAA5A4;
padding-bottom: 5px;
}
div{
margin-bottom:50px;
}
<!DOCTYPE html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="//#" />
</head>
<body>
<div class="center">
<table id="carsid" class="carsclass skillsTable class">
<thead></thead>
<tbody></tbody>
</table>
</div>
</body>
</html>
This is what im trying to accomplish.
use blow code
td {
border-width: 1px;
border-radius: 50px;
border-color:black;
padding: 10px;
cursor:pointer;
font-size: 15px;
background-color: #9fc5e8;
}
th {
font-weight: normal;
border: 0;
padding: 10px 0;
}
div {
margin-bottom: 50px;
}
here is working example https://jsfiddle.net/deepakvaishnav/gfr36c1d/9/
I have changed some script and CSS to achieve your desired output but here you can't get an exact look like given image due to table
var obj2 = {};
var key3 = "Cars";
obj2[key3] = ['Toyota', 'Audi', 'Mercedes', 'Ferrari', 'Jeep', 'Honda', 'Nissan', 'Lamborghini'];
var myArray3 = [];
myArray3.push(obj2);
var bodyString = '<tr>';
var headString = '';
$.each(obj2[key3], function(index) {
bodyString += ('<td>' + obj2[key3][index] + '</td>');
});
bodyString += '</tr>';
headString += ('<tr><th colspan="' + obj2[key3].length + '">' + 'Cars' + '</th></tr>');
$('.carsclass tbody').html(bodyString);
$('.carsclass thead').html(headString);
$(document).ready(function() {
$("#carsid td").click(function() {
getval(this);
});
});
function getval(cel) {
alert(cel.innerHTML);
}
.class {
font-family: Open Sans;
}
.center {
display: flex;
justify-content: center
}
table {
float: left;
border-collapse: collapse;
width: 70%
}
td {
border: 0;
padding: 8px 10px;
padding-left: 11px;
font-size: 15px;
border-radius: 50px;
background-color: #007bff;
}
th {
font-weight: normal;
border: 0;
padding: 10px 0;
}
div {
margin-bottom: 50px;
}
<!DOCTYPE html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="//#" />
</head>
<body>
<div class="center">
<table id="carsid" class="carsclass skillsTable class">
<thead></thead>
<tbody></tbody>
</table>
</div>
</body>
</html>
use below css.
<style>
#carsid {
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
border-collapse: collapse;
width: 100%;
}
#carsid td, #customers th {
border: 1px solid #ddd;
padding: 8px;
cursor: pointer;
}
#carsid tr:nth-child(even){background-color: #f2f2f2;}
#carsid tr:hover {background-color: #ddd;}
#carsid th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: #4CAF50;
color: white;
}
</style>
Here is the approach using flex-box instead of table.
HTML
<div id="cars-container"></div>
JavaScript with jQuery
let cars = [
'Toyota',
'Audi',
'Mercedes',
'Ferrari',
'Jeep',
'Honda',
'Nissan',
'Lamborghini',
'Hyundai'
];
let $carsContainer = $('#cars-container');
// Empty the container first
$carsContainer.html('');
// Loop through the car collection
$.each(cars, function(index, car) {
let $button = $('<button />', {
text: car,
value: car,
click: function() {
alert(this.value);
}
});
$carsContainer.append($button);
});
CSS
#cars-container {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
}
#cars-container button {
padding: .375rem 1.25rem;
border-radius: 1rem;
border: 1px solid #aaa5a4;
background-color: #9fc5e8;
margin: .25rem;
}
#cars-container button:hover {
cursor: pointer;
background-color: #8ab9e3;
}
Result
Here is the working example: https://jsfiddle.net/xpvt214o/233802/
Now reading from one of the comments, if the user of OP wants only 5 cars in a row, you can easily add a style to the button:
#cars-container button {
...
width: calc(100% / 5 - 2 * .25rem); <!-- Percentage - margin left - margin right -->
}
But I would highly not recommend to put a fixed width on the button element. That defeats the purpose of using flex-box - the flexibility and responsiveness it gives.
Instead, you can setup media breakpoints and do what works fine at that breakpoint (mobile-first approach). For example:
At extra small devices (portrait phones, less than 576px), I want the buttons to be vertically aligned. I can change the initial css flex-flow property to column instead of row.
#cars-container {
...
flex-flow: column nowrap;
...
}
Then on small devices (landscape phones, 576px and up), I might want only 2 items per row.
#media (min-width: 576px) {
#cars-container {
flex-flow: row wrap;
}
#cars-container button {
width: calc(100% / 2 - 2 * .25rem);
}
}
On Medium devices (tablets, 768px and up), I might want only 3 items per row.
#media (min-width: 768px) {
#cars-container {
width: calc(100% / 3 - 2 * .25rem);
}
}
You got the idea. You just need to change the divisor for the numbers of items you want per row.
Here is the working example with breakpoints: https://jsfiddle.net/rnvt689w/13/

Javascript uploading file alignment

In the above image the delete button need to align properly. in my code it get align based on file name length.
<script>
var filelist = new Array();
updateList = function () {
var input = document.getElementById('fileUploader');
var output = document.getElementById('divFiles');
var HTML = "<table>";
for (var i = 0; i < input.files.length; ++i) {
filelist[i]=input.files.item(i).name;
HTML += "<tr><td>" + filelist[i] + "</td><td> <button ></button></td></tr>";
}
HTML += "</table>";
output.innerHTML += HTML;
}
</script>
Please try this.
table {
border-collapse: separate;
border-spacing: 0 3px;
width: 600px;
}
Try this
table
{
table-layout: fixed;
width: 300px;
}
td
{
border: 1px solid green;
word-wrap:break-word;
}
try jsfiddle
<style>
table {
border-collapse: separate;
border-spacing: 0 2px;
width: 600px;
table-layout: fixed;
}
tr:nth-child(1n) {
border: 2px solid;
background-color: #eceff1;
color: Black;
}
tr:nth-child(2n) {
border: 2px solid;
color: Black;
}
td {
padding-top: .5em;
padding-left: .5em;
padding-right: .5em;
padding-bottom: .5em;
}
input[type="file"] {
display: none;
}
.label1 {
padding: 3px;
background: #fff;
display: table;
color:black;
}
button {
background-image: url('../../Images/delete.ico');
background-size: cover;
padding-right:0px;
background-color: Transparent;
cursor: pointer;
border: none;
width: 30px;
height: 30px;
}
</style>
<script>
$(document).ready(function () {
$(document).on('click', "button", function (e) {
$(this).closest('tr').remove();
});
});
</script>
<script>
var filelist = new Array();
updateList = function () {
var input = document.getElementById('fileUploader');
var output = document.getElementById('divFiles');
var HTML = "<table>";
for (var i = 0; i < input.files.length; ++i) {
filelist[i]=input.files.item(i).name;
HTML += "<tr><td>" + filelist[i] + "</td><td><button ></button></td></tr>";
}
HTML += "</table>";
output.innerHTML += HTML;
}
</script>
In the above script the delete button is showing in fixed order but i want the file name to be aligned at left and delete button need to at right side corner.

Import array from external JS file into HTML

I try to load an array from an external JS file into my HTML and have problems with that.
My js.js:
var temp_max = [4,9,2,5,8,4,2,10];
My HTML:
Note: Please download this file DateJS and insert it into "DATE-JS"!!
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--CSS for layout-->
<link rel="stylesheet" type="text/css" href="mystyle.css">
<!--Date library for german date layout-->
<script src="DATE-JS"></script>
<script src="js.js"></script>
</head>
<body>
<br>
<br>
<div style="width:80%" position="absolute">
<div class="header">
<script>
for(var i = 0 ; i <8 ; i++)
{
var weekday=Date.today().addDays(i).toString('dddd');
document.write("<div id='div_weekday'>" + weekday + "</div>");
}
for(var i = 0 ; i <8 ; i++)
{
var day = Date.today().addDays(i).toString('dd');
document.write("<div id='div_date'>" + day + "</div>")
}
</script>
</div>
</div>
</body>
</html>
My CSS:
* {
box-sizing: border-box;
}
body {
background-color: rgb(86,86,85);
}
h1:after {
content: " ";
width: 70.5%;
height: 2px;
background-color: rgb(228,203,153);
position:absolute;
top: 50%;
margin-left: 15px
}
.header {
width: 100%;
}
.header > div {
color: rgb(228,203,153);
width: 12.5%;
float: left;
border: solid rgb(228,203,153);
border-width: 1px 1px 1px 0;
text-align: left;
word-break: break-all;
}
.header > div:first-child {
border-width: 1px;
}
#div_date {
border: none;
width: 12.5%;
font-size: 60px;
text-align: right;
border-bottom: solid rgba(228,203,153,0.3);
border-width: 0.5px;
padding-right: 1%
}
#div_weekday {
border: none;
width: 12.5%;
font-size: 20px;
text-align: left;
padding-left: 1%
}
Here is a screenshot without importing the JS array.
So I want that my temp_max array values are displayed exactly above the German weekdays!
So above the first information: 'Donnerstag' the script should display the value 4 from the array and so on.
Please note that I want to export this array from an external JS-file, I am not able to write this variable into my HTML file!
I already tried to use
document.getElementById
but this does not work for me.
If the problem just in looping over the created divs, I think you can do this.
All what you need to change is just adding a different ids to your divs.
Just use i index in your ids.
Something like this:
Creation:
for(var i = 0 ; i <8 ; i++) {
var weekday=Date.today().addDays(i).toString('dddd');
document.write("<div id='div_weekday_" + i + "'>" + weekday + "</div>");
}
Updating data:
for (var i = 0; i < 8; i++) {
document.getElementById('div_weekday_' + i).innerHTML = temp_max[i].weekday;
}

Trouble applying CSS changes to dynamically created via JS/JQuery

I've been trying to alter the size of my ".square" divs that are created using JS/JQuery. I've successfully changed the size of the container div, but using the exact same code does not work for the dynamically created .square divs, despite being able to apply events the .square divs in other ways.
I've been trying to understand the problem for the last two days, and have been writing and rewriting solutions, but I think my current skills are overlooking a very simple answer.
The aim was to have the .square divs' size be determined by how many squares will be in the container. The more squares, the smaller the .square div css.
Thanks for any help anyone can give.
$(document).ready(function() {
var create = function(king) {
return $("#container").prepend("<div class='square' id=king></div>");
}
var sLoad = function() {
for (i = 0; i < 16; i++) {
$("#16").click(function() {
$("#container").prepend("<div class='square'></div>");
});
};
};
sLoad();
$("#clear").on("click", function() {
$(".square").remove();
num = prompt("How many squares would you like?");
// var containerSize = function(){
// var siz = 112 * num;
// $("#container").css({"height": siz+15+"px" , "width": siz+"px"});
// }
// containerSize()
$(".square").css({
"height": "50px",
"width": "50px"
});
var make = function(num) {
return num * num;
};
//var squareSize = function(){
// var sqr = 600 / make(num);
// $(".square").css({"height":sqr+"px" , "width":sqr+"px"});
//};
//squareSize();
for (i = 0; i < make(num); i++) {
$("#container").prepend("<div class='square'></div>");
};
});
// $(".button").click(function(){
//
//making the square dis and reappear
$("#container").on("mouseenter", function() {
$(".square").mouseenter(function() {
$(this).fadeTo("fast", 0);
}),
$(".square").mouseleave(function() {
$(this).fadeTo("fast", 1);
});
});
});
#menuContainer {
height: 45px;
width: 50%;
margin: auto;
}
#container {
width: 600px;
height: 600px;
border: 1px blue dotted;
border-radius: 2%;
margin: auto;
padding: 0px;
}
#controlDiv {
height: 30px;
width: 30px;
border: 1px dashed red;
margin: auto;
margin-top: 50%;
background-color: black;
}
.square {
width: 100px;
height: 100px;
background-color: grey;
border: 1px black dashed;
border-radius: 3%;
margin: 5px 5px 5px 5px;
display: inline-block;
}
.button {
height: 27px;
width: 70px;
background-color: gold;
border: solid 1px yellow;
text-decoration-color: blue;
border-radius: 5%;
text-align: center;
padding-top: 7px;
/*margin: auto;*/
margin-bottom: 4px;
display: inline-block;
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<div id="menuContainer">
<div class="button" id="16">Click</div>
<div class="button" id="clear">Clear</div>
</div>
<div id="container">
<!-- <div id="controlDiv"></div> -->
</div>
<!--<div class="square"></div>-->
</body>
</html>
This fiddle should work : https://jsfiddle.net/x0x9rv30/2/
You applied the CSS on removed elements, you need to create the elements first, then you can apply CSS on it.
I just swapped two code blocks :
Before
$(".square").remove();
$(".square").css({"height":"50px" , "width": "50px"});
for (i = 0; i < make(num); i++){
$("#container").prepend("<div class='square'></div>");
};
After
$(".square").remove();
for (i = 0; i < make(num); i++){
$("#container").prepend("<div class='square'></div>");
};
$(".square").css({"height":"50px" , "width": "50px"});

Categories