Home > Blockchain >  Golang render new template on button press
Golang render new template on button press

Time:11-14

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">&times;</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 by addPlayer

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">&times;</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])
  • Related