Table messing up formatting of text - html

I am using Anki (you don't have to be familiar with this) which is a flashcard app. When designing the cards, I cannot figure out what is going wrong.
The front of the card:
<div class="front">
{{#Title}}<div class="title">{{Title}}</div>{{/Title}}
<div class="subtitle">Details</div>
<table id="clozed">
<tr>
<td class="heading">Origin</td>
<td>{{cloze:Text1}}</td>
</tr>
<tr>
<td class="heading">Insertion</td>
<td>{{cloze:Text2}}</td>
</tr>
<tr>
<td class="heading">Innervation</td>
<td>{{cloze:Text3}}</td>
</tr>
<tr>
<td class="heading">Action</td>
<td>{{cloze:Text4}}</td>
</tr>
</table>
</div>
<script>
// Scroll to cloze
function scrollToCloze () {
const cloze1 = document.getElementsByClassName("cloze")[0];
const rect = cloze1.getBoundingClientRect();
const absTop = rect.top + window.pageYOffset;
const absBot = rect.bottom + window.pageYOffset;
if (absBot >= window.innerHeight) {
const height = rect.top - rect.bottom
const middle = absTop - (window.innerHeight/2) - (height/2);
window.scrollTo(0, middle);
};
}
if ( document.readyState === 'complete' ) {
setTimeout(scrollToCloze, 1);
} else {
document.addEventListener('DOMContentLoaded', function() {
setTimeout(scrollToCloze, 1);
}, false);
}
</script>
The back of the card:
<div class="back">
{{#Title}}<div class="title">{{Title}}</div>{{/Title}}
<div class="subtitle">Details</div>
<table id="clozed">
<tr>
<td class="heading">Origin</td>
<td>{{cloze:Text1}}</td>
</tr>
<tr>
<td class="heading">Insertion</td>
<td>{{cloze:Text2}}</td>
</tr>
<tr>
<td class="heading">Innervation</td>
<td>{{cloze:Text3}}</td>
</tr>
<tr>
<td class="heading">Action</td>
<td>{{cloze:Text4}}</td>
</tr>
</table>
</div>
<script>
// Remove cloze syntax from revealed hint
var hint = document.getElementById("original");
if (hint) {
var html = hint.innerHTML.replace(/\[\[oc(\d+)::(.*?)(::(.*?))?\]\]/mg,
"<span class='cloze'>$2</span>");
hint.innerHTML = html
};
// Scroll to cloze
function scrollToCloze () {
const cloze1 = document.getElementsByClassName("cloze")[0];
const rect = cloze1.getBoundingClientRect();
const absTop = rect.top + window.pageYOffset;
const absBot = rect.bottom + window.pageYOffset;
if (absBot >= window.innerHeight) {
const height = rect.top - rect.bottom
const middle = absTop - (window.innerHeight/2) - (height/2);
window.scrollTo(0, middle);
};
}
if ( document.readyState === 'complete' ) {
setTimeout(scrollToCloze, 1);
} else {
document.addEventListener('DOMContentLoaded', function() {
setTimeout(scrollToCloze, 1);
}, false);
}
// Reveal full list
var olToggle = function() {
var orig = document.getElementById('original');
var clozed = document.getElementById('clozed');
var origHtml = orig.innerHTML
orig.innerHTML = clozed.innerHTML
clozed.innerHTML = origHtml
}
</script>
The css styling of the card:
html {
/* scrollbar always visible in order to prevent shift when revealing answer*/
overflow-y: scroll;
}
.card {
border: 1px solid #404040;
padding: 8px;
font-weight: normal;
font-size: 16px;
text-align: left;
color: black;
background-color: white;
}
/* general layout */
.text {
/* center left-aligned text on card */
column-count: 2;
display: inline-block;
align: center;
text-align: left;
margin: auto;
max-width: 40em;
}
.hidden {
/* guarantees a consistent width across front and back */
font-weight: bold;
display: block;
line-height:0;
height: 0;
overflow: hidden;
visibility: hidden;
}
.title {
background-color: #edcac5;
color: #000000;
font-weight: bold;
font-size: 20px;
margin-bottom: 10px;
text-align: center;
}
.subtitle {
background-color: #3b3b3d;
color: #FFFFFF;
font-weight: bold;
font-size: 16px;
padding: 3px;
margin-bottom: 5px;
text-align: center;
}
.heading {
color: #6395ff;
font-weight: bold;
text-align: left;
width: 30%;
}
table {
table-layout: fixed;
width: 100%;
}
td {
word-wrap: break-word;
}
/* clozes */
.cloze {
/* regular cloze deletion */
font-weight: bold;
color: #FFFFFF;
}
.card21 #btn-reveal{
/* no need to display reveal btn on last card */
display:none;
}
/* additional fields */
.extra{
margin-top: 0.5em;
margin: auto;
max-width: 40em;
}
.extra-entry{
margin-top: 0.8em;
font-size: 0.9em;
text-align:left;
}
.extra-descr{
margin-bottom: 0.2em;
font-weight: bold;
font-size: 1em;
}
#btn-reveal {
font-size: 0.5em;
display:none;
}
.mobile #btn-reveal {
font-size: 0.8em;
display:none;
}
This is how it is supposed to look:
But this is how it ends up looking:
I think the table has something to do with this, I greatly appreciate any help/feedback.

I went ahead and threw a section id and called it wrapper and give it a with. This way will minimize any format issues.
// Scroll to cloze
function scrollToCloze () {
const cloze1 = document.getElementsByClassName("cloze")[0];
const rect = cloze1.getBoundingClientRect();
const absTop = rect.top + window.pageYOffset;
const absBot = rect.bottom + window.pageYOffset;
if (absBot >= window.innerHeight) {
const height = rect.top - rect.bottom
const middle = absTop - (window.innerHeight/2) - (height/2);
window.scrollTo(0, middle);
};
}
if ( document.readyState === 'complete' ) {
setTimeout(scrollToCloze, 1);
} else {
document.addEventListener('DOMContentLoaded', function() {
setTimeout(scrollToCloze, 1);
}, false);
}
// back of card
// Remove cloze syntax from revealed hint
var hint = document.getElementById("original");
if (hint) {
var html = hint.innerHTML.replace(/\[\[oc(\d+)::(.*?)(::(.*?))?\]\]/mg,
"<span class='cloze'>$2</span>");
hint.innerHTML = html
};
// Scroll to cloze
function scrollToCloze () {
const cloze1 = document.getElementsByClassName("cloze")[0];
const rect = cloze1.getBoundingClientRect();
const absTop = rect.top + window.pageYOffset;
const absBot = rect.bottom + window.pageYOffset;
if (absBot >= window.innerHeight) {
const height = rect.top - rect.bottom
const middle = absTop - (window.innerHeight/2) - (height/2);
window.scrollTo(0, middle);
};
}
if ( document.readyState === 'complete' ) {
setTimeout(scrollToCloze, 1);
} else {
document.addEventListener('DOMContentLoaded', function() {
setTimeout(scrollToCloze, 1);
}, false);
}
// Reveal full list
var olToggle = function() {
var orig = document.getElementById('original');
var clozed = document.getElementById('clozed');
var origHtml = orig.innerHTML
orig.innerHTML = clozed.innerHTML
clozed.innerHTML = origHtml
}
html {
/* scrollbar always visible in order to prevent shift when revealing answer*/
overflow-y: scroll;
}
.card {
border: 1px solid #404040;
padding: 8px;
font-weight: normal;
font-size: 16px;
text-align: left;
color: black;
background-color: white;
}
/* general layout */
.text {
/* center left-aligned text on card */
column-count: 2;
display: inline-block;
align-items: center;
text-align: left;
margin: auto;
max-width: 40em;
}
.hidden {
/* guarantees a consistent width across front and back */
font-weight: bold;
display: block;
line-height:0;
height: 0;
overflow: hidden;
visibility: hidden;
}
.title {
background-color: #edcac5;
color: #000000;
font-weight: bold;
font-size: 20px;
margin-bottom: 10px;
text-align: center;
}
.subtitle {
background-color: #3b3b3d;
color: #FFFFFF;
font-weight: bold;
font-size: 16px;
padding: 3px;
margin-bottom: 5px;
text-align: center;
}
.heading {
color: #6395ff;
font-weight: bold;
text-align: left;
width: 30%;
}
table {
table-layout: fixed;
width: 100%;
}
td {
word-wrap: break-word;
}
/* clozes */
.cloze {
/* regular cloze deletion */
font-weight: bold;
color: #FFFFFF;
}
.card21 #btn-reveal{
/* no need to display reveal btn on last card */
display:none;
}
/* additional fields */
.extra{
margin-top: 0.5em;
margin: auto;
max-width: 40em;
}
.extra-entry{
margin-top: 0.8em;
font-size: 0.9em;
text-align:left;
}
.extra-descr{
margin-bottom: 0.2em;
font-weight: bold;
font-size: 1em;
}
#btn-reveal {
font-size: 0.5em;
display:none;
}
.mobile #btn-reveal {
font-size: 0.8em;
display:none;
}
/* new css */
#wrapper {
width: 309px;
margin: auto;
}
<section id="wrapper">
<div class="front">
<div class="title">Title</div>
<div class="subtitle">Details</div>
<table id="clozed">
<tr>
<td class="heading">Origin</td>
<td>cloze:Text1</td>
</tr>
<tr>
<td class="heading">Insertion</td>
<td>cloze:Text2</td>
</tr>
<tr>
<td class="heading">Innervation</td>
<td>cloze:Text3</td>
</tr>
<tr>
<td class="heading">Action</td>
<td>cloze:Text4</td>
</tr>
</table>
</div>
<!-- back of card -->
<div class="back">
<div class="title">Title</div>
<div class="subtitle">Details</div>
<table id="clozed">
<tr>
<td class="heading">Origin</td>
<td>cloze:Text1</td>
</tr>
<tr>
<td class="heading">Insertion</td>
<td>cloze:Text2</td>
</tr>
<tr>
<td class="heading">Innervation</td>
<td>cloze:Text3</td>
</tr>
<tr>
<td class="heading">Action</td>
<td>cloze:Text4</td>
</tr>
</table>
</div>
</section>

Related

How to push DIVs down when they run out of screen space

When I new books to the library, it generates a new div with the book information, however, when you spam the books, they will run out of screen space but they wont drop down. Just keep spamming the add book, notice how they got shrunk. It can be related to CSS settings. My book DIVs were not lining up horizontally, so I added
#book-list { display: flex; flex-direction:row }
How can I push the DIVs generated when they have no screen space left?
// ############ Selectors ############
const newBtn = document.querySelector('#newBtn');
const addBtn = document.querySelector('#addBtn');
const closeSpan = document.querySelector('.delete');
const display = document.querySelector('.display-lib');
//############ Listeners ############
// pop up the modal
newBtn.addEventListener('click', function () {
popUp.style.display = "block";
})
// closes the form
closeSpan.addEventListener('click', function () {
popUp.style.display = "none";
})
// closes the form when you click anywhere on the window
window.addEventListener('click', function (e) {
if (e.target == popUp) {
popUp.style.display = "none";
}
})
addBtn.addEventListener('click', function(){
const titleBook = document.querySelector('#title').value;
const authorBook = document.querySelector('#author').value;
const pagesBook = document.querySelector('#pages').value;
const notesBook = document.querySelector('#notes').value;
const readBook = document.querySelector('#read').checked;
if (titleBook === "" || authorBook === "" || pagesBook === "" || notesBook === "") {
showAlert("Please fill in all the blanks", 'error');
} else {
book = new Book(titleBook, authorBook, pagesBook, notesBook, readBook);
myLibrary.push(book);
displayBook(book);
showAlert("book is added", 'success');
}
event.preventDefault();
});
let myLibrary = [];
function Book(title, author, pages, notes, read) {
this.title = title;
this.author = author;
this.pages = pages;
this.notes = notes;
this.read = read;
}
function addBookToLibrary() {
const titleBook = document.querySelector('#title').value;
const authorBook = document.querySelector('#author').value;
const pagesBook = document.querySelector('#pages').value;
const notesBook = document.querySelector('#notes').value;
const readBook = document.querySelector('#read').checked;
if(titleBook === "" && authorBook === "" && pagesBook === "" && notesBook === ""){
showAlert("Please fill in all the blanks", 'success');
} else {
book = new Book(titleBook, authorBook, pagesBook, notesBook, readBook);
myLibrary.push(book);
displayBook(book);
showAlert("book is added", 'success');
}
event.preventDefault();
}
function displayBook(book) {
const shelf = document.querySelector('#book-list');
const books = document.createElement('div');
const row = document.createElement('tr');
const makeTitle = document.createElement('p');
const makeAuthor = document.createElement('p');
const makePages = document.createElement('p');
const makeNotes = document.createElement('p');
const deleteBtn = document.createElement('button');
const readBox = document.createElement('checkbox');
books.classList.add('book');
makeTitle.classList.add("title");
makeAuthor.classList.add("author");
makePages.classList.add("pages");
makeNotes.classList.add("notes");
deleteBtn.classList.add("delete");
readBox.classList.add("switch");
makeTitle.innerHTML = `Title: ${book.title}`;
makeAuthor.innerHTML = `Author: ${book.author}`;
makePages.innerHTML = `Pages: ${book.pages}`;
makeNotes.innerHTML = `Notes: ${book.notes}`;
readBox.innerHTML = `Read: ${book.read}`;
row.appendChild(makeTitle);
row.appendChild(makeAuthor);
row.appendChild(makePages);
row.appendChild(makeNotes);
row.appendChild(deleteBtn);
row.appendChild(readBox);
shelf.appendChild(books);
books.appendChild(row);
const dltBtn = books.querySelector('.delete');
dltBtn.addEventListener('click', function (e) {
deleteBook(e.target);
showAlertDelete('book removed', 'success');
})
}
// ######### ALERTS FOR THE UI ###########
function showAlert(message, className) {
const div = document.createElement('div');
div.className = `alert ${className}`;
div.appendChild(document.createTextNode(message));
const form = document.querySelector('#form');
form.appendChild(div);
setTimeout(function () {
document.querySelector('.alert').remove();
}, 3000);
}
function showAlertDelete(message, className) {
const div = document.createElement('div');
div.className = `alert ${className}`;
div.appendChild(document.createTextNode(message));
const form = document.querySelector('.content');
form.appendChild(div);
setTimeout(function () {
document.querySelector('.alert').remove();
}, 3000);
}
// function that deletes the book. aims at parentElements
function deleteBook(target) {
if (target.className === 'delete') {
target.parentElement.parentElement.remove();
}
}
h1 {
display: flex;
justify-content: center;
}
.title {
display: flex;
justify-content: center;
padding-top: 4rem;
}
p {
display: flex;
justify-content: center;
padding-top: 1rem;
}
body {
background-color: #41b3a3;
}
.success,
.error {
color: white;
padding: 5px;
border-radius: 3px;
}
.error {
background: rgb(190, 0, 0);
}
.success {
background: green;
margin: auto;
}
/* Modal popup box https://www.w3schools.com/howto/howto_css_modals.asp */
/* The Modal (background) */
input#title {
height: 30px;
width: 200px;
font-size: 20px;
}
input#author {
height: 30px;
width: 200px;
font-size: 20px;
}
input#pages {
height: 30px;
width: 200px;
font-size: 20px;
margin-bottom: 20px;
}
input[type=checkbox] {
transform: scale(2);
}
#popUp {
display: none;
/* Hidden by default */
position: fixed;
/* Stay in place */
z-index: 1;
/* Sit on top */
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: rgb(0, 0, 0);
/* Fallback color */
background-color: rgba(0, 0, 0, 0.4);
/* Black w/ opacity */
font-size: 30px;
}
/* Modal Content/Box */
#form {
margin: 15% auto;
/* 15% from the top and centered */
padding: 20px;
width: 20%;
/* Could be more or less, depending on screen size */
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
.mark_as_read {
display: inline-block;
vertical-align: middle;
justify-content: center;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
vertical-align: middle;
justify-content: center;
margin: auto;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked+.slider {
background-color: #41b3a3;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked+.slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
#switch_container {
display: flex;
justify-content: center;
}
/* Styles for the added book */
.book{
display:flex;
align-items: center;
padding: 15px;
margin: 20px;
background-color: #83d898;
border-radius: 20px;
}
.title {
font-size: 30px;
font-weight: bold;
margin-bottom: 20px;
}
.author {
font-size: 30px;
margin-bottom: 20px;
}
.pages {
font-size: 25px;
margin-bottom: 20px;
}
.notes {
font-size: 25px;
margin-bottom: 20px;
}
#book-list {
display: flex;
flex-direction: row;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma#0.9.2/css/bulma.min.css">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Library</title>
</head>
<body>
<div class="content">
<h1 class="title">A Book Library</h1>
<p>A library project where you can store your books, coded for the Odin Project</p>
<div id="addBtn_container" class="has-text-centered">
<a id="newBtn" class="button is-primary is-inverted">Add a New Book</a>
</div>
<div id="popUp" >
<form id='form'>
<header class="modal-card-head">
<p class="modal-card-title">New Book</p>
<span class="delete" id="close" aria-label="close"></span>
</header>
<section class="modal-card-body">
<div id='textInput'>
<p><input type='text' id='title' name='title' placeholder='Title'></p>
<p><input type='text' id='author' name='author' placeholder='Author'></p>
<p><input type='text' id='pages' name='pages' placeholder='Pages'></p>
</div>
<p class="modal-card-title">Notes</p>
<textarea id='notes' class="textarea" placeholder="Notes"></textarea>
</section>
<footer class="modal-card-foot">
<span class="mark_as_read">Mark as read: </span>
<label class="switch">
<input type="checkbox" value="yes" id='read' name='read'>
<span class="slider round"></span>
</label>
<button class="button is-success is-rounded is-pulled-right" type='submit' form='form'
id='addBtn'>Add</button></div>
</footer>
</form>
</div>
</div>
<h1>MY BOOKS</h1>
<div class="display-lib">
<table>
<tbody id="book-list">
</tbody>
</table>
</div>
</tbody>
<script src="app.js"></script>
</body>
</html>
It is happening because you put the div into a table and it is not well formed. A table has to have <tr> and <td> to make the row and the cell, but the thing I recommend you is to get rid of <table> and <tbody>. Flex should be enough. Or if you need a two directions layout you could try grid instead. It is the new way to display things in a 'table way'.
You can make different things. Two of them are: removing <table> and <tbody> tags and changing them to just one <div> (with 100% width) or to make a well formed table with <tr>and <td> and checking the whole table width is your desired (100%).

Issue understanding flexbox formatting [duplicate]

This question already has answers here:
Image inside div has extra space below the image
(10 answers)
Align inline-block DIVs to top of container element
(5 answers)
Closed 2 years ago.
I just finished the basic react tic tac toe tutorial and I modified the base code so I can dynamically generate n x n tic tac toe grids. Currently I'm using flexbox to format my "grid" of buttons and I'm running into an issue where flexbox column appears to be adding a margin between entities. I'm not sure why this is the case. Additionally, when I click on every element in a row, react rerenders the entire row with the correct margins. Below is my css and javascript.
function Square(props) {
return (
<button className="square" onClick={props.onClick}>
{props.value}
</button>
);
}
class Board extends React.Component {
// essentially these are fields that store the state of the board
constructor(props) {
super(props);
this.state = {
squares: Array(16).fill(null),
xIsNext: true
};
}
// generate row
generateRow(j) {
var i;
var columns = 4;
var row = [];
for (i = 0; i < columns; i++) {
row.push(
<div key={i + columns * j}> {this.renderSquare(i + columns * j)} </div>
);
}
return row;
}
// create board
renderBoard() {
var i;
var rows = 4;
var board = [];
for (i = 0; i < rows; i++) {
board.push(<div className="board-row"> {this.generateRow(i)}</div>);
}
return board;
}
handleClick(i) {
const squares = this.state.squares.slice();
if (squares[i]) {
return;
}
squares[i] = this.state.xIsNext ? "X" : "O";
this.setState({
squares: squares,
xIsNext: !this.state.xIsNext
});
}
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onClick={() => this.handleClick(i)}
/>
);
}
render() {
let status;
status = "Next player " + (this.state.xIsNext ? "X" : "O");
return (
<div>
<div className="status">{status}</div>
{this.renderBoard()}
</div>
);
}
}
class Game extends React.Component {
render() {
return (
<div className="game">
<div className="game-board">
<Board />
</div>
</div>
);
}
}
// ========================================
ReactDOM.render(<Game />, document.getElementById("root"));
body {
font: 14px "Century Gothic", Futura, sans-serif;
margin: 20px;
}
ol,
ul {
padding-left: 30px;
}
.status {
margin-bottom: 10px;
}
.square:focus {
outline: none;
}
.kbd-navigation .square:focus {
background: #ddd;
}
.game-info {
margin-left: 20px;
}
.game-board {
display: flex;
flex-direction: column;
}
.board-row {
display: flex;
flex-direction: row;
margin-bottom: -1px;
}
.square {
background: #fff;
border: 1px solid #999;
font-size: 24px;
font-weight: bold;
line-height: 34px;
height: 40px;
padding: 0;
text-align: center;
width: 40px;
margin-right: -1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Image of the issue
One effective way of debugging your layout is examining your elements' dimensions.
As you can see in the images, the button's parent div has a higher height of 2 pixels greater than the button. This is because of the additional size generated by the inline-block (button) element's borders. To address this, I simply assigned button a display: block CSS property.
function Square(props) {
return (
<button className="square" onClick={props.onClick}>
{props.value}
</button>
);
}
class Board extends React.Component {
// essentially these are fields that store the state of the board
constructor(props) {
super(props);
this.state = {
squares: Array(16).fill(null),
xIsNext: true
};
}
// generate row
generateRow(j) {
var i;
var columns = 4;
var row = [];
for (i = 0; i < columns; i++) {
row.push(
<div key={i + columns * j}> { this.renderSquare(i + columns * j) } </div>
);
}
return row;
}
// create board
renderBoard() {
var i;
var rows = 4;
var board = [];
for (i = 0; i < rows; i++) {
board.push(<div className="board-row"> {this.generateRow(i)}</div>);
}
return board;
}
handleClick(i) {
const squares = this.state.squares.slice();
if (squares[i]) {
return;
}
squares[i] = this.state.xIsNext ? "X" : "O";
this.setState({
squares: squares,
xIsNext: !this.state.xIsNext
});
}
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onClick={() => this.handleClick(i)}
/>
);
}
render() {
let status;
status = "Next player " + (this.state.xIsNext ? "X" : "O");
return (
<div>
<div className="status">{status}</div>
{this.renderBoard()}
</div>
);
}
}
class Game extends React.Component {
render() {
return (
<div className="game">
<div className="game-board">
<Board />
</div>
</div>
);
}
}
// ========================================
ReactDOM.render(<Game />, document.getElementById("root"));
body {
font: 14px "Century Gothic", Futura, sans-serif;
margin: 20px;
}
ol,
ul {
padding-left: 30px;
}
.status {
margin-bottom: 10px;
}
.square:focus {
outline: none;
}
.kbd-navigation .square:focus {
background: #ddd;
}
.game-info {
margin-left: 20px;
}
.game-board {
display: flex;
flex-direction: column;
}
.board-row {
display: flex;
flex-direction: row;
margin-bottom: -1px;
}
.square {
background: #fff;
border: 1px solid #999;
font-size: 24px;
font-weight: bold;
line-height: 34px;
height: 40px;
padding: 0;
text-align: center;
width: 40px;
margin-right: -1px;
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
I think I've reproduced your markup output here and I don't see the issue you're having. I suspect there's a CSS rule somewhere that's not represented in your example; something adding a bottom margin to buttons maybe?
Have you inspected it via the browser's dev tools?
body {
font: 14px "Century Gothic", Futura, sans-serif;
margin: 20px;
}
ol,
ul {
padding-left: 30px;
}
.status {
margin-bottom: 10px;
}
.square:focus {
outline: none;
}
.kbd-navigation .square:focus {
background: #ddd;
}
.game-info {
margin-left: 20px;
}
.game-board {
display: flex;
flex-direction: column;
}
.board-row {
display: flex;
flex-direction: row;
margin-bottom: -1px;
}
.square {
background: #fff;
border: 1px solid #999;
font-size: 24px;
font-weight: bold;
line-height: 34px;
height: 40px;
padding: 0;
text-align: center;
width: 40px;
margin-right: -1px;
}
<div class="game">
<div class="game-board">
<div class="board-row">
<button class="square">1</button>
<button class="square">2</button>
<button class="square">3</button>
<button class="square">4</button>
</div>
<div class="board-row">
<button class="square">1</button>
<button class="square">2</button>
<button class="square">3</button>
<button class="square">4</button>
</div>
<div class="board-row">
<button class="square">1</button>
<button class="square">2</button>
<button class="square">3</button>
<button class="square">4</button>
</div>
<div class="board-row">
<button class="square">1</button>
<button class="square">2</button>
<button class="square">3</button>
<button class="square">4</button>
</div>
</div>
</div>

Why my post method only send 1 row of table data after I added the htacess file?

post method only send 1 row of my table after I remove the extension file (.php) using .htaccess file.
if I remove the .htaccess file it will run normally. This my .htaccess file.
DirectoryIndex index
RewriteEngine on
#remove .php extension
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ %1 [R,L,NC]
#add back the .php extension (ex: include 'index.php')
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [NC,L]
#add the .html extension
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^.]+)$ $1.html [NC,L]
The post data should send all the row of data
One missing part in .htaccess is the RewriteBase / , otherwise .php stripped url when u take *.php will not work.
Regarding the data not posted up, could you please check the form action and ensure there is no php extension in it. If the form action has .php extension, then on submitting, htaccess redirect to url without .php so the data get ignored.
i.e. if your form is like
<form action="save.php" method="post">
then replace that with
<form action="save" method="post">
function print_today() {
// ***********************************************
// AUTHOR: WWW.CGISCRIPT.NET, LLC
// URL: http://www.cgiscript.net
// Use the script, just leave this message intact.
// Download your FREE CGI/Perl Scripts today!
// ( http://www.cgiscript.net/scripts.htm )
// ***********************************************
var now = new Date();
var months = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
var date = ((now.getDate()<10) ? "0" : "")+ now.getDate();
function fourdigits(number) {
return (number < 1000) ? number + 1900 : number;
}
var today = date + " " + months[now.getMonth()] + " " + (fourdigits(now.getYear()));
return today;
}
// from http://www.mediacollege.com/internet/javascript/number/round.html
function roundNumber(number,decimals) {
var newString;// The new rounded number
decimals = Number(decimals);
if (decimals < 1) {
newString = (Math.round(number)).toString();
} else {
var numString = number.toString();
if (numString.lastIndexOf(".") == -1) {// If there is no decimal point
numString += ".";// give it one at the end
}
var cutoff = numString.lastIndexOf(".") + decimals;// The point at which to truncate the number
var d1 = Number(numString.substring(cutoff,cutoff+1));// The value of the last decimal place that we'll end up with
var d2 = Number(numString.substring(cutoff+1,cutoff+2));// The next decimal, after the last one we want
if (d2 >= 5) {// Do we need to round up at all? If not, the string will just be truncated
if (d1 == 9 && cutoff > 0) {// If the last digit is 9, find a new cutoff point
while (cutoff > 0 && (d1 == 9 || isNaN(d1))) {
if (d1 != ".") {
cutoff -= 1;
d1 = Number(numString.substring(cutoff,cutoff+1));
} else {
cutoff -= 1;
}
}
}
d1 += 1;
}
if (d1 == 10) {
numString = numString.substring(0, numString.lastIndexOf("."));
var roundedNum = Number(numString) + 1;
newString = roundedNum.toString() + '.';
} else {
newString = numString.substring(0,cutoff) + d1.toString();
}
}
if (newString.lastIndexOf(".") == -1) {// Do this again, to the new string
newString += ".";
}
var decs = (newString.substring(newString.lastIndexOf(".")+1)).length;
for(var i=0;i<decimals-decs;i++) newString += "0";
//var newNumber = Number(newString);// make it a number if you like
return newString; // Output the result to the form field (change for your purposes)
}
function update_total() {
var total = 0;
$('.price').each(function(i){
price = $(this).html().replace("RM ","");
if (!isNaN(price)) total += Number(price);
});
total = roundNumber(total,2);
$('#subtotal').html("RM "+total);
$('#total').html("RM "+total);
update_balance();
}
function update_balance() {
var due = $("#total").html().replace("RM ","") - $("#paid").val().replace("RM ","");
due = roundNumber(due,2);
$('.due').html("RM "+due);
}
function update_price() {
var row = $(this).parents('.item-row');
var price = row.find('.cost').val().replace("RM ","") * row.find('.qty').val();
price = roundNumber(price,2);
isNaN(price) ? row.find('.price').html("N/A") : row.find('.price').html("RM "+price);
update_total();
}
function bind() {
$(".cost").blur(update_price);
$(".qty").blur(update_price);
}
$(document).ready(function() {
$('input').click(function(){
$(this).select();
});
$("#paid").blur(update_balance);
var count=1;
$("#addrow").click(function(){
count++;
$(".item-row:last").after('<tr class="item-row"><td class="item-name" name="item[]"><div class="delete-wpr"><textarea></textarea><a class="delete" href="javascript:;" title="Remove row">X</a></div></td><td class="description" ><textarea name="desc[]">Location: </textarea></td><td style="width:90px;"><textarea class="cost" name="cost[]">RM 0.00</textarea></td><td style="width:30px;"><textarea class="qty" name="qty[]" style="width:100%; text-align: center;" >1</textarea></td><td style="width:90px;"><textarea name="price[]" class="price">RM 0.00</textarea></td></tr>');
if ($(".delete").length > 0) $(".delete").show();
bind();
});
bind();
$(".delete").live('click',function(){
$(this).parents('.item-row').remove();
update_total();
if ($(".delete").length < 1) $(".delete").hide();
});
$("#cancel-logo").click(function(){
$("#logo").removeClass('edit');
});
$("#delete-logo").click(function(){
$("#logo").remove();
});
$("#change-logo").click(function(){
$("#logo").addClass('edit');
$("#imageloc").val($("#image").attr('src'));
$("#image").select();
});
$("#save-logo").click(function(){
$("#image").attr('src',$("#imageloc").val());
$("#logo").removeClass('edit');
});
$("#date").val(print_today());
});
/*
CSS-Tricks Example
by Chris Coyier
http://css-tricks.com
*/
* { margin: 0; padding: 0; }
body { font: 14px/1.4 Georgia, serif; }
#page-wrap { width: 800px; margin: 0 auto; }
textarea { border: 0; font: 14px Georgia, Serif; overflow: hidden; resize: none; }
table { border-collapse: collapse; }
table td, table th {
border: 1px solid black;
padding: 5px;
text-align: left;
}
input[type=text] {
width: 130px;
-webkit-transition: width 0.4s ease-in-out;
transition: width 0.4s ease-in-out;
}
/* When the input field gets focus, change its width to 100% */
input[type=text]:focus {
width: 100%;
}
textarea { border: 0; font: 14px Georgia, Serif; overflow: hidden; resize: none; }
#myInput {
background-image: url('/css/searchicon.png'); /* Add a search icon to input */
background-position: 10px 12px; /* Position the search icon */
background-repeat: no-repeat; /* Do not repeat the icon image */
width: 100%; /* Full-width */
font-size: 16px; /* Increase font-size */
padding: 12px 20px 12px 40px; /* Add some padding */
border: 1px solid #ddd; /* Add a grey border */
margin-bottom: 12px; /* Add some space below the input */
}
#myTable {
border-collapse: collapse; /* Collapse borders */
width: 100%; /* Full-width */
border: 1px solid #ddd; /* Add a grey border */
font-size: 18px; /* Increase font-size */
}
#myTable th, #myTable td {
text-align: left; /* Left-align text */
padding: 12px; /* Add padding */
}
#myTable tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
#myTable tr.header, #myTable tr:hover {
/* Add a grey background color to the table header and on hover */
background-color: #f1f1f1;
}
#header { height: 15px; width: 100%; margin: 20px 0; background: #222; text-align: center; color: white; font: bold 15px Helvetica, Sans-Serif; text-decoration: uppercase; letter-spacing: 20px; padding: 8px 0px; }
#address { width: 250px; height: 150px; float: left; }
#customer { overflow: hidden; }
#logo { text-align: right; float: right; margin-top: 25px; }
#customer-title { height: 90px; float: left; }
#meta { margin-top: 1px; width: 300px; float: right; }
#meta td { text-align: right; }
#meta td.meta-head { text-align: left; background: #eee; }
#meta td textarea { width: 100%; height: 20px; text-align: right; }
#metas { margin-top: 1px; width: 800px; float: right; }
#metas td { text-align: right; }
#metas td.metas-head { text-align: left; background: #eee; }
#metas td textarea { width: 100%; height: 20px; text-align: left; }
#items { clear: both; width: 100%; margin: 30px 0 0 0; border: 1px solid black; }
#items th { background: #eee; }
#items textarea { width: 80px; height: 50px; }
#items tr.item-row td { border: 0; vertical-align: top; }
#items td.description { width: 300px; }
#items td.item-name { width: 175px; }
#items td.jumlah { width: 30px; text-align: center; }
#items td.description textarea, #items td.item-name textarea, #items td.jumlah textarea { width: 100%; }
#items td.total-line { border-right: 0; text-align: right; }
#items td.total-value { border-left: 0; padding: 10px; }
#items td.total-value textarea { height: 20px; background: none; }
#items td.balance { background: #eee; }
#items td.blank { border: 0; }
#terms { text-align: center; margin: 20px 0 0 0; }
#terms h5 { text-transform: uppercase; font: 13px Helvetica, Sans-Serif; letter-spacing: 10px; border-bottom: 1px solid black; padding: 0 0 8px 0; margin: 0 0 8px 0; }
#terms textarea { width: 100%; text-align: center;}
textarea:hover, textarea:focus, #items td.total-value textarea:hover, #items td.total-value textarea:focus, .delete:hover { background-color:#EEEEEE; }
.delete-wpr { position: relative; }
.delete { display: block; color: #000; text-decoration: none; position: absolute; background: #EEEEEE; font-weight: bold; padding: 0px 3px; border: 1px solid; top: -6px; left: -22px; font-family: Verdana; font-size: 12px; }
$(".delete").live('click',function(){
$(this).parents('.item-row').remove();
update_total();
if ($(".delete").length < 1) $(".delete").hide();
});
$("#cancel-logo").click(function(){
$("#logo").removeClass('edit');
});
$("#delete-logo").click(function(){
$("#logo").remove();
});
$("#change-logo").click(function(){
$("#logo").addClass('edit');
$("#imageloc").val($("#image").attr('src'));
$("#image").select();
});
$("#save-logo").click(function(){
$("#image").attr('src',$("#imageloc").val());
$("#logo").removeClass('edit');
});
$("#date").val(print_today());
});
<?PHP
if(isset($db,$_POST['save_btn']))
{
$invoiceno=mysqli_real_escape_string($db,$_POST['invoiceno']);
$paid=mysqli_real_escape_string($db,$_POST['paid']);
$kosong="RM 0.00";
$number = count($_POST["item"]);
$check="SELECT * FROM sales2";
$result=mysqli_query($db,$check);
while($row= mysqli_fetch_array($result))
{
if($row['invoiceno']==$invoiceno){
$id=$row['id']; //store to session
$del = "DELETE FROM sales2 WHERE id=$id";
$dahdelete=true;
mysqli_query($db,$del);
}
}
for($i=0; $i<$number; $i++)
{
echo $_POST["item"][$i];
if(trim($_POST["item"][$i] != '') || trim($_POST["desc"][$i] != '') || trim($_POST["qty"][$i] != '') || trim($_POST["cost"][$i] != '') || trim($_POST["price"][$i] != ''))
{
$checker=$i+1;
if($number==$checker){
$sql = "INSERT INTO sales2(invoiceno,date,item, descriptions, qty, cost, price, paid) VALUES('$invoiceno',CURDATE(),
'".mysqli_real_escape_string($db, $_POST["item"][$i]) ."',
'".mysqli_real_escape_string($db, $_POST["desc"][$i]) ."',
'".mysqli_real_escape_string($db, $_POST["qty"][$i]) ."',
'".mysqli_real_escape_string($db, $_POST["cost"][$i]) ."',
'".mysqli_real_escape_string($db, $_POST["price"][$i])."',
'$paid' )";
mysqli_query($db, $sql);
}
else{
$sql = "INSERT INTO sales2(invoiceno,date,item, descriptions, qty, cost, price,paid) VALUES('$invoiceno',CURDATE(),
'".mysqli_real_escape_string($db, $_POST["item"][$i]) ."',
'".mysqli_real_escape_string($db, $_POST["desc"][$i]) ."',
'".mysqli_real_escape_string($db, $_POST["qty"][$i]) ."',
'".mysqli_real_escape_string($db, $_POST["cost"][$i]) ."',
'".mysqli_real_escape_string($db, $_POST["price"][$i])."','$kosong')";
mysqli_query($db, $sql);
}
}
}
if ($dahdelete==false){
$id=1;
$updatetable= "UPDATE countertable SET no='$invoiceno' WHERE id=$id";
mysqli_query($db,$updatetable);
}
#header("location:");
}
?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<form action="invoice.php" method="POST" role="form">
<textarea id="header">INVOICE</textarea>
<div id="identity">
<textarea id="address" readonly>
ADDRESS:
Email:
Phone: </textarea>
</div>
<div style="clear:both"></div>
<div id="customer">
<p style="font-size: 20px; font-weight: bold; float: left; color: black;">MY COMPANY</p><br><br>
<textarea style="width: 400px; height: 115px; float: left; font-size: 12px" >
</textarea>
<table id="meta">
<tr>
<td class="meta-head">Invoice #</td>
<td><textarea name="invoiceno" readonly><?php echo $invoice?></textarea></td>
</tr>
<tr>
<td class="meta-head">Date</td>
<td><textarea name="date" id="date"></textarea></td>
</tr>
<tr>
<td class="meta-head">Amount Due</td>
<td><textarea class="due">RM 0.00</textarea></td>
</tr>
</table>
</div>
<table id="items" >
<tr>
<th>Item</th>
<th>Description</th>
<th>Unit Cost</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<tr class="item-row">
<td class="item-name"><textarea name="item[]"></textarea></td>
<td class="description"><textarea name="desc[]" >Location:</textarea></td>
<td><textarea name="cost[]" class="cost" style="width: 90px;">RM 0.00</textarea></td>
<td style="width: 30px;"><textarea name="qty[]" class="qty" style="width: 100%; text-align: center;" >1</textarea></td>
<td><textarea name="price[]" class="price" style="width: 90px;">RM 0.00</textarea></td>
</tr>
<tr id="hiderow">
<td colspan="5"><a id="addrow" href="javascript:;" title="Add a row">Add a row</a>
</td>
</tr>
<tr>
<td colspan="2" class="blank" > <textarea style="width: 500px; height:20px;"> </textarea></td>
<td colspan="2" class="total-line">Subtotal</td>
<td class="total-value"><textarea name="subtotal" id="subtotal" style="width: 90px;">RM 0.00</textarea></td>
</tr>
<tr>
<td colspan="2" class="blank"> <textarea style="width: 500px; height:20px;"></textarea></td>
<td colspan="2" class="total-line">Total</td>
<td class="total-value"><textarea name="total" id="total" style="width: 90px;">RM 0.00</textarea></td>
</tr>
<tr>
<td colspan="2" class="blank"><textarea style="width: 500px; height:20px;"></textarea></td>
<td colspan="2" class="total-line">Amount Paid</td>
<td class="total-value paid"><textarea name="paid" id="paid" style="width: 90px;">RM 0.00</textarea></td>
</tr>
<tr>
<td colspan="2" class="blank"></td>
<td colspan="2" class="total-line balance">Balance Due</td>
<td class="total-value balance"><textarea name="due" class="due" style="width: 90px;">RM 0.00</textarea></td>
</tr>
</table>
<div id="terms">
<h5 ><b>Terms</b></h5>
<textarea style="font-size: 13px; text-align: center;" ></textarea>
</div>
<br>
<br>
<center><div id="hiderow">
<button title="save invoice" name="save_btn" type="submit" class="btn btn-info">&nbsp&nbsp Save Data &nbsp&nbsp</button>
</div></center>
</form>

Sync Embedded YouTube Video Time Stamp to Custom Progress Bar

I am stuck on a portion of a project I have been working on today. The task is to sync the timestamp information from the embedded youtube video and display a custom progress bar matching the length of the song at the bottom of the page. Here is the layout so far:
So basically, how do I pull constant timestamps to update the progress and how do I animate the bar to complete 100% matching the end of the video.
I have already disabled the user's ability to scrobble the embedded youtube video. NOTE: the user should not be able to change the time of the youtube video using the custom progress bar either (it is just there for visual queue)!
Please let me know if you need more clarification. HTML and CSS are below. Thank you!! :)
HTML >>>
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="header-bar">
<div class="bar"></div>
<div class="dropshadow"></div>
</div>
<div class="container-middle-third">
<div class="youtube-video" style="float: left;">
<div class="DJ-text">Affinity FM DJ Room</div>
<div class="DJ-underline"></div>
<div class="transparent-layer"> <iframe width="850px" height="477px" src="https://www.youtube.com/embed/2GvIq2SpVFM?autoplay=0&showinfo=0&controls=0" frameborder="0" allowfullscreen></iframe></div>
</div>
<div class="chat" style="float: left;">
<div class="Chat-text">Chat</div>
<div class="Chat-underline"></div>
<input type="text" class="chat-name" placeholder="Chat">
<div class="info-rect">Info</div>
<div class="chat-messages"></div>
<textarea placeholder="Join the conversation..."></textarea>
<div class="chat-status">Status: <span>Idle</span></div>
</div>
</div>
<div class="bottom-bar">
<div class="thumbnail" style="float: left"></div>
<div class="title-bar" style="float: left;">
<div class="song-name">Finding Hope - Let Go (feat. Deverano)</div>
<div class="dj-playing">Affinity FM is playing</div>
<div class="progress-background"></div>
<div class="progress-bar"></div>
</div>
<div class="subscribe" style="float: left;"></div>
</div>
<script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>
<script>
(function() {
var getNode = function(s) {
return document.querySelector(s);
},
// Get required nodes
status = getNode('.chat-status span'),
messages = getNode('.chat-messages'),
textarea = getNode('.chat textarea'),
chatName = getNode('.chat-name'),
statusDefault = status.textContent,
setStatus = function(s){
status.textContent = s;
if(s !== statusDefault){
var delay = setTimeout(function(){
setStatus(statusDefault);
clearInterval(delay);
}, 3000);
}
};
//try connection
try{
var socket = io.connect('http://127.0.0.1:8080');
} catch(e){
//Set status to warn user
}
if(socket !== undefined){
//Listen for output
socket.on('output', function(data){
if(data.length){
//Loop through results
for(var x = 0; x < data.length; x = x + 1){
var message = document.createElement('div');
message.setAttribute('class', 'chat-message');
message.textContent = ': ' + data[x].message;
var name=document.createElement('span');
name.setAttribute('class', 'userName');
name.textContent = data[x].name;
message.insertBefore(name, message.firstChild);
//Append
messages.appendChild(message);
messages.insertBefore(message, messages.firstChild);
}
}
});
//Listen for a status
socket.on('status', function(data){
setStatus((typeof data === 'object') ? data.message : data);
if(data.clear === true){
textarea.value = '';
}
});
//Listen for keydown
textarea.addEventListener('keydown', function(event){
var self = this,
name = chatName.value;
if(event.which === 13 && event.shiftKey === false){
socket.emit('input', {
name: name,
message: self.value
});
}
});
}
})();
</script>
</body>
</html>
and CSS >>>
body {
background-color: #0f0f17;
margin: 0px;
width: 100%;
}
.container-middle-third{
margin-top: 20px;
margin-left: 155px;
}
body,
textarea,
input {
font: 13px "Raleway", sans-serif;
color: #ffffff;
}
.bar{
height: 80px;
width: 100%;
background-color: #15151d;
}
.DJ-text{
font-weight: 700;
/*position:relative;*/
text-transform: uppercase;
}
.Chat-text{
font-weight: 700;
text-transform: uppercase;
}
.DJ-underline{
width: 850px;
height: 1px;
position:relative;top:10px;
background-color: #3f3f45;
margin: 0px 0px 40px;
}
.Chat-underline{
width: 100%;
position:relative;
/*left:-140px;*/
float:right;
height: 1px;
position:relative;top:10px;
background-color: #3f3f45;
margin: 0px 0px 40px;
}
.transparent-layer{
width: 850px;
height: 477px;
pointer-events: none;
background-color: #ffffff;
}
.ad{
width: 728px;
height: 90px;
border: 1px solid #000000;
margin-left: 11px;
margin-top: 20px;
}
.chat {
min-width: 400px;
margin: 0px 0px 0px 135px;
}
.chat-messages,
.chat-textarea,
.chat-name {
border: 1px solid #1a1a23;
background-color: #1a1a23;
}
.userName{
font-weight: 700;
color: #079ce0;
}
.chat-messages {
width:380px;
height:400px;
overflow-y:scroll;
padding:10px;
}
.chat-message {
margin-bottom:10px;
}
.info-rect{
height: 40px;
width: 180px;
padding:10px;
max-width: 100%;
margin:0;
border:0;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
text-transform: uppercase;
background-color: #15151d
}
.chat-name{
height: 40px;
max-width: 100%;
width: 180px;
padding:10px;
border:0;
margin:0;
font-weight: 700;
text-transform: uppercase;
float:left;
text-align: center;
}
.chat textarea {
width:380px;
padding:10px;
margin:0;
border-top:0;
max-width:100%;
border-top: 1px solid #0f0f17;
border-bottom: 1px solid #1a1a23;
border-right: 1px solid #1a1a23;
border-left: 1px solid #1a1a23;
background-color: #1a1a23;
}
.chat-status {
color: #bbb;
opacity: 0;
background-color: #0f0f17;
}
.info-rect,
.chat textarea,
.chat-name {
max-width: 100%;
}
.bottom-bar{
position: fixed;
bottom: 0;
width: 100%;
}
.thumbnail{
width: 80px;
height: 80px;
background-color: #ffffff
}
.title-bar{
width:1000px;
height: 80px;
background-color: #1a1a23;
}
.song-name{
font-weight: 700;
text-transform: uppercase;
margin-left: 30px;
margin-top: 25px;
}
.dj-playing{
margin-left: 30px;
}
.progress-background{
width: 1000px;
height: 4px;
background-color: #313139;
position: fixed;
bottom: 0;
}
.progress-bar{
width: 400px;
height: 4px;
background-color: #fa1d57;
position: fixed;
bottom: 0;
}
.subscribe{
width: 520px;
height: 80px;
background-color: #15151d;
}
Love your questions!
switch the iframe with a div with id="player" (any name you want, it could be "my_own_player" or "XYZ_player"...)
Then now you're all set to convert your iframe player into a Youtube player object so that you can accomplish what you desire, using the "IFrame player API".
Make sure you style your div the same way you wanted your iframe.
Just add the following script :
//This function creates an <iframe> (and YouTube player)
function onYouTubeIframeAPIReady()
{
player = new YT.Player("player",
{
height: "850",
width: "477",
videoId: "2GvIq2SpVFM",
events:
{
"onReady": onPlayerReady,
"onStateChange": onPlayerStateChange
}
});
}
Replace videoId with your video's ID.
Replace height with your video's height.
Replace width with your video's width.
NOW, to get the "Video Time Stamps" like you say, in order to make the progress bar is easy. The player object has two methods that will do that:
getCurrentTime()
getDuration()
getDuration is the total time of the video in seconds. While getCurrentTime is the time where the video has played up to. Divide
getCurrentTime by getDuration and you'll get a ratio for the progress bar. Multiply it by 100 and you get the percentage you're looking for:
(player.getCurrentTime()/player.getDuration())*100;
That's it! Once you got a percentage that represents getCurrentTime / getDuration, you don't need anything else for an html progress bar. Just style that html bar element's width to that percentage. Just make sure that red "bar" has a background (another div) that's easily recognized as the outward limit for the progress bar. Or just put it inside another div that's visible on the page like so :
<div id="progress" style="width: 800px; height: 10px; border: 1px solid #fff;">
<div id="bar" style="width: 1px; height: 10px; background: #f00;"></div>
</div>
Please, just try out your modified HTML:
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="header-bar">
<div class="bar"></div>
<div class="dropshadow"></div>
</div>
<div class="container-middle-third">
<div class="youtube-video" style="float: left;">
<div class="DJ-text">Affinity FM DJ Room</div>
<div class="DJ-underline"></div>
<div class="transparent-layer"> <div id="player" style="width: 850px; height: 477px;"></div></div>
</div>
<div class="chat" style="float: left;">
<div class="Chat-text">Chat</div>
<div class="Chat-underline"></div>
<input type="text" class="chat-name" placeholder="Chat">
<div class="info-rect">Info</div>
<div class="chat-messages"></div>
<textarea placeholder="Join the conversation..."></textarea>
<div class="chat-status">Status: <span>Idle</span></div>
</div>
</div>
<div class="bottom-bar">
<div class="thumbnail" style="float: left"></div>
<div class="title-bar" style="float: left;">
<div class="song-name">Finding Hope - Let Go (feat. Deverano)</div>
<div class="dj-playing">Affinity FM is playing</div>
<div class="progress-background">
<div id="progress-bar" class="progress-bar"></div>
</div>
</div>
<div class="subscribe" style="float: left;"></div>
</div>
<script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>
<script>
(function() {
var getNode = function(s) {
return document.querySelector(s);
},
// Get required nodes
status = getNode('.chat-status span'),
messages = getNode('.chat-messages'),
textarea = getNode('.chat textarea'),
chatName = getNode('.chat-name'),
statusDefault = status.textContent,
setStatus = function(s){
status.textContent = s;
if(s !== statusDefault){
var delay = setTimeout(function(){
setStatus(statusDefault);
clearInterval(delay);
}, 3000);
}
};
//try connection
try{
var socket = io.connect('http://127.0.0.1:8080');
} catch(e){
//Set status to warn user
}
if(socket !== undefined){
//Listen for output
socket.on('output', function(data){
if(data.length){
//Loop through results
for(var x = 0; x < data.length; x = x + 1){
var message = document.createElement('div');
message.setAttribute('class', 'chat-message');
message.textContent = ': ' + data[x].message;
var name=document.createElement('span');
name.setAttribute('class', 'userName');
name.textContent = data[x].name;
message.insertBefore(name, message.firstChild);
//Append
messages.appendChild(message);
messages.insertBefore(message, messages.firstChild);
}
}
});
//Listen for a status
socket.on('status', function(data){
setStatus((typeof data === 'object') ? data.message : data);
if(data.clear === true){
textarea.value = '';
}
});
//Listen for keydown
textarea.addEventListener('keydown', function(event){
var self = this,
name = chatName.value;
if(event.which === 13 && event.shiftKey === false){
socket.emit('input', {
name: name,
message: self.value
});
}
});
}
})();
</script>
<script>
var time_total;
var timeout_setter;
var player;
var tag = document.createElement("script");//This code loads the IFrame Player API code asynchronously
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
//This function creates an <iframe> (and YouTube player) OR uses the iframe if it exists at the "player" element after the API code downloads
function onYouTubeIframeAPIReady()
{
player = new YT.Player("player",
{
height: "850",
width: "477",
videoId: "2GvIq2SpVFM",
events:
{
"onReady": onPlayerReady,
"onStateChange": onPlayerStateChange
}
});
}
//The API will call this function when the video player is ready
function onPlayerReady(event)
{
event.target.playVideo();
time_total = convert_to_mins_and_secs(player.getDuration(), 1);
loopy();
}
function loopy()
{
var current_time = convert_to_mins_and_secs(player.getCurrentTime(), 0);
document.getElementById("progress-bar").style.width = (player.getCurrentTime()/player.getDuration())*100+"%";
console.log( current_time + " / " + time_total);
timeout_setter = setTimeout(loopy, 1000);
}
function convert_to_mins_and_secs(seconds, minus1)
{
var mins = (seconds>=60) ?Math.round(seconds/60):0;
var secs = (seconds%60!=0) ?Math.round(seconds%60):0;
var secs = (minus1==true) ?(secs-1):secs; //Youtube always displays 1 sec less than its duration time!!! Then we have to set minus1 flag to true for converting player.getDuration()
var time = mins + ":" + ((secs<10)?"0"+secs:secs);
return time;
}
// 5. The API calls this function when the player's state changes
function onPlayerStateChange(event)
{
if (event.data == YT.PlayerState.ENDED)
{
console.log("END!");
clearTimeout(timeout_setter);
}
else
{
console.log(event.data);
}
}
</script>
</body>
</html>
With your CSS:
body {
background-color: #0f0f17;
margin: 0px;
width: 100%;
}
.container-middle-third{
margin-top: 20px;
margin-left: 155px;
}
body,
textarea,
input {
font: 13px "Raleway", sans-serif;
color: #ffffff;
}
.bar{
height: 80px;
width: 100%;
background-color: #15151d;
}
.DJ-text{
font-weight: 700;
/*position:relative;*/
text-transform: uppercase;
}
.Chat-text{
font-weight: 700;
text-transform: uppercase;
}
.DJ-underline{
width: 850px;
height: 1px;
position:relative;top:10px;
background-color: #3f3f45;
margin: 0px 0px 40px;
}
.Chat-underline{
width: 100%;
position:relative;
/*left:-140px;*/
float:right;
height: 1px;
position:relative;top:10px;
background-color: #3f3f45;
margin: 0px 0px 40px;
}
.transparent-layer{
width: 850px;
height: 477px;
pointer-events: none;
background-color: #ffffff;
}
.ad{
width: 728px;
height: 90px;
border: 1px solid #000000;
margin-left: 11px;
margin-top: 20px;
}
.chat {
min-width: 400px;
margin: 0px 0px 0px 135px;
}
.chat-messages,
.chat-textarea,
.chat-name {
border: 1px solid #1a1a23;
background-color: #1a1a23;
}
.userName{
font-weight: 700;
color: #079ce0;
}
.chat-messages {
width:380px;
height:400px;
overflow-y:scroll;
padding:10px;
}
.chat-message {
margin-bottom:10px;
}
.info-rect{
height: 40px;
width: 180px;
padding:10px;
max-width: 100%;
margin:0;
border:0;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
text-transform: uppercase;
background-color: #15151d
}
.chat-name{
height: 40px;
max-width: 100%;
width: 180px;
padding:10px;
border:0;
margin:0;
font-weight: 700;
text-transform: uppercase;
float:left;
text-align: center;
}
.chat textarea {
width:380px;
padding:10px;
margin:0;
border-top:0;
max-width:100%;
border-top: 1px solid #0f0f17;
border-bottom: 1px solid #1a1a23;
border-right: 1px solid #1a1a23;
border-left: 1px solid #1a1a23;
background-color: #1a1a23;
}
.chat-status {
color: #bbb;
opacity: 0;
background-color: #0f0f17;
}
.info-rect,
.chat textarea,
.chat-name {
max-width: 100%;
}
.bottom-bar{
position: fixed;
bottom: 0;
width: 100%;
}
.thumbnail{
width: 80px;
height: 80px;
background-color: #ffffff
}
.title-bar{
width:1000px;
height: 80px;
background-color: #1a1a23;
}
.song-name{
font-weight: 700;
text-transform: uppercase;
margin-left: 30px;
margin-top: 25px;
}
.dj-playing{
margin-left: 30px;
}
.progress-background{
width: 1000px;
height: 4px;
background-color: #313139;
position: fixed;
bottom: 0;
}
.progress-bar{
width: 400px;
height: 4px;
background-color: #fa1d57;
position: fixed;
bottom: 0;
}
.subscribe{
width: 520px;
height: 80px;
background-color: #15151d;
}
Or just look at the result there :
http://lespointscom.com/a/misc/demo/2016_06_19/main.html
IFrame player API reference:
https://developers.google.com/youtube/iframe_api_reference#Loading_a_Video_Player

Div is stuck inside another div

I have a DIV with an H2 inside. The DIV is completely separate from all the other work, placed at the bottom of the HTML, yet for some reason it is sticking to the top of the page, inside one of the other DIVs. I've tried Googling but to no avail, I need it below the background to start working on a new section. What should I be looking at?
https://jsfiddle.net/5vLvm3xx/
ps. I dont know how many people browse these forums, but I've been asking alot of questions here today because I keep running into these small issues that stop me from continuing (im a beginner). I hope it is no bother. :)
HTML
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>onepageskiw</title>
<link href="styles.css" rel="stylesheet" type="text/css">
<script src="js.js"></script>
</head>
<body>
<div>
<nav>
<ul id="menu">
<li>Top</li>
<li>Om Eventet</li>
<li>Lokation</li>
<li>Kontakt</li>
</ul>
</nav>
</div>
<div id="logodiv">
<img src="../design/logotop.png">
</div>
<div id="overskrift">
<h1>EVENTET STARTER OM</h1>
</div>
<div id="countdowner">
<table id="table">
<tr>
<div id="countdown">
<td id="id1"></td>
<td id="id2"></td>
<td id="id3"></td>
<td id="id4"></td>
</div>
<tr>
<tr>
<td class="timeLabel">DAGE</td>
<td class="timeLabel">TIMER</td>
<td class="timeLabel">MIN</td>
<td class="timeLabel">SEK</td>
</tr>
</tr>
</tr>
</table>
</div>
<script>
CountDownTimer('06/25/2016 10:00 AM', 'id');
function CountDownTimer(dt, id)
{
var end = new Date(dt);
var _second = 1000;
var _minute = _second * 60;
var _hour = _minute * 60;
var _day = _hour * 24;
var timer;
function showRemaining() {
var now = new Date();
var distance = end - now;
if (distance < 0) {
clearInterval(timer);
document.getElementById(id).innerHTML = 'EXPIRED!';
return;
}
var days = Math.floor(distance / _day);
var hours = Math.floor((distance % _day) / _hour);
var minutes = Math.floor((distance % _hour) / _minute);
var seconds = Math.floor((distance % _minute) / _second);
document.getElementById(id+"1").innerHTML = days;
document.getElementById(id+"2").innerHTML = hours;
document.getElementById(id+"3").innerHTML = minutes;
document.getElementById(id+"4").innerHTML = seconds;
}
timer = setInterval(showRemaining, 1000);
}
</script>
<div id="information">
<h2>Help me. I'm stuck.</h2>
</div>
</body>
</html>
CSS
#charset "utf-8";
#import url(https://fonts.googleapis.com/css? family=Montserrat:400|Raleway:100,400|);
body {
margin:0;
}
html {
background:url(http://www.freelargeimages.com/wp- content/uploads/2014/12/Black_background.jpg) no-repeat center center fixed;
background-size: cover;
background-repeat: no-repeat;
/*background-position: top center;*/
}
#logodiv {
position:relative;
text-align:center;
}
#logodiv>img {
width:15%;
}
h1 {
font-family:raleway;
font-weight:100;
position:absolute;
width:100%;
text-align:center;
color:white;
letter-spacing:11px;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-230%);
font-size:2.5em;
white-space: nowrap;
}
#countdowner {
font-family:sans-serif;
color:white;
position:absolute;
margin:0;
padding:0;
width:100%;
font-size:2em;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-20%);
}
#id1 {
font-size:2.5em;
}
#id2 {
font-size:2.5em;
}
#id3 {
font-size:2.5em;
}
#id4 {
font-size:2.5em;
}
.timeLabel {
font-size:0.7em;
color:#f1a01e;
font-family:montserrat;
font-weight:700;
}
#table {
margin:0 auto;
text-align:center;
}
#table td{
padding:0px 45px;
}
#menu {
position:absolute;
padding:0;
width:100%;
bottom:0;
text-align:center;
}
#menu>li {
font-size:20px;
list-style:none;
display:inline-block;
text-transform:uppercase;
letter-spacing:3px;
font-family:raleway;
font-weight:400;
}
#menu>li>a {
padding:0 15px;
text-decoration:none;
color:white;
}
#menu>li>a:hover {
color:#f1a01e;
}
#information {
position:relative;
clear:both;
color:red;
}
This is because all of your other elements are using position: absolute;
You may use the flex properties, height order and rearrange a bit the structure (1 wrapper and a class): https://jsfiddle.net/5vLvm3xx/2/
CountDownTimer('06/25/2016 10:00 AM', 'id');
function CountDownTimer(dt, id) {
var end = new Date(dt);
var _second = 1000;
var _minute = _second * 60;
var _hour = _minute * 60;
var _day = _hour * 24;
var timer;
function showRemaining() {
var now = new Date();
var distance = end - now;
if (distance < 0) {
clearInterval(timer);
document.getElementById(id).innerHTML = 'EXPIRED!';
return;
}
var days = Math.floor(distance / _day);
var hours = Math.floor((distance % _day) / _hour);
var minutes = Math.floor((distance % _hour) / _minute);
var seconds = Math.floor((distance % _minute) / _second);
document.getElementById(id + "1").innerHTML = days;
document.getElementById(id + "2").innerHTML = hours;
document.getElementById(id + "3").innerHTML = minutes;
document.getElementById(id + "4").innerHTML = seconds;
}
timer = setInterval(showRemaining, 1000);
}
#charset "utf-8";
#import url(https://fonts.googleapis.com/css?family=Montserrat:400|Raleway:100,400|);
body {
margin: 0;
}
html {
background-repeat: no-repeat;
/*background-position: top center;*/
}
#logodiv {
position: relative;
text-align: center;
}
#logodiv>img {
width: 15%;
}
h1 {
font-family: raleway;
font-weight: 100;
width: 100%;
text-align: center;
color: white;
letter-spacing: 11px;
font-size: 2.5em;
white-space: nowrap;
}
#countdowner {
font-family: sans-serif;
color: white;
margin: 0;
padding: 0;
width: 100%;
font-size: 2em;
}
#id1 {
font-size: 2.5em;
}
#id2 {
font-size: 2.5em;
}
#id3 {
font-size: 2.5em;
}
#id4 {
font-size: 2.5em;
}
.timeLabel {
font-size: 0.7em;
color: #f1a01e;
font-family: montserrat;
font-weight: 700;
}
#table {
margin: 0 auto;
text-align: center;
}
#table td {
padding: 0px 45px;
}
#menu {
padding: 0;
width: 100%;
bottom: 0;
text-align: center;
}
#menu>li {
font-size: 20px;
list-style: none;
display: inline-block;
text-transform: uppercase;
letter-spacing: 3px;
font-family: raleway;
font-weight: 400;
}
#menu>li>a {
padding: 0 15px;
text-decoration: none;
color: white;
}
#menu>li>a:hover {
color: #f1a01e;
}
#information {
position: relative;
clear: both;
color: red;
}
html,
body,
.splash {
height: 100%;
}
.splash {
display: flex;
flex-flow: column;
min-height:450px; background: url(http://www.freelargeimages.com/wp-content/uploads/2014/12/Black_background.jpg) no-repeat center center fixed;
background-size: cover;
}
.splash>* {
order: -1;
flex: 1;
}
.splash:before {
content: '';
display: block;
order: 0;
flex: 1;
}
.menu {
order: 1;
flex: none;
margin-top: auto;
margin-bottom: 0;
}
<div class="splash">
<div class="menu">
<nav>
<ul id="menu">
<li>Top
</li>
<li>Om Eventet
</li>
<li>Lokation
</li>
<li>Kontakt
</li>
</ul>
</nav>
</div>
<div id="logodiv">
<img src="../design/logotop.png">
</div>
<div id="overskrift">
<h1>EVENTET STARTER OM</h1>
</div>
<div id="countdowner">
<table id="table">
<tr>
<div id="countdown">
<td id="id1"></td>
<td id="id2"></td>
<td id="id3"></td>
<td id="id4"></td>
</div>
<tr>
<tr>
<td class="timeLabel">DAGE</td>
<td class="timeLabel">TIMER</td>
<td class="timeLabel">MIN</td>
<td class="timeLabel">SEK</td>
</tr>
</table>
</div>
</div>
<div id="information">
<h2>Help me. I'm stuck.</h2>
</div>