Create datatables.go
This commit is contained in:
parent
2be29595e4
commit
8098e07b65
170
datatables.go
Normal file
170
datatables.go
Normal file
@ -0,0 +1,170 @@
|
||||
// This package parse a http request from datatables (jQuery plugin) to a friendly structure
|
||||
// More details in https://github.com/saulortega/datatables
|
||||
// import "github.com/saulortega/datatables"
|
||||
|
||||
package datatables
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Column struct {
|
||||
Data string
|
||||
Name string
|
||||
Index int
|
||||
Orderable bool
|
||||
Searchable bool
|
||||
SearchValue string
|
||||
SearchRegex bool
|
||||
}
|
||||
|
||||
type Order struct {
|
||||
Column Column
|
||||
Dir string
|
||||
}
|
||||
|
||||
type Filter struct {
|
||||
Draw int
|
||||
Start int
|
||||
Length int
|
||||
Order []Order
|
||||
Columns []Column
|
||||
SearchValue string
|
||||
SearchRegex bool
|
||||
}
|
||||
|
||||
func Parse(r *http.Request) (Filter, error) {
|
||||
return parse(r)
|
||||
}
|
||||
|
||||
func MustParse(r *http.Request) Filter {
|
||||
f, err := parse(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func parse(r *http.Request) (Filter, error) {
|
||||
var E error
|
||||
var F = Filter{
|
||||
Order: []Order{},
|
||||
Columns: []Column{},
|
||||
}
|
||||
|
||||
var errores = []string{}
|
||||
var mapColsTmp = make(map[int]map[string]string)
|
||||
var mapOrdsTmp = make(map[int]map[string]string)
|
||||
|
||||
for ll, v := range r.Form {
|
||||
if regexp.MustCompile(`^columns\[`).MatchString(ll) {
|
||||
a := regexp.MustCompile(`^columns\[([0-9]+)\]\[`).ReplaceAllString(ll, "$1-")
|
||||
a = regexp.MustCompile(`search\]\[(value|regex)`).ReplaceAllString(a, "search$1")
|
||||
a = regexp.MustCompile(`\]$`).ReplaceAllString(a, "")
|
||||
p := strings.Split(a, "-")
|
||||
i, er := strconv.Atoi(p[0])
|
||||
if er != nil {
|
||||
errores = append(errores, er.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := mapColsTmp[i]; !ok {
|
||||
mapColsTmp[i] = make(map[string]string)
|
||||
}
|
||||
mapColsTmp[i][p[1]] = v[0]
|
||||
} else if regexp.MustCompile(`^order\[`).MatchString(ll) {
|
||||
a := regexp.MustCompile(`^order\[([0-9]+)\]\[`).ReplaceAllString(ll, "$1-")
|
||||
a = regexp.MustCompile(`\]$`).ReplaceAllString(a, "")
|
||||
p := strings.Split(a, "-")
|
||||
i, er := strconv.Atoi(p[0])
|
||||
if er != nil {
|
||||
errores = append(errores, er.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := mapOrdsTmp[i]; !ok {
|
||||
mapOrdsTmp[i] = make(map[string]string)
|
||||
}
|
||||
mapOrdsTmp[i][p[1]] = v[0]
|
||||
} else if ll == "search[value]" {
|
||||
F.SearchValue = strings.TrimSpace(v[0])
|
||||
} else if ll == "search[regex]" {
|
||||
F.SearchRegex, E = strconv.ParseBool(v[0])
|
||||
if E != nil {
|
||||
errores = append(errores, E.Error())
|
||||
}
|
||||
} else if ll == "start" {
|
||||
F.Start, E = strconv.Atoi(v[0])
|
||||
if E != nil {
|
||||
errores = append(errores, E.Error())
|
||||
}
|
||||
} else if ll == "length" {
|
||||
F.Length, E = strconv.Atoi(v[0])
|
||||
if E != nil {
|
||||
errores = append(errores, E.Error())
|
||||
}
|
||||
} else if ll == "draw" {
|
||||
F.Draw, E = strconv.Atoi(v[0])
|
||||
if E != nil {
|
||||
errores = append(errores, E.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < len(mapColsTmp); i++ {
|
||||
c := Column{Index: i}
|
||||
c.Data = strings.TrimSpace(mapColsTmp[i]["data"])
|
||||
c.Name = strings.TrimSpace(mapColsTmp[i]["name"])
|
||||
c.Orderable, E = strconv.ParseBool(mapColsTmp[i]["orderable"])
|
||||
if E != nil {
|
||||
errores = append(errores, E.Error())
|
||||
}
|
||||
c.Searchable, E = strconv.ParseBool(mapColsTmp[i]["searchable"])
|
||||
if E != nil {
|
||||
errores = append(errores, E.Error())
|
||||
}
|
||||
c.SearchValue = strings.TrimSpace(mapColsTmp[i]["searchvalue"])
|
||||
c.SearchRegex, E = strconv.ParseBool(mapColsTmp[i]["searchregex"])
|
||||
if E != nil {
|
||||
errores = append(errores, E.Error())
|
||||
}
|
||||
F.Columns = append(F.Columns, c)
|
||||
}
|
||||
|
||||
for i := 0; i < len(mapOrdsTmp); i++ {
|
||||
dir := strings.ToUpper(mapOrdsTmp[i]["dir"])
|
||||
ic, er := strconv.Atoi(mapOrdsTmp[i]["column"])
|
||||
if er != nil || (dir != "ASC" && dir != "DESC") {
|
||||
if er != nil {
|
||||
errores = append(errores, er.Error())
|
||||
} else {
|
||||
errores = append(errores, "dir invalid: «"+dir+"»")
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
o := Order{Dir: dir}
|
||||
for _, c := range F.Columns {
|
||||
if c.Index == ic {
|
||||
o.Column = c
|
||||
break
|
||||
}
|
||||
}
|
||||
if o.Column == (Column{}) {
|
||||
errores = append(errores, "column with index "+strconv.Itoa(ic)+" not found")
|
||||
continue
|
||||
}
|
||||
|
||||
F.Order = append(F.Order, o)
|
||||
}
|
||||
|
||||
if len(errores) > 0 {
|
||||
E = errors.New(strings.Join(errores, "; "))
|
||||
}
|
||||
|
||||
return F, E
|
||||
}
|
Loading…
Reference in New Issue
Block a user