It is not possible for me to restore a previously deleted element from the table

                <table class="files-table table">
                <thead>
                    <th>Filename</th>
                    <th>Type</th>
                    <th>Status</th>
                    <th onclick="sortTableByDate()">
                        Date
                        <i
                            class="fa-solid fa-angle-down"
                            ,
                            style="
                                font-size: 12px;
                                color: white;
                                height: 0;
                                margin-top: 0 !important;
                            "
                        ></i>
                    </th>
                    <th></th>
                </thead>
                <tbody></tbody>
            </table>
            <div class="add-table-row d-flex justify-content-end">
                <label for="tableFiles" class="choose-file-btn">
                    <span>Add Files</span>
                </label>
                <input
                    type="file"
                    id="tableFiles"
                    style="display: none"
                    multiple
                    onchange="handleFiles(this.files)"
                />
            </div>

The table was constructed here, with data appearing under corresponding table headers when files are added using the "Add Files" button.

<script>
    function handleFiles(files) {
        const tbody = document.querySelector(".files-table tbody");

        for (const file of files) {
            const fileName = file.name;

            const isDuplicate = Array.from(tbody.rows).some(
                (row) => row.cells[0].textContent === fileName
            );

            if (!isDuplicate) {
                const row = tbody.insertRow();
                const filenameCell = row.insertCell(0);
                const typeCell = row.insertCell(1);
                const statusCell = row.insertCell(2);
                const dateCell = row.insertCell(3);
                const deleteCell = row.insertCell(4);

                filenameCell.textContent = fileName;
                typeCell.textContent = getFileType(file.type);
                statusCell.textContent = "Pending";

                const currentDate = new Date();
                const formattedDate = currentDate.toISOString().split("T")[0];
                dateCell.textContent = formattedDate; // Date only

                // Add delete icon to the last cell
                const deleteIcon = document.createElement("i");
                deleteIcon.className = "fa-regular fa-trash-can";
                deleteIcon.style.color = "#d90000";
                deleteIcon.addEventListener("click", function () {
                    deleteRow(this);
                });
                deleteCell.appendChild(deleteIcon);
            }
        }

        checkIconVisibility();
    }

    function getFileType(fileType) {
        return fileType || "Unknown Type";
    }

    function handleDragOver(event) {
        event.preventDefault();
        const dragContainer = document.getElementById("drag-drop-container");
    }

    function handleDrop(event) {
        event.preventDefault();
        const dragContainer = document.getElementById("drag-drop-container");

        const files = event.dataTransfer.files;
        handleFiles(files);
    }

    function deleteRow(icon) {
        const row = icon.closest("tr");
        row.parentNode.removeChild(row);
        checkIconVisibility();
    }
</script>

Through this script, I populated the table with the selected file's name under "Filename", the upload date under "Date", and the file type under "Type". A delete icon was included at the end of each table row.

All functions are operational, however, a noteworthy issue arises. If a file named x.png is uploaded and then deleted, it cannot be re-uploaded. But if a different file, let's say z.png, is uploaded, then x.png can be re-uploaded. The ability to directly re-upload a previously deleted file is inaccessible. This poses a limitation on re-adding the last deleted file.

Answer №1

Your current issue arises from the fact that the handleFiles() function is connected to the <input> element using the change event through the onchange attribute. The event triggers when the value of the <input> element changes, but selecting the same file does not alter the value, as it remains the same.

To solve this, you can reset the <input> value to empty after the handleFiles() function runs by setting .value = ''.

const checkIconVisibility = () => {};

function handleFiles(files) {
  const tbody = document.querySelector(".files-table tbody");

  for (const file of files) {
    const fileName = file.name;

    const isDuplicate = Array.from(tbody.rows).some(
      (row) => row.cells[0].textContent === fileName,
    );

    if (!isDuplicate) {
      const row = tbody.insertRow();
      const filenameCell = row.insertCell(0);
      const typeCell = row.insertCell(1);
      const statusCell = row.insertCell(2);
      const dateCell = row.insertCell(3);
      const deleteCell = row.insertCell(4);

      filenameCell.textContent = fileName;
      typeCell.textContent = getFileType(file.type);
      statusCell.textContent = "Pending";

      const currentDate = new Date();
      const formattedDate = currentDate.toISOString().split("T")[0];
      dateCell.textContent = formattedDate; // Only the date

      // Add delete icon to the last cell
      const deleteIcon = document.createElement("i");
      deleteIcon.className = "fa-regular fa-trash-can";
      deleteIcon.style.color = "#d90000";
      deleteIcon.addEventListener("click", function () {
        deleteRow(this);
      });
      deleteCell.appendChild(deleteIcon);
    }
  }

  checkIconVisibility();
  
}

function getFileType(fileType) {
  return fileType || "Unknown Type";
}

function handleDragOver(event) {
  event.preventDefault();
  const dragContainer = document.getElementById("drag-drop-container");
}

function handleDrop(event) {
  event.preventDefault();
  const dragContainer = document.getElementById("drag-drop-container");

  const files = event.dataTransfer.files;
  handleFiles(files);
}

function deleteRow(icon) {
  const row = icon.closest("tr");
  row.parentNode.removeChild(row);
  checkIconVisibility();
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<table class="files-table table">
  <thead>
    <th>Filename</th>
    <th>Type</th>
    <th>Status</th>
    <th onclick="sortTableByDate()">
      Date
      <i
        class="fa-solid fa-angle-down"
        ,
        style="
          font-size: 12px;
          color: white;
          height: 0;
          margin-top: 0 !important;
        "
      ></i>
    </th>
    <th></th>
  </thead>
  <tbody></tbody>
</table>
<div class="add-table-row d-flex justify-content-end">
  <label for="tableFiles" class="choose-file-btn">
    <span>Add Files</span>
  </label>
  <input
    type="file"
    id="tableFiles"
    style="display: none"
    multiple
    onchange="handleFiles(this.files); this.value = ''"
  />
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Displaying a list of values in Angular using data retrieved from an Entity Framework query

Is there a way to populate a list (ul li) with data from an array that is populated through Entity Framework code? Currently, I am able to populate an option dropdown successfully using the following code: <select class="form-control" name="Search" ...

Issue with Angular's ngOnChanges Lifecycle Hook Preventing Function ExecutionWhen attempting to run a function within Angular's ngOn

In the midst of my evaluation process to ensure that specific values are properly transmitted from one component to another using Angular's custom Output() and EventEmitter(), I am encountering some issues. These values are being sent from the view of ...

Understanding how to display a component within another component in Vue.js

I am faced with a scenario where I have a component that has the following template: <div v-for:"item in store" v-bind:key="item.type"> <a>{{item.type}}</a> </div> Additionally, I have another component named 'StoreCompone ...

Arranging elements within a div using inline positioning

Currently, I am trying to arrange elements within a div. Below is the div that needs positioning: https://i.sstatic.net/5nZUt.jpg This is the desired layout: https://i.sstatic.net/vXSV9.jpg Here is the HTML and CSS code snippet: #channel-header * { ...

Can you explain the HTML semantic layout for having multiple titles matched with their respective lists?

In my directional segment, I have included details such as the address, phone number, email, and service date/time. I envision it looking like the example below: https://i.sstatic.net/5h4SM.jpg Currently, my code appears as follows: <div class="co ...

What is the best way to locate an element in the HTML content that contains the class 'sponsored-post'?

This code snippet is flawed as it assigns 'none' to the variable article, even though the variable articles contains all the listing results. articles = soup.select('.listingResult') for article in articles: # <div class=&qu ...

Filtering out undefined elements from an array created by mapping over a nested array using map() and filter()

I'm currently in the process of creating multiple variables to be utilized later on, each one representing a specific array within a set of nested arrays (essentially a data array that will be used for various projects). As I attempt to select the pr ...

Routes are no longer being qualified by Express once a subdomain is incorporated

We had developed a compact app that was working flawlessly, but then we were tasked with transforming it into something accessible for others in our organization to utilize... and that led to everything breaking down. Our initial setup included a simple ex ...

The checkboxes seem to be malfunctioning following an ajax request

I've been attempting to utilize ajax to load data, but for some reason the checkboxes aren't functioning. Below is the HTML I'm trying to load via ajax: <div class="mt-checkbox-list" > <?php foreach($product_offerings as $row){ $c ...

Is the accuracy of the in-situ convolution filter guaranteed?

After analyzing my simple box blur function, I have come to the realization that it may be incorrect. The current implementation edits the ImageData object in place, leading to convolution filters depending on surrounding pixels that have already been ch ...

Looking to retrieve the key value or iteration of a specific item within an Angular UI tree?

Here is a snippet of code showcasing how to use angular-ui-tree: <div ui-tree> <ol ui-tree-nodes="" ng-model="list"> <li ng-repeat="item in list" ui-tree-node> <div ui-tree-handle> {{item.title}} </div& ...

The header cannot be adjusted once it has been sent to the client

Encountering an issue where I receive the error message "Can't set the header after they are sent to client" when the incoming request lacks basic authentication and jwt token. This error occurs because I am unable to prevent node.js from executing t ...

Choosing the Right Project for Developing HTML/Javascript Applications in Eclipse

Whenever I attempt to build a webpage using eclipse, I am presented with two choices: -- A Javascript project -- A Static web project If I opt for the former, setting up run to open a web browser can be quite challenging. If I decide on the latter ...

Having trouble accessing the inline transform scale with jQuery

I am working on a new feature where I need to extract the inline transform scale value from each list item (li). Below is a demonstration for you to assist me: HTML <div style="color:red;transform:scale(1);">Dummy content</div> JS $(functi ...

How to send parameters to the jquery .css() method

I'm attempting to create hyperlinks that can dynamically set inline styles for different elements on a webpage. I have managed to save the element and attribute settings in hidden span elements and retrieve them to display in an alert dialog. However, ...

Select the five previous siblings in reverse order using jQuery's slice method

I have a unique approach to displaying a series of divs where only 5 are shown at a time using the slice() method. To navigate through the items, I include an ellipsis (...) link after every 4th item, which allows users to easily move on to the next set of ...

Is it possible to modify the button icon on hover by utilizing chakra-ui and vanilla-extract?

My stack includes nextjs13, chakra-ui, and vanilla-extract Seeking guidance on how to update both icon and text within a button upon hover, utilizing chakra-ui and vanilla-extract. The current setup of my button is as follows: <Button > <svg wi ...

Disable the moving of the DIV button with a left-margin of 0px

Having a bit of a challenge here. I'm attempting to craft my own slider using jQuery along with some css and javascript. I've managed to get my slider functioning, moving a Div 660px to the left and right upon button clicks. However, I'm h ...

The bootstrap navbar dropdown feature isn't functioning properly on iPhones

Currently utilizing "bootstrap": "~3.3.4" within the mean.js framework, I am facing an issue with the navbar dropdown menu. On desktop, everything functions as expected - the dropdown opens and remains open when the icon is clicked. However, once deployed ...

Jasmine examination fails to progress to the subsequent segment of the promise

I want to test a specific function: function initializeView() { var deferred = $q.defer(); if(this.momentArray) { core.listMoments(constants.BEST_MOMENT_PREFIX, '').then(function(moments) { //Ommit ...