How to specify API objects in Bootstrap 5 modal? - javascript

I'cant get this straight, been on this for quite some time. Basically, I'm on this movie app and need a modal. So far I got to point to show each movie individually, show their poster, title and score.
Now, the idea is to press on title and modal will pop up with description ${overview}. Okay, it works, BUT! Modal only shows first object's description, no matter on which movie's title I press.
Once you remove a modal and add a <div>${overview}</div> it works, shows description of each movie correctly, but once I put it in modal - won't work.
I tried to play around with on click with that button, googled all around but can't find a solution. Any help or direction would be amazing, thank you!
Please see code here: https://github.com/sscip/movie-app-ms2

You need change data-bs-target to bind different button and modal.
movies.forEach((movie) => {
const {poster_path, title, vote_average, overview, uid} = movie; // Pulling necessary names from API
console.log(overview)
const movieBox = document.createElement("div"); //creating a div for individual movie elements
movieBox.classList.add("movie"); // creating a class for it
movieBox.innerHTML = `
<div class="movie-image"><img src="${IMGPath + poster_path}" alt="${title}" /></div>
<div class="movie-info">
<button type="button" class="btn" data-bs-toggle="modal" data-bs-target="#${uid}">
${title}
</button>
<span class="${classByRating(vote_average)}">${vote_average}</span>
<div class="modal fade" id="${uid}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">${title}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
${overview}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
`; // creating markup for every movie element and pulling information from API
mainSection.appendChild(movieBox); // sending back to HTML file
});
varying-modal-content

Yeah you were basically missing two things:
Text color for the modal content
Unique id for each button and modal
Here is a working solution:
P.S: You can also check it at on JSfiddle here.
// API link with key, please follow readme how to create own API key for application to work.
const APIKey = 'dontreallyneedit';
const APIURL = "https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=" + APIKey + "&page-1";
const IMGPath = "https://image.tmdb.org/t/p/w1280";
const SearchAPI = "https://api.themoviedb.org/3/search/movie?&api_key=" + APIKey + "&query=";
const mainSection = document.getElementById("main-section"); // selecting DOM element to work with
const searchForm = document.getElementById("search-form");
const searchInput = document.getElementById("search-field");
movies(APIURL); // calling popular movies funcion to work
async function movies(url) {
/* const resp = await fetch(url);
const respData = await resp.json(); */
const results = [{
poster_path: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTP4mb3V7kJHqWTf5GUr-wHUOfHaTv71Ypf3-WGYqjJr-OpYPJslwk2IYY-Phi4hGxpfFQ&usqp=CAU",
title: "Movie 1",
vote_average: 5,
overview: "Great Overview One!"
},
{
poster_path: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTP4mb3V7kJHqWTf5GUr-wHUOfHaTv71Ypf3-WGYqjJr-OpYPJslwk2IYY-Phi4hGxpfFQ&usqp=CAU",
title: "Movie 2",
vote_average: 4,
overview: "Great Overview Two!"
},
{
poster_path: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTP4mb3V7kJHqWTf5GUr-wHUOfHaTv71Ypf3-WGYqjJr-OpYPJslwk2IYY-Phi4hGxpfFQ&usqp=CAU",
title: "Movie 3",
vote_average: 3,
overview: "Great Overview Three!"
}
];
showMovies(results);
}
function showMovies(movies) {
mainSection.innerHTML = ""; // clearing page to show new reults
movies.forEach((movie, index) => {
const {
poster_path,
title,
vote_average,
overview
} = movie; // Pulling necessary names from API
const movieBox = document.createElement("div"); //creating a div for individual movie elements
movieBox.classList.add("movie"); // creating a class for it
movieBox.innerHTML = `
<div class="movie-image"><img src="${poster_path}" alt="${title}" /></div>
<div class="movie-info">
<button type="button" class="btn" data-bs-toggle="modal" data-bs-target="#exampleModal_${index}">
${title}
</button>
<span class="${classByRating(vote_average)}">${vote_average}</span>
<div class="modal fade" id="exampleModal_${index}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">${title}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
${overview}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
`; // creating markup for every movie element and pulling information from API
mainSection.appendChild(movieBox); // sending back to HTML file
});
}
function classByRating(vote) { //checking how high is the movie rating and giving apropriate class name.
if (vote >= 8) {
return "green";
} else if (vote >= 5) {
return "amber"
} else {
return "red";
}
}
searchForm.addEventListener("submit", (i) => {
i.preventDefault();
const searchTerm = searchInput.value;
if (searchTerm) {
movies(SearchAPI + searchTerm)
searchInput.value = "";
}
})
#import url('https://fonts.googleapis.com/css2?family=Lato:wght#100;300&display=swap');
.modal-content {
color: black;
}
/* Main Styles */
* {
box-sizing: border-box;
font-family: 'Lato', serif;
}
/* Navigation */
header {
background-color: #D16BA5;
padding: 1rem 0.5rem;
}
header a {
font-size: 1.5rem;
}
header button:focus {
outline: none;
}
#navbar-brand {
font-size: 1.7rem;
}
#search-field {
border-radius: 10px;
font-size: 1.2rem;
border: none;
}
.search-btn:focus {
outline: none;
}
.search-btn:active {
background-color: #FF8F80;
}
.search-btn {
font-size: 1.2rem;
padding: 0 1rem;
border: none;
border-radius: 10px;
color: #eee;
background-color: #FF8F80;
}
/* Main section styling */
#main-section {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
/* Movies Box styling */
.movie {
margin: 0.7rem;
width: 15rem;
border-radius: 5px;
background-color: #FF8F80;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
overflow: hidden;
}
/* Movie image */
.movie img {
max-width: 100%;
}
/* Movie Basic info */
.movie-info {
display: flex;
justify-content: space-between;
color: #eee;
padding: 0.5rem;
align-items: center;
max-height: 100%;
}
.movie-info h3 {
margin: 0;
font-size: 1.21rem;
}
.movie-info span {
background-color: #D16BA5;
padding: 0.5rem;
border-radius: 5px;
width: 2.5rem;
height: 2.5rem;
text-align: center;
font-weight: bold;
}
.movie-info span.green {
color: rgb(0, 214, 54);
}
.movie-info span.amber {
color: rgb(255, 163, 87);
}
.movie-info span.red {
color: rgb(223, 45, 0);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Title -->
<title>Movies TOP-20 LIVE!</title>
<!-- Bootstrap 5 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<!-- Font Awesome 5 -->
<script src="https://kit.fontawesome.com/0d4c39c5bf.js" crossorigin="anonymous"></script>
<!-- Custom CSS -->
<link rel="stylesheet" href="assets/css/styles.css" />
<!-- Custom JS -->
<script src="assets/js/config.js" type="text/javascript" defer></script>
<script src="assets/js/script.js" type="text/javascript" defer></script>
</head>
<body>
<header>
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" id="navbar-brand" href="#">Movies TOP-20 LIVE</a>
<button class="navbar-toggler" id="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contact Us</a>
</li>
</ul>
<form class="d-flex" id="search-form">
<input class="form-control me-2" id="search-field" type="search" placeholder="Search" aria-label="Search">
<button class="search-btn" id="search-btn" type="submit">
Search
</button>
</form>
</div>
</div>
</nav>
</header>
<section id="main-section"></section>
<!-- Bootstrap 5 JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>

Related

I am trying to change the background-color/opacity of a modal before it is opened/shown in a simple Bug tracker

I am creating a simple bug tracker that uses a modal to pop up different bugs. The problem I have is that when I delete a bug, there is a thin grey box where the background of the modal was. So basically the list of bugs is empty but it shows the background of the modal even when it should not be there. For example , if you load up the files and open with live server; create a new bug, then delete the bug, you will see the grey box where the bug was just at. I am trying to have the background not be there, when there is no bugs in the list. Any help is greatly appreciated.
I have tried changing the opacity of the modal and issuesList as well as background color, but tbh I am completely lost on how to dynamically change the opacity.
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<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 href="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD"
crossorigin="anonymous">
<script src="https://kit.fontawesome.com/4582c8b826.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="/css/styles.css">
<title>Issue Tracker</title>
</head>
<body>
<div class="contaienr">
<h1>Issue Tracker</h1>
<div class="jumbotron">
<h3>Add New Issue:</h3>
<form id="issueinputform">
<div class="form-group">
<label for="issueDescription">Description</label>
<input type="text" class="form-control" id="issueDescription" placeholder="Describe the issue ...">
</div>
<div class="form-group">
<label for="issueSeverity">Severity</label>
<select class="form-control" id="issueSeverity">
<option value="Low">Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
</select>
</div>
<div class="form-group">
<label for="issueAssignedTo">Assigned To</label>
<input type="text" class="form-control" id="issueAssignedTo" placeholder="Enter responsible ...">
</div>
<button id="add-issue" onclick="submitIssue()" class="btn btn-primary">Add</button>
</form>
</div>
<div class="col-lg-12">
<div id="issuesList">
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="emptyField" tabindex="-1" role="dialog" aria-labelledby="emptyFieldLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="emptyFieldLabel">Invalid Input!</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Please provide the desciption of the issue and also the person name who you want to assign the issue.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/js/bootstrap.min.js" integrity="sha384-mQ93GR66B00ZXjt0YO5KlohRA5SY2XofN4zfuZxLkoj1gXtW8ANNCe9d5Y3eG5eD" crossorigin="anonymous"></script>
<script src="app.js"></script>
</body>
</html>
app.js
function submitIssue(e) {
const getInputValue = id => document.getElementById(id).value;
const description = getInputValue('issueDescription');
const severity = getInputValue('issueSeverity');
const assignedTo = getInputValue('issueAssignedTo');
const id = Math.floor(Math.random() * 100000000) + '';
const status = 'Open';
if ((description.length == 0) || (assignedTo.length == 0)) {
alert("Please fill all fields with required data.");
document.getElementById('add-issue').setAttribute("data-toggle", "modal");
document.getElementById('add-issue').setAttribute("data-target", "#emptyField")
}
else {
document.getElementById('add-issue').removeAttribute("data-toggle", "modal");
document.getElementById('add-issue').removeAttribute("data-target", "#emptyField")
const issue = { id, description, severity, assignedTo, status };
let issues = [];
if (localStorage.getItem('issues')) {
issues = JSON.parse(localStorage.getItem('issues'));
}
issues.push(issue);
localStorage.setItem('issues', JSON.stringify(issues));
fetchIssues();
}
}
const closeIssue = id => {
const issues = JSON.parse(localStorage.getItem('issues'));
const currentIssue = issues.find(issue => issue.id == id);
currentIssue.status = 'Closed';
currentIssue.description = `<strike>${currentIssue.description}</strike>`
localStorage.setItem('issues', JSON.stringify(issues));
fetchIssues();
}
const deleteIssue = id => {
const issues = JSON.parse(localStorage.getItem('issues'));
const remainingIssues = issues.filter(issue => ((issue.id) != id))
localStorage.removeItem('issues');
localStorage.setItem('issues', JSON.stringify(remainingIssues));
fetchIssues();
}
const fetchIssues = () => {
const issues = JSON.parse(localStorage.getItem('issues'));
const issuesList = document.getElementById('issuesList');
issuesList.innerHTML = '';
for (let i = 0; i < issues.length; i++) {
const { id, description, severity, assignedTo, status } = issues[i];
issuesList.innerHTML += `<div class="well">
<h6>Issue ID: ${id} </h6>
<p><span class="label label-info"> ${status} </span></p>
<h3> ${description} </h3>
<p><i class="fa-solid fa-bolt"></i> ${severity}</p>
<p><i class="fa-solid fa-user"></i> ${assignedTo}</p>
<button onclick="closeIssue(${id})" class="btn btn-warning">Close</button>
<button onclick="deleteIssue(${id})" class="btn btn-danger">Delete</button>
</div>`;
}
}
fetchIssues();
styles.css
*{
box-sizing: border-box;
}
.jumbotron{
background: rgb(225, 224, 224);
margin-top: 20px;
margin-left: 150px;
margin-right: 150px;
padding-left: 60px;
padding-right: 60px;
padding-top: 50px;
padding-bottom: 50px;
border-radius: 6px;
}
.container{
}
p{
margin: 0 0 10px;
}
h1{
font-size: 36px;
margin-top: 20px;
margin-bottom: 10px;
margin-left: 150px;
}
/* .col-lg-12{
display: block;
font-size: 14px;
line-height: 1.42857143;
color: #333;
} */
#issuesList{
padding-top: 40px;
padding-left: 20px;
padding-right: 20px;
padding-bottom: 20px;
display: block;
margin-left: 170px;
margin-right: 170px;
margin-top: 40px;
margin-bottom: 20px;
background-color: rgb(233, 233, 233);
border-radius: 6px;
border: solid grey transparent ;
border-width: thin;
}
h6{
font-size: 12px;
font-family: inherit;
margin-bottom: 10px;
}
h3{
margin-bottom: 10px;
margin-top: 30px;
font-weight: 500;
line-height: 1.1;
}
.label{
background-color: #5bc0de;
border: solid rgb(10, 198, 240);
border-radius: 0.25em;
padding: 3px;
color: white;
line-height: 1;
font-weight: 700;
font-size: 75%;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
}
#add-issue{
margin-top: 20px;
}
.container::after{
clear: both
}
.modal
{
opacity:0.5 !important;
}

Vanilla Javascript Adding This.Title, Value, Amount for Expense Form on Budget App

Hello I'm developing a budget app following a tutorial via Coding Addict, I'm having trouble with the submitExpenseForm of the code. It's suppose to work when the user submit multiple "expenses" the problem after the first values the "expense.title" & "expense.amount" has been appended to the html the 2nd+ of the entries for the expense form of the app keeps showing up as undefined and NaN and it's been wrecking my brain for the past two days with rewatching the video, research and coming up with some other codes that didn't work. Any tips would be greatly helpful, thank you so much.
//JS tutorial from freecodecamp.org
// window.alert("javascript is loaded and ready!");
class UI {
//setting variables
constructor() {
this.budgetFeedback = document.querySelector(".budget-feedback");
this.expenseFeedback = document.querySelector(".expense-feedback");
this.budgetForm = document.getElementById("budget-form");
this.budgetInput = document.getElementById("budget-input");
this.budgetAmount = document.getElementById("budget-amount");
this.expenseAmount = document.getElementById("expense-amount");
this.balance = document.getElementById("balance");
this.balanceAmount = document.getElementById("balance-amount");
this.expenseForm = document.getElementById("expense-form");
this.expenseInput = document.getElementById("expense-input");
this.amountInput = document.getElementById("amount-input");
this.expenseList = document.getElementById("expense-list");
this.itemList = [];
this.itemID = 0;
}
//submit button budget, function will run the following code
submitBudgetForm(){
// console.log('hello from es6');
const value = this.budgetInput.value;
if(value === '' || value <0){
this.budgetFeedback.classList.add('showItem');
this.budgetFeedback.innerHTML = `<p>field can't be empty or negative.</p>`;
console.log('error message will appear on DOM');
}
else{
this.budgetAmount.textContent = value;
this.budgetInput.value = "";
this.showBalance();
}
}
//show balance
showBalance(){
const expense = this.totalExpense();
//parseInt would convert argument into a string (string of numbers with no [,]).
const total = parseInt(this.budgetAmount.textContent) - expense;
this.balanceAmount.textContent = total;
if(total < 0){
this.balance.classList.remove("showGreen", "showBlack");
this.balance.classList.add("showRed")
}
else if(total > 0){
this.balance.classList.remove("showRed", "showBlack");
this.balance.classList.add("showGreen");
}
else if(total === 0){
this.balance.classList.remove("showRed", "showGreen");
this.balance.classList.add("showBlack");
}
// console.log(`hey I'm getting a hold of 'this' keyword`);
}
//submit expense form function
submitExpenseForm(){
const expenseValue = this.expenseInput.value;
const amountValue = this.amountInput.value;
if(expenseValue === '' || amountValue === '' || amountValue < 0)
{
this.expenseFeedback.classList.add('showItem');
this.expenseFeedback.innerHTML = `<p>field can't be empty or negative.</p>`
}
else {
let amount = parseInt(amountValue);
this.expenseInput = "";
this.amountInput = "";
let expense = {
id:this.itemID,
title:expenseValue,
amount:amount,
}
this.itemID++;
this.itemList.push(expense);
this.addExpense(expense);
this.showBalance();
//show balance
}
}
//add expense
addExpense(expense){
const div = document.createElement('div');
div.classList.add('expense');
div.innerHTML = `<div class="expense-item d-flex justify-content-between align-items-baseline">
<h6 class="expense-title mb-0 text-uppercase list-item">-${expense.title}</h6>
<h5 class="expense-amount mb-0 list-item">${expense.amount}</h5>
<div class="expense-icons list-item">
<a href="#" class="edit-icon mx-2" data-id="${expense.id}">
<i class="fas fa-edit"></i>
</a>
<a href="#" class="delete-icon" data-id="${expense.id}">
<i class="fas fa-trash"></i>
</a>
</div>
</div>
</div>`;
this.expenseList.appendChild(div);
}
//total expense
totalExpense(){
let total = 0;
if(this.itemList.length > 0){
console.log(this.itemList);
}
this.expenseAmount.textContent = total;
return total;
}
}
function eventListeners(){
const budgetForm = document.getElementById('budget-form');
const expenseForm = document.getElementById('expense-form');
const expenseList = document.getElementById('expense-list');
//new UI Class
const ui = new UI()
//budget form submit
budgetForm.addEventListener('submit', function(event){
event.preventDefault();
ui.submitBudgetForm();
});
//expense form submit
expenseForm.addEventListener('submit', function(event){
event.preventDefault();
ui.submitExpenseForm();
})
//expense click (expense value & title edit and trash)
expenseList.addEventListener('click', function(){
})
}
document.addEventListener('DOMContentLoaded', function(){
eventListeners();
})
:root {
--mainWhite: #f5f5f5f5;
--mainDark: #333333;
--mainGreen: #317b22;
--mainRed: #b80c09;
--mainBlue: #05668d;
--mainYellow: yellow;
}
body {
background: var(--mainWhite);
color: var(--mainDark);
}
.budget-feedback,
.expense-feedback {
display: none;
}
.budget-form {
border: 0.15rem solid var(--mainGreen);
padding: 1rem;
border-radius: 0.25rem;
}
.expense-form {
border: 0.15rem solid var(--mainRed);
padding: 1rem;
border-radius: 0.25rem;
}
.budget-submit {
background: transparent;
border: 0.1rem solid var(--mainGreen);
color: var(--mainGreen);
}
.expense-submit {
background: transparent;
border: 0.1rem solid var(--mainRed);
color: var(--mainRed);
}
.expense-submit:hover {
background: var(--mainRed);
color: var(--mainWhite);
}
.budget-submit:hover {
background: var(--mainGreen);
color: var(--mainDark);
}
.budget-input {
border: 0.05rem solid var(--mainGreen) !important;
margin-bottom: 10px;
}
.expense-input {
border: 0.05rem solid var(--mainRed) !important;
}
.expense-group {
margin-bottom: 10px;
}
.expense-amount,
.expense-title {
color: var(--mainRed);
}
.edit-icon {
color: var(--mainBlue);
cursor: pointer;
font-size: 1rem;
text-decoration: none !important;
}
.delete-icon {
color: var(--mainRed);
cursor: pointer;
font-size: 1rem;
text-decoration: none !important;
}
.edit-icon:hover {
color: var(--mainBlue);
}
.delete-icon:hover {
color: var(--mainRed);
}
.showItem {
display: block;
}
.info-title {
font-size: 1.5rem;
}
.budget {
font-size: 1.6rem;
color: var(--mainGreen);
}
.expense {
font-size: 1.6rem;
color: var(--mainRed);
}
.balance {
font-size: 1.6rem;
}
.budget-icon,
.expense-icon,
.balance-icon {
font-size: 2.5rem;
color: var(--mainBlue);
}
.showRed {
color: var(--mainRed);
}
.showGreen {
color: var(--mainGreen);
}
.showBlack {
color: var(--mainDark);
}
#media screen and (min-width: 992px) {
.budget {
font-size: 2.6rem;
color: var(--mainGreen);
}
.expense {
font-size: 2.6rem;
color: var(--mainRed);
}
.balance {
font-size: 2.6rem;
}
.budget-icon,
.expense-icon,
.balance-icon {
font-size: 3.5rem;
color: var(--mainBlue);
}
}
.list-item {
flex: 0 0 33.33%;
text-align: center;
}
.expense-item {
height: 2rem;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link rel="stylesheet" href="./fontawesome-free-5.15.2-web/css/all.css">
<link rel="stylesheet" href="./style.css">
<title>UPPERclassman</title>
</head>
<body>
<div class="container-fluid">
<div class="row">
<!--title of app-->
<div class="col-11 mx-auto p-3">
<h3 class="UPPERclassman">UPPERclassman</h3>
</div>
<div class="row">
<div class="col-md-5 my-3">
<!--budget alert message-->
<div class="budget-feedback alert alert-danger text-capitalize">budget feedback</div>
<!---budget form-->
<form id="budget-form" class="budget-form">
<h5>Please enter your budget</h5>
<div class="form-group">
<input type="number" class="form-control budget-input" id="budget-input">
</div>
<!--submit button-->
<button type="submit" class="btn text-capitalize budget-submit" id="budget-submit">calculate</button>
</form>
</div>
<div class="col-md-7">
<div class="row my-3">
<div class="col-4 text-center mb-2">
<h6 class="info-title">Budget</h6>
<span class="budget-icon"><i class="fas fa-money-bill-wave fa-2x"></i></span>
<h4 class="mt-2 budget" id="budget"><span>$</span><span id="budget-amount">0</span></h4>
</div>
<div class="col-4 text-center">
<h6 class="info-title">Expense</h6>
<span class="expense-icon"><i class="far fa-credit-card fa-2x"></i></span>
<h4 class="mt-2 expense" id="expense"><span>$</span><span id="expense-amount">0</span></h4>
</div>
<div class="col-4 text-center">
<h6 class="info-title">Balance</h6>
<span class="balance-icon"><i class="fas fa-hand-holding-usd fa-2x"></i></span>
<h4 class="mt-2 balance" id="balance"><span>$</span><span id="balance-amount">0</span></h4>
</div>
</div>
</div>
<div class="row">
<div class="col-md-5 my-3">
<div class="expense-feedback alert alert-danger text-capitalize">expense feedback</div>
<form id="expense-form" class="expense-form">
<h5 class="text-capitalize">please enter your expense</h5>
<div class="form-group expense-group">
<input type="text" class="form-control expense-input" id="expense-input">
</div>
<div class="form-group expense-group">
<input type="number" class="form-control expense-input" id="amount-input">
</div>
<button type="submit" class="btn text-capitalize expense-submit" id="expense-submit">add expense</button>
</form>
</div>
<div class="col-md-7 my-3">
<div class="expense-list" id="expense-list">
<div class="expense-list__info d-flex justify-content-between text-capitalize">
<h5 class="list-item">expense title</h5>
<h5 class="list-item">expense value</h5>
<h5 class="list-item"></h5>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- jquery -->
<!-- <script src="js/jquery-3.3.1.min.js"></script> -->
<!-- bootstrap js -->
<!-- <script src="js/bootstrap.bundle.min.js"></script> -->
<!-- script js -->
<script src="budget.js"></script>
</body>
</html>
These two lines:
this.expenseInput = "";
this.amountInput = "";
are clearing your reference to the controls.
Perhaps they should be:
this.expenseInput.value = "";
this.amountInput.value = "";

Modal does not close, when clicked

So I have a menu, where models pop-up on click. In each model, there's a close button, marked by an "x". Only problem is, that the model does not close, when the "x" is clicked.
I have tried multiple ways of filing this seemingly simple problem. But with no luck.
I have tried, using a z-index property, I have tried fiddling with the divs. I have tried to link to bootstrap external links. I have tried different kind of "close" button. I have tried to modifying the javascript code. Still I have not arrived at the desired outcome. Can anyone help ?
Here's my code
window.onload = function () {
list = document.querySelectorAll(".Project");
for (let i = 0; i < list.length; i++) {
list[i].addEventListener("click", function (e) {
e.preventDefault();
let currentElement = e.target.parentNode;
let modalId = currentElement.dataset.modal;
let modal = document.getElementById(modalId);
modal.style.display = "block";
});
}
};
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
<li class="Project" data-modal="myModal_1">
<span id="myBtn_1"> Wer Baut Der Stadt </span>
<span id="year"> 2019 </span>
<div class="Describtion">
<p style="display:none;">
Identity and Font developed for the lecture series on architecture conducted by No Image in Berlin.
</p>
</div>
<div id="myModal_1" class="modal">
<div class="modal-content">
<img src="Images/WER BAUT 2018/HVIDAktiv 20.png" width="1000px">
<span class="close">× </span>
<p> Some text in the Modal..1 </p>
</div>
</div>
</li>
It is very easy to use modal in Bootstrap.
You just have to make sure that, as in the example below, jquery.js, popper.js and bootstrap.js are placed in order.
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
this is because you have a bad use of JS event delegation.
the corect way is tu use the matches method https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
like this :
window.onload = function () {
list = document.querySelectorAll(".Project");
document.querySelectorAll(".Project").forEach(LIelm=>{
LIelm.addEventListener('click', showHideModal)
})
};
function showHideModal(e) {
if (!e.target.parentNode.matches('.Project , .modal-content' )) return
e.preventDefault();
let currentParent = e.target.parentNode;
if (currentParent.matches('.Project') ){
document.getElementById( currentParent.dataset.modal ).style.display = "block";
}
else {
currentParent.parentNode.style.display = "";
}
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
<li class="Project" data-modal="myModal_1">
<span id="myBtn_1"> Wer Baut Der Stadt ee</span>
<span id="year"> 2019 </span>
<div class="Describtion">
<p style="display:none;">
Identity and Font developed for the lecture series on architecture conducted by No Image in Berlin.
</p>
</div>
<div id="myModal_1" class="modal">
<div class="modal-content">
<img src="https://picsum.photos/200/300" >
<span class="close">× </span>
<p>Some text in the Modal..1
</p>
</div>
</div>
</li>

Output wrong div width by width() in jQuery

I created a popup with bootstrap to store several Social media share buttons. Then I created two left and right buttons to navigate between them. My logic is, if modal-body width is less than share buttons content div width, then navigation buttons should be appeared and move to the very end in both sides. Here, in my code, I'm getting wrong modal-body width and therefore right-side navigation button is not working as expected which is I can't go to the last share button. It seems perfectly working with the default loading screen size. The Problem can be exactly seen by reducing the screen size and trying to navigate to the last share button. What I missed here?
$('.modal').on('show.bs.modal', function () {
var currentPos = 0;
var shareBtns = $(".a2a_kit a").length;
var sampleDivWidth = $(".a2a_button_facebook span").width();
var actualButtonWidth = sampleDivWidth + 26
var shareDivWidth = (actualButtonWidth * shareBtns) / 3;
var mainDivWidth = $(".modal-body").width();
//var mainDivWidth = 445;
var x = shareDivWidth / actualButtonWidth;
var y = mainDivWidth / actualButtonWidth;
var z = (x - y);
var stopPos = z * (-actualButtonWidth);
//alert(mainDivWidth);
if( (mainDivWidth - 30) < shareDivWidth ) {
$(".move-btn").css("display", "block");
}
else {
$(".move-btn").css("display", "none");
}
if ( currentPos === 0 ) {
$(".move-btn-l").css("display", "none");
}
$(".move-btn-r").on("click", function() {
$(".a2a_kit").animate({
left : ""+ (currentPos -= 66) +"px"
}, 200);
$(".move-btn-l").css("display", "block");
if (currentPos <= stopPos) {
$(".move-btn-r").css("display", "none");
}
})
$(".move-btn-l").on("click", function() {
$(".a2a_kit").animate({
left : ""+ (currentPos += 66) +"px"
}, 200);
$(".move-btn-r").css("display", "block");
if (currentPos == 0) {
$(".move-btn-l").css("display", "none");
}
})
})
.share-link-div{
overflow: hidden;
width: 75%;
margin: auto;
}
.a2a_kit {
display: inline-flex;
position: relative;
width: max-content;
}
.a2a_kit a .a2a_svg {
border-radius: 50% !important;
padding: 5px;
width: 50px;
height: 50px;
float: none !important;
}
.a2a_kit a:hover {
text-decoration: none !important;
}
.move-btn{
background-color: #fff;
border: 1px solid #ccc;
border-radius: 50%;
width: 35px;
height: 35px;
position: absolute;
top: 20px;
cursor: pointer;
box-shadow: 0 3px 3px #7d7d7d;
}
.move-btn-r {
right: 15px;
}
.move-btn-l {
left: 15px;
}
.move-btn span{
margin-left: 12px;
margin-top: 6px;
position: absolute;
}
.embed-btn .a2a_svg {
float: left;
background-color: #dedede;
color: #000;
font-size: 12px;
height: 32px;
font-weight: 600;
}
.embed-btn .a2a_svg:hover {
opacity: 0.7;
}
.embed-btn .a2a_svg p {
margin: 0px;
top: 5px;
position: relative;
text-align: center;
}
.embed-src{
padding: 10px;
border: 1px solid #ececec;
background-color: #fafafa;
font-size: 14px;
font-weight: 400;
}
.embed-button{
overflow: hidden;
display: flex;
margin-top: 20px;
}
.embed-button .embed-src {
float: left;
width: 100%;
}
.copy-iframe {
border-radius : 0 4px 4px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script async src="https://static.addtoany.com/menu/page.js"></script>
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="share-link-div">
<div class="a2a_kit a2a_kit_size_32 a2a_default_style">
<a class="a2a_button_facebook"></a>
<a class="a2a_button_twitter"></a>
<a class="a2a_button_google_plus"></a>
<a class="a2a_button_pinterest"></a>
<a class="a2a_button_facebook"></a>
<a class="a2a_button_twitter"></a>
<a class="a2a_button_google_plus"></a>
<a class="a2a_button_pinterest"></a>
<a class="a2a_button_facebook"></a>
<a class="a2a_button_twitter"></a>
<a class="a2a_button_google_plus"></a>
<a class="a2a_button_pinterest"></a>
</div>
<div class="move-btn move-btn-l">
<span><</span>
<!-- <i class="fas fa-chevron-left"></i> -->
</div>
<div class="move-btn move-btn-r">
<span>></span>
<!-- <i class="fas fa-chevron-right"></i> -->
</div>
</div>
<div class="embed-button">
<div class="embed-src">
<span>URL and Code</span>
</div>
<button type="button" class="btn btn-primary copy-iframe">Copy</button>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
Here is the editable code :
http://jsfiddle.net/rgL2ak0z/3/
I think you cant get width of dynamicaly created div without prior width initialization. Maybe you could get width of document and calculate it? Like:
var mainDivWidth=document.documentElement.clientWidth;

Twitter share button inside bootstrap modal not working on firefox

I have two twitter share button , one on body and another inside a bootstrap modal.
Both Share button works on chrome but not on Firefox. On Firefox the first share button which is out side modal is working but when I open the modal I can't see the share button.
Is it a bug? Is there any workaround for this problem?
Here is my code
https://jsfiddle.net/swarnendu/fb7t0fpe/3/embedded/result/
<html>
<head>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</head>
<body>
<script>
window.twttr = (function (d,s,id) {
var t, js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return; js=d.createElement(s); js.id=id;
js.src="https://platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs);
return window.twttr || (t = { _e: [], ready: function(f){ t._e.push(f) } });
}(document, "script", "twitter-wjs"));
</script>
<div class="row">
<a class="twitter-share-button" href="https://twitter.com/intent/tweet" target="_self">Tweet</a>
</div>
<div class="container">
<h2>Modal Example</h2>
<!-- Trigger the modal with a button -->
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<a class="twitter-share-button"
href="https://twitter.com/intent/tweet" target="_self">
Tweet</a>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
It looks like a bug, because the widget button is hidden in the Firefox and this css provided by Twitter. However, I have found workaround for that - basically you can create the missing button by yourself.
1) Change contents of modal-bodydiv like this:
<div class="modal-body">
<a href="https://twitter.com/intent/tweet">
<i class="btn-icon"></i>
<span class="btn-text">Tweet</span>
</a>
</div>
2) Add following styles to your page:
.modal-body a .btn-icon{
position: relative;
width:60px;
height: 20px;
padding: 1px 10px 1px 7px;
font-weight: 500;
color: #fff;
cursor: pointer;
background-color: #1b95e0;
border-radius: 3px;
box-sizing: border-box;
background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2072%2072%22%3E%3Cpath%20fill%3D%22none%22%20d%3D%22M0%200h72v72H0z%22%2F%3E%3Cpath%20class%3D%22icon%22%20fill%3D%22%23fff%22%20d%3D%22M68.812%2015.14c-2.348%201.04-4.87%201.744-7.52%202.06%202.704-1.62%204.78-4.186%205.757-7.243-2.53%201.5-5.33%202.592-8.314%203.176C56.35%2010.59%2052.948%209%2049.182%209c-7.23%200-13.092%205.86-13.092%2013.093%200%201.026.118%202.02.338%202.98C25.543%2024.527%2015.9%2019.318%209.44%2011.396c-1.125%201.936-1.77%204.184-1.77%206.58%200%204.543%202.312%208.552%205.824%2010.9-2.146-.07-4.165-.658-5.93-1.64-.002.056-.002.11-.002.163%200%206.345%204.513%2011.638%2010.504%2012.84-1.1.298-2.256.457-3.45.457-.845%200-1.666-.078-2.464-.23%201.667%205.2%206.5%208.985%2012.23%209.09-4.482%203.51-10.13%205.605-16.26%205.605-1.055%200-2.096-.06-3.122-.184%205.794%203.717%2012.676%205.882%2020.067%205.882%2024.083%200%2037.25-19.95%2037.25-37.25%200-.565-.013-1.133-.038-1.693%202.558-1.847%204.778-4.15%206.532-6.774z%22%2F%3E%3C%2Fsvg%3E");
}
.modal-body a .btn-icon:hover{
background-color:#0c7abf;
}
.btn-text{
display: inline-block;
vertical-align: top;
margin-left: 3px;
}
.modal-body a{
position: relative;
height: 20px;
padding: 5px 14px 5px 6px;
font-weight: 500;
color: #fff;
cursor: pointer;
background-color: #1b95e0;
border-radius: 3px;
box-sizing: border-box;
}
.modal-body a:hover{
background-color:#0c7abf;
}
3) Add jQuery event handlers
$(document).ready(function(){
$('.modal-body a .btn-icon, .modal-body a').hover(function(){
$('.modal-body a .btn-icon, .modal-body a')
.css('background-color', '#0c7abf');
},
function(){
$('.modal-body a .btn-icon, .modal-body a')
.css('background-color', '#1b95e0');
})
})
That's it. So now you have buttons in FF and Chrome inside popup window. You can adjust the styles for button and icon to make it looks better, if necessary.
Working example:
http://plnkr.co/edit/LPyveKju0zQAELpOzkQW?p=preview
Hope this helps.
Or just go ahead and clone the button with jQuery:
$(function() {
$('#myModal').on('shown.bs.modal', function(e) {
if ($(".modal-body").find('.twitter-share-button').size())
return;
$('.twitter-share-button:first').clone().appendTo('.modal-body');
});
});
https://jsfiddle.net/jonathanzuniga/k2nk651d/

Categories

Resources