ui add for filter and search, start of backend for filter

This commit is contained in:
Dan Ballard 2016-01-10 20:01:34 -08:00
parent 9476bf1e74
commit fdb8f8fa76
8 changed files with 82 additions and 51 deletions

View File

@ -15,11 +15,14 @@ type Category struct {
Children []*Category Children []*Category
} }
var CategoriesTree []*Category var CategoriesTree []*Category = nil
var CategoriesFlat map[int]*Category var CategoriesFlat map[int]*Category = nil
// Cavet: slight cheat. All parents must have Category_id < their children. // Cavet: slight cheat. All parents must have Category_id < their children.
func LoadCategories(db *sql.DB) { func LoadCategories(db *sql.DB) {
if CategoriesFlat != nil {
return //already loaded
}
CategoriesTree = []*Category{} CategoriesTree = []*Category{}
CategoriesFlat = make(map[int]*Category) CategoriesFlat = make(map[int]*Category)
@ -99,6 +102,14 @@ func Delete(db *sql.DB, id int) error {
return err return err
} }
func GetListOfChildrenIds(id int) []int {
list := []int{id}
for _,category := range CategoriesFlat[id].Children {
list = append(list, GetListOfChildrenIds(category.Id)...)
}
return list
}
func (category *Category) ChangeParent(db *sql.DB, parent *Category) error { func (category *Category) ChangeParent(db *sql.DB, parent *Category) error {
var err error var err error
if parent == nil { if parent == nil {

View File

@ -21,8 +21,12 @@ $(document).ready( function () {
$(".add-category-col").addClass("has-error"); $(".add-category-col").addClass("has-error");
} }
}); });
$("form.search .filter-category").change(function (e) {
e.target.parentElement.submit();
});
$(".category-change-parent").change(function (e) { $("form.change-parent .category-change-parent").change(function (e) {
e.target.parentElement.submit(); e.target.parentElement.submit();
}); });

View File

@ -94,10 +94,14 @@ func Get(db *sql.DB, id int) (*News, error) {
} }
// Load and return in NewsContainer format all the unexported news items // Load and return in NewsContainer format all the unexported news items
func LoadPage(db *sql.DB, offset, amount int) ([]*News, int, error) { func LoadPage(db *sql.DB, offset, amount int, categoryFilter []int) ([]*News, int, error) {
categories.LoadCategories(db) // required by addContainer categories.LoadCategories(db) // required by addContainer
rows, err := db.Query("SELECT " + SQL_NEWS_FIELDS + " FROM news ORDER BY timestamp DESC LIMIT $1 OFFSET $2", amount, offset) where := ""
if categoryFilter != nil {
where = "WHERE id in $3"
}
rows, err := db.Query("SELECT " + SQL_NEWS_FIELDS + " FROM news " + where + " ORDER BY timestamp DESC LIMIT $1 OFFSET $2", amount, offset, categoryFilter)
if err != nil { if err != nil {
fmt.Println("DB errpr reading LoadPage news: ", err) fmt.Println("DB errpr reading LoadPage news: ", err)
return nil, 0, err return nil, 0, err

View File

@ -405,6 +405,7 @@ func categoryDeleteHandler(w http.ResponseWriter, r *http.Request, user *user.Us
func newsFormHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) { func newsFormHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
flashes := GetFlashes(session) flashes := GetFlashes(session)
session.Save(r, w) session.Save(r, w)
categories.LoadCategories(db)
var offset = 0 var offset = 0
var amount = 100 var amount = 100
@ -412,8 +413,14 @@ func newsFormHandler(w http.ResponseWriter, r *http.Request, user *user.User, se
if eOffset == nil { if eOffset == nil {
offset = amount * argOffset offset = amount * argOffset
} }
categoryFilterId, cidErr := strconv.Atoi(r.FormValue("category"))
categoryFilter := []int{}
if cidErr == nil {
categories.GetListOfChildrenIds(categoryFilterId)
}
news, count, err := news.LoadPage(db, offset, amount) news, count, err := news.LoadPage(db, offset, amount, categoryFilter)
if err != nil { if err != nil {
session.AddFlash("Error loading news", flash_err) session.AddFlash("Error loading news", flash_err)
} }

View File

@ -80,3 +80,32 @@
{{end}} {{end}}
</div> </div>
{{end}} {{end}}
<!-- reused widgets -->
<!--
Print a full <select> of categories with one selected
categories: a flat map of categories ordered by parent
id: the category id that should be selected (or -1 for none)
fieldName: the html form field name
-->
{{define "select-category"}}
<select class="form-control add-category category-change-parent filter-category" name="{{ .fieldName }}" >
<option value="none" {{if not .category.Parent.Valid}} selected="true"{{end}}>-- None --</option>
{{range $category := .categories}}
{{template "option-category" dict "category" $category "id" $.id}}
{{end}}
</select>
{{end}}
<!--
print all the <option> inside a select for a category and its children
category: the category to print as an option (and it's nested children)
id: the category id that should be selected
-->
{{define "option-category"}}
<option value="{{.category.Id}}" {{if eq .id .category.Id}}selected="true"{{end}}>{{.category.ToString}}</option>
{{range $child := .category.Children}}
{{template "option-category" dict "category" $child "id" $.id}}
{{end}}
{{end}}

View File

@ -6,12 +6,12 @@
{{end}} {{end}}
<div class="row"> <div class="row">
<form method="POST" action="/categories/add"> <form method="POST" action="/categories/add" class="add-category">
<div class="col-xs-3"> <div class="col-xs-3">
<input name="name" class="form-control" placeholder="Name" /> <input name="name" class="form-control" placeholder="Name" />
</div> </div>
<div class="col-xs-3"> <div class="col-xs-3">
{{template "select-category" dict "categories" .categories "id" -1}} {{template "select-category" dict "categories" .categories "id" -1 "fieldName" "parent"}}
</div> </div>
<div class="col-xs-2"> <div class="col-xs-2">
{{ .csrfField }} {{ .csrfField }}
@ -39,12 +39,13 @@ new category select
</form> </form>
</div> </div>
<div class="col-xs-3"> <div class="col-xs-3">
<form action="/categories/{{.category.Id}}/change-parent" method="POST"> <form action="/categories/{{.category.Id}}/change-parent" method="POST" class="change-parent">
{{ .csrfField }} {{ .csrfField }}
<!-- select-category defined in layout -->
{{if $.category.Parent.Valid }} {{if $.category.Parent.Valid }}
{{template "select-category" dict "categories" .categories "id" $.category.Parent.Value}} {{template "select-category" dict "categories" .categories "id" $.category.Parent.Value "fieldName" "parent"}}
{{else}} {{else}}
{{template "select-category" dict "categories" .categories "id" -1}} {{template "select-category" dict "categories" .categories "id" -1 "fieldName" "parent"}}
{{end}} {{end}}
</form> </form>
</div> </div>
@ -55,28 +56,3 @@ new category select
{{end}} {{end}}
{{end}} {{end}}
<!--
Print a full <select> of categories with one selected
categories: a flat map of categories ordered by parent
id: the category id that should be selected (or -1 for none)
-->
{{define "select-category"}}
<select class="form-control category-change-parent" name="parent" >
<option value="none" {{if not .category.Parent.Valid}} selected="true"{{end}}>-- None --</option>
{{range $category := .categories}}
{{template "option-category" dict "category" $category "id" $.id}}
{{end}}
</select>
{{end}}
<!--
print all the <option> inside a select for a category and its children
category: the category to print as an option (and it's nested children)
id: the category id that should be selected
-->
{{define "option-category"}}
<option value="{{.category.Id}}" {{if eq .id .category.Id}}selected="true"{{end}}>{{.category.ToString}}</option>
{{range $child := .category.Children}}
{{template "option-category" dict "category" $child "id" $.id}}
{{end}}
{{end}}

View File

@ -10,6 +10,19 @@
Drag this bookmarklet to bookmark bar and click anywhere to add a link Drag this bookmarklet to bookmark bar and click anywhere to add a link
</div> </div>
<div class="col-xs-4"></div> <div class="col-xs-4"></div>
<div class="col-xs-12">&nbsp;</div>
<form method="GET" class="search" />
<input type="hidden" name="offset" value="{{.offset}}" />
<div class="col-xs-2">Filter by Category:</div>
<div class="col-xs-3">
{{template "select-category" dict "categories" .categories "id" -1 "fieldName" "category"}}
</div>
<div class="col-xs-1">&nbsp;</div>
<div class="col-xs-4"><input name="search" class="form-control" placeholder="Search title" /></div>
<div class="col-xs-2">&nbsp;</div>
</form>
{{template "pager" .}} {{template "pager" .}}

View File

@ -7,24 +7,11 @@
<div class="col-xs-2">Link:</div><div class="col-xs-10"><input type="text" class="form-control" name="link" placeholder="Link" value="{{.link}}"/></div> <div class="col-xs-2">Link:</div><div class="col-xs-10"><input type="text" class="form-control" name="link" placeholder="Link" value="{{.link}}"/></div>
<div class="col-xs-2">Title:</div><div class="col-xs-10"><input type="text" class="form-control" name="title" placeholder="Title" value="{{.title}}"/></div> <div class="col-xs-2">Title:</div><div class="col-xs-10"><input type="text" class="form-control" name="title" placeholder="Title" value="{{.title}}"/></div>
<div class="col-xs-2">Category:</div><div class="col-xs-10 add-category-col"> <div class="col-xs-2">Category:</div><div class="col-xs-10 add-category-col">
<select class="form-control add-category" name="category" placeholder="Category"> {{template "select-category" dict "categories" .categories "id" $.category_id "fieldName" "category"}}
<option value="-1">-- Pick a Category --</option>
{{range $category := .categories}}
{{template "option-category" dict "category" $category "category_id" $.category_id}}
{{end}}
</select>
</div> </div>
<div class="col-xs-2">Notes:</div><div class="col-xs-10"><textarea class="form-control" name="notes" placeholder="Notes" rows="5" cols="80">{{.notes}}</textarea></div> <div class="col-xs-2">Notes:</div><div class="col-xs-10"><textarea class="form-control" name="notes" placeholder="Notes" rows="5" cols="80">{{.notes}}</textarea></div>
<div class="col-xs-2"></div><div class="col-xs-10">{{ .csrfField }}<input class="add-submit btn btn-lg btn-primary btn-block" type="submit" value="{{if eq .mode "add"}}Add Link{{else}}Commit Edit{{end}}" /></div> <div class="col-xs-2"></div><div class="col-xs-10">{{ .csrfField }}<input class="add-submit btn btn-lg btn-primary btn-block" type="submit" value="{{if eq .mode "add"}}Add Link{{else}}Commit Edit{{end}}" /></div>
</div> </div>
</form> </form>
{{end}}
{{define "option-category"}}
<option value="{{.category.Id}}" {{if eq .category.Id .category_id}}selected="true"{{end}} >{{.category.ToString}}</option>
{{range $child := .category.Children}}
{{template "option-category" dict "category" $child "category_id" $.category_id}}
{{end}}
{{end}} {{end}}