lot of breaking changes, checking in before stepping away
This commit is contained in:
@@ -20,9 +20,33 @@ const (
|
||||
Other
|
||||
)
|
||||
|
||||
// entities
|
||||
type Item struct {
|
||||
var CategoryMap = map[Category]string{
|
||||
Bedroom: "Bedroom",
|
||||
Bathroom: "Bathroom",
|
||||
Kitchen: "Kitchen",
|
||||
Office: "Office",
|
||||
LivingRoom: "Living Room",
|
||||
Other: "Other",
|
||||
}
|
||||
|
||||
var PackingStageMap = map[PackingStage]string{
|
||||
Essentials: "Essentials",
|
||||
StageOne: "Stage One",
|
||||
StageTwo: "Stage Two",
|
||||
StageThree: "Stage Three",
|
||||
}
|
||||
|
||||
type EntityLabel string
|
||||
|
||||
const (
|
||||
ItemType EntityLabel = "items"
|
||||
BoxType EntityLabel = "boxes"
|
||||
BoxItemType EntityLabel = "box_items"
|
||||
)
|
||||
|
||||
type Entity struct {
|
||||
ID int
|
||||
EntityLabel EntityLabel
|
||||
Name string
|
||||
Notes *string
|
||||
Description *string
|
||||
@@ -30,14 +54,8 @@ type Item struct {
|
||||
Category Category
|
||||
}
|
||||
|
||||
type Box struct {
|
||||
ID int
|
||||
Name string
|
||||
Notes *string
|
||||
Description *string
|
||||
Stage PackingStage
|
||||
Category Category
|
||||
}
|
||||
type Item Entity
|
||||
type Box Entity
|
||||
|
||||
// joins
|
||||
type BoxItem struct {
|
||||
|
||||
14
db/seed.go
14
db/seed.go
@@ -58,12 +58,12 @@ func GetSeedData() (items []Item, boxes []Box, boxitems []BoxItem) {
|
||||
func CreateTables(client *sql.DB) (int64, error) {
|
||||
script, err := os.ReadFile("/home/mikayla/go/go-htmx-tailwind-example/db/seed.sql")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return -1, err
|
||||
}
|
||||
|
||||
result, err := client.Exec(string(script))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return -1, err
|
||||
}
|
||||
|
||||
return result.RowsAffected()
|
||||
@@ -86,6 +86,11 @@ func SeedDB() (int64, error) {
|
||||
for i := range(items) {
|
||||
_, err := PostItem(items[i])
|
||||
if err != nil {
|
||||
// ignore unique constraint violations and continue
|
||||
if err.Error() == "UNIQUE constraint failed: items.Name" {
|
||||
continue
|
||||
}
|
||||
|
||||
return -1, err
|
||||
}
|
||||
insertCount++
|
||||
@@ -94,6 +99,11 @@ func SeedDB() (int64, error) {
|
||||
for i := range(boxes) {
|
||||
_, err := PostBox(boxes[i])
|
||||
if err != nil {
|
||||
// ignore unique constraint violations and continue
|
||||
if err.Error() == "UNIQUE constraint failed: boxes.Name" {
|
||||
continue
|
||||
}
|
||||
|
||||
return -1, err
|
||||
}
|
||||
insertCount++
|
||||
|
||||
157
db/sql.go
157
db/sql.go
@@ -2,13 +2,33 @@ package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
func CreateClient() (db *sql.DB, err error) {
|
||||
return sql.Open("sqlite3", "./example.db")
|
||||
}
|
||||
|
||||
func GetAllItems() (result []Item, err error) {
|
||||
func GetAllItems() (rows *sql.Rows, err error) {
|
||||
db, err := CreateClient()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer db.Close()
|
||||
|
||||
rows, err = db.Query("SELECT * FROM items")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// fmt.Println("rows", rows)
|
||||
|
||||
defer rows.Close()
|
||||
return
|
||||
}
|
||||
|
||||
func GetAll(table EntityLabel) (rows *sql.Rows, err error) {
|
||||
db, err := CreateClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -16,46 +36,50 @@ func GetAllItems() (result []Item, err error) {
|
||||
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("SELECT * FROM items")
|
||||
rows, err = db.Query("SELECT * FROM ?", table)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
return
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
item := Item{}
|
||||
func GetByID(table EntityLabel, id int) (row *sql.Row, err error) {
|
||||
db, err := CreateClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = rows.Scan(&item.ID, &item.Name, &item.Notes, &item.Description, &item.Stage, &item.Category)
|
||||
defer db.Close()
|
||||
|
||||
row = db.QueryRow("SELECT * FROM ? WHERE id = ?", table, id)
|
||||
return
|
||||
}
|
||||
|
||||
func Put[T Entity](table EntityLabel, record Entity) (sql.Result, error) {
|
||||
db, err := CreateClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer db.Close()
|
||||
|
||||
query := `UPDATE ? SET name = ?, notes = ?, description = ?, stage = ?, category = ? WHERE id = ?`
|
||||
|
||||
result, err := db.Exec(query, table, record.Name, record.Notes, record.Description, record.Stage, record.Category, record.ID)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = append(result, item)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func GetItemByID(id int) (item Item, err error) {
|
||||
func PostItem(record Item) (sql.Result, error) {
|
||||
db, err := CreateClient()
|
||||
if err != nil {
|
||||
return Item{}, err
|
||||
}
|
||||
|
||||
defer db.Close()
|
||||
|
||||
row := db.QueryRow("SELECT * FROM items WHERE id = ?", id)
|
||||
err = row.Scan(&item.ID, &item.Name, &item.Notes, &item.Description, &item.Stage, &item.Category)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func PostItem(item Item) (int64, error) {
|
||||
db, err := CreateClient()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer db.Close()
|
||||
@@ -63,37 +87,16 @@ func PostItem(item Item) (int64, error) {
|
||||
query := `INSERT INTO items (name, notes, description, stage, category)
|
||||
VALUES (?, ?, ?, ?, ?)`
|
||||
|
||||
result, err := db.Exec(query, item.Name, item.Notes, item.Description, item.Stage, item.Category)
|
||||
result, err := db.Exec(query, record.Name, record.Notes, record.Description, record.Stage, record.Category)
|
||||
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result.LastInsertId()
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
func PostBox(box Box) (int64, error) {
|
||||
db, err := CreateClient()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
defer db.Close()
|
||||
|
||||
query := `INSERT INTO boxes (name, notes, description, stage, category) VALUES (?, ?, ?, ?, ?)`
|
||||
|
||||
result, err := db.Exec(query, box.Name, box.Notes, box.Description, box.Stage, box.Category)
|
||||
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
return result.LastInsertId()
|
||||
}
|
||||
|
||||
func GetAllBoxes() (result []Box, err error) {
|
||||
func PostBox(record Box) (sql.Result, error) {
|
||||
db, err := CreateClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -101,34 +104,50 @@ func GetAllBoxes() (result []Box, err error) {
|
||||
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("SELECT * FROM boxes")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query := `INSERT INTO boxes (name, notes, description, stage, category)
|
||||
VALUES (?, ?, ?, ?, ?)`
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
box := Box{}
|
||||
|
||||
err = rows.Scan(&box.ID, &box.Name, &box.Notes, &box.Description, &box.Stage, &box.Category)
|
||||
result, err := db.Exec(query, record.Name, record.Notes, record.Description, record.Stage, record.Category)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = append(result, box)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func Delete(table EntityLabel, id int) (sql.Result, error) {
|
||||
db, err := CreateClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer db.Close()
|
||||
|
||||
query := `DELETE FROM ? WHERE id = ?`
|
||||
|
||||
return db.Exec(query, table, id)
|
||||
}
|
||||
|
||||
func ParseItem(item *Item, scan func(dest ...any) error) (err error) {
|
||||
return scan(&item.ID, &item.Name, &item.Notes, &item.Description, &item.Stage, &item.Category)
|
||||
}
|
||||
|
||||
func ParseBox(box *Box, scan func(dest ...any) error) error {
|
||||
return scan(&box.ID, &box.Name, &box.Notes, &box.Description, &box.Stage, &box.Category)
|
||||
}
|
||||
|
||||
func ParseEntityFromBytes(b []byte) (entity Entity, err error) {
|
||||
err = json.Unmarshal(b, &entity)
|
||||
return
|
||||
}
|
||||
|
||||
// func PostBoxItem(itemid int, boxid int) (int64, error) {
|
||||
// db, err := CreateClient()
|
||||
// if err != nil {
|
||||
// return -1, err
|
||||
// }
|
||||
func ParseItemFromBytes(b []byte) (item Item, err error) {
|
||||
err = json.Unmarshal(b, &item)
|
||||
return
|
||||
}
|
||||
|
||||
// defer db.Close()
|
||||
// // query :=
|
||||
// }
|
||||
func ParseBoxFromBytes(b []byte) (box Box, err error) {
|
||||
err = json.Unmarshal(b, &box)
|
||||
return
|
||||
}
|
||||
|
||||
12
main.go
12
main.go
@@ -34,10 +34,14 @@ func main() {
|
||||
|
||||
//exit process immediately upon sigterm
|
||||
handleSigTerms()
|
||||
db.SeedDB()
|
||||
i, err := db.SeedDB()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("seeded db with %d records\n", i)
|
||||
|
||||
//parse templates
|
||||
var err error
|
||||
html, err = web.TemplateParseFSRecursive(templateFS, ".html", true, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -52,7 +56,11 @@ func main() {
|
||||
|
||||
router.Handle("/", web.Action(routes.HomePage))
|
||||
router.Handle("/items", web.Action(routes.Items(html).GetAll))
|
||||
router.Handle("/items/{id}", web.Action(routes.Items(html).GetByID))
|
||||
router.Handle("/boxes", web.Action(routes.Boxes(html).GetAll))
|
||||
router.Handle("/unrelated", web.Action(func(r *http.Request) *web.Response {
|
||||
return web.HTML(http.StatusOK, html, "row-edit.html", nil, nil)
|
||||
}))
|
||||
|
||||
//logging/tracing
|
||||
nextRequestID := func() string {
|
||||
|
||||
@@ -3,17 +3,10 @@ package routes
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/innocuous-symmetry/moving-mgmt/db"
|
||||
"github.com/jritsema/gotoolbox/web"
|
||||
)
|
||||
|
||||
type Entity int
|
||||
|
||||
const (
|
||||
Item Entity = iota
|
||||
Box
|
||||
BoxItem
|
||||
)
|
||||
|
||||
type RouterActions struct {
|
||||
GetAll func(r *http.Request) *web.Response
|
||||
GetByID func(r *http.Request) *web.Response
|
||||
@@ -23,8 +16,7 @@ type RouterActions struct {
|
||||
}
|
||||
|
||||
type Router struct {
|
||||
Entity Entity
|
||||
Path string
|
||||
Entity db.EntityLabel
|
||||
GetAll func(r *http.Request) *web.Response
|
||||
GetByID func(r *http.Request) *web.Response
|
||||
Post func(r *http.Request) *web.Response
|
||||
@@ -32,10 +24,9 @@ type Router struct {
|
||||
Delete func(r *http.Request) *web.Response
|
||||
}
|
||||
|
||||
func NewRouter(entity Entity, path string, actions RouterActions) *Router {
|
||||
func NewRouter(entity db.EntityLabel, actions RouterActions) *Router {
|
||||
return &Router{
|
||||
Entity: entity,
|
||||
Path: path,
|
||||
GetAll: actions.GetAll,
|
||||
GetByID: actions.GetByID,
|
||||
Post: actions.Post,
|
||||
|
||||
@@ -12,8 +12,7 @@ func Boxes(_html *template.Template) *Router {
|
||||
html = _html
|
||||
|
||||
return NewRouter(
|
||||
Box,
|
||||
"/boxes",
|
||||
"boxes",
|
||||
RouterActions{
|
||||
GetAll: GetAllBoxes,
|
||||
GetByID: nil,
|
||||
@@ -25,11 +24,23 @@ func Boxes(_html *template.Template) *Router {
|
||||
}
|
||||
|
||||
func GetAllBoxes(_ *http.Request) *web.Response {
|
||||
result, err := db.GetAllBoxes()
|
||||
result, err := db.GetAll("boxes")
|
||||
if err != nil {
|
||||
return web.Error(http.StatusBadRequest, err, nil)
|
||||
}
|
||||
|
||||
boxes := []db.Box{}
|
||||
|
||||
for result.Next() {
|
||||
box := db.Box{}
|
||||
err = db.ParseBox(&box, result.Scan)
|
||||
if err != nil {
|
||||
return web.Error(http.StatusInternalServerError, err, nil)
|
||||
}
|
||||
|
||||
boxes = append(boxes, box)
|
||||
}
|
||||
|
||||
return web.HTML(
|
||||
http.StatusOK,
|
||||
html,
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
// "github.com/innocuous-symmetry/moving-mgmt/"
|
||||
db "github.com/innocuous-symmetry/moving-mgmt/db"
|
||||
"github.com/jritsema/gotoolbox/web"
|
||||
@@ -12,15 +14,32 @@ var html *template.Template
|
||||
|
||||
func HomePage(r *http.Request) *web.Response {
|
||||
result, err := db.GetAllItems()
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return web.Error(http.StatusNotFound, err, nil)
|
||||
}
|
||||
|
||||
items := []db.Item{}
|
||||
for result.Next() {
|
||||
item := db.Item{}
|
||||
err = db.ParseItem(&item, result.Scan)
|
||||
|
||||
fmt.Println("name", item.Name)
|
||||
|
||||
if err != nil {
|
||||
return web.Error(http.StatusInternalServerError, err, nil)
|
||||
}
|
||||
|
||||
items = append(items, item)
|
||||
}
|
||||
|
||||
return web.HTML(
|
||||
http.StatusOK,
|
||||
html,
|
||||
"index.html",
|
||||
result,
|
||||
items,
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
db "github.com/innocuous-symmetry/moving-mgmt/db"
|
||||
"github.com/innocuous-symmetry/moving-mgmt/util"
|
||||
"github.com/jritsema/gotoolbox/web"
|
||||
)
|
||||
|
||||
@@ -13,11 +15,10 @@ func Items(_html *template.Template) *Router {
|
||||
html = _html
|
||||
|
||||
return NewRouter(
|
||||
Item,
|
||||
"/items",
|
||||
"items",
|
||||
RouterActions{
|
||||
GetAll: GetAllItems,
|
||||
GetByID: nil,
|
||||
GetByID: GetItemByID,
|
||||
Post: nil,
|
||||
Put: nil,
|
||||
Delete: nil,
|
||||
@@ -26,11 +27,26 @@ func Items(_html *template.Template) *Router {
|
||||
}
|
||||
|
||||
func GetAllItems(_ *http.Request) *web.Response {
|
||||
result, err := db.GetAllItems()
|
||||
result, err := db.GetAll("items")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return web.Error(http.StatusNotFound, err, nil)
|
||||
}
|
||||
|
||||
items := []db.Item{}
|
||||
|
||||
for result.Next() {
|
||||
item := db.Item{}
|
||||
err = db.ParseItem(&item, result.Scan)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return web.Error(http.StatusInternalServerError, err, nil)
|
||||
}
|
||||
|
||||
items = append(items, item)
|
||||
}
|
||||
|
||||
fmt.Println("items", items)
|
||||
|
||||
return web.HTML(
|
||||
http.StatusOK,
|
||||
html,
|
||||
@@ -41,14 +57,57 @@ func GetAllItems(_ *http.Request) *web.Response {
|
||||
}
|
||||
|
||||
func GetItemByID(r *http.Request) *web.Response {
|
||||
var id int
|
||||
id, err := strconv.Atoi(r.URL.Query().Get("id"))
|
||||
id, err := util.GetIDFromPath(r)
|
||||
if err != nil {
|
||||
return web.Error(http.StatusBadRequest, err, nil)
|
||||
}
|
||||
|
||||
result, err := db.GetItemByID(id)
|
||||
editMode, err := strconv.ParseBool(r.URL.Query().Get("edit"))
|
||||
if err != nil {
|
||||
return web.Error(http.StatusBadRequest, err, nil)
|
||||
}
|
||||
|
||||
res, err := db.GetByID("items", id)
|
||||
|
||||
item := db.Item{}
|
||||
err = db.ParseItem(&item, res.Scan)
|
||||
if err != nil {
|
||||
return web.Error(http.StatusInternalServerError, err, nil)
|
||||
}
|
||||
|
||||
var tmpl string
|
||||
|
||||
if editMode {
|
||||
tmpl = "entity-edit.html"
|
||||
} else {
|
||||
tmpl = "entity-row.html"
|
||||
}
|
||||
|
||||
return web.HTML(
|
||||
http.StatusOK,
|
||||
html,
|
||||
tmpl,
|
||||
item,
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
func PutItem(r *http.Request) *web.Response {
|
||||
body := r.Body
|
||||
defer body.Close()
|
||||
|
||||
bodyBytes := make([]byte, r.ContentLength)
|
||||
_, err := body.Read(bodyBytes)
|
||||
if err != nil {
|
||||
return web.Error(http.StatusInternalServerError, err, nil)
|
||||
}
|
||||
|
||||
item, err := db.ParseEntityFromBytes(bodyBytes)
|
||||
if err != nil {
|
||||
return web.Error(http.StatusBadRequest, err, nil)
|
||||
}
|
||||
|
||||
result, err := db.Put("items", item)
|
||||
if err != nil {
|
||||
return web.Error(http.StatusInternalServerError, err, nil)
|
||||
}
|
||||
@@ -56,7 +115,7 @@ func GetItemByID(r *http.Request) *web.Response {
|
||||
return web.HTML(
|
||||
http.StatusOK,
|
||||
html,
|
||||
"item-by-id.html",
|
||||
"entity-row.html",
|
||||
result,
|
||||
nil,
|
||||
)
|
||||
|
||||
@@ -5,4 +5,14 @@
|
||||
<td class="whitespace-nowrap px-6 py-4">{{.Category}}</td>
|
||||
<td class="whitespace-nowrap px-6 py-4">{{.Description}}</td>
|
||||
<td class="whitespace-nowrap px-6 py-4">{{.Notes}}</td>
|
||||
<td class="whitespace-nowrap px-6 py-4">
|
||||
<button
|
||||
hx-get="/items/{{.ID}}"
|
||||
hx-params="edit=true"
|
||||
hx-target="#datarow-{{.ID}}"
|
||||
hx-swap="outerHTML"
|
||||
class="inline-flex items-center h-8 px-4 m-2 text-sm text-blue-100 transition-colors duration-150 bg-blue-700 rounded-lg focus:shadow-outline hover:bg-blue-800"
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
</tr>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<script src="https://unpkg.com/htmx.org@1.9.2"></script>
|
||||
<link href="/css/output.css" rel="stylesheet" />
|
||||
<title>Go + HTMX + Tailwind</title>
|
||||
<title>Mikayla's Move Manager</title>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
@@ -34,7 +34,9 @@
|
||||
</nav>
|
||||
|
||||
<br/>
|
||||
|
||||
<span class="text-xl">Items</span>
|
||||
|
||||
<div id="home-page-container">
|
||||
{{ template "entity-list.html" . }}
|
||||
</div>
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
type="text"
|
||||
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
|
||||
data-include-edit="{{.ID}}"
|
||||
name="company"
|
||||
value="{{.Company}}"
|
||||
name="Name"
|
||||
value="{{.Name}}"
|
||||
/>
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-6 py-4">
|
||||
@@ -14,8 +14,8 @@
|
||||
type="text"
|
||||
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
|
||||
data-include-edit="{{.ID}}"
|
||||
name="contact"
|
||||
value="{{.Contact}}"
|
||||
name="stage"
|
||||
value="{{.Stage}}"
|
||||
/>
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-6 py-4">
|
||||
@@ -23,13 +23,31 @@
|
||||
type="text"
|
||||
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
|
||||
data-include-edit="{{.ID}}"
|
||||
name="country"
|
||||
value="{{.Country}}"
|
||||
name="Category"
|
||||
value="{{.Category}}"
|
||||
/>
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-6 py-4">
|
||||
<input
|
||||
type="text"
|
||||
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
|
||||
data-include-edit="{{.ID}}"
|
||||
name="Description"
|
||||
value="{{.Description}}"
|
||||
/>
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-6 py-4">
|
||||
<input
|
||||
type="text"
|
||||
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
|
||||
data-include-edit="{{.ID}}"
|
||||
name="Notes"
|
||||
value="{{.Notes}}"
|
||||
/>
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-1 py-1">
|
||||
<a
|
||||
hx-put="/company/{{.ID}}"
|
||||
hx-put="/items/{{.ID}}"
|
||||
hx-target="#datarow-{{.ID}}"
|
||||
hx-swap="outerHTML"
|
||||
hx-indicator="#processing"
|
||||
@@ -41,7 +59,8 @@
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-1 py-1">
|
||||
<a
|
||||
hx-get="/company/{{.ID}}"
|
||||
hx-get="/items/{{.ID}}"
|
||||
hx-params="edit=false"
|
||||
hx-target="#datarow-{{.ID}}"
|
||||
hx-swap="outerHTML"
|
||||
hx-indicator="#processing"
|
||||
|
||||
15
util/main.go
Normal file
15
util/main.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func GetIDFromPath(r *http.Request) (id int, err error) {
|
||||
path := r.URL.Path
|
||||
segments := strings.Split(path, "/")
|
||||
last := segments[len(segments)-1]
|
||||
id, err = strconv.Atoi(last)
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user