Fields
Customize visible fields
By default all fields are visible if you specifically declare fields, only defined fields will be visible and they will be presented in the order defined:
// Add resources `Order`, `Product` to Admin:
order := Admin.AddResource(&models.Order{})
product := Admin.AddResource(&models.Product{})
// show given attributes
order.IndexAttrs("User", "PaymentAmount", "ShippedAt", "CancelledAt", "State", "ShippingAddress")
// show all attributes except `State`
order.IndexAttrs("-State")
// Set attributes will be shown in the new page
order.NewAttrs("User", "PaymentAmount", "ShippedAt", "CancelledAt", "State", "ShippingAddress")
// show all attributes except `State`
order.NewAttrs("-State")
// Structure the new form to make it tidy and clean with `Section`
product.NewAttrs(
&admin.Section{
Title: "Basic Information",
Rows: [][]string{
{"Name"},
{"Code", "Price"},
}
},
&admin.Section{
Title: "Organization",
Rows: [][]string{
{"Category", "Collections", "MadeCountry"},
}
},
"Description",
"ColorVariations",
}
// Set attributes will be shown for the edit page, similar to new page
order.EditAttrs("User", "PaymentAmount", "ShippedAt", "CancelledAt", "State", "ShippingAddress")
// Set attributes will be shown for the show page, similar to new page
// If ShowAttrs haven't been configured, there will be no show page generated, by will show the edit form instead
order.ShowAttrs("User", "PaymentAmount", "ShippedAt", "CancelledAt", "State", "ShippingAddress")
Customize fields for nested resources
order := Admin.AddResource(&models.Order{})
orderItemMeta := order.Meta(&admin.Meta{Name: "OrderItems"})
orderItemResource := orderItemMeta.Resource
orderItemResource.EditAttrs("ProductCode", "Price", "Quantity")
Meta
By default, resource's fields are rendered based on its types and relations. The default should satisfy the usual cases, you can customize the rendering by overwriting the Meta
definition.
There are some Meta
types that have been predefined, including string
, password
, date
, datetime
, rich_editor
, select_one
, select_many
and so on (see full list below).
QOR Admin will auto select a type for Meta
based on a field's data type. For example, if a field's type is time.Time
, QOR Admin will determine datetime
as the type.
Here's an example about make "Gender" of a user as a select element in the user form that includes three options "Male", "Female" and "Unknown".
user.Meta(&admin.Meta{Name: "Gender", Config: &admin.SelectOneConfig{Collection: []string{"Male", "Female", "Unknown"}}})
Customize Meta
If default configuration of a field doesn't match your needs, you would like to customize the field, here are possible options:
type Meta struct {
Name string
FieldName string
Label string
Type string
Setter func(object interface{}, metaValue *resource.MetaValue, context *qor.Context)
Valuer func(object interface{}, context *qor.Context) (value interface{})
FormattedValuer func(object interface{}, context *qor.Context) (formattedValue interface{})
Permission *roles.Permission
Config MetaConfigInterface
Collection interface{}
Resource *Resource
}
Name
The name of the field's name that you would like to overwrite
// Overwrite field `Gender`, change it to select with three options from default input box user.Meta(&admin.Meta{Name: "Gender", Config: &admin.SelectOneConfig{Collection: []string{"Male", "Female", "Unknown"}}})
FieldName
Mapping to the attribute name in the resource, Usually, This is no need to set and same with
Name
by default.This is usually needed when you want to use QOR Admin as RESTFul API Service and expose fields with a different name, e.g:
// Generate JSON { "Code": "value-of-ExternalCode", ... } order.Meta(&admin.Meta{Name: "Code", FieldName: "ExternalCode"})
Type
The display type of the attribute, e.g.
select_one
,password
. see full list of predefined meta typesLabel
The label of the attribute in the form and the table title for the index page.
The default label of "address" is "Address". You can set another label for "address" by this option.
Setter
// Setter's type func(record interface{}, metaValue *resource.MetaValue, context *qor.Context)
Setter
defined how to decode a form value into the field, the defaultSetter
generated by QOR Admin, it gets form value frommetaValue
and decodes that value torecord
based on field's type.-
// Value's type func(record interface{}, context *qor.Context) (result interface{})
Valuer
defined how to fetch field's value fromobject
, it returns a golang object as result, QOR usually will render field's template differently based on its value and state. FormattedValuer
// FormattedValuer's type func(record interface{}, context *qor.Context) (result interface{})
FormattedValuer
is similar likeValuer
, but it usually returns formatted string as result, it will be shown to end user in index page and API.Resource
This could be used to customize attributes in nested form, usually, this is no need to set, check How to customize attribute in nested form for detail.
Permission
Define user authority of this attribute, Check Authentication for detail.
Config
The configuration of current type of attribute, e.g.
Config: &admin.SelectOneConfig{Collection: []string{"Male", "Female", "Unknown"}}
. Check each meta's document for detail.
Virtual Field
You can configure QOR Admin to display "virtual" fields - fields that are not database attributes. Just define them as Meta
to your resource, to define it for a virtual field, Valuer
is must be required (refer Customize Meta), so QOR Admin knows how to display it to end user.
product.Meta(&admin.Meta{Name: "MainImageURL", Valuer: func(record interface{}, context *qor.Context) interface{} {
if p, ok := record.(*models.Product); ok && len(p.Images) > 0 {
return p.Images[0].URL
}
return ""
}})
If you want to use the virtual field in NewAttrs
, EditAttrs
, ShowAttrs
, you have to:
Define meta's
Type
Then QOR Admin knows which template to use when rendering it
Define meta's
Setter
Then QOR Admin knows how to save form's value
e.g:
user.Meta(&admin.Meta{Name: "Password",
Type: "password",
Valuer: func(interface{}, *qor.Context) interface{} { return "" },
Setter: func(record interface{}, metaValue *resource.MetaValue, context *qor.Context) {
if newPassword := utils.ToString(metaValue.Value); newPassword != "" {
bcryptPassword, _ := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
record.(*models.User).EncryptedPassword = string(bcryptPassword)
}
},
})