Browse Source

Builder, data table

Vova Tkach 6 years ago
parent
commit
c752ed1d53
3 changed files with 148 additions and 3 deletions
  1. 0 3
      engine/builder/builder.go
  2. 125 0
      engine/builder/data_table.go
  3. 23 0
      modules/module_users.go

+ 0 - 3
engine/builder/builder.go

@@ -1,4 +1 @@
 package builder
 package builder
-
-// TODO: Return table builder
-// TODO: Return forms builder

+ 125 - 0
engine/builder/data_table.go

@@ -0,0 +1,125 @@
+package builder
+
+import (
+	"fmt"
+	"html"
+	"math"
+	"strconv"
+
+	"golang-fave/engine/wrapper"
+)
+
+type DataTableRow struct {
+	DBField     string
+	NameInTable string
+	CallBack    func(values *[]string) string
+}
+
+func DataTable(wrap *wrapper.Wrapper, table string, order_by string, order_way string, data []DataTableRow, action func(values *[]string) string, pagination_url string) string {
+	var num int
+	err := wrap.DB.QueryRow("SELECT COUNT(*) FROM `" + table + "`;").Scan(&num)
+	if err != nil {
+		return ""
+	}
+	pear_page := 10
+	max_pages := int(math.Ceil(float64(num) / float64(pear_page)))
+	curr_page := 1
+	p := wrap.R.URL.Query().Get("p")
+	if p != "" {
+		pi, err := strconv.Atoi(p)
+		if err != nil {
+			curr_page = 1
+		} else {
+			if pi < 1 {
+				curr_page = 1
+			} else if pi > max_pages {
+				curr_page = max_pages
+			} else {
+				curr_page = pi
+			}
+		}
+	}
+	limit_offset := curr_page*pear_page - pear_page
+	result := `<table class="table data-table table-striped table-bordered table-hover table_` + table + `">`
+	result += `<thead>`
+	result += `<tr>`
+	sql := "SELECT"
+	for i, column := range data {
+		if column.NameInTable != "" {
+			result += `<th scope="col" class="col_` + column.DBField + `">` + html.EscapeString(column.NameInTable) + `</th>`
+		}
+		sql += " `" + column.DBField + "`"
+		if i+1 < len(data) {
+			sql += ","
+		}
+	}
+	sql += " FROM `" + table + "` ORDER BY `" + order_by + "` " + order_way + " LIMIT ?, ?;"
+	if action != nil {
+		result += `<th scope="col" class="col_action">&nbsp;</th>`
+	}
+	result += `</tr>`
+	result += `</thead>`
+	result += `<tbody>`
+	rows, err := wrap.DB.Query(sql, limit_offset, pear_page)
+	if err == nil {
+		values := make([]string, len(data))
+		scan := make([]interface{}, len(values))
+		for i := range values {
+			scan[i] = &values[i]
+		}
+		for rows.Next() {
+			err = rows.Scan(scan...)
+			if err == nil {
+				result += `<tr>`
+				for i, val := range values {
+					if data[i].NameInTable != "" {
+						if data[i].CallBack == nil {
+							result += `<td class="col_` + data[i].DBField + `">` + html.EscapeString(string(val)) + `</td>`
+						} else {
+							result += `<td class="col_` + data[i].DBField + `">` + data[i].CallBack(&values) + `</td>`
+						}
+					}
+				}
+				if action != nil {
+					result += `<td class="col_action">` + action(&values) + `</td>`
+				}
+				result += `</tr>`
+			}
+		}
+	}
+	result += `</tbody></table>`
+	result += `<nav>`
+	result += `<ul class="pagination" style="margin-bottom:0px;">`
+	class := ""
+	if curr_page <= 1 {
+		class = " disabled"
+	}
+	result += `<li class="page-item` + class + `">`
+	result += `<a class="page-link" href="` + pagination_url + `?p=` + fmt.Sprintf("%d", curr_page-1) + `" aria-label="Previous">`
+	result += `<span aria-hidden="true">&laquo;</span>`
+	result += `<span class="sr-only">Previous</span>`
+	result += `</a>`
+	result += `</li>`
+	for i := 1; i <= max_pages; i++ {
+		class = ""
+		if i == curr_page {
+			class = " active"
+		}
+		result += `<li class="page-item` + class + `">`
+		result += `<a class="page-link" href="` + pagination_url + `?p=` + fmt.Sprintf("%d", i) + `">` + fmt.Sprintf("%d", i) + `</a>`
+		result += `</li>`
+	}
+	class = ""
+	if curr_page >= max_pages {
+		class = " disabled"
+	}
+	result += `<li class="page-item` + class + `">`
+	result += `<a class="page-link" href="` + pagination_url + `?p=` + fmt.Sprintf("%d", curr_page+1) + `" aria-label="Next">`
+	result += `<span aria-hidden="true">&raquo;</span>`
+	result += `<span class="sr-only">Next</span>`
+	result += `</a>`
+	result += `</li>`
+	result += `</ul>`
+	result += `</nav>`
+	return result
+}

+ 23 - 0
modules/module_users.go

@@ -1,8 +1,11 @@
 package modules
 package modules
 
 
 import (
 import (
+	"html"
+
 	"golang-fave/assets"
 	"golang-fave/assets"
 	"golang-fave/consts"
 	"golang-fave/consts"
+	"golang-fave/engine/builder"
 	"golang-fave/engine/wrapper"
 	"golang-fave/engine/wrapper"
 )
 )
 
 
@@ -25,6 +28,26 @@ func (this *Modules) RegisterModule_Users() *Module {
 			content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
 			content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
 				{Name: "List of Users"},
 				{Name: "List of Users"},
 			})
 			})
+			content += builder.DataTable(wrap, "users", "email", "ASC", []builder.DataTableRow{
+				{DBField: "id", NameInTable: "", CallBack: nil},
+				{DBField: "email", NameInTable: "Email", CallBack: func(values *[]string) string {
+					email := `<a href="/cp/users/modify/` + (*values)[0] + `/">` + html.EscapeString((*values)[1]) + `</a>`
+					name := html.EscapeString((*values)[2])
+					if name != "" && (*values)[3] != "" {
+						name += ` ` + (*values)[3]
+					}
+					if name != "" {
+						name = `<div><small>` + name + `</small></div>`
+					}
+					return `<div>` + email + `</div>` + name
+				}},
+				{DBField: "first_name", NameInTable: "", CallBack: nil},
+				{DBField: "last_name", NameInTable: "", CallBack: nil},
+			}, func(values *[]string) string {
+				return `<a class="ico" href="/cp/users/modify/` + (*values)[0] + `/">` +
+					assets.SysSvgIconEdit + `</a>` +
+					`<a class="ico" href="#">` + assets.SysSvgIconRemove + `</a>`
+			}, "/cp/users/default/")
 		} else if wrap.CurrSubModule == "add" {
 		} else if wrap.CurrSubModule == "add" {
 			content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
 			content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
 				{Name: "Add New User"},
 				{Name: "Add New User"},