I have a button which adds a player to the program, this is done in HTML. I would like this button to render a new partial template when the player is submitted. This is currently not happening even though the code is reaching this point. The jQuery is working fine and sending the correct data through, the code is just not rendering the new template. Any help would be great thanks.
Go code:
package main
import (
"html/template"
"log"
"net/http"
"strings"
)
type playerType struct {
Fname string
Lname string
// Men are true and Women are false
Gender bool
}
var players []playerType
var templates *template.Template
func handleFilePath() {
http.Handle("/templates/", http.StripPrefix("/templates/", http.FileServer(http.Dir("templates"))))
http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets"))))
//templates = template.Must(template.ParseFiles("./templates/index.html", "./templates/displayPlayer.html"))
templates = template.Must(template.New("").ParseGlob("./templates/*.html"))
}
func landingPage(w http.ResponseWriter, r *http.Request) {
err := templates.ExecuteTemplate(w, "home", nil)
if err != nil {
log.Panicln(err)
return
}
}
func addPlayerHandler(w http.ResponseWriter, r *http.Request) {
Fname := r.FormValue("fname")
Lname := r.FormValue("lname")
Gender := r.FormValue("gender")
if addPlayer(Fname, Lname, Gender) {
log.Printf("Player added: %v, %v, %v", Fname, Lname, Gender)
err := templates.ExecuteTemplate(w, "displayPlayer", players[0])
if err != nil {
log.Panicln(err)
return
}
}
}
func addPlayer(Fname string, Lname string, Gender string) bool {
if Fname == "" || Lname == "" || Gender == "" {
return false
}
var playerToBeAdded playerType
// Set men to true and women to false
if strings.ToLower(Gender) == "male" {
playerToBeAdded = playerType{Fname, Lname, true}
} else {
playerToBeAdded = playerType{Fname, Lname, false}
}
players = append(players, playerToBeAdded)
return true
}
func main() {
handleFilePath()
http.HandleFunc("/", landingPage)
log.Println("Listening...")
http.HandleFunc("/addPlayer", addPlayerHandler)
err := http.ListenAndServe(":8081", nil)
if err != nil {
log.Panicln(err)
}
}
HMTL Templates: index.html:
{{ define "home" }}
<head xmlns="http://www.w3.org/1999/html">
<meta charset="UTF-8">
<link rel="stylesheet" href="/assets/home.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<title>Home - Match Maker</title>
</head>
<body>
<script src="/assets/home.js"></script>
<!-- Button to open the modal login form -->
<button onclick="document.getElementById('id01').style.display='block'" class="addPlayer">Add Player</button>
<button onclick="generateGames()">Generate Games</button>
</br>
{{ template "displayPlayer" .}}
</br>
<!-- The Modal -->
<div id="id01" class="modal">
<form class="modal-content animate" action="/" method="post">
<div class="imgcontainer">
<span onclick="document.getElementById('id01').style.display='none'" class="close" title="Close Modal">×</span>
<img src="/assets/be.png" alt="Avatar" class="avatar">
</div>
<div class="container">
<label for="fname" style="align-content: center"><b>First Name</b></label>
<input type="text" placeholder="John" name="firstName" required>
<label for="lname" style="align-content: center"><b>Last Name</b></label>
<input type="text" placeholder="Smith" name="lastName" required>
</div>
<div class="container">
Select Gender:
</br>
<label>
<input type="radio" name="gender" value="male" required>Male
</label>
</br>
<label>
<input type="radio" name="gender" value="female">Female
</label>
</div>
<div class="container" style="background-color:#f1f1f1; text-align: center">
<button type="button" onclick="document.getElementById('id01').style.display='none'" class="modelButtons">
Cancel
</button>
<button id="subbtn" type="submit" class="modelButtons"
onclick="submitPlayer(firstName.value, lastName.value, gender.value)">Submit
</button>
</div>
</form>
</div>
<script>
// Get the modal
var modal = document.getElementById('id01');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
</body>
</html>
{{ end }}
displayPlayer.html:
{{ define "displayPlayer" }}
<html lang="en">
<body>
{{ .Fname }}
</br>
{{ .Lname }}
</br>
{{ .Gender }}
</body>
</html>
{{ end }}
Javascript:
home.js:
function submitPlayer(fname, lname, gender) {
if (fname == "" || lname == "" || gender == "") {
return;
}
$.ajax({
url: '/addPlayer',
method: 'post',
data: {
fname: fname,
lname: lname,
gender: gender,
},
success: (d) => {
console.log("Player Added");
},
error: (d) => {
console.log("An error occurred. Please try again");
}
});
}
function generateGames() {
$.ajax({
url: '/createGames',
method: 'post',
success: (d) => {
console.log("Generated Games");
},
error: (d) => {
console.log("An error occurred. Please try again");
}
});
}
CodePudding user response:
- Moved home.js down at the end so js loads after html content are loaded to DOM.
- Added table with players id to add data returned by
addPlayers
- removed
submitPlayer
- added
onSubmit
to form so we can prevent page from reloading because as soon we submit form the page reloads causes to lose data returned byaddPlayer
index.html
{{ define "home" }}
<head xmlns="http://www.w3.org/1999/html">
<meta charset="UTF-8">
<link rel="stylesheet" href="/assets/home.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<title>Home - Match Maker</title>
</head>
<body>
<!-- Button to open the modal login form -->
<button onclick="document.getElementById('id01').style.display='block'" class="addPlayer">Add Player</button>
<button onclick="generateGames()">Generate Games</button>
</br>
{{ template "displayPlayer" .}}
</br>
<!-- The Modal -->
<div id="id01" class="modal">
<form class="modal-content animate" action="/" method="post" onsubmit="return onSubmit(event);">
<div class="imgcontainer">
<span onclick="document.getElementById('id01').style.display='none'" class="close" title="Close Modal">×</span>
<img src="/assets/be.png" alt="Avatar" class="avatar">
</div>
<div class="container">
<label for="fname" style="align-content: center"><b>First Name</b></label>
<input type="text" placeholder="John" name="firstName" required>
<label for="lname" style="align-content: center"><b>Last Name</b></label>
<input type="text" placeholder="Smith" name="lastName" required>
</div>
<div class="container">
Select Gender:
</br>
<label>
<input type="radio" name="gender" value="male" required>Male
</label>
</br>
<label>
<input type="radio" name="gender" value="female">Female
</label>
</div>
<div class="container" style="background-color:#f1f1f1; text-align: center">
<button type="button" onclick="document.getElementById('id01').style.display='none'" class="modelButtons">
Cancel
</button>
<button id="subbtn" type="submit" class="modelButtons">Submit
</button>
</div>
</form>
<div>
<table id="players"></table>
</div>
</div>
<script src="/assets/home.js"></script>
<script>
// Get the modal
var modal = document.getElementById('id01');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
</body>
</html>
{{ end }}
- Updated displayPlayer.html to table row format so we can add it to table.
displayPlayer.html
{{ define "displayPlayer" }}
<tr>
<td>
{{ .Fname }}
</td>
<td>
{{ .Lname }}
</td>
<td>
{{ .Gender }}
</td>
{{ end }}
- function to send form data to
addPlayer
api
home.js
var players = document.querySelector('#players');
function onSubmit(evt) {
evt.preventDefault()
let form = evt.target;
let formData = new FormData(form);
let fname = formData.get('firstName');
let lname = formData.get('lastName');
let gender = formData.get('gender');
if (fname != "" || lname != "" || gender != "") {
$.ajax({
url: '/addPlayer',
method: 'post',
data: formData,
processData: false,
contentType: false,
success: (d) => {
console.log("Player Added", d);
players.innerHTML = d;
form.reset();
},
error: (d) => {
console.log("An error occurred. Please try again");
}
});
}
return false;
}
Changes in main.go
Fname := r.FormValue("firstName")
Lname := r.FormValue("lastName")
Gender := r.FormValue("gender")
# return the last element added to slice before it was always returning the first element.
err := templates.ExecuteTemplate(w, "displayPlayer", players[len(players) - 1])