This dosen't work in chrome nor firefox. What I'm trying to do is get the logo of a discord server and let the user download it. My python backend succesfully did the first part, so I don't think that's the problem. My HTML code below has the download button inside a link. Everything works, except instead of downloading the image I just get to a page with the link. I've tried the other answers on this site, but I could not find something that worked for me.
My 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" />
<!-- Bootstrap's CSS stylesheet -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous" />
<!-- My CSS stylesheet -->
<link href="{{ url_for('static',filename='css/style.css') }}" rel="stylesheet" />
<title>Discord Profile Picture</title>
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet" />
</head>
<body class="text-white">
<div class="bg">
<div id="main">
<p class="roboto fifty">Discord server invite:</p>
<!-- Text Input using Bootstrap -->
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon3">
discord.gg/</span>
<input type="text" placeholder="XXXXXXXX" class="form-control" id="basic-url"
aria-describedby="basic-addon3" />
<button class="btn btn-outline-secondary" type="button" id="button-addon2" onClick="send()">
Send
</button>
</div>
<a id="download-link">
<button type="button" class="btn btn-outline-primary btn-lg">Download</button>
</a>
</div>
</div>
<!-- My JS Script -->
<script src="{{ url_for('static',filename='js/script.js') }}"></script>
<!-- Bootstrap's JS Script -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj"
crossorigin="anonymous"></script>
</body>
</html>
My JS:
function send() {
var data = {
invite: document.getElementById("basic-url").value
};
console.log("Sent.")
fetch("/scrape", {
headers: {'Content-Type': 'application/json',},
method: "POST",
body: JSON.stringify(data)
}).then(res => res.json()).then(data => {
downloadLink = document.getElementById("download-link")
downloadLink.style.display = "unset"; downloadLink.href = data; downloadLink.download = data
})
}
My Python backend:
#!/usr/bin/env python3
from flask import Flask, render_template, request, jsonify
from bs4 import BeautifulSoup
import requests
app = Flask(__name__)
# Web Page
#app.route("/")
def hello():
return render_template('index.html')
# RESTful api endpoint
#app.route("/scrape", methods=["POST"])
def scrape():
code = request.get_json()["invite"]
invite = requests.get(f"https://discord.gg/{code}").text
soup = BeautifulSoup(invite, features="html.parser")
for meta_tag in soup.find_all("meta"):
try:
if meta_tag["property"] == "og:image":
return jsonify(meta_tag["content"]), 200
except KeyError:
pass
if __name__ == "__main__":
app.run(debug=True)
And my CSS
body, html { height: 100% }
/* Center everything */
#main {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* Roboto text */
p.roboto.fifty {
font-family : 'Roboto',
sans-serif;
font-size: 40px;
padding-left: 15px;
}
.parent { position: relative }
/* Full screen background */
#background-image {
height: 100%;
width: 100%;
}
/* Background */
.bg {
background-image: url("../images/background.png");
height: 100%;
/* Center and scale the image nicely */
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
#download-link {
padding-left: 35%;
display:none;
}
I think you should use downloadLink.setAttribute("download", data) instead of downloadLink.download = data.
that should work
Related
I tried to use EyeDropper API but I think there are some issues on Linux because it requires me to share my screen and Although I shared, I could not get a result. I'm getting this after clicking the button. image
<!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>COLOR PICKER</title>
<!-- GOOGLE FONTS -->
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:opsz,wght,FILL,GRAD#20..48,100..700,0..1,-50..200"
/>
<!-- CSS & SCRIPT -->
<link rel="stylesheet" href="style.css" />
<script defer src="./script.js"></script>
</head>
<body class="grid pi-cent">
<div class="container flex-col">
<header class="flex jc-cnt ai-cnt">
<button class="pick-btn">Pick Color</button>
</header>
<article class="flex jc-sb">
<p>Picked Color<s class="plural">s</s></p>
Clear All
</article>
<ul class="grid">
<li class="flex">
<div
class="color"
style="--bg: #000000; width: 15px; height: 15px"
></div>
<p class="clr-code">#0000</p>
</li>
</ul>
</div>
<script>
const pickBtn = document.querySelector(".pick-btn");
const pickColor = async (e) => {
try {
const eDrop = new window.EyeDropper();
const resp = await eDrop.open();
console.log(resp);
} catch (err) {
console.log(err);
}
};
pickBtn.addEventListener("click", pickColor);
</script>
</body>
</html>
You forgot to add click event to the button.
const button = document.querySelector('button');
button.addEventListener('click', () => {
if (!window.EyeDropper) {
resultElement.textContent = 'Your browser does not support the EyeDropper API';
return;
}
const eyeDropper = new EyeDropper();
eyeDropper.open().then((result) => {
console.log(result.sRGBHex);
}).catch((e) => {
console.log(e)
});
})
.green,
.blue,
.red {
cursor: pointer;
margin-bottom: 1rem;
}
.green {
color: green;
}
.blue {
color: blue;
}
.red {
color: red;
}
<div class="green">Green color</div>
<div class="blue">Blue color</div>
<div class="red">Red color</div>
<button>Pick color</button>
As #ourmaninamsterdam mentioned the EyeDropper is experimental and only supported in chromium browsers like edge, chrome, opera
Browser compatibility
When hovering over the picture, hide information about the link that will appear at the bottom left. When adding this script, the image became unclickable. I think the main problem is the incorrect connection of the js file or the execution of this script. I have added the code of 3 files below
openUrl(url: string): void {
window.open(url, '_blank');
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Roshan Timing</title>
<script src="eel.js"></script>
<link rel="icon" type="image/ico" href="/Roshan.ico"></link>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<!-- TIMER -->
<p class="timer">Timer</p>
<!-- CHAT(INPUT) -->
<!-- created by dankYbat -->
<div class="about_right">
<div class="text_wrap">
<p class="noselect">created by dankYoff</p>
</div>
<!--Connect js to tage image -->
<div class="image_wrap">
<a><img src="github.svg" (click)="openUrl('https://github.com/dankYoff')" width="50"></a>
</div>
</div>
</body>
</html>
You can not use openUrl(url: string): void in a *.js file, looks like you want to use TypeScript. If you want to create a faster vanilla typescript project you can use vite.
Anyway the a solution can be this:
const imgProfile = document.querySelector('#img-profile');
const openUrl = (url) => {
window.open(url, '_blank');
};
imgProfile.addEventListener('click', () => {
openUrl('https://github.com/dankYoff');
});
.img-profile {
cursor: pointer;
}
.img-profile img {
width: 100px;
height: 100px;
border-radius: 50%;
object-fit: cover;
transition: 0.3s;
}
.img-profile img:hover {
transform: scale(1.1);
}
<a class="img-profile" id="img-profile">
<img src="https://cdn.pixabay.com/photo/2022/09/16/13/07/woman-7458584_960_720.jpg" />
</a>
Okay so I'm making this thing where I use the reddit api and i get a post number then spit out all the info from it. Now I am making a custom number input and here is images of me using it.
How it looks when i load it
How it looks when i update the number
Here's my code:
const numberText = document.querySelector("#numberText")
const modalOpenBtn = document.querySelector("#numberBtn")
const modal = document.querySelector("#modal")
const done = document.querySelector("#done")
modalOpenBtn.addEventListener("click", () => {
modal.showModal()
})
done.addEventListener("click", () => {
let number = document.querySelector("#number")
number.textContent = numberText.value;
modal.close()
})
// The code below is in another file
const add = document.querySelector('#add');
const subtract = document.querySelector('#subtract');
let number = document.querySelector('#number');
add.addEventListener('click', () => {
number.innerHTML = `<h1>${parseInt(number.textContent) + 1}</h1>`;
})
subtract.addEventListener('click', () => {
if (parseInt(number.textContent) <= 0) {
alert('Cannot subtract from 0');
} else {
number.innerHTML = `<h1>${parseInt(number.textContent) - 1}</h1>`;
}
})
body, h1 {
background: rgb(34, 116, 165);
color: rgb(250, 250, 255);
font-family: 'Dosis', sans-serif;
}
button {
background: none;
border: none;
cursor: pointer;
resize: none;
}
div, button {
display: flex;
justify-content: center;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type=number] {
-moz-appearance: textfield;
}
<!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>the most stupidest app ive ever made</title>
<script defer src="input.js"></script>
<script defer src="openModal.js"></script>
<link rel="stylesheet" href="style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Dosis:wght#200;800&display=swap" rel="stylesheet">
</head>
<body>
<!-- intro -->
<h1>the most stupidest app ive ever made</h1>
<p>this app is from a reddit post with random knowledge; enter the number of the reddit post and you'll get it's info:</p><br>
<!-- buttons -->
<div>
<button class="add-subtract"><img src="add.svg" width="50" height="50" title="add" id="add"></button>
<button title="number" id="numberBtn"><h1 id="number">0</h1></button>
<button class="add-subtract"><img src="subtract.svg" width="50" height="50" title="subtract" id="subtract"></button>
</div>
<!-- da modal -->
<dialog id="modal">
<input type="number" id="numberText"><br>
<button id="done"><img src="./check.svg"></button>
</dialog>
</body>
</html>
Ask me any question in the comments regarding the code.
Help is appreciated. Thanks!!!
You should have inspected the layout first. You're adding a new h1 to the existing one. Thats what causing the shift. Instead replace the number inside it.
Just replace this line with
number.innerHTML = `<h1>${parseInt(number.textContent) + 1}</h1>`
to
number.innerHTML = `${parseInt(number.textContent) + 1}`
Since according to your comment you couldn't make this simple fix and say that solution isn't working for you, I'm adding the snippet you shared with the change I mentioned
const numberText = document.querySelector("#numberText")
const modalOpenBtn = document.querySelector("#numberBtn")
const modal = document.querySelector("#modal")
const done = document.querySelector("#done")
modalOpenBtn.addEventListener("click", () => {
modal.showModal()
})
done.addEventListener("click", () => {
let number = document.querySelector("#number")
number.textContent = numberText.value;
modal.close()
})
// The code below is in another file
const add = document.querySelector('#add');
const subtract = document.querySelector('#subtract');
let number = document.querySelector('#number');
add.addEventListener('click', () => {
number.innerHTML = `${parseInt(number.textContent) + 1}`;
})
subtract.addEventListener('click', () => {
if (parseInt(number.textContent) <= 0) {
alert('Cannot subtract from 0');
} else {
number.innerHTML = `${parseInt(number.textContent) - 1}`;
}
})
body, h1 {
background: rgb(34, 116, 165);
color: rgb(250, 250, 255);
font-family: 'Dosis', sans-serif;
}
button {
background: none;
border: none;
cursor: pointer;
resize: none;
}
div, button {
display: flex;
justify-content: center;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type=number] {
-moz-appearance: textfield;
}
<!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>the most stupidest app ive ever made</title>
<script defer src="input.js"></script>
<script defer src="openModal.js"></script>
<link rel="stylesheet" href="style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Dosis:wght#200;800&display=swap" rel="stylesheet">
</head>
<body>
<!-- intro -->
<h1>the most stupidest app ive ever made</h1>
<p>this app is from a reddit post with random knowledge; enter the number of the reddit post and you'll get it's info:</p><br>
<!-- buttons -->
<div>
<button class="add-subtract"><img src="add.svg" width="50" height="50" title="add" id="add"></button>
<button title="number" id="numberBtn"><h1 id="number">0</h1></button>
<button class="add-subtract"><img src="subtract.svg" width="50" height="50" title="subtract" id="subtract"></button>
</div>
<!-- da modal -->
<dialog id="modal">
<input type="number" id="numberText"><br>
<button id="done"><img src="./check.svg"></button>
</dialog>
</body>
</html>
You can add position: relative to your navbar.
example for mi code
.navbar.navbar-inverse {
position: relative;
}
<div style="margin-top: 15px;text-align: center;" class="navbar navbar-inverse navbar-fixed-top container">
I have a side navigation bar with a button to toggle showing just the icons or to show the icons and the text. There are multiple different HTML pages that share this nav bar, so I needed to save the nav bar's state for when you switch to each (Dashboard to Items, Contacts to Dashboard, etc). I do this using the follow code:
var navBar = document.querySelector(".side-bar");
var toggle = document.querySelector(".nav-toggle");
window.onload = () =>
{
let isClosed = localStorage.getItem("navState");
navBar.classList.toggle("nav-is-closed", isClosed);
}
toggle.addEventListener("click", () =>
{
let isClosed = navBar.classList.toggle("nav-is-closed");
localStorage.setItem("navState", isClosed);
});
.side-bar {
position: relative;
background-color: var(--default-back-color);
min-width: 200px;
}
.nav-is-closed {
min-width: inherit;
}
.nav-is-closed a h2 {
display: none;
}
<!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 rel="stylesheet" href="resources/css/styles.css">
<!--Google Fonts-->
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Neucha&family=Poppins:wght#300&display=swap" rel="stylesheet">
<title>Rucksack</title>
</head>
<body>
<header>
<div>
<img src="resources/images/rucksack.png" alt="">
<h1 class="title">Rucksack</h1>
</div>
<div>
<a class="smaller-icon" href="#"><img src="resources/images/gear.png" alt=""></a>
<img src="resources/images/blue-profile.png" alt="">
</div>
</header>
<main>
<section id="main-section">
<nav class="side-bar">
<a class="selected-nav" href="dashboard"><img src="resources/images/house-icon.png" alt=""><h2>Dashboard</h2></a>
<img src="resources/images/item-icon.png" alt=""><h2>Items</h2>
<hr class="nav-break">
<img src="resources/images/contacts-icon.png" alt=""><h2>Contacts</h2>
<hr class="nav-break">
<img src="resources/images/reports-icon.png" alt=""><h2>Reports</h2>
<div class="nav-toggle"><img src="resources/images/arrow-icon.png" alt=""></div>
</nav>
<div class="content">
<strong>Content</strong>
</div>
</section>
</main>
<script src="shell-controls.js"></script>
</body>
</html>
Everything works fine, except when you move to a new page while the nav is open. It closes even though in window.onload, isClosed is false. As far as I know, toggle with force set to false removes the class, but in this case it's still adding it.
As Kaiido said, isClosed was being pulled from localStorage as a string, which caused toggleClass to think the string of "false" was truthy, therefore still adding the 'nav-is-closed' class. Adding JSON.parse when getting isClosed and adding JSON.stringify when setting isClosed in localStorage solves the problem.
so here is the thing i have a block of html code that needs to be replaced when a button is clicked. Its no big deal using
$('div.myCustomReplacer').replaceWith(newHTML);
but i also need to render a django-form {{ form }} in the new HTML
when i simply use
<div class="NewDiv"> {{ form }} </div? the html is rendered as "{{ form }}" because of those quotes the form is not rendered.
So how i do remove those ?
sorry just new to JavaScript.
I don't think you can achieve it like that. Remember that the form is added when html is rendered in the server, so basically {{form}} doesn't exist in client.
No worries, there are several simple ways to reach you goal just using simple JavaScript. One way is to simple let server inject the form, and just make it visible when user click button. Take a look at the example I made for you.
document.getElementById('showBtn')
.addEventListener('click', function () {
document.getElementById('targetDiv').style.display = 'block';
});
document.getElementById('hideBtn')
.addEventListener('click', function () {
document.getElementById('targetDiv').style.display = 'none';
});
html, body {
width: 100%;
height: 100%;
font-family: 'Roboto', sans-serif;
}
button {
margin: 1rem;
}
section {
margin: 1rem;
}
section span {
background-color: lightcoral;
font-size: small;
padding: .5rem;
}
<!doctype html>
<html lang="en">
<head>
<title>Hide Form</title>
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
<link href="./style.css" rel="stylesheet">
</head>
<body>
<button id="showBtn">Show Form</button>
<button id="hideBtn">Hide Form</button>
<section>
<div id="targetDiv" style="display: none;">
<h2>Form <span> (a moment ago I was just hidden)</span></h2>
<form>
<label for="someInput">Bla bla</label>
<input id="someInput" type="text"/>
</form>
</div>
</section>
<script src="./app.js"></script>
</body>
</html>