Checkbox need two clicks to uncheck? - html

My checkboxes need 2 clicks to be unchecked.
I have the issue in all 7 checkboxes.
To check the boxes, one click is enough.
I have no onchange() function or something in TS.
.............................................................................................................................................................
import { Component, OnInit, Inject } from '#angular/core';
import { PHPAPIService } from '../../php-api.service';
import * as socketIO from 'socket.io-client';
import {MatTableModule} from '#angular/material/table';
import * as $ from 'jquery';
import { ToastrService } from 'ngx-toastr';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '#angular/material';
export interface DialogData {
name: string;
}
#Component({
selector: 'app-module',
templateUrl: './module.component.html',
styleUrls: ['./module.component.css'],
providers: [PHPAPIService]
})
export class ModuleComponent implements OnInit {
toastChanges = 0;
xForToastMSG = 1;
moduleTimer = [];
fileToUpload: File = null;
moduleExpandState = [];
constructor(public PHPAPIService:PHPAPIService, private toastrService: ToastrService, public dialog: MatDialog) {
}
ngOnInit() {
for(var i=0;i<1000;i++)
this.moduleExpandState[i] = false;
this.PHPAPIService.get("tprofile").subscribe(
(data) => this.PHPAPIService.profiles = data
);
this.PHPAPIService.get("ttimer").subscribe(
(data) => this.PHPAPIService.timers = data
);
this.PHPAPIService.get("tmodule").subscribe(
(data) => this.PHPAPIService.modules = data
);
const socket = socketIO(this.PHPAPIService.apiUrl);
socket.on('tmodule', (snapshot) => this.PHPAPIService.modules = snapshot);
socket.on('timeUpdate', (snapshot) => this.PHPAPIService.date = snapshot);
setTimeout(()=>{
for(var i=0; i< this.PHPAPIService.modules.length ;i++){
/*Konvertiert die einelenen Daten HH und MM in ein String HH:MM*/
this.moduleTimer[i] = this.PHPAPIService.modules[i].time_h + ":" + this.PHPAPIService.modules[i].time_m;
//console.log(this.localTimerVar[i].on);
}
},1200);
//socket.on('tmodule', () => this.showSuccess());
}
/* showSuccess(text) {
/* if(this.xForToastMSG == 1){
this.xForToastMSG = 0;*/
// this.toastrService.success(text,'',{
// positionClass: 'toast-bottom-right'
// });
/* this.toastChanges = 1;*/
// }
/* setTimeout(()=>{
this.toastChanges = 0;
this.xForToastMSG = 1;
},500);*/
//}*/
showWarning(text) {
this.toastrService.warning(text,'',{
positionClass: 'toast-bottom-right'
});
}
/* showDownload() {
this.toastrService.success('Datensicherung wird erstellt','',{
positionClass: 'toast-bottom-right'
});
}*/
/*NUR FÜR MEHERERE FILES*/
/*handleFileInput(files: FileList) {
// console.log("TEST");
this.fileToUpload = files.item(0);
this.uploadFileToActivity();
}
*/
uploadFileToActivity(files: FileList) {
this.fileToUpload = files.item(0);
console.log(files.item(0));
if(files.item(0).name.substring(0,6) === 'module'){
this.PHPAPIService.uploadBackupModule(files.item(0)).subscribe(data => {
// do something, if upload success
this.showSuccess('Import erfolgreich!');
console.log(data);
}, error => {
console.log(error);
});
}else{
this.showWarning('fehlerhafte Datei');
}
}
backupModule(m_id, m_name){
this.showSuccess('Datensicherung wird erstellt');
this.PHPAPIService.backupModule(m_id, m_name).subscribe(response => this.downLoadFile(response.text(), "application/plain", m_name));
}
downLoadFile(data: any, type: string, name) {
var blob = new Blob([data], { type: type});
var url = window.URL.createObjectURL(blob);
// var pwa = window.open(url);
var anchor = document.createElement("a");
anchor.setAttribute("type", "hidden"); // make it hidden if needed
anchor.download = "module_"+name+".sql";
anchor.href = url;
document.body.appendChild(anchor);
anchor.click();
anchor.remove();
/*if (!pwa || pwa.closed || typeof pwa.closed == 'undefined') {
alert( 'Please disable your Pop-up blocker and try again.');
}*/
}
showSuccessNoChanges() {
this.toastrService.warning('keine Änderungen','',{
positionClass: 'toast-bottom-right'
});
}
showSuccess(x){
console.log(this.PHPAPIService.modules[x].time_h);
if(this.PHPAPIService.modules[x].time_h != '' && this.PHPAPIService.modules[x].time_m != ''){
this.toastrService.success('Änderung gespeichert','',{
positionClass: 'toast-bottom-right'
});
}else{
this.toastrService.error('Bitte Zeit eintragen','',{
positionClass: 'toast-bottom-right'
});
}
if(x == "zeit verfügbar"){
this.toastrService.error('Zeit bereits verfügbar','Die eingetragene Zeit ist bereits in einem andern Modul verfügbar, bitte eine andere Uhrzeit eintragen.',{
positionClass: 'toast-bottom-right'
});
}
}
togglePanel(x){
this.moduleExpandState[x] = !this.moduleExpandState[x];
$('#nameInput-'+x+' ').toggleClass('inputEdit');
}
saveModule(mID, x){
if(this.PHPAPIService.modules[x]['0'] == false) this.PHPAPIService.modules[x]['0'] = "";
if(this.PHPAPIService.modules[x]['1'] == false) this.PHPAPIService.modules[x]['1'] = "";
if(this.PHPAPIService.modules[x]['2'] == false) this.PHPAPIService.modules[x]['2'] = "";
if(this.PHPAPIService.modules[x]['3'] == false) this.PHPAPIService.modules[x]['3'] = "";
if(this.PHPAPIService.modules[x]['4'] == false) this.PHPAPIService.modules[x]['4'] = "";
if(this.PHPAPIService.modules[x]['5'] == false) this.PHPAPIService.modules[x]['5'] = "";
if(this.PHPAPIService.modules[x]['6'] == false) this.PHPAPIService.modules[x]['6'] = "";
if(this.PHPAPIService.modules[x]['0'] == true) this.PHPAPIService.modules[x]['0'] = "checked";
if(this.PHPAPIService.modules[x]['1'] == true) this.PHPAPIService.modules[x]['1'] = "checked";
if(this.PHPAPIService.modules[x]['2'] == true) this.PHPAPIService.modules[x]['2'] = "checked";
if(this.PHPAPIService.modules[x]['3'] == true) this.PHPAPIService.modules[x]['3'] = "checked";
if(this.PHPAPIService.modules[x]['4'] == true) this.PHPAPIService.modules[x]['4'] = "checked";
if(this.PHPAPIService.modules[x]['5'] == true) this.PHPAPIService.modules[x]['5'] = "checked";
if(this.PHPAPIService.modules[x]['6'] == true) this.PHPAPIService.modules[x]['6'] = "checked";
/*checke ob gleiche Uhrzeiten verfügbar sind*/
/*for(var i = 0; i < this.PHPAPIService.modules.length+1; i++){
console.log(this.moduleTimer[x]);
console.log(this.PHPAPIService.modules[x].time_h+":"+this.PHPAPIService.modules[x].time_m);
if(this.PHPAPIService.modules[i].time_h+":"+this.PHPAPIService.modules[i].time_m == this.moduleTimer[x]){
this.showSuccess("zeit verfügbar");
return null;
}
}*/
/*Konvertiert den 19:45 String in 19 und 45*/
//console.log(this.PHPAPIService.modules[x]);
if(this.PHPAPIService.modules[x].m_active == false){
this.PHPAPIService.modules[x].m_active = "";
}
if(this.PHPAPIService.modules[x].m_active == true){
this.PHPAPIService.modules[x].m_active = "checked";
// this.PHPAPIService.saveModule(mID, this.PHPAPIService.modules[x]).subscribe();
}
if(this.moduleTimer[x] != ''){
this.PHPAPIService.modules[x].time_h = this.moduleTimer[x].split(":")[0];
this.PHPAPIService.modules[x].time_m = this.moduleTimer[x].split(":")[1];
}
if(this.PHPAPIService.modules[x].time_h != '' && this.PHPAPIService.modules[x].time_m != ''){
this.PHPAPIService.saveModule(mID, this.PHPAPIService.modules[x]).subscribe();
}
setTimeout(()=>{
// if(this.toastChanges != 1){
this.showSuccess(x);
// };
},200);
}
deleteModule(mID, x){
const dialogRef = this.dialog.open(DialogOverviewModule, {
width: '250px',
data: {name: this.PHPAPIService.modules[x].m_name}
});
dialogRef.afterClosed().subscribe(result => {
console.log(result);
if(result == true){
this.PHPAPIService.deleteModule(mID).subscribe();
}
});
//this.PHPAPIService.deleteModule(mID).subscribe();
// this.PHPAPIService.profiles[x] = null;
}
addModule(){
this.PHPAPIService.addModule().subscribe();
for(var i=0;i<1000;i++)
this.moduleExpandState[i] = false;
// this.PHPAPIService.profiles[x] = null;
}
}
#Component({
selector: 'dialog-overview-example-dialog',
templateUrl: 'dialog-overview-example-dialog.html',
})
export class DialogOverviewModule {
constructor(
public dialogRef: MatDialogRef<DialogOverviewModule>,
#Inject(MAT_DIALOG_DATA) public data: DialogData) {}
save = true;
onNoClick(): void {
this.dialogRef.close();
}
}
h1{
display: block;
margin: 0;
padding: 20px;
padding-left: 220px;
}
h4{
margin: auto 0px;
padding: 0;
font-weight: 200;
padding-right: 50px;
}
h2{
margin: 10px;
font-weight: 100;
}
header{
display: flex;
flex-direction: row;
justify-content: space-between;
margin: 0;
margin-left:200px;
padding-left: 20px;
padding-right: 20px;
background-color: #323741;
color: #D7E2F7;
}
input[type="file"] + label {
margin: 0;
padding: 0;
}
/*input[type="file"]:focus + label,
input[type="file"] + label:hover {
background-color: red;
}*/
input[type="file"]{
float: right;
margin: 20px;
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
.modSelect, .modSelect option{
font-size: 1.2em;
width: 250px !important;
}
input{
height: 30px;
outline: none;
border: none;
background: transparent;
font-size: 1.2em;
}
input:focus{
background: white;
outline: none;
border: solid 1px black;
}
input[type="checkbox"]{
margin: auto 0px;
margin-left: 10px;
width: 18px;
}
/deep/ .mat-expansion-panel-header{
padding-top: 10px !important;
padding-bottom: 10px !important;
margin-left:200px;
}
.row_expansion_column{
display: flex;
flex-wrap: nowrap;
flex-direction: row;
justify-content: center;
align-items: center;
flex-grow: 0;
text-align: center;
margin-left:200px;
}
.row_expansion_column select{
margin: 10px;
width: 100px;
}
.delBtn{
background-color: #ed1212;
border: 1px solid #ed1212;
font-size: 1.2em;
color: white;
}
.saveBtn{
background-color: green;
border: 1px solid green;
font-size: 1.2em;
color: white;
}
.exportBtn{
background-color: #707070FF;
border: 1px solid #707070FF;
font-size: 1.2em;
color: white;
}
.addBtn{
background-color: #707070FF;
border: 1px solid #707070FF;
float: right;
margin: 20px;
padding: 0 10px;
font-size: 1.2em;
color : white;
}
.importBtn{
background-color: #707070FF;
border: 1px solid #707070FF;
float: right;
margin: 20px;
padding: 0;
font-size: 1.2em;
color : white;
}
.fileBtn{
background-color: #707070FF;
border: 1px solid #707070FF;
float: right;
padding: 0px 20px;
font-size: 1em;
color : white;
line-height: 34px;
cursor: pointer;
}
.editBtn{
margin: 0 0 0 auto;
//background-color: #DADADAFF;
border: 1px solid #707070FF;
color : #707070FF;
padding: 2px 10px 2px 10px;
font-size: 1.2em;
}
input[type="text"]{
outline: none;
border: none;
background: transparent;
height: 30px;
font-size: 1.2em;
pointer-events: none;
}
input[type="text"]:hover{
cursor: default;
pointer-events: none;
}
input[type="text"].inputEdit:hover{
pointer-events: auto;
outline: none;
cursor: text;
border: 1px solid #707070FF;
}
input[type="text"].inputEdit{
background: white;
pointer-events: auto;
outline: none;
cursor: text;
border: 1px solid #707070FF;
}
img{
width: 120px;
position: absolute;
right: 20px;
bottom: 20px;
}
/deep/ .mat-slide-toggle.mat-warn.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb {
background-color: blue;
float: right;
}
/deep/ .mat-slide-toggle.mat-warn.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar {
background-color: rgba(124, 172, 249,.5);
float: right;
}
/deep/ .mat-slide-toggle{
position: relative;
top: 15px;
padding-right: 10px;
margin-left: 20px;
}
/deep/ .mat-slide-toggle-bar {
height: 15px !important;
width: 40px !important;
}
/deep/ .mat-slide-toggle-thumb {
height: 25px !important;
width: 25px !important;
background-color: #ececec;
margin-left: -2px;
margin-top: -2px;
}
/deep/ .mat-slide-toggle.mat-checked .mat-slide-toggle-thumb-container {
transform: translate3d(23px,0,0) !important;
}
.seperateContainer{
padding-left: 20px;
display: inherit;
background-color: #f5f5f5;
}
#modAct{
margin-left: 20px;
}
#media only screen and (max-width: 600px) {
header h2{
padding-left: 20px;
}
.row_expansion_column{
margin-left:0px;
}
/deep/ .mat-expansion-panel-header{
margin-left:0px;
}
header{
margin-left:0px;
}
}
<header>
<h2>Module</h2>
<h4 [(ngModel)]="PHPAPIService.date" ngDefaultControl>
{{PHPAPIService.date | date:'HH:mm:ss dd.MM.yyyy'}}
</h4>
</header>
<mat-expansion-panel *ngFor="let module of PHPAPIService.modules; let x = index" [expanded]="moduleExpandState[module.m_id]"
[disabled]="true">
<mat-expansion-panel-header>
<input type="text" name="" id="{{ 'nameInput-' + module.m_id }}" placeholder="Bezeichnung"
required [(ngModel)]="module.m_name" [value]="module.m_name"/>
<button mat-button class="editBtn" (click)="togglePanel(module.m_id)">Bearbeiten</button>
</mat-expansion-panel-header>
<div class="row_expansion">
<div class=row_expansion_column>
<h3>Profil</h3>
<select class="modSelect" required [(ngModel)]="module.m_profile">
<option [value]="profile.profileID" *ngFor="let profile of PHPAPIService.profiles">{{profile.Name}}</option>
</select>
<h3>schaltetzeit</h3>
<input type="time" name="" required [(ngModel)]="moduleTimer[x]" value="{{module.time_h}}:{{module.time_m}}"/>
<div class="seperateContainer">
<div class="dayCheckBox"><h3>MO</h3>
<input type="checkbox" required [(ngModel)]="module['1']" checked="{{module['1']}}"/> <!-- timer.1 funktiniert nicht, DB hat leider 0 - 7 als spalten -->
</div>
<div class="dayCheckBox"><h3>DI</h3>
<input type="checkbox" required [(ngModel)]="module['2']" checked="{{module['2']}}"/></div>
<div class="dayCheckBox"><h3>MI</h3>
<input type="checkbox" required [(ngModel)]="module['3']" checked="{{module['3']}}"/></div>
<div class="dayCheckBox"><h3>DO</h3>
<input type="checkbox" required [(ngModel)]="module['4']" checked="{{module['4']}}"/></div>
<div class="dayCheckBox"><h3>FR</h3>
<input type="checkbox" required [(ngModel)]="module['5']" checked="{{module['5']}}"/></div>
<div class="dayCheckBox"><h3>SA</h3>
<input type="checkbox" required [(ngModel)]="module['6']" checked="{{module['6']}}"/></div>
<div class="dayCheckBox"><h3>SO</h3>
<input type="checkbox" required [(ngModel)]="module['0']" checked="{{module['0']}}"/></div>
</div>
<h3 id="modAct">Active</h3>
<mat-slide-toggle [(ngModel)]="module.m_active" color="warn"
[checked]="module.m_active"></mat-slide-toggle>
</div>
</div>
<mat-action-row>
<button mat-button class="exportBtn" (click)="backupModule(module.m_id, module.m_name)">Export</button>
<button mat-button class="delBtn" (click)="deleteModule(module.m_id, x)">Löschen</button>
<button mat-button class="saveBtn" (click)="saveModule(module.m_id, x)">Speichern</button>
</mat-action-row>
</mat-expansion-panel>
<button mat-button class="addBtn" (click)="addModule()">neues Modul erstellen</button>
<!-- <div class="form-group"> -->
<!-- <button mat-button class="fileBtn"> <label for="file">Datei auswählen</label></button> -->
<input type="file"
class="inputfile"
enctype="multipart/form-data"
id="file"
name="filetoupload"
(change)="uploadFileToActivity($event.target.files)" >
<button mat-button class="importBtn" ><label for="file"class="fileBtn">Import</label></button>
<!-- <label for="file"class="fileBtn">Import</label> -->
<!-- </div> -->

You don't need checked="{{module['1']}}", data binding is handling that. So please remove below code from your check boxes and it would work.
checked="{{module['1']}}" //Remove this
Let me know if you need full code, I can share.
Check running code at below repository.
https://stackblitz.com/github/nitin1982/StackOverFlowProblems/tree/master/CheckBoxIssue?file=src%2Fapp%2Fapp.component.html

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%).

html countdown time is not stopping after specified time

I am new to coding and preparing a download button time for my blogger blog but in the script timer doesn't stop after 10 seconds. In this script download button should be hide and display only after 10 seconds. and after click it goes on the link that is given in the page url that is working fine.
2 problem 1st one download button is not hiding before 10 seconds and counter is not stopping here below is code:
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
return (false);
}
var time = 10;
var page = getQueryVariable("pms");
function countDown() {
time--;
gett("timecount").innerHTML = time;
if (time == 0) {
}
}
function gett(id) {
if (document.getElementById) return document.getElementById(id);
if (document.all) return document.all.id;
if (document.layers) return document.layers.id;
if (window.opera) return window.opera.id;
}
function init() {
if (gett('timecount')) {
setInterval(countDown, 1000);
gett("timecount").innerHTML = time;
} else {
setTimeout(init, 10);
}
}
document.onload = init();
$(document).ready(function() {
$('.link-out-btn').click(function() {
window.location = page;
});
$('#linkout').text(page);
});
function closeWindow() {
window.open('', '_parent', '');
window.close();
}
#button1 {
background-color: Blue;
border: none;
border-radius: 4px;
color: white;
padding: 10px 30px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 20px;
cursor: pointer;
}
#button2 {
background-color: white;
border: none;
border-radius: 4px;
color: white;
padding: 7px 14px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
cursor: pointer;
}
.footer-credits {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span style="color: blue;"><span style="background-color: white; color: black; font-size: 16px; white-space: pre-wrap;"></span><b> </b></span><span style="color: blue;"><b><span style="color: red; font-size: large;"> PLEASE WAITING...
</span><span id="timecount" style="color: red; font-size: large;"></span><span style="color: red; font-size: large;"> s</span><span style="color: blue;">! </span></b>
</span><br/>
<button class="link-out-btn" id="button1">DOWNLOAD</button>
<button id="button2" onclick="javascript:closeWindow();">.</button>
I have got the problem. and edited the code please see.. now time is running and after completion it hide and change to another text and white running counter download button is not shown.
<script>function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
return (false);
}
var time = 15;
var page = getQueryVariable("pms");
var tId;
function countDown() {
time--;
$("#time").html(time);
if (time == 0) {
clearInterval(tId)
console.log("DONE");
$("#wt").html("Your Download Link is Ready");
$("#button1").show();
$("#button2").show();
$('.link-out-btn').click(function() {
window.location = page;
});
}
if (time !== 0){
$("#button1").hide();
$("#button2").hide();
}
}
function init() {
tId = setInterval(countDown, 1500);
$("#time").html(time);
$("#linkout").html(page);
$("#button1").hide();
$("#button2").hide();
}
$(document).ready(function() {
init();
});
function closeWindow() {
window.open('', '_parent', '');
window.close();
}</script>
<style>#button1 {
background-color: Blue;
border: none;
border-radius: 4px;
color: white;
padding: 10px 30px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 20px;
cursor: pointer;
}
#button2 {
background-color: white;
border: none;
border-radius: 4px;
color: white;
padding: 7px 14px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
cursor: pointer;
}
.footer-credits {
display: none;
}</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span id="wt" style="color: red; font-size: large;">
Please Wait... <span id="time" style="color: red; font-size: large;"></span> s!</span><span style="color: blue;"> </span>
<button class="link-out-btn" id="button1">DOWNLOAD</button>
<button id="button2" onclick="closeWindow();">.</button>
Quite a few issues.
Study the simplified code below
I am not sure what the element with id=linkout is supposed be
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
return "";
}
var time = 10;
var page = getQueryVariable("pms") || "not passed";
var tId;
function countDown() {
time--;
$("#time").html(time);
if (time == 0) {
clearInterval(tId)
console.log("DONE");
$('.link-out-btn').click(function() {
window.location = page;
});
}
}
function init() {
tId = setInterval(countDown, 1000);
$("#time").html(time);
$("#linkout").html(page);
}
$(document).ready(function() {
init();
});
function closeWindow() {
window.open('', '_parent', '');
window.close();
}
#button1 {
background-color: Blue;
border: none;
border-radius: 4px;
color: white;
padding: 10px 30px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 20px;
cursor: pointer;
}
#button2 {
background-color: white;
border: none;
border-radius: 4px;
color: white;
padding: 7px 14px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
cursor: pointer;
}
.footer-credits {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p style="color: red; font-size: large;"> PLEASE WAIT...
<span id="time" style="color: red; font-size: large;"></span>s
<span style="color: blue;">! </span>
<button class="link-out-btn" id="button1">DOWNLOAD</button> page: <span id="linkout"></span>
<button id="button2" onclick="closeWindow();">.</button>
</p>

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 side-by-side alignment with YouTube video

While I understand that aligning two div's side by side is a common question, I am having a little bit of an issue getting the YouTube video and chat box to align next to each other. I should be using a span, since this would allow the chatbox in the same space as the youtube video correct? I'm still learning the ropes here in HTML. Here is what the page currently looks like:
Here is my current HTML code, the divs dealing with the youtube video is class name "youtube-video" and div dealing with the chat box is class "chat"
<!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="DJ-text">Affinity FM DJ Room
<span class="Chat-text">Chat</span>
<div class="DJ-underline"></div>
<div class="Chat-underline"></div></div>
<div class="youtube-video" style="float: left;">
<iframe width="900px" height="500px" src="https://www.youtube.com/embed/2GvIq2SpVFM" frameborder="0" allowfullscreen></iframe>
</div>
<div class="chat" style="float: left; padding: 0px 0px 0px 12px;">
<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>
<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>
Here is my CSS for youtube-video and chat:
body {
background-color: #0f0f17;
margin: 0px;
width: 100%;
}
body,
textarea,
input {
font: 13px "Raleway", sans-serif;
color: #ffffff;
}
.bar{
height: 115px;
width: 100%;
background-color: #15151d;
}
.DJ-text{
font-weight: 700;
position:relative;left:50px;
position:relative;top:80px;
text-transform: uppercase;
}
.Chat-text{
position:relative;left:900px;
}
.DJ-underline{
width: 900px;
height: 1px;
position:relative;top:20px;
background-color: #3f3f45;
}
.Chat-underline{
width: 400px;
position:relative;left:-140px;
float:right;
height: 1px;
position:relative;top:20px;
background-color: #3f3f45;
}
/*.youtube-video{
position: relative; left: 50px;
position: relative; top: 130px;
}
.chat {
max-width: 400px;
background-color: #0f0f17;
position:relative;left:1093px;
position:relative;top:150px;
}*/
.chat-messages,
.chat-textarea,
.chat-name {
border: 1px solid #1a1a23;
background-color: #1a1a23;
}
.userName{
font-weight: 700;
color: #079ce0;
}
.chat-messages {
width:100%;
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;
}
.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:100%;
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;
background-color: #0f0f17;
}
.info-rect,
.chat textarea,
.chat-name {
max-width: 100%;
}
Using the code above supplied by #georges_user2251342, this is what the page looks like:
Here is the reference PSD: http://imgur.com/4XU62C9
It is true what they say! If I understand correctly, by centering, you mean to put 2 things side by side, next to each other so to speak.
In your case, the "youtube-video" element and the "chat" element need to be put side by side with percentages, yes. However, I would use 66% with 33% for percentages instead of 80% with 20%. Because your "chat" element doesn't look good with just 20%. It looks crunched up.
Look at these :
(66%-33%) http://lespointscom.com/a/misc/demo/2016_06_18/main_4.html
(80%-20%) http://lespointscom.com/a/misc/demo/2016_06_18/main_5.html
AGAIN THE NEW HTML :
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<link rel="stylesheet" href="main6.css">
</head>
<body>
<div class="header-bar">
<div class="bar"></div>
<div class="dropshadow"></div>
</div>
<div class="container">
<div class="youtube-video">
<div class="DJ-text">Affinity FM DJ Room</div>
<div class="DJ-underline"></div>
<iframe class="iframe" src="https://www.youtube.com/embed/2GvIq2SpVFM" frameborder="0" allowfullscreen></iframe>
</div>
<div class="chat">
<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>
<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>
AGAIN THE NEW CSS :
.youtube-video{
float: left;
width:66%;
}
.chat {
float: left;
width:33%;
}
.iframe {
width:98%;
min-height:500px;
}
.container {
width:98%;
}
body {
background-color: #0f0f17;
margin: 0px;
width: 100%;
}
body,
textarea,
input {
font: 13px "Raleway", sans-serif;
color: #ffffff;
}
.bar{
height: 115px;
width: 100%;
background-color: #15151d;
}
.DJ-text{
font-weight: 700;
/*position:relative;
left:50px;
top:80px;*/
text-transform: uppercase;
}
.Chat-text{
font-weight: 700;
/*position:relative;left:900px;*/
text-transform: uppercase;
}
.DJ-underline{
width: 98%;
height: 1px;
position:relative;top:20px;
background-color: #3f3f45;
margin: 0px 0px 50px;
}
.Chat-underline{
width: 100%;
position:relative;
/*left:-140px;*/
float:right;
height: 1px;
position:relative;top:20px;
background-color: #3f3f45;
margin: 0px 0px 50px;
}
.chat-messages,
.chat-textarea,
.chat-name {
border: 1px solid #1a1a23;
background-color: #1a1a23;
}
.userName{
font-weight: 700;
color: #079ce0;
}
.chat-messages {
width:95%;
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;
}
.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:95%;
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;
background-color: #0f0f17;
}
.info-rect,
.chat textarea,
.chat-name {
max-width: 100%;
}
#media only screen and (max-width: 772px) and (min-width: 0px)
{
.youtube-video{
width:100%;
}
.chat{
width:100%;
}
}
#media only screen and (max-width: 1254px) and (min-width: 0px)
{
.info-rect{
width:30%;
}
}
#media only screen and (max-width: 1054px) and (min-width: 0px)
{
.info-rect{
width:10%;
}
}
You can bring the chat box to the right by using position property.
Add this css for youtube-video
width:80%;
height:100%;
position:absolute;
left:0;
top:0;
Add this css for chat
width:20%;
height:100%;
position:absolute;
right:0;
top:0;
So, by doing this, you can bring the chat box to right.
Here is the Plnkr
Hope it works for you :)
Just put a float: left; to both divs :
<!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="DJ-text">Affinity FM DJ Room
<span class="Chat-text">Chat</span>
<div class="DJ-underline"></div>
<div class="Chat-underline"></div></div>
<div class="youtube-video" style="float: left;">
<iframe width="900px" height="500px" src="https://www.youtube.com/embed/2GvIq2SpVFM" frameborder="0" allowfullscreen></iframe>
</div>
<div class="chat" style="float: left; padding: 0px 0px 0px 12px;">
<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>
<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 for a better look, add padding: 0px 0px 0px 12px; or a similar small padding to seperate both divs.
Add this css for youtube-video
width:80%;
float:left;
Add this css for chat
width:20%;
float:left;

Styling The File Upload 'Browse' Button

I have an asp.net website which is using Bootstrap and on one page I have a file upload field. Now I know this has been asked may times before but I cant seem to find a solution for asp.net.
Ideally what i'm after is to style the file upload 'Browse' button so it's just a file glyphicon so looking at the Bootstrap site I would like to use something like
What I'm after it looking like (take from Bootstrap website)
<div class="input-group">
<input type="text" class="form-control" placeholder="Username" aria-describedby="basic-addon1">
<span class="input-group-addon" id="basic-addon1">
<i class="glyphicon glyphicon-folder-open"></i>
</span>
</div>
So I would have the input field with the folder icon at the end of it but I can't seem to find a way to do this and was wondering if anyone else could help.
My current code is:
<div class="form-group">
<asp:Label ID="Label3" class="col-md-3 control-label" runat="server" Text="Upload"></asp:Label>
<div class="col-md-3">
<asp:FileUpload ID="fuAttachment" runat="server" class="fileupload"></asp:FileUpload>
</div>
</div>
And my custom CSS is
.fileupload
{
font-family: inherit;
font-size: inherit;
line-height: inherit;
width: 100%;
height: 32px;
pointer-events: none;
}
Jasny Plugin This plugin may help.
/* ===========================================================
* Bootstrap: fileinput.js v3.1.3
* http://jasny.github.com/bootstrap/javascript/#fileinput
* ===========================================================
* Copyright 2012-2014 Arnold Daniels
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
+ function($) {
"use strict";
var isIE = window.navigator.appName == 'Microsoft Internet Explorer'
// FILEUPLOAD PUBLIC CLASS DEFINITION
// =================================
var Fileinput = function(element, options) {
this.$element = $(element)
this.$input = this.$element.find(':file')
if (this.$input.length === 0) return
this.name = this.$input.attr('name') || options.name
this.$hidden = this.$element.find('input[type=hidden][name="' + this.name + '"]')
if (this.$hidden.length === 0) {
this.$hidden = $('<input type="hidden">').insertBefore(this.$input)
}
this.$preview = this.$element.find('.fileinput-preview')
var height = this.$preview.css('height')
if (this.$preview.css('display') !== 'inline' && height !== '0px' && height !== 'none') {
this.$preview.css('line-height', height)
}
this.original = {
exists: this.$element.hasClass('fileinput-exists'),
preview: this.$preview.html(),
hiddenVal: this.$hidden.val()
}
this.listen()
}
Fileinput.prototype.listen = function() {
this.$input.on('change.bs.fileinput', $.proxy(this.change, this))
$(this.$input[0].form).on('reset.bs.fileinput', $.proxy(this.reset, this))
this.$element.find('[data-trigger="fileinput"]').on('click.bs.fileinput', $.proxy(this.trigger, this))
this.$element.find('[data-dismiss="fileinput"]').on('click.bs.fileinput', $.proxy(this.clear, this))
},
Fileinput.prototype.change = function(e) {
var files = e.target.files === undefined ? (e.target && e.target.value ? [{
name: e.target.value.replace(/^.+\\/, '')
}] : []) : e.target.files
e.stopPropagation()
if (files.length === 0) {
this.clear()
return
}
this.$hidden.val('')
this.$hidden.attr('name', '')
this.$input.attr('name', this.name)
var file = files[0]
if (this.$preview.length > 0 && (typeof file.type !== "undefined" ? file.type.match(/^image\/(gif|png|jpeg)$/) : file.name.match(/\.(gif|png|jpe?g)$/i)) && typeof FileReader !== "undefined") {
var reader = new FileReader()
var preview = this.$preview
var element = this.$element
reader.onload = function(re) {
var $img = $('<img>')
$img[0].src = re.target.result
files[0].result = re.target.result
element.find('.fileinput-filename').text(file.name)
// if parent has max-height, using `(max-)height: 100%` on child doesn't take padding and border into account
if (preview.css('max-height') != 'none') $img.css('max-height', parseInt(preview.css('max-height'), 10) - parseInt(preview.css('padding-top'), 10) - parseInt(preview.css('padding-bottom'), 10) - parseInt(preview.css('border-top'), 10) - parseInt(preview.css('border-bottom'), 10))
preview.html($img)
element.addClass('fileinput-exists').removeClass('fileinput-new')
element.trigger('change.bs.fileinput', files)
}
reader.readAsDataURL(file)
} else {
this.$element.find('.fileinput-filename').text(file.name)
this.$preview.text(file.name)
this.$element.addClass('fileinput-exists').removeClass('fileinput-new')
this.$element.trigger('change.bs.fileinput')
}
},
Fileinput.prototype.clear = function(e) {
if (e) e.preventDefault()
this.$hidden.val('')
this.$hidden.attr('name', this.name)
this.$input.attr('name', '')
//ie8+ doesn't support changing the value of input with type=file so clone instead
if (isIE) {
var inputClone = this.$input.clone(true);
this.$input.after(inputClone);
this.$input.remove();
this.$input = inputClone;
} else {
this.$input.val('')
}
this.$preview.html('')
this.$element.find('.fileinput-filename').text('')
this.$element.addClass('fileinput-new').removeClass('fileinput-exists')
if (e !== undefined) {
this.$input.trigger('change')
this.$element.trigger('clear.bs.fileinput')
}
},
Fileinput.prototype.reset = function() {
this.clear()
this.$hidden.val(this.original.hiddenVal)
this.$preview.html(this.original.preview)
this.$element.find('.fileinput-filename').text('')
if (this.original.exists) this.$element.addClass('fileinput-exists').removeClass('fileinput-new')
else this.$element.addClass('fileinput-new').removeClass('fileinput-exists')
this.$element.trigger('reset.bs.fileinput')
},
Fileinput.prototype.trigger = function(e) {
this.$input.trigger('click')
e.preventDefault()
}
// FILEUPLOAD PLUGIN DEFINITION
// ===========================
var old = $.fn.fileinput
$.fn.fileinput = function(options) {
return this.each(function() {
var $this = $(this),
data = $this.data('bs.fileinput')
if (!data) $this.data('bs.fileinput', (data = new Fileinput(this, options)))
if (typeof options == 'string') data[options]()
})
}
$.fn.fileinput.Constructor = Fileinput
// FILEINPUT NO CONFLICT
// ====================
$.fn.fileinput.noConflict = function() {
$.fn.fileinput = old
return this
}
// FILEUPLOAD DATA-API
// ==================
$(document).on('click.fileinput.data-api', '[data-provides="fileinput"]', function(e) {
var $this = $(this)
if ($this.data('bs.fileinput')) return
$this.fileinput($this.data())
var $target = $(e.target).closest('[data-dismiss="fileinput"],[data-trigger="fileinput"]');
if ($target.length > 0) {
e.preventDefault()
$target.trigger('click.bs.fileinput')
}
})
}(window.jQuery);
.form-group .boot-input {
color: transparent;
}
.form-group .boot-input::-webkit-file-upload-button {
visibility: hidden;
}
.form-group .boot-input::before {
content: "\e204";
font-family: 'Glyphicons Halflings';
color: #444;
display: inline-block;
border: none;
border-radius: 2px;
margin: 0;
padding: 0;
outline: transparent;
white-space: nowrap;
-webkit-user-select: none;
cursor: pointer;
font-weight: 700;
font-size: 10pt;
float: right;
}
/*!
* Jasny Bootstrap v3.1.3 (http://jasny.github.io/bootstrap)
* Copyright 2012-2014 Arnold Daniels
* Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE)
*/
.container-smooth {
max-width: 1170px;
}
#media (min-width: 1px) {
.container-smooth {
width: auto;
}
}
.btn-labeled {
padding-top: 0;
padding-bottom: 0;
}
.btn-label {
position: relative;
left: -12px;
display: inline-block;
padding: 6px 12px;
background: transparent;
background: rgba(0, 0, 0, .15);
border-radius: 3px 0 0 3px;
}
.btn-label.btn-label-right {
right: -12px;
left: auto;
border-radius: 0 3px 3px 0;
}
.btn-lg .btn-label {
left: -16px;
padding: 10px 16px;
border-radius: 5px 0 0 5px;
}
.btn-lg .btn-label.btn-label-right {
right: -16px;
left: auto;
border-radius: 0 5px 5px 0;
}
.btn-sm .btn-label {
left: -10px;
padding: 5px 10px;
border-radius: 2px 0 0 2px;
}
.btn-sm .btn-label.btn-label-right {
right: -10px;
left: auto;
border-radius: 0 2px 2px 0;
}
.btn-xs .btn-label {
left: -5px;
padding: 1px 5px;
border-radius: 2px 0 0 2px;
}
.btn-xs .btn-label.btn-label-right {
right: -5px;
left: auto;
border-radius: 0 2px 2px 0;
}
.btn-file {
position: relative;
overflow: hidden;
vertical-align: middle;
}
.btn-file > input {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
margin: 0;
font-size: 23px;
cursor: pointer;
filter: alpha(opacity=0);
opacity: 0;
direction: ltr;
}
.fileinput {
display: inline-block;
margin-bottom: 9px;
}
.fileinput .form-control {
display: inline-block;
padding-top: 7px;
padding-bottom: 5px;
margin-bottom: 0;
vertical-align: middle;
cursor: text;
}
.fileinput .thumbnail {
display: inline-block;
margin-bottom: 5px;
overflow: hidden;
text-align: center;
vertical-align: middle;
}
.fileinput .thumbnail > img {
max-height: 100%;
}
.fileinput .btn {
vertical-align: middle;
}
.fileinput-exists .fileinput-new,
.fileinput-new .fileinput-exists {
display: none;
}
.fileinput-inline .fileinput-controls {
display: inline;
}
.fileinput-filename {
display: inline-block;
overflow: hidden;
vertical-align: middle;
}
.form-control .fileinput-filename {
vertical-align: bottom;
}
.fileinput.input-group {
display: table;
}
.fileinput.input-group > * {
position: relative;
z-index: 2;
}
.fileinput.input-group > .btn-file {
z-index: 1;
}
.fileinput-new.input-group .btn-file,
.fileinput-new .input-group .btn-file {
border-radius: 0 4px 4px 0;
}
.fileinput-new.input-group .btn-file.btn-xs,
.fileinput-new .input-group .btn-file.btn-xs,
.fileinput-new.input-group .btn-file.btn-sm,
.fileinput-new .input-group .btn-file.btn-sm {
border-radius: 0 3px 3px 0;
}
.fileinput-new.input-group .btn-file.btn-lg,
.fileinput-new .input-group .btn-file.btn-lg {
border-radius: 0 6px 6px 0;
}
.form-group.has-warning .fileinput .fileinput-preview {
color: #8a6d3b;
}
.form-group.has-warning .fileinput .thumbnail {
border-color: #faebcc;
}
.form-group.has-error .fileinput .fileinput-preview {
color: #a94442;
}
.form-group.has-error .fileinput .thumbnail {
border-color: #ebccd1;
}
.form-group.has-success .fileinput .fileinput-preview {
color: #3c763d;
}
.form-group.has-success .fileinput .thumbnail {
border-color: #d6e9c6;
}
.input-group-addon:not(:first-child) {
border-left: 0;
}
/*# sourceMappingURL=jasny-bootstrap.css.map */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<div class="container">
<h3>Jasny Plugin (Extracted)</h3>
<div class="fileinput fileinput-new input-group" data-provides="fileinput">
<div class="form-control" data-trigger="fileinput"><i class="glyphicon glyphicon-file fileinput-exists"></i> <span class="fileinput-filename"></span>
</div> <span class="input-group-addon btn btn-default btn-file"><span class="fileinput-new"><span class="glyphicon glyphicon-level-up"></span></span><span class="fileinput-exists">Change</span>
<input type="file" name="...">
</span> Remove
</div>
<hr>
<h3>Standalone CSS</h3>
<div class="form-group">
<input type="file" class="boot-input form-control" />
</div>
</div>
html
<div class="upload">
<input type="file" name="upload"/>
</div>
css
div.upload {
width: 157px;
height: 57px;
background: #ccc;
overflow: hidden;
}
div.upload input {
display: block;
width: 157px;
height: 57px;
opacity: 0;
overflow: hidden;
}
You can try like this: Demo
Used Bootstrap buttons for styling upload button.
.fileUpload {
position: relative;
overflow: hidden;
margin: 10px;
}
.fileUpload input.upload {
position: absolute;
top: 0;
right: 0;
margin: 0;
padding: 0;
font-size: 20px;
cursor: pointer;
opacity: 0;
filter: alpha(opacity=0);
}