Home > other >  Adding a Form into My HTML Keeps Function in Javascript File from Working
Adding a Form into My HTML Keeps Function in Javascript File from Working

Time:08-05

For some inexplicable reason, whenever I add <form></form> around the three lines above the blockquote, the text inside the blockquote stops being replaced with the text returned from the flask server. I don't have any problem that needs to be solved, as I can easily work around this. I am just curious as to why this issue exists in the first place.

HTML:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="{{ url_for('static', filename='CSSsheets/SBPstyle.css') }}" />
    <title></title>
</head>
<body>
    <input id="expertiseReq" placeholder="leave blank for any skill level" />
    <input id="locationReq" placeholder="leave blank for any location" />
    <button id="gatherNames">Click to Get List of Player Names</button> 
    <blockquote id="playerNamesGoHere" >No Player Names Loaded</blockquote>
    <script src="{{ url_for('static', filename='JSscripts/SBPscript.js') }}"></script>
</body>
</html>

CSS:

.properly_sized_blockquote {
    border: solid;
    border-block-width: 20px;
    height: 600px;
    width: 150px;
}

JavaScript:

const gatherPlayersButton = document.getElementById('gatherNames');
const areaForPlayerNames = document.getElementById('playerNamesGoHere')
const summon_players = () => {
    let eR
    let lR
    if (document.getElementById('expertiseReq').value == "") {
        eR = "None";
    } else {
        eR = document.getElementById('expertiseReq').value
    };
    if (document.getElementById('locationReq').value == "") {
        lR = "None";
    } else {
        lR = document.getElementById('locationReq').value
    };
    let tagsString = eR   ","   lR;
    fetch(`/battle?tags=${tagsString}`, { method: "GET" }).then((response) => response.text()).then((text) => {
        areaForPlayerNames.innerText = text;
    });
};

gatherPlayersButton.addEventListener("click", () => summon_players());

Flask Server:

from flask import Flask, render_template, request
from static.SNEKfiles import SpaceShipGame
import json


game_app = Flask(__name__)

@game_app.route('/') 
@game_app.route('/home')
def home():
    return render_template("HTMLPage1.html")

@game_app.route('/battle', methods=['GET', 'POST'])
def battle():
    if request.method == 'GET':
        gathering_player_requirements = request.args.get('tags')
        if gathering_player_requirements != None:
            print(gathering_player_requirements)
            skill_requirement = gathering_player_requirements.split(",")[0]
            location_requirement = gathering_player_requirements.split(",")[1]
            gathering_player = SpaceShipGame.Player()
            gathered_player_names = gathering_player.obtainAllPlayerNames(skill_requirement, location_requirement)
            return gathered_player_names
        else:
            return render_template("SingleBattlePage.html")

CodePudding user response:

Buttons default to type="submit". When you add the <form>, the button suddenly has a form to submit in addition to triggering its click handler.

Consider:

document.querySelector("form")
  .addEventListener("submit", e => {
    e.preventDefault();
    console.log("form submitted");
  });

document.querySelectorAll("button")
  .forEach(e =>
    e.addEventListener("click", e =>
      console.log("button clicked")
    )
  );
form {
  background: red;
  padding: 1em;
  margin-bottom: 1em;
}
<form>
  <button>Submit and trigger click</button>
</form>

<button>Outside of form--just click</button>

While it's not clear what your <form> element you added looks like (what are its method and action attributes?), it sounds like you just want some clarity on the scenario, so hopefully this is sufficient. Adding type="button" to the button will prevent it from triggering the form submission, so whatever your behavior was before should be unaltered.

document.querySelector("form")
  .addEventListener("submit", e => {
    e.preventDefault();
    console.log("form submitted");
  });

document.querySelectorAll("button")
  .forEach(e =>
    e.addEventListener("click", e =>
      console.log("button clicked")
    )
  );
form {
  background: red;
  padding: 1em;
  margin-bottom: 1em;
}
<form>
  <button type="button">
    Inside of form--trigger click only since type="button" was added
  </button>
</form>

<button>Outside of form--just click</button>

See Button Type In HTML: Here's Why You Should Always Declare It for details.


A few other suggestions for reducing your code smell and adhering to best practices:

  • Use kebab-case for CSS classes and ids (or at least be consistent).
  • Use camelCase for JS functions and variables.
  • Use snake_case for Python functions and variables.
  • Avoid injecting script snippets inline throughout the template. Use modules if possible and load the script(s) at the end of the document. This keeps the HTML and JS separate and ensures the DOM is loaded fully before you begin manipulating it. All of this should make debugging easier.
  • Use closures around your scripts to prevent variable name clashes.
  • Avoid let when you can refactor to const. const provides stronger guarantees of reassignment and generally makes the logic easier to understand and debug.
  • Use === instead of == to avoid weird false positives due to type coercion.
  • Avoid building query string payloads with concatenation or other custom delimiters: let tagsString = eR "," lR;. Use something like encodeURIComponent into separate parameters or switch the route to a POST and use a JSON payload. If the user provides a comma, your code will likely misbehave.
  • Check the response from all fetch calls to make sure it was OK and handle any errors if it wasn't.
  • Folders, files and HTML pages should be lowercase.
  • Related