Search code examples
javascripthtmlfetchdom-eventssubmit

Remove Specific HTML Component After Successful Response With JavaScript Fetch API


I have an image component where the user has the option to delete the component (basically the image). The deletion in the MySQL database is handled by PHP, and I use the JavaScript fetch() API on form submission so that no hard refresh happens on the page when this happens. All of this works OK.

The Problem

The issue I have is there will virtually always be multiple instances of the component in the form, so after the fetch happens I obviously only want to remove the specific component that is tied to its related delete button. To do this I understand I need to use the remove() method on the component/HTML.

Normally with events such as click I would use something like e.target.closest('.element').querySelector('.child-element') but the issue I have is I need to link the remove() method to the e.submitter event, because I only want to remove that specific component that is linked to its delete button, and I want to do this after getting a 200 response to show the deletion happened in the database.

In the javascript below, the specific button used on delete submission is referenced using e.submitter, but I guess I need to find a way of storing that as a variable that I can then use in the if(response.status === 200) {} line of code ?

JavaScript

const forms = document.querySelectorAll('.upload-form-js'),
uploadDetailsComponent = document.querySelectorAll('.upload-details-component')

// URL details
const myURL = new URL(window.location.href),
pagePath = myURL.pathname

if (forms) {
    forms.forEach((form) => {
        form.addEventListener('submit', function (e) {
            e.preventDefault();
            
            const formData = new FormData(this);
        
            if (e.submitter) {
                formData.set(e.submitter.name, e.submitter.value);
            }
        
            fetch(pagePath, {
                method: "post",
                body: formData
            })
                .then(function(response){
                return response.text(); // stops hard refresh of the page
            })
                .catch((e) => console.error(e));
        });

        if(response.status === 200) {

            // remove the specific component linked to the 'submit' event using the 'remove()' method

        }

    });
} // end of if (forms)

HTML There are multiple instances of the image component inside the form. In the HTML below I've just shown two instances

<section>
    <form class="upload-form-js" enctype="multipart/form-data" method="post">
        <div class="upload-details-component">
            <div class="image-wrapper">
                <img src="image.jpg" alt="image">
            </div>
            <button type="submit" name="delete" title="delete" value="12" class="dl-button">Delete</button>
            <input type="hidden" name="image-id" value="12">
        </div>
        <div class="upload-details-component">
            <div class="image-wrapper">
                <img src="image.jpg" alt="image">
            </div>
            <button type="submit" name="delete" title="delete" value="13" class="dl-button">Delete</button>
            <input type="hidden" name="image-id" value="13">
        </div>
    </form>
</section>

Solution

  • You can use the closest() method for finding the image componenet closest to the button returned by e.submitter.

    const forms = document.querySelectorAll('.upload-form-js'),
        uploadDetailsComponent = document.querySelectorAll('.upload-details-component')
        
        // URL details
        const myURL = new URL(window.location.href),
        pagePath = myURL.pathname
        
        if (forms) {
            forms.forEach((form) => {
                form.addEventListener('submit', function (e) {
                    e.preventDefault(); // this stops hard refresh of the page
                    
                    const formData = new FormData(this);
                
                    if (e.submitter) {
                        formData.set(e.submitter.name, e.submitter.value);
                    }
                
                    fetch(pagePath, {
                        method: "post",
                        body: formData
                    })
                        .then(function(response){
                          // you already have the response at this point. 
                          // Give a callback if required.
                          if(response.status === 200) {
                            // remove the specific component linked to the 'submit' event using the 'remove()' method. 
                            // 'closest()' will go up the DOM hierarchy 
                            e.submitter.closest('.upload-details-component').remove()
                          }
                          return response.text(); 
                    })
                        .catch((e) => console.error(e));
                });
            });
        } // end of if (forms)