0

I'm still very new to Javascript and I had a question pertaining to creating an alert at the top of my page once an API call is made. I would like an alert to be created once a form is submitted. However I am having a few problems, notably the form is refreshing my page even though I have my form's onSubmit coupled with a function which returns false. Furthermore, I am not even sure if this is the correct approach if I would like my user to be able to resubmit the form without refreshing the page. Anything helps thank you.

document.addEventListener('DOMContentLoaded', function() {

  // Use buttons to toggle between views
  document.querySelector('#inbox').addEventListener('click', () => load_mailbox('inbox'));
  document.querySelector('#sent').addEventListener('click', () => load_mailbox('sent'));
  document.querySelector('#archived').addEventListener('click', () => load_mailbox('archive'));
  document.querySelector('#compose').addEventListener('click', compose_email);

  // By default, load the inbox
  load_mailbox('inbox');
});

function compose_email() {

  // Show compose view and hide other views
  document.querySelector('#emails-view').style.display = 'none';
  document.querySelector('#compose-view').style.display = 'block';

  // Clear out composition fields
  document.querySelector('#compose-recipients').value = '';
  document.querySelector('#compose-subject').value = '';
  document.querySelector('#compose-body').value = '';

  document.querySelector("#compose-form").onsubmit = () => {

    const message = document.createElement("div")
    const recipients = document.querySelector('#compose-recipients').value;
    const subject = document.querySelector('#compose-subject').value;
    const body = document.querySelector('#compose-body').value;

    
     fetch("/emails", {
       method: "POST",
       body: JSON.stringify({
         recipients: recipients,
         subject: subject,
         body: body
       })
     })
     .then(response => response.json())
     .then(successMessage => {
       message.innerHTML = successMessage["message"]
       message.className = "alert alert-success";
     })
     .catch(errorMessage => {
       message.innerHTML = errorMessage["error"]
       message.className = "alert alert-danger";
     })
     .finally(() => {
       insertAfter(message, document.getElementById("hr"))
       })

    
    return false;
  }

}

function insertAfter(newNode, referenceNode) {
  referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}

Here's the HTML:

<button class="btn btn-sm btn-outline-primary" id="inbox">Inbox</button>
    <button class="btn btn-sm btn-outline-primary" id="compose">Compose</button>
    <button class="btn btn-sm btn-outline-primary" id="sent">Sent</button>
    <button class="btn btn-sm btn-outline-primary" id="archived">Archived</button>
    <a class="btn btn-sm btn-outline-primary" href="{% url 'logout' %}">Log Out</a>
    <hr>

    <div id="emails-view">
    </div>

    <div id="compose-view">
        <h3>New Email</h3>
        <form id="compose-form">
            <div class="form-group">
                From: <input disabled class="form-control" value="{{ request.user.email }}">
            </div>
            <div class="form-group">
                To: <input id="compose-recipients" class="form-control">
            </div>
            <div class="form-group">
                <input class="form-control" id="compose-subject" placeholder="Subject">
            </div>
            <textarea class="form-control" id="compose-body" placeholder="Body"></textarea>
            <input type="submit" class="btn btn-primary"/>
        </form>
    </div>
Alejandro Armas
  • 308
  • 1
  • 2
  • 10

1 Answers1

0

You need to set the event listener outside of a function block and call the compose_email function inside that event listener.

document.addEventListener('DOMContentLoaded', function() {

  // Use buttons to toggle between views
  document.querySelector('#inbox').addEventListener('click', () => load_mailbox('inbox'));
  document.querySelector('#sent').addEventListener('click', () => load_mailbox('sent'));
  document.querySelector('#archived').addEventListener('click', () => load_mailbox('archive'));
  document.querySelector('#compose').addEventListener('click', compose_email);

  // By default, load the inbox
  load_mailbox('inbox');
});

function compose_email() {
  // Show compose view and hide other views
  document.querySelector('#emails-view').style.display = 'none';
  document.querySelector('#compose-view').style.display = 'block';

  // Clear out composition fields
  document.querySelector('#compose-recipients').value = '';
  document.querySelector('#compose-subject').value = '';
  document.querySelector('#compose-body').value = '';

  const message = document.createElement("div")
  const recipients = document.querySelector('#compose-recipients').value;
  const subject = document.querySelector('#compose-subject').value;
  const body = document.querySelector('#compose-body').value;


  fetch("/emails", {
      method: "POST",
      body: JSON.stringify({
        recipients: recipients,
        subject: subject,
        body: body
      })
    })
    .then(response => response.json())
    .then(successMessage => {
      message.innerHTML = successMessage["message"]
      message.className = "alert alert-success";
    })
    .catch(errorMessage => {
      message.innerHTML = errorMessage["error"]
      message.className = "alert alert-danger";
    })
    .finally(() => {
      insertAfter(message, document.getElementById("hr"))
    })

}



document.querySelector("#compose-form").onsubmit = (e) => {
  event.preventDefault();
  compose_email();
}

function insertAfter(newNode, referenceNode) {
  referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
<button class="btn btn-sm btn-outline-primary" id="inbox">Inbox</button>
<button class="btn btn-sm btn-outline-primary" id="compose">Compose</button>
<button class="btn btn-sm btn-outline-primary" id="sent">Sent</button>
<button class="btn btn-sm btn-outline-primary" id="archived">Archived</button>
<a class="btn btn-sm btn-outline-primary" href="{% url 'logout' %}">Log Out</a>
<hr>

<div id="emails-view">
</div>

<div id="compose-view">
  <h3>New Email</h3>
  <form id="compose-form">
    <div class="form-group">
      From: <input disabled class="form-control" value="{{ request.user.email }}">
    </div>
    <div class="form-group">
      To: <input id="compose-recipients" class="form-control">
    </div>
    <div class="form-group">
      <input class="form-control" id="compose-subject" placeholder="Subject">
    </div>
    <textarea class="form-control" id="compose-body" placeholder="Body"></textarea>
    <input type="submit" class="btn btn-primary" />
  </form>
</div>
Harshana
  • 5,151
  • 1
  • 17
  • 27