Input File Processing - javascript

I have a piece of code that is working....it allows me to display multiple files in a list when a user clicks on Choose File. The code works fine. However, I am trying to figure out if it's possible to append to the list instead of creating a new one each time. I've researched this most of the afternoon and a vast majority of the articles say it's not easily done. Should I be using a FormData approach instead? Would that buy me anything?
Here is my Javascript code...It works fine...
window.onload = function() {
const inputElement = document.getElementById("my_files");
const fileNames = document.getElementById("file_names");
let fileList = [];
function removeFile(event) {
event.preventDefault();
let filename = this.dataset.filename;
let modifiedFileList = new DataTransfer();
for (let i = 0; i < fileList.length; i++) {
if (fileList[i].name !== filename) {
modifiedFileList.items.add(fileList[i]);
}
}
inputElement.files = modifiedFileList.files;
fileList = inputElement.files;
handleFiles(fileList);
return false;
}
inputElement.addEventListener("change", handleFilesListener, false);
function handleFilesListener() {
fileList = this.files;
handleFiles(fileList);
}
function handleFiles(fileList) {
fileNames.textContent = '';
for (let i = 0; i < fileList.length; i++) {
let listElement = document.createElement("li");
let textNode = document.createTextNode(fileList[i].name);
listElement.appendChild(textNode);
listElement.setAttribute("class","attachmentname");
let removeButton = document.createElement("button");
removeButton.innerHTML = "Remove&nbsp";
removeButton.setAttribute('type', 'button')
removeButton.setAttribute("class", "button121");
removeButton.setAttribute('data-filename', fileList[i].name)
removeButton.addEventListener('click', removeFile)
listElement.appendChild(removeButton);
fileNames.appendChild(listElement);
}
}
}
Again, I'm trying to figure out if I can append to this list instead of constantly looping through it if the list changes. I did try to do an append instead of add below...but that didn't work. I'm a self proclaimed newb...so please go easy on me. :).
let filename = this.dataset.filename;
let modifiedFileList = new DataTransfer();
for (let i = 0; i < fileList.length; i++) {
if (fileList[i].name !== filename) {
modifiedFileList.items.add(fileList[i]);
}
}
Thanks in advance for any pointers.

Related

sum up user input with javascript

I'm trying to store a user input in a variable and output it.
I actually thought it would be very easy, but right now I'm stuck on this task
I'm trying to store this in an array. but I would also be happy if it was simply stored in a variable and I could output it.
I've been searching for it for a long time, but I have the feeling that I don't know exactly what to look for
here is my code:
let inputValuePrice = document.getElementById("myInput2").value;
let outputSumme = document.getElementById("summe");
outputSumme = parseFloat(inputValuePrice);
let sum = [];
sum.push(outputSumme);
console.log(sum);
<input type="number" id="myInput2" />
<input type="text" id="summe" />
edit:
I'm sorry. I'll explain it again in more detail. I want to add the number after each entry. It is a kind of to-do list with products and prices. each product is entered one by one along with the price. I would then like to add up the price of each product. In this case it is enough for me if it is first output in the console. If it is correct then I will let it output to the html.
if you need to calculate the sum of all inputs values as an integer or a float number it's very simple. you can use a simple function to sums all of your array elements like this:
let inputValuePrice = document.getElementById("myInput2").value;
let outputSumme = document.getElementById("summe");
outputSumme = parseFloat(inputValuePrice);
let sum = [];
sum.push(outputSumme);
console.log(getSumOfArray(sum));
function getSumOfArray(array){
let sumOfElements=0;
for (let i=0;i<array.length;i++){
sumOfElements=sumOfElements+array[i];
}
return sumOfElements;
}
If your array elements are all numbers you can use the reduce operator as follows:
const sumOfArray = sum.reduce((a, b) => a + b, 0)
Unfortunately I don't understand how it works. I have now the products with prices in the indexedDB in my code. There I wanted to read them out and sum them up again in an array. I'll send you the whole code. I would be very grateful for an explanation. what is wrong with my thinking? Here is my code.
This snippet is in a function that when run puts the products in a list in the HTML. The products are created in a foreach loop and in that I intercept the prices and send them outside of the function to another function which then has the data to calculate with. I hope it is understandable. I'll link the whole code at the end of this thread.
let products = makeTransaction('produkte', "readonly");
let request = products.getAll();
request.addEventListener('success', (event) => {
event.preventDefault();
document.querySelector('#product-list').innerHTML = "";
let data = event.target.result;
data.forEach((element) => {
/*-----------Elemente Kreieren------------*/
let li = document.createElement("li");
let edit = document.createElement('i');
let spanPrimary = document.createElement('span');
let inputLabel = document.createElement('label');
let productName = document.createElement('span');
let productPrice = document.createElement('span');
let spanSecondary = document.createElement('span');
let checkBox = document.createElement('input');
let closeBtn = document.createElement("span");
/*-----------Elemente einfügen------------*/
li.setAttribute('data-key', element.id);
productName.appendChild(document.createTextNode(element.title));
productPrice.appendChild(document.createTextNode(element.price + " €"));
spanPrimary.appendChild(productName);
spanPrimary.appendChild(productPrice);
inputLabel.appendChild(checkBox);
spanSecondary.appendChild(inputLabel);
li.appendChild(edit);
li.appendChild(spanPrimary);
li.appendChild(spanSecondary);
li.appendChild(closeBtn);
/*-----------Elemente klassifizieren------------*/
li.className = "mdl-list__item mdl-shadow--2dp";
edit.className = "material-symbols-outlined icon-edit-document";
edit.textContent = 'edit_document';
spanPrimary.className = "mdl-list__item-primary-content";
spanSecondary.className = "mdl-list__item-secondary-action";
inputLabel.className = "mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect";
productName.className = 'product-text';
productPrice.className = 'product-preis';
checkBox.className = "mdl-checkbox__input";
checkBox.setAttribute('id', 'my-id');
checkBox.setAttribute('type', 'checkbox');
closeBtn.className = "material-symbols-outlined hiding-list-item";
closeBtn.textContent = 'close';
componentHandler.upgradeElement(li);
let list = document.getElementById("product-list").appendChild(li);
// Füge die "edit" Funtion hinzu
let editieren = document.getElementsByClassName("icon-edit-document");
for (let i = 0; i < editieren.length; i++) {
editieren[i].onclick = function() {
showProducts(element.id);
}
}
// Füge die "close" Button Funktion hinzu
let close = document.getElementsByClassName("hiding-list-item");
for (let i = 0; i < close.length; i++) {
close[i].onclick = function() {
deleteProduct();
}
}
// Function for totalizing product prices
let produktPreis = element.price
sumPrice(produktPreis);
});
});
request.addEventListener('error', (event) => {
console.log(event.target.error);
});
}
and now the summation...
function sumPrice(produktPreis) {
produktPreis = parseFloat(produktPreis);
let arr = [];
arr.push(produktPreis);
console.log(getSum(arr));
console.log(sumOfArray);
function getSum(array) {
let sumOfElements = 0;
for (let i = 0; i < arr.length; i++) {
sumOfElements = sumOfElements + array[i];
}
return sumOfElements;
}
}
I've always been able to help myself. But I can't get any further with this supposedly simple thing.
and for the completeness. Here is my temporarily hosted website and Github. Thanks also for the previous replies.
Project site
https://liquefied-stripe.000webhostapp.com/
Github
https://github.com/StevoEs/Einkaufsliste/blob/main/main.js
Thanks!

Update Array when new elements are displayed on webpage

I'm working on a chrome extension where I need to gather the total number of books in a library.
The code below works fine, however, the page where I'm getting the data only loads half of the books at once until you scroll down further and the array doesn't update accordingly.
Is there a way to automatically update the array to keep up with the changes?
let list = document.querySelectorAll("ul > li");
let numBooks = [];
for (let i = 0; i < list.length; i++) {
numBooks.push(i + 1);
}
console.log(numBooks);
// Variables
let list = document.querySelectorAll("ul > li");
let mlist = document.querySelector("ul");
let numBooks = [];
// Push books to array
for (let i = 0; i < list.length; i++) {
numBooks.push(i + 1);
}
// Observe changes
const observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.addedNodes.length) {
// Create Element: Book Count
let url = "myurl";
let nBooks = numBooks.length / 10;
let nChanges = mutation.addedNodes.length - 1;
if (url == window.location.href) {
let el = document.createElement("span");
el.innerHTML = nBooks + nChanges;
let par = document.getElementsByTagName("h2")[0];
par.appendChild(el);
}
}
});
});
observer.observe(mlist, {
childList: true,
});

how to remove a file from file upload control before uploading it using jQuery

I am using a multi-file upload control to upload files.
I am listing the files before I upload so users can see the names of file what are they uploading.
I have a delete button in each file name row.
I am trying to remove the file from the list when I click the remove button, just in case I changed my before I upload.
I am running out of ideas on
var fileInput = document.getElementById('inputfile');
var fileListDisplay = document.getElementById('allfiles');
var fileList = [];
var renderFileList, sendFile;
fileInput.addEventListener('change', function (evnt) {
fileList = [];
for (var i = 0; i < fileInput.files.length; i++) {
fileList.push(fileInput.files[i]);
}
renderFileList();
});
renderFileList = function () {
fileListDisplay.innerHTML = '';
fileList.forEach(function (file, index) {
var fileDisplayEl = document.createElement('p');
fileDisplayEl.innerHTML = file.name +"<div class=deletfile></div>";
fileListDisplay.appendChild(fileDisplayEl);
});
};
$(document).on('click','.deletfile', function()
{
var filen=($(this).parent().text());
console.log(fileList);
const index = fileList.indexOf(filen);
console.log(index,filen);
if (index > -1) {
fileList.splice(index,1);
}
//console.log(fileList);
});
<input id="inputfile" type="file" multiple> <br><div id='allfiles'></div>
how to do it?
here is my code
delete file function is where I am trying to do it.
From your code, I can see that you forget to remove the dom that why the file still exists.
Another, to make the code simple we can attach data-index inside the delete button to remember the file index when we're deleting it will be easy than compare the string of filename.
Here is the modified code.
var fileInput = document.getElementById('inputfile');
var fileListDisplay = document.getElementById('allfiles');
var fileList = [];
var renderFileList, sendFile;
fileInput.addEventListener('change', function (evnt) {
fileList = [];
for (var i = 0; i < fileInput.files.length; i++) {
fileList.push(fileInput.files[i]);
}
renderFileList();
});
renderFileList = function () {
fileListDisplay.innerHTML = '';
fileList.forEach(function (file, index) {
var fileDisplayEl = document.createElement('p');
fileDisplayEl.innerHTML = `${file.name} <button data-index="${index}" class='deletfile'>X</button>`;
fileListDisplay.appendChild(fileDisplayEl);
});
};
$(document).on('click','.deletfile', function()
{
const index= $(this).attr('data-index');
fileList.splice(parseInt(index, 10), 1);
$(this).parent().remove();
});

Hide/Show div p5.js

I am using the p5.js library, and I am working on a speech recognition - text to speech project. Kind of a chatbot.
Input is voice input which becomes a string.
I am outputting the result from a txt file, using a markov chain. Output is a string contained in a div.
My question is:
Is there a way to hide/show the div containing my input/output (.myMessage and .robotMessage) in intervals?
I want the whole screen first showing only the input when I am talking, then input disappears and only output showing, then when the computer voice finishes speaking my input is shown in the screen and so on...
Here some parts of the code, let me know if it is clear enough.
//bot
function setup() {
noCanvas();
//reads and checks into the text file
for (var j = 0; j < names.length; j++) {
var txt = names[j];
for (var i = 0; i <= txt.length - order; i++) {
var gram = txt.substring(i, i + order);
if (i == 0) {
beginnings.push(gram);
}
if (!ngrams[gram]) {
ngrams[gram] = [];
}
ngrams[gram].push(txt.charAt(i + order));
}
}
//voice recognition
let lang = 'en-US';
let speechRec = new p5.SpeechRec(lang, gotSpeech);
let continuous = true;
let interim = false;
speechRec.start(continuous, interim);
//text-to-speach
speech = new p5.Speech();
speech.onLoad = voiceReady;
function voiceReady() {
console.log('voice ready');
}
//input-ouput
function gotSpeech() {
if (speechRec.resultValue) {
var p = createP(speechRec.resultString);
p.class('myMessage');
}
markovIt();
chooseVoice();
speech.speak(answer);
}
}
and
function markovIt() {
var currentGram = random(beginnings);
var result = currentGram;
for (var i = 0; i < 100; i++) {
var possibilities = ngrams[currentGram];
if (!possibilities) {
break;
}
var next = random(possibilities);
result += next;
var len = result.length;
currentGram = result.substring(len - order, len);
}
var answer = result;
window.answer = answer;
var p2 = createP(answer);
p2.class('robotMessage');
}
how the HTML looks
<div class="container">
<div class="myMessage"></div>
<div class="robotMessage"></div>
</div>
Use select() to get a document element by its id, class, or tag name. e.g:
let my_div = select("myMessage");
Change the style of an element by style().
e.g hide:
my_div.style("display", "none");
e.g. show:
my_div.style("display", "block");
See also Toggle Hide and Show

Change selected files in input element with JQuery

I need to change selected files in input:file element with Jquery. Firstly, user select files. There is a file size control in input:file change event. So, if control return false selected file should be removed in file_list. I searched this and try something for 3 - 4 hours. But not achieved still. I hope someone can help me.
Here is my function.
function handleFiles2() {
var names = [];
var newList = [];
var text = '';
var x = 0;
var fsize = 0;
var files = $(".fileUpBasvuru").get(0).files;
for (var i = 0; i < files.length; ++i) {
fsize = parseInt(files[i].size);
if (fsize > 102400) {
newList.push(files.item(i));
names.push(files[i].name);
}
}
$(".fileUpBasvuru").get(0).files = newList;
$(".file_list").html(text);
};

Categories

Resources