Modifying User Properties

In this chapter we’re going to add a few elements and an event handler to the client to allow the user to modify their name and password.  To accomplish this we’re going to use a bootstrap and the following process:

  1. Add bootstrap <meta> and <link> tags to the <head> and a <script> tag to the <body> of our main page.
  2. Create a partials hbs template file that contains a bootstrap modal and include that modal in the main page’s hbs template file.  This will load the modal, though not initially displayed, in the DOM when the main page is loaded.
  3. Add a modify account menu item in the user menu.  We include two special attributes in the menu item to cause the modal to be unhidden when the user clicks on the menu item.
  4. Register a click event handler so that when the Save button in the modal is pressed, the form data is sent in a request to the API server, a result statement is displayed on the screen, the modal is hidden, and the form is cleared.

Let’s get started.

Load Bootstrap CSS and JS Files

If you haven’t already, add the appropriate boostrap <meta> and <link> elements in the head of your main hbs template file so that the bootstrap CSS file loads when your main page is loaded by the browser.  In addition, add the appropriate bootstrap <script> tag right before the closing </body> tag in your main hbs template file to load the bootstrap JavaScript file.

Create Modal Partials File

Create a file named modify-account-modal.hbs in your templates/partials directory and copy the following bootstrap code to the new file.

Notice that we have ids for the outermost modal div (modifyAccountModal), the form inside modal-body (modifyAccountForm), the inputs inside the form (nameInput and passwordInput), and the save button (modifyAccountModalSaveButton).  All of these elements are referenced in the JavaScript code.

<div class="modal fade" id="modifyAccountModal" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Modify Account Information</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <form id="modifyAccountForm">
                <div class="mb-3">
                    <label for="nameInput" class="form-label">Name</label>
                    <input type="text" class="form-control" id="nameInput">
                </div>
                <div class="mb-3">
                    <label for="passwordInput" class="form-label">Password</label>
                    <input type="password" class="form-control" id="passwordInput">
                </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                <button id="modifyAccountModalSaveButton" type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div>
    </div>
</div>

Load Modal in Main Template

In your main page’s hbs template file, load the modal by adding the following line after the <body> element.  The modal is initially hidden, but will be made visible later when the user chooses to modify their account.

 {{>modify_account_modal}}

Link Menu Item to Modal

Recall that the modal has an id attribute set to modifyAccountModal.  Add a “Modify Account” entry to your user menu and include data-bs-toggle and data-bs-target attributes in the menu element.  These attributes (along with the boostrap JavaScript code) make the modal visible when the user clicks the menu item.  The data-bs-toggle property causes bootstrap to toggles (unhide) the modal having the id specified in the data-bs-target property (modifyAccountModal).

My menu is a boostrap drop down, so my menu item looks as follows.

 <li><div class="dropdown-item" data-bs-toggle="modal" data-bs-target="#modifyAccountModal">Modify Account</div></li>

Add Modal Button Event Handler

In public/js/user.js, we need get the modal’s Save button node and register a click event handler for the button.  The event handler will retrieve the user data from the form, submit the data to the API server, display a message to the user depending on the response, hide the modal, and clear the form.  Please copy the following code into user.js and review it carefully.

const modifyAccountModalSaveButton = document.querySelector("#modifyAccountModalSaveButton")
...
modifyAccountModalSaveButton.addEventListener("click", async(e) => {
    e.preventDefault()

    const token = localStorage.getItem("token")

    const url = "http://localhost:3001/users/me"
        //const url = 'https://n0code-web-api-4.herokuapp.com/users/me'

    const nameInput = document.querySelector("#nameInput")
    const passwordInput = document.querySelector("#passwordInput")
    const name = nameInput.value
    const password = passwordInput.value
    const requestData = {...name && { name }, ...password && { password } }
    //console.log(requestData)

    const options = {
        method: "PATCH",
        headers: {
            Authorization: `Bearer ${token}`,
            "Content-Type": "application/json",
        },
        body: JSON.stringify(requestData),
    }

    let response = await fetch(url, options)

    if (response.status === 200) {
        const contentArea = document.querySelector("#contentArea")
        contentArea.innerHTML = `Saved successful.`
    } else {
        console.log("HTTP-Error: " + response.status)
    }

    const modal = document.querySelector("#modifyAccountModal")
    bootstrap.Modal.getInstance(modal).hide()

    const form = document.querySelector("#modifyAccountForm").reset()
})

Test the Client

Test the client with the client on localhost and the API server on heroku.  Make sure that the fetch URLs in public/js/login.js, public/js/create-account.js, and public/js/main all point to your heroku API server. If you suspect there is an issue with the API server, you may have to power up your API server locally (changing all of the URLs in the client to localhost) so that you can see the output of console.log() statements placed in the API server code.

Push to Heroku

When satisfied that the client works, push to heroku and test.

© 2022 – 2024, Eric McGregor. All rights reserved. Unauthorized use, distribution and/or duplication of this material without express and written permission from the author is strictly prohibited.