upload button multiple - file lists in new line (break line) :) - javascript

What's Up :)
I styled custom upload file button, it looks like i want, but i don't know how to make it in .js that - each file name will be shown in new line not like right now after "," - i saw in .js code - line: .join(", ") but i don't know how to replace it with code which will make those files names into new lines :(
Here's my code:
HTML:
<div>
<input class="file-upload__input" type="file" name="myFile[]" id="myFile" multiple>
<button class="file-upload__button" type="button">Choose File(s)</button>
<span class="file-upload__label"></span>
</div>
</div>
CSS:
display: inline-flex;
align-items: center;
font-size: 15px;
}
.file-upload__input {
display: none;
}
.file-upload__button {
-webkit-appearance: none;
background: #009879;
border: 2px solid #00745d;
border-radius: 4px;
outline: none;
padding: 0.5em 0.8em;
margin-right: 15px;
color: #ffffff;
font-size: 1em;
font-family: "Quicksand", sans-serif;
font-weight: bold;
cursor: pointer;
}
.file-upload__button:active {
background: #00745d;
}
.file-upload__label {
max-width: 250px;
font-size: 0.95em;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
font-family: "Quicksand", sans-serif;
display: block;
margin-top: 15px;
}
.JS
document.querySelectorAll(".file-upload__button"),
function(button) {
const hiddenInput = button.parentElement.querySelector(
".file-upload__input"
);
const label = button.parentElement.querySelector(".file-upload__label");
const defaultLabelText = "No file(s) selected";
// Set default text for label
label.textContent = defaultLabelText;
label.title = defaultLabelText;
button.addEventListener("click", function() {
hiddenInput.click();
});
hiddenInput.addEventListener("change", function() {
const filenameList = Array.prototype.map.call(hiddenInput.files, function(
file
) {
return file.name;
});
label.textContent = filenameList.join(", ") || defaultLabelText;
label.title = label.textContent;
});
}
);
Thanks everyone who will help <3

I'm adding this as an answer instead of a comment so there is an official answer to this question.
Simply swap this
label.textContent = filenameList.join(", ") || defaultLabelText;
with this instead
label.innerHTML = filenameList.join("<br>") || defaultLabelText;

Related

Is there a way to change the value of any one button in a set of buttons at a time when one of them is clicked?

im looking for a way to change the backgroundColor of only the button which is clicked in a set of 4 buttons in react. Example:- default color is white, if the 2nd button is clicked its background color becomes blue, if the 4th button is clicked its bg color becomes blue but all others become white. I could do it with getElementBy classes/id or queryselector but the thing is it is present in 4 columns so it messes with the same button number in the other rows.
If you dont get what I mean, see the image.
export default function Quiz() {
const [quiz, setQuiz] = React.useState([]);
function getQuiz() {
fetch("my api key")
.then((res) => res.json())
.then((data) => setQuiz(data["results"]));
}
//the api gives 5 questions with 4 options each
React.useEffect(() => {
getQuiz();
}, []);
const renderQuiz = quiz.map((val) => {
// im using decodeURIComponent since its a "url base" or something type array.
let question = decodeURIComponent(val["question"]);
let correctAnswer = decodeURIComponent(val["correct_answer"]);
let wrongOptions = val["incorrect_answers"];
let allOptions = [];
wrongOptions.map((elem) => allOptions.push(decodeURIComponent(elem)));
allOptions.push(correctAnswer);
allOptions = shuffle(allOptions); //suffle is a function in another file which shuffles the contents of an array.
function RenderOptions() {
return allOptions.map((val) => {
return (
<>
<button className="opt-btn">{val}</button> {" "}
</>
);
});
}
return (
<div className="container">
<div className="question">{question}</div>
<div className="options">
<RenderOptions />
</div>
<hr className="dash" />
</div>
);
});
return <div className="quiz">{renderQuiz}</div>;
}
CSS
#import url("https://fonts.googleapis.com/css2?family=Karla&display=swap");
#import url("https://fonts.googleapis.com/css2?family=Inter&display=swap");
body {
background-color: #f5f7fb;
height: 100%;
overflow: hidden;
}
.quiz {
display: block;
margin: auto;
text-align: center;
margin-top: 30px;
width: 800px;
}
.question {
font-family: "Karla";
font-style: normal;
font-weight: bold;
font-size: 16px;
line-height: 19px;
color: #293264;
padding-top: 10px;
padding-bottom: 15px;
text-align: justify;
}
.options{
text-align: left;
max-width: 700px;
}
.opt-btn {
border: 0.794239px solid #4d5b9e;
width: -moz-fit-content;
width: fit-content;
box-sizing: border-box;
border-radius: 7.94239px;
padding-left: 15px;
padding-right: 15px;
padding-top: 5px;
padding-bottom: 5px;
background: #f5f7fb;
font-family: Inter;
font-style: normal;
font-weight: 600;
font-size: 11px;
line-height: 12px;
text-align: justify;
color: #293264;
}
.dash {
width: 630px;
height: 0px;
border: 0.794239px solid #dbdef0;
transform: rotate(-0.05deg);
margin-left: 0;
}
Will give more info if needed.

Requesting a list from an API, populating <select> with all items on that list

I wasn't really sure how to work that title but, hello, I'm taking a JS course and at the end of one of the lecture there was an optional extra credit assignment:
The dog.ceo API allows you to request a list of breeds. Use this list
to populate a select field. Then when a user select a dog breed,
show a picture of that dog using the random image by breed API.
I've got the first half done, populating the select field with the breeds from the API but i've tried for hours to try to get the second part to work. On click, it should show a random image from that breed. I feel like i'm too close to give up on this, even if it's optional work. Any help would be greatly appreciated or even maybe a nudge in the right way
Demo
const RANDOM_DOG = 'https://dog.ceo/api/breeds/image/random';
const RANDOM_BREED = `https://dog.ceo/api/breed/hound/images/random`;
const BREED_LIST = 'https://dog.ceo/api/breeds/list/all';
const dogBtn = document.querySelector('.get-doggo');
const dogDropdown = document.querySelector('.dropdown');
const dogImages = document.querySelector('.images');
const loader = document.querySelector('.loader');
function randomDogPromise() {
const promise = fetch(RANDOM_DOG);
loader.classList.add('show'); // Showing our Loader Before new images load
promise
.then((response) => {
const processedResponse = response.json();
return processedResponse;
})
.then((data) => {
loader.classList.remove('show'); // Hiding our Loader hter new images load
// creating image element and appending them to the images div
const img = document.createElement('img');
img.src = data.message;
img.alt = 'Cute Doggos';
img.width = 300;
dogImages.appendChild(img);
});
}
function populateDropdownList() {
const promise = fetch(BREED_LIST);
promise
.then((response) => {
const processedResponse = response.json();
return processedResponse;
})
.then((data) => {
const breedList = Object.keys(data.message);
breedList.map((breed) => {
const option = document.createElement('option');
option.value = breed;
option.innerText = breed;
dogDropdown.appendChild(option);
});
});
}
window.addEventListener('click', populateDropdownList());
dogBtn.addEventListener('click', randomDogPromise);
*,
*:before,
*:after {
box-sizing: border-box;
}
body {
font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande',
'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
background-color: #f3e9c5;
}
.doggos {
width: 90%;
margin: 0 auto;
}
.doggos .controls {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.doggos .controls div {
flex: 1;
}
.doggos .controls .dropdown {
width: 90%;
height: 50px;
margin: 0 20px;
}
.doggos .controls button {
border: none;
margin: 0 20px;
width: 90%;
height: 50px;
background-color: #d7503e;
color: #fff;
text-transform: uppercase;
border-radius: 10px;
box-shadow: 2px 2px 2px #b0b0b0;
font-weight: 500;
font-size: 20px;
padding: 0px 40px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
letter-spacing: 2px;
}
.doggos button:hover {
background-color: #ab3b2c;
}
.doggos .images {
margin-top: 30px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.doggos .images img {
border: 2px solid #f3e9c5;
flex: 1;
max-width: 100%;
object-fit: cover;
}
.loader-wrapper {
display: flex;
justify-content: center;
}
.loader {
display: none;
width: 300px;
height: 300px;
}
.show {
display: block;
}
<div class="doggos">
<div class="controls">
<div class="half">
<button class="get-doggo">Click for doggo</button>
</div>
<div class="half">
<select class="dropdown" name="" id="">
<option selected disabled>Choose Your Random Doggo</option>
</select>
</div>
</div>
<div class="loader-wrapper">
<img class="loader" src="200.gif" alt="">
</div>
<div class="images">
</div>
</div>

How to position a h1 directly over an input and have it be for all screens?

So I want to replace the text inside of an input field with a h1 tag as soon as the user hits submit because i want the text to have an animation but i can't animate the text inside the text field.
I linked the code pen project version of it to make it easier then organizing all the code in here. I added all the code I had so I wouldn't leave anything out although some of it may be irrelevant.
Basically I want the h1 tag to appear exactly where the input text was so it looks like nothing ever got replaced.
https://codepen.io/timvancowabunga/pen/rNOqdYd
$(document).ready(function() {
$('#btn1').click(function() {
$('#test').text($("#message").val());
$('#message').val('');
$('#test').val('');
});
});
function onTextClick() {
document.getElementById('btn1').className = "show";
}
function showButton() {
document.getElementById('btn1').style.display = 'block';
}
function showSendButton() {
document.getElementById('btn2').style.display = 'block';
}
function formCheck() {
var input = $('#message').val();
if (input == '') {
alert("Please Submit a Valid Message");
} else {
hideButton();
showSendButton();
}
}
function hideButton() {
document.getElementById('btn1').style.display = 'none';
}
function hideSendButton() {
document.getElementById('btn2').style.display = 'none';
document.getElementById('sent').style.display = 'block';
}
function myMove() {
var textWrapper = document.querySelector('.ml13');
textWrapper.innerHTML = textWrapper.textContent.replace(/\S/g, "<span class='letter'>$&</span>");
anime.timeline()
.add({
targets: '.ml13 .letter',
translateY: [0, -1600],
opacity: [1, 0],
easing: "easeInSine",
duration: 3600,
delay: (el, i) => 800 + 60 * i
});
}
body {
background-color: #368670;
font-family: sans-serif;
}
.ml13,
.ml14,
.ml15 {
font-size: 1.9em;
text-transform: uppercase;
letter-spacing: 0.2em;
font-weight: 600;
}
.ml15 {
letter-spacing: 0em;
text-align: center;
}
.ml13 .letter {
display: inline-block;
line-height: 1em;
}
.line {
display: flex;
margin: auto;
width: 50%;
margin-top: 500px;
}
.wrappy {
position: relative;
}
.wrappy h1 {
position: absolute;
left: 48.5%;
top: 20%
}
.butt {
padding-top: 50px;
display: flex;
margin: 0 auto;
width: 100%;
}
#btn1,
#btn2 {
display: table;
margin: 0 auto;
}
input {
z-index: 1000;
margin-left: 10%;
width: 80%;
background: transparent;
border: 0;
border-bottom: 1px solid;
padding: 1em 0 .1em;
text-align: center;
font-size: 18px;
font-family: inherit;
font-weight: 300;
line-height: 1.5;
color: inherit;
outline: none;
}
input:focus {
border-color: #ffffff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
<div class="truth">
<!-- <div class="line"> -->
<div class="message-box">
<form class="message-form">
<h2 class="ml15" for="message">TELL A TRUTH</h2>
<div class="wrappy">
<input type="text" id="message" name="message" autocomplete="off" class="ml14">
<!-- <h1 id="test" class="ml13">I love your music!</h1> -->
<h1 id="test" class="ml13"></h1>
</div>
</form>
</div>
<div class="butt">
<button id="btn1" onclick="formCheck();">Ready to Send?</button>
<button id="btn2" style="display: none" onclick="myMove(); setTimeout(showButton, 3000); hideSendButton();">Send!</button>
</div>
</div>
You want to put H1 below the input.
Then you make the text input transparent. Bind the input value to h1.
So in effect when user clicks and type, they are selecting the input and changing its value, but it's transparent, to be shown by the h1 below the input that you will eventually animate.
Also because you mentioned you want it to display correctly in all platforms. You then have to be cognisant of the default behaviours of DOM and CSS properties. If you alter them to get what you want without knowing its natural order, you can get unexpected behaviour and reduce cross-browser compatibility. I have made changes to reflect that.
$(document).ready(function () {
$("#btn1").click(function () {
$("#test").text($("#message").val());
$("#message").val("");
$("#test").val("");
});
});
function onTextClick() {
document.getElementById("btn1").className = "show";
}
function showButton() {
document.getElementById("btn1").style.display = "block";
}
function showSendButton() {
document.getElementById("btn2").style.display = "block";
}
function formCheck() {
var input = $("#message").val();
if (input == "") {
alert("Please Submit a Valid Message");
} else {
hideButton();
showSendButton();
}
}
function hideButton() {
document.getElementById("btn1").style.display = "none";
}
function hideSendButton() {
document.getElementById("btn2").style.display = "none";
document.getElementById("sent").style.display = "block";
}
// attach this to bind h1 to the input value at all times.
$("#message").keyup(function () {
var self = this;
$("#test").text($(this).val());
});
function myMove() {
var textWrapper = document.querySelector(".ml13");
textWrapper.innerHTML = textWrapper.textContent.replace(
/\S/g,
"<span class='letter'>$&</span>"
);
anime.timeline().add({
targets: ".ml13 .letter",
translateY: [0, -1600],
opacity: [1, 0],
easing: "easeInSine",
duration: 3600,
delay: (el, i) => 800 + 60 * i
});
}
body {
background-color: #368670;
font-family: sans-serif;
}
.ml13,
.ml14,
.ml15 {
font-size: 1.9em;
text-transform: uppercase;
letter-spacing: 0.2em;
font-weight: 600;
}
.ml15 {
letter-spacing: 0em;
text-align: center;
}
.ml13 .letter {
display: inline-block;
line-height: 1em;
}
.line {
display: flex;
margin: auto;
width: 50%;
margin-top: 500px;
}
.wrappy {
position: relative;
text-align: center;
}
.wrappy h1 {
position: absolute; /* you then want to give wrappy h1 this to make it occupy no space. */
width: 100%; /* to centralize the text, your option here is to make this 100% width and use text-align */
text-align: center;
padding-top: 21px;
}
.butt {
padding-top: 50px;
display: flex;
margin: 0 auto;
width: 100%;
}
#btn1,
#btn2 {
display: table;
margin: 0 auto;
}
input {
position: relative; /* in order for z-index to work, you need to give an element `position` attribute of value `static`, `relative` or `absolute`. */
z-index: 1000; /* now this will work. wrappy h1 is not given a `z-index` so it defaults to `1`, hence input will be on top of wrappy h1 now. */
width: 80%;
background: transparent;
border: 0;
border-bottom: 1px solid #000; /* you need the line back because we are going to assign color to be transparent */
padding: 35px 0 0 0;
text-align: center;
font-size: 18px;
font-family: inherit;
font-weight: 300;
line-height: 1.5;
color: transparent; /* make the text transparent */
outline: none;
}
input:focus {
border-color: #ffffff;
}
<div class="truth">
<!-- <div class="line"> -->
<div class="message-box">
<form class="message-form">
<h2 class="ml15" for="message">TELL A TRUTH</h2>
<div class="wrappy">
<!-- for natural flow, you want to shift #test to above the input, so that input can stack on top of it -->
<h1 id="test" class="ml13"></h1>
<input type="text" id="message" name="message" autocomplete="off" class="ml14">
<!-- <h1 id="test" class="ml13">I love your music!</h1> -->
</div>
</form>
</div>
<div class="butt">
<button id="btn1" onclick="formCheck();">Ready to Send?</button>
<button id="btn2" style="display: none" onclick="myMove(); setTimeout(showButton, 3000); hideSendButton();">Send!</button>
</div>
</div>

remove blur from textarea on file upload html | css | javascript

I have a html page where I want the text to be appear clear not blur
when I upload file the text is read from file and displayed on TextArea but the text appears to be blur
The concept I am using is when I type some specific keyword if that specific keyword matches when a type in the textarea then it appears in a different color like keyword "connected" if I type this in textarea then apperas green this is how my function is defined
Issue : when I take the text from file, the text is displayed on my textarea but appears blur how to fix that blur
work with this file and see gives blur content
could you please upload this text file and see (sample text file) link : sendspace.com/file/67ge9n you may get to see blur content as shown in image sendspace.com/file/r25qme
const color = {
"connected successfully": "green",
"connected": "green",
"connection failure": "red"
};
let textArea = document.getElementById("myTextArea");
let colorsArea = document.querySelector(".colors");
let backdrop = document.querySelector(".backdrop");
// Event listeners.
textArea.addEventListener("input", function() {
colorsArea.innerHTML = applyColors(textArea.value);
});
textArea.addEventListener("scroll", function() {
backdrop.scrollTop = textArea.scrollTop;
});
function applyColors(text) {
let re = new RegExp(Object.keys(color).join("|"), "gi");
return text.replace(re, function(m) {
let c = color[m.toLowerCase()];
return `<spam style="color:${c}">${m}</spam>`;
});
}
function rdata() {
var file = document.getElementById("myFile").files[0];
var reader = new FileReader();
reader.onload = function(e) {
var textArea = document.getElementById("myTextArea");
textArea.value = e.target.result;
};
reader.readAsText(file);
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 50%;
}
td {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
input[type=text],
select {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.container,
.backdrop,
#myTextArea {
font: 12px 'Open Sans', sans-serif;
letter-spacing: 1px;
width: 48%;
height: 250px;
}
#myTextArea {
margin: 0;
position: absolute;
border-radius: 0;
background-color: transparent;
z-index: 2;
color: black;
/* i change it to red , u can change to any color u want */
resize: none;
}
.backdrop {
position: absolute;
z-index: 1;
border: 2px solid transparent;
overflow: auto;
pointer-events: none;
}
.colors {
white-space: pre-wrap;
word-wrap: break-word;
}
<tr>
<td><input id="myFile" type="file" /></td>
</tr>
<tr>
<td colspan="2">
<div class="container">
<div class="backdrop">
<div class="colors">
</div>
</div>
<textarea id="myTextArea" onclick="rdata();"></textarea>
</div>
</td>
</tr>
its not blur ? ur code is correct

removing the input text in the text field that matches the removed tab

In this example I made, since it uses keyup event, each input text (separated by comma) entered is converted into a tab. I want the input text to be deleted from the text field according to the tab I remove; for example, I enter "Item 1" but I suddenly change my mind and decide to remove the "Item 1" tab, the input text in the text field that has a string that matches the textContent of the removed tab should be automatically deleted from the text field.
var query = document.querySelector.bind(document);
query('#textfield').addEventListener('keyup', addTag);
function addTag(e) {
var evt = e.target;
if(evt.value) {
var items = evt.value.split(',');
if(items.length <= 10) {
evt.nextElementSibling.innerHTML = null;
for(var i = 0; i < items.length; i++) {
if(items[i].length > 0) {
var label = document.createElement('label'),
span = document.createElement('span');
label.className = 'tag';
label.textContent = items[i];
span.className = 'remove';
span.title = 'Remove';
span.textContent = 'x';
label.insertAdjacentElement('beforeend', span);
evt.nextElementSibling.appendChild(label);
span.addEventListener('click', function() {
var currentElement = this;
currentElement.parentNode.parentNode.removeChild(currentElement.parentNode);
})
}
}
}
} else {
evt.nextElementSibling.innerHTML = null;
}
}
section {
width: 100%;
height: 100vh;
background: orange;
display: flex;
align-items: center;
justify-content: center;
}
.container {
width: 50%;
}
input[name] {
width: 100%;
border: none;
border-radius: 1rem 1rem 0 0;
font: 1rem 'Arial', sans-serif;
padding: 1rem;
background: #272727;
color: orange;
box-shadow: inset 0 0 5px 0 orange;
}
input[name]::placeholder {
font: 0.9rem 'Arial', sans-serif;
opacity: 0.9;
}
.tags {
width: 100%;
height: 250px;
padding: 1rem;
background: #dfdfdf;
border-radius: 0 0 1rem 1rem;
box-shadow: 0 5px 25px 0px rgba(0,0,0,0.4);
position: relative;
}
.tags > label {
width: auto;
display: inline-block;
background: #272727;
color: orange;
font: 1.1rem 'Arial', sans-serif;
padding: 0.4rem 0.6rem;
border-radius: .2rem;
margin: 5px;
}
.tags > label > span {
font-size: 0.7rem;
margin-left: 10px;
position: relative;
bottom: 2px;
color: #ff4d4d;
cursor: pointer;
}
<section id="tags-input">
<div class="container">
<input type="text" name="items" id="textfield" placeholder="Enter any item, separated by comma(','). Maximum of 10" autofocus>
<div class="tags"></div>
</div>
</section>
How can I make that feature possible?
Replace the 'x' button listener with this one:
span.addEventListener('click', function () {
var text_field = document.getElementById("textfield");
var evt = this.parentNode;
var tags = text_field.value;
this.parentNode.removeChild(this); // remove the 'x' span so you can get the pure tag text with .innerHTML
var evname = evt.innerHTML;
var tags_array = tags.split(",");
var tag_position = tags_array.indexOf(evname);
if(tag_position > -1)
tags_array.splice(tag_position,1);
text_field.value = tags_array.join(',');
evt.parentNode.removeChild(evt);
})
// Coding this complexity in pure javascript when there is jQuery is ... like eating soup with a fork. You will get the job done, but it is dammn hard!

Categories

Resources