* Complete add-player modal
* New player listing * New player action layout
This commit is contained in:
3
.idea/inspectionProfiles/Project_Default.xml
generated
3
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -4,9 +4,10 @@
|
||||
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="myValues">
|
||||
<value>
|
||||
<list size="2">
|
||||
<list size="3">
|
||||
<item index="0" class="java.lang.String" itemvalue="hx-get" />
|
||||
<item index="1" class="java.lang.String" itemvalue="hx-target" />
|
||||
<item index="2" class="java.lang.String" itemvalue="hx-vals" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
|
||||
@@ -31,8 +31,8 @@ func GetAllClans(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, clans)
|
||||
}
|
||||
|
||||
// GetAllClanOptions GET /clan_options
|
||||
func GetAllClanOptions(c *gin.Context) {
|
||||
// GetAllClansHTML GET /clans_html
|
||||
func GetAllClansHTML(c *gin.Context) {
|
||||
var clans []models.Clan
|
||||
models.DB.Find(&clans)
|
||||
|
||||
|
||||
@@ -2,10 +2,26 @@ package controllers
|
||||
|
||||
import (
|
||||
"InfrantrySkillCalculator/models"
|
||||
"InfrantrySkillCalculator/utils"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type AddPlayerInput struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
ClanID uint `json:"clan_id" binding:"required"`
|
||||
}
|
||||
|
||||
type UpdatePlayerInput struct {
|
||||
Name string `json:"name"`
|
||||
ClanID uint `json:"clan_id"`
|
||||
}
|
||||
|
||||
// GetAllPlayers GET /player
|
||||
func GetAllPlayers(c *gin.Context) {
|
||||
var players []models.Player
|
||||
@@ -13,3 +29,154 @@ func GetAllPlayers(c *gin.Context) {
|
||||
|
||||
c.JSON(http.StatusOK, players)
|
||||
}
|
||||
|
||||
// GetPlayersByClanHTML GET /players_html
|
||||
func GetPlayersByClanHTML(c *gin.Context) {
|
||||
var players []models.Player
|
||||
clanId := c.Request.URL.Query().Get("id")
|
||||
if err := models.DB.Where("clan_id = ?", utils.StringToUint(clanId)).Find(&players).Error; err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
file, err := os.ReadFile("./templates/player_list_item.html")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
playerItem := string(file)
|
||||
//player_item = strings.Replace(player_item, "PLAYERNAME", player.Name, 1)
|
||||
|
||||
var htmlOptions string
|
||||
for _, player := range players {
|
||||
htmlOptions += fmt.Sprintf(playerItem, player.Name)
|
||||
}
|
||||
|
||||
c.Header("Content-Type", "text/html")
|
||||
c.String(http.StatusOK, htmlOptions)
|
||||
}
|
||||
|
||||
// AddPlayer POST /player
|
||||
func AddPlayer(c *gin.Context) {
|
||||
var input AddPlayerInput
|
||||
if err := c.BindJSON(&input); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
var player models.Player
|
||||
if err := models.DB.Where("name = ?", input.Name).First(&player).Error; err == nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Player with this name already exists!"})
|
||||
return
|
||||
}
|
||||
|
||||
player = models.Player{Name: input.Name, ClanID: input.ClanID}
|
||||
models.DB.Create(&player)
|
||||
|
||||
//UpdatePlayerTimestamp()
|
||||
|
||||
c.JSON(http.StatusOK, player)
|
||||
|
||||
_, err := fmt.Fprintf(utils.GinWriter, "Added player '"+player.Name+"'\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// GetPlayerByID GET /player/:id
|
||||
func GetPlayerByID(c *gin.Context) {
|
||||
player := FindPlayerByID(utils.StringToUint(c.Param("id")))
|
||||
if player == nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, player)
|
||||
}
|
||||
|
||||
// GetPlayerIDByName GET /playerid/:name
|
||||
func GetPlayerIDByName(c *gin.Context) {
|
||||
var player models.Player
|
||||
|
||||
if err := FindPlayerByName(&player, c).Error; err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, player.ID)
|
||||
}
|
||||
|
||||
// UpdatePlayerByID PATCH /player/:id
|
||||
func UpdatePlayerByID(c *gin.Context) {
|
||||
player := FindPlayerByID(utils.StringToUint(c.Param("id")))
|
||||
if player == nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
|
||||
return
|
||||
}
|
||||
|
||||
var input UpdatePlayerInput
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if player.Name != input.Name {
|
||||
if err := FindPlayerByName(&player, c).Error; err == nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Player with this name already exists!"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
msg := "Updating player '" + player.Name + "'#" + strconv.FormatUint(uint64(player.ID), 10)
|
||||
if player.Name != input.Name {
|
||||
msg += " (new: '" + input.Name + "')"
|
||||
}
|
||||
msg += " with clan #" + utils.UintToString(player.ClanID)
|
||||
if player.ClanID != input.ClanID {
|
||||
msg += " (new: ä" + utils.UintToString(input.ClanID) + ")"
|
||||
}
|
||||
_, err := fmt.Fprintf(utils.GinWriter, msg+"\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
models.DB.Model(&player).Updates(map[string]interface{}{
|
||||
"Name": input.Name,
|
||||
"ClanID": input.ClanID,
|
||||
})
|
||||
|
||||
//UpdatePlayerTimestamp()
|
||||
|
||||
c.JSON(http.StatusOK, player)
|
||||
}
|
||||
|
||||
// DeletePlayerByID DELETE /player/:id
|
||||
func DeletePlayerByID(c *gin.Context) {
|
||||
player := FindPlayerByID(utils.StringToUint(c.Param("id")))
|
||||
if player == nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
|
||||
return
|
||||
}
|
||||
|
||||
models.DB.Delete(&player)
|
||||
|
||||
//UpdatePlayerTimestamp()
|
||||
|
||||
c.JSON(http.StatusOK, true)
|
||||
|
||||
_, err := fmt.Fprintf(utils.GinWriter, "Deleted player '"+player.Name+"'\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func FindPlayerByID(id uint) *models.Player {
|
||||
var res models.Player
|
||||
if err := models.DB.Where("id = ?", id).First(&res).Error; err != nil {
|
||||
return nil
|
||||
} else {
|
||||
return &res
|
||||
}
|
||||
}
|
||||
|
||||
func FindPlayerByName(out interface{}, c *gin.Context) *gorm.DB {
|
||||
return models.DB.Where("name = ?", c.Param("name")).First(out)
|
||||
}
|
||||
|
||||
BIN
isc_data.db
BIN
isc_data.db
Binary file not shown.
10
main.go
10
main.go
@@ -32,8 +32,6 @@ func main() {
|
||||
"./templates/index.html",
|
||||
"./templates/components/home_clan_bar.html",
|
||||
"./templates/components/opp_clan_bar.html",
|
||||
"./templates/components/home_player_bar.html",
|
||||
"./templates/components/opp_player_bar.html",
|
||||
"./templates/components/home_player_list.html",
|
||||
"./templates/components/opp_player_list.html",
|
||||
"./templates/components/bottom_controls.html",
|
||||
@@ -62,13 +60,19 @@ func main() {
|
||||
})
|
||||
|
||||
router.GET("/clans", controllers.GetAllClans)
|
||||
router.GET("/clan_options", controllers.GetAllClanOptions)
|
||||
router.GET("/clans_html", controllers.GetAllClansHTML)
|
||||
router.GET("/clan/:id", controllers.GetClanByID)
|
||||
router.POST("/clan", controllers.AddClan)
|
||||
router.PATCH("/clan/:id", controllers.UpdateClanByID)
|
||||
router.DELETE("/clan/:id", controllers.DeleteClanByID)
|
||||
|
||||
router.GET("/players", controllers.GetAllPlayers)
|
||||
router.GET("/players_html", controllers.GetPlayersByClanHTML)
|
||||
router.GET("/player/:id", controllers.GetPlayerByID)
|
||||
router.GET("/playerid/:name", controllers.GetPlayerIDByName)
|
||||
router.POST("/player", controllers.AddPlayer)
|
||||
router.PATCH("/player/:id", controllers.UpdatePlayerByID)
|
||||
router.DELETE("/player/:id", controllers.DeletePlayerByID)
|
||||
|
||||
log.Println("Running on 8000...")
|
||||
log.Fatal(router.Run(":8000"))
|
||||
|
||||
@@ -9,21 +9,19 @@ function setupClanButtons(dropdownId, delBtnId, editBtnId) {
|
||||
});
|
||||
}
|
||||
|
||||
function setupPlayerButtons(dropdownId, listId, delBtnId, editBtnId, addBtnId) {
|
||||
function getSelectedClanId(dropdownId) {
|
||||
const dropdown = document.getElementById(dropdownId);
|
||||
const selectedClanId = dropdown.options[dropdown.selectedIndex].value;
|
||||
return parseInt(selectedClanId);
|
||||
}
|
||||
|
||||
function setupPlayerButtons(dropdownId, listId, addBtnId) {
|
||||
const dropdown = document.getElementById(dropdownId);
|
||||
const deleteButton = document.getElementById(delBtnId);
|
||||
const editButton = document.getElementById(editBtnId);
|
||||
const addButton = document.getElementById(addBtnId);
|
||||
|
||||
dropdown.addEventListener('change', function () {
|
||||
deleteButton.disabled = !this.value;
|
||||
editButton.disabled = !this.value && (dropdown.selectedIndex !== -1);
|
||||
addButton.disabled = !this.value && (dropdown.selectedIndex !== -1);
|
||||
});
|
||||
|
||||
dropdown.addEventListener('change', function () {
|
||||
deleteButton.disabled = (this.selectedIndex !== -1);
|
||||
editButton.disabled = (this.selectedIndex !== -1);
|
||||
addButton.classList.toggle("bg-secondary-subtle");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="input-group input-group-lg mb-3">
|
||||
<select class="form-select form-control border-secondary" id="home-clan" hx-get="/players" hx-target="#home-player-list">
|
||||
<select class="form-select form-control border-secondary" id="home-clan" hx-get="/players_html" hx-target="#home-player-list" hx-vals='js:{"id": getSelectedClanId("home-clan")}'>
|
||||
<option disabled selected value>Auswählen...</option>
|
||||
<!-- Options will be loaded dynamically -->
|
||||
</select>
|
||||
@@ -26,7 +26,7 @@
|
||||
<script lang="javascript">
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
setupClanButtons('home-clan', 'home-delete', 'home-edit');
|
||||
htmx.ajax('GET', '/clan_options', {target: '#home-clan'});
|
||||
htmx.ajax('GET', '/clans_html', {target: '#home-clan'});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
{{ define "home_player_bar" }}
|
||||
|
||||
<div class="row mt-3 justify-content-between align-items-center">
|
||||
<div class="col-auto">
|
||||
<div class="btn-group btn-group-lg" role="group">
|
||||
<button type="button" class="btn btn-outline-secondary text-secondary-emphasis py-1 px-3"><i class="bi bi-check-square fs-4"></i></button>
|
||||
<button type="button" class="btn btn-outline-secondary text-secondary-emphasis py-1 px-3"><i class="bi bi-square fs-4"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col px-0">
|
||||
<span class="badge fs-5 w-100 text-secondary-emphasis">0 von 0 ausgewählt</span>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="btn-group btn-group-lg" role="group">
|
||||
<button type="button" class="btn btn-outline-secondary text-danger py-1 px-3" id="home-player-delete" disabled>
|
||||
<i class="bi bi-person-dash fs-4"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary text-primary py-1 px-3" id="home-player-edit" disabled>
|
||||
<i class="bi bi-person-gear fs-4"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary text-success py-1 px-3" id="home-player-add" data-bs-toggle="modal" data-bs-list="#home-player-list" data-bs-target="#addPlayerModal" disabled>
|
||||
<i class="bi bi-person-add fs-4"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script lang="javascript">
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
setupPlayerButtons('home-clan', 'home-player-list', 'home-player-delete', 'home-player-edit', 'home-player-add');
|
||||
});
|
||||
</script>
|
||||
|
||||
{{ end }}
|
||||
@@ -1,8 +1,32 @@
|
||||
{{ define "home_player_list" }}
|
||||
|
||||
<label for="home-player-list" class="col-form-label col-form-label-lg pt-0">Spieler:</label>
|
||||
<select multiple class="form-control form-control-lg overflow-auto border-secondary" id="home-player-list" size="10">
|
||||
<!-- Player list items go here -->
|
||||
</select>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div id="home-player-list" class="border rounded p-1 overflow-auto" style="height: 47vh;">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto ps-0">
|
||||
<div class="btn-group-vertical btn-group-lg" role="group">
|
||||
<button type="button" class="btn btn-outline-secondary text-primary-emphasis"><i class="bi bi-check-square fs-4"></i></button>
|
||||
<button type="button" class="btn btn-outline-secondary text-primary-emphasis"><i class="bi bi-square fs-4"></i></button>
|
||||
</div>
|
||||
<br>
|
||||
<button type="button" class="btn btn-outline-secondary text-success px-3 mt-2 bg-secondary-subtle" id="home-player-add" data-bs-toggle="modal" data-bs-list="#home-player-list" data-bs-target="#addPlayerModal" disabled>
|
||||
<i class="bi bi-person-add fs-4"></i>
|
||||
</button>
|
||||
<br>
|
||||
<div class="vstack text-center border border-secondary rounded mt-2">
|
||||
<i class="bi bi-ui-checks fs-4 mt-2 mb-1"></i>
|
||||
<span class="badge fs-5 mb-2">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script lang="javascript">
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
setupPlayerButtons('home-clan', 'home-player-list', 'home-player-add');
|
||||
});
|
||||
</script>
|
||||
|
||||
{{ end }}
|
||||
@@ -6,7 +6,7 @@
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="input-group input-group-lg mb-3">
|
||||
<select class="form-select form-control border-secondary" id="opponent-clan" hx-get="/players" hx-target="#opponent-player-list">
|
||||
<select class="form-select form-control border-secondary" id="opponent-clan" hx-get="/players_html" hx-target="#opponent-player-list" hx-vals='js:{"id": getSelectedClanId("opponent-clan")}'>
|
||||
<option disabled selected value>Auswählen...</option>
|
||||
</select>
|
||||
<button class="btn btn-lg btn-outline-secondary text-danger" type="button" id="opponent-delete" data-bs-toggle="modal" data-bs-list="#opponent-clan" data-bs-target="#deleteClanModal" disabled>
|
||||
@@ -25,7 +25,7 @@
|
||||
<script lang="javascript">
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
setupClanButtons('opponent-clan', 'opponent-delete', 'opponent-edit');
|
||||
htmx.ajax('GET', '/clan_options', {target: '#opponent-clan'});
|
||||
htmx.ajax('GET', '/clans_html', {target: '#opponent-clan'});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
{{ define "opp_player_bar" }}
|
||||
|
||||
<div class="row mt-3 justify-content-between align-items-center">
|
||||
<div class="col-auto">
|
||||
<div class="btn-group btn-group-lg" role="group">
|
||||
<button type="button" class="btn btn-outline-secondary text-secondary-emphasis py-1 px-3"><i class="bi bi-check-square fs-4"></i></button>
|
||||
<button type="button" class="btn btn-outline-secondary text-secondary-emphasis py-1 px-3"><i class="bi bi-square fs-4"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col px-0">
|
||||
<span class="badge fs-5 w-100 text-secondary-emphasis">0 von 0 ausgewählt</span>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="btn-group btn-group-lg" role="group">
|
||||
<button type="button" class="btn btn-outline-secondary text-danger py-1 px-3" id="opponent-player-delete" disabled>
|
||||
<i class="bi bi-person-dash fs-4"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary text-primary py-1 px-3" id="opponent-player-edit" disabled>
|
||||
<i class="bi bi-person-gear fs-4"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary text-success py-1 px-3" id="opponent-player-add" data-bs-toggle="modal" data-bs-list="#opponent-player-list" data-bs-target="#addPlayerModal" disabled>
|
||||
<i class="bi bi-person-add fs-4"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script lang="javascript">
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
setupPlayerButtons('opponent-clan', 'opponent-player-list', 'opponent-player-delete', 'opponent-player-edit', 'opponent-player-add');
|
||||
});
|
||||
</script>
|
||||
|
||||
{{ end }}
|
||||
@@ -1,8 +1,32 @@
|
||||
{{ define "opp_player_list" }}
|
||||
|
||||
<label for="opponent-player-list" class="col-form-label col-form-label-lg pt-0">Spieler:</label>
|
||||
<select multiple class="form-control form-control-lg overflow-auto border-secondary" id="opponent-player-list" size="10">
|
||||
<!-- Player list items go here -->
|
||||
</select>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div id="opponent-player-list" class="border rounded p-1 overflow-auto" style="height: 47vh;">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto ps-0">
|
||||
<div class="btn-group-vertical btn-group-lg" role="group">
|
||||
<button type="button" class="btn btn-outline-secondary text-primary-emphasis"><i class="bi bi-check-square fs-4"></i></button>
|
||||
<button type="button" class="btn btn-outline-secondary text-primary-emphasis"><i class="bi bi-square fs-4"></i></button>
|
||||
</div>
|
||||
<br>
|
||||
<button type="button" class="btn btn-outline-secondary text-success px-3 mt-2 bg-secondary-subtle" id="opponent-player-add" data-bs-toggle="modal" data-bs-list="#opponent-player-list" data-bs-target="#addPlayerModal" disabled>
|
||||
<i class="bi bi-person-add fs-4"></i>
|
||||
</button>
|
||||
<br>
|
||||
<div class="vstack text-center border border-secondary rounded mt-2">
|
||||
<i class="bi bi-ui-checks fs-4 mt-2 mb-1"></i>
|
||||
<span class="badge fs-5 mb-2">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script lang="javascript">
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
setupPlayerButtons('opponent-clan', 'opponent-player-list', 'opponent-player-add');
|
||||
});
|
||||
</script>
|
||||
|
||||
{{ end }}
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
{{ template "header" . }}
|
||||
</head>
|
||||
<body data-bs-theme="dark">
|
||||
<body data-bs-theme="dark" class="h-auto">
|
||||
<div class="container-xxl bg-dark mt-5 p-4 rounded-3 text-light">
|
||||
<div class="row">
|
||||
<!-- Home-Clan Column -->
|
||||
@@ -14,9 +14,6 @@
|
||||
|
||||
<!-- Player List -->
|
||||
{{ template "home_player_list" . }}
|
||||
|
||||
<!-- List Controls -->
|
||||
{{ template "home_player_bar" . }}
|
||||
</div>
|
||||
|
||||
<!-- Opponent-Clan Column -->
|
||||
@@ -27,9 +24,6 @@
|
||||
|
||||
<!-- Player List -->
|
||||
{{ template "opp_player_list" . }}
|
||||
|
||||
<!-- List Controls -->
|
||||
{{ template "opp_player_bar" . }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control form-control-lg" id="clanName" placeholder="Clan-Name" disabled>
|
||||
<label for="clanName">Clan-Name</label>
|
||||
<input type="text" class="form-control form-control-lg" id="playerClanName" placeholder="Clan-Name" disabled>
|
||||
<label for="playerClanName">Clan-Name</label>
|
||||
</div>
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control form-control-lg" id="playerName" placeholder="Spieler-Name">
|
||||
@@ -33,18 +33,45 @@
|
||||
addPlayerModal.addEventListener('show.bs.modal', event => {
|
||||
const [playerList, otherPlayerList] = getPlayerLists(event);
|
||||
const selectedClan = getSelectedClan(event);
|
||||
const clanTag = addPlayerModal.querySelector('#playerName');
|
||||
const clanName = addPlayerModal.querySelector('#clanName');
|
||||
const playerName = addPlayerModal.querySelector('#playerName');
|
||||
const clanName = addPlayerModal.querySelector('#playerClanName');
|
||||
clanName.value = selectedClan.innerText;
|
||||
const clanId = parseInt(selectedClan.value);
|
||||
|
||||
const submitButton = addPlayerModal.querySelector('button[name="submit"]');
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
submitButton.onclick = function () {}
|
||||
|
||||
fetch("/player", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
name: playerName.value,
|
||||
clan_id: clanId
|
||||
}),
|
||||
headers: {
|
||||
"Content-type": "application/json; charset=UTF-8"
|
||||
}
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((json) => {
|
||||
const opt = document.createElement('option');
|
||||
opt.innerText = playerName.value;
|
||||
opt.value = json['ID'];
|
||||
|
||||
playerList.appendChild(opt.cloneNode(true));
|
||||
playerList.selectedIndex = playerList.children.length - 1;
|
||||
playerList.dispatchEvent(new Event('change'));
|
||||
|
||||
if (document.getElementById('home-clan').selectedIndex === document.getElementById('opponent-clan').selectedIndex)
|
||||
otherPlayerList.appendChild(opt);
|
||||
|
||||
addPlayerModalBS.hide();
|
||||
playerName.value = "";
|
||||
clanName.value = "";
|
||||
}).catch((error) => {
|
||||
throw new Error(error)
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
11
templates/player_list_item.html
Normal file
11
templates/player_list_item.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="input-group input-group-lg mb-1">
|
||||
<div class="input-group-text py-1 px-2">
|
||||
<input class="form-check-input fs-4 border-secondary mt-0" type="checkbox" value="">
|
||||
</div>
|
||||
<span class="form-control py-1 px-2">%s</span>
|
||||
<button class="btn btn-outline-secondary text-secondary-emphasis dropdown-toggle py-1" type="button" data-bs-toggle="dropdown"></button>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li><a class="dropdown-item text-primary fs-5" href="#"><i class="bi bi-person-gear fs-4 me-2"></i>Bearbeiten</a></li>
|
||||
<li><a class="dropdown-item text-danger fs-5" href="#"><i class="bi bi-person-dash fs-4 me-2"></i>Löschen</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
19
utils/conv.go
Normal file
19
utils/conv.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func UintToString(val uint) string {
|
||||
return strconv.FormatUint(uint64(val), 10)
|
||||
}
|
||||
|
||||
func StringToUint(val string) uint {
|
||||
res, _ := strconv.ParseUint(val, 10, 16)
|
||||
return uint(res)
|
||||
}
|
||||
|
||||
func FloatToString(val float32) string {
|
||||
return fmt.Sprintf("%f", val)
|
||||
}
|
||||
Reference in New Issue
Block a user